Various S/MIME fixes. Fix for memory leak, recipient list bug
[openssl.git] / crypto / pkcs7 / pk7_attr.c
1 /* pk7_attr.c */
2 /* S/MIME code.
3  * Copyright (C) 1997-8 Dr S N Henson (shenson@bigfoot.com) 
4  * All Rights Reserved. 
5  * Redistribution of this code without the authors permission is expressly
6  * prohibited.
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <openssl/bio.h>
12 #include <openssl/asn1.h>
13 #include <openssl/pem.h>
14 #include <openssl/pkcs7.h>
15 #include <openssl/err.h>
16
17 int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap)
18 {
19         ASN1_STRING *seq;
20         unsigned char *p, *pp;
21         int len;
22         len=i2d_ASN1_SET(cap,NULL,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
23                                                 V_ASN1_UNIVERSAL, IS_SEQUENCE);
24         if(!(pp=(unsigned char *)Malloc(len))) {
25                 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
26                 return 0;
27         }
28         p=pp;
29         i2d_ASN1_SET(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
30                                                 V_ASN1_UNIVERSAL, IS_SEQUENCE);
31         if(!(seq = ASN1_STRING_new())) {
32                 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
33                 return 0;
34         }
35         if(!ASN1_STRING_set (seq, pp, len)) {
36                 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
37                 return 0;
38         }
39         Free (pp);
40         return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
41                                                         V_ASN1_SEQUENCE, seq);
42 }
43
44 STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
45 {
46         ASN1_TYPE *cap;
47         unsigned char *p;
48         cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
49         if (!cap) return NULL;
50         p = cap->value.sequence->data;
51         return d2i_ASN1_SET (NULL, &p, cap->value.sequence->length, 
52                 (char *(*)())d2i_X509_ALGOR, X509_ALGOR_free, V_ASN1_SEQUENCE,
53                                                          V_ASN1_UNIVERSAL);
54 }
55
56 /* Basic smime-capabilities OID and optional integer arg */
57 int PKCS7_simple_smimecap(STACK *sk, int nid, int arg)
58 {
59         X509_ALGOR *alg;
60         if(!(alg = X509_ALGOR_new())) {
61                 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
62                 return 0;
63         }
64         ASN1_OBJECT_free(alg->algorithm);
65         alg->algorithm = OBJ_nid2obj (nid);
66         if (arg > 0) {
67                 ASN1_INTEGER *nbit;
68                 if(!(alg->parameter = ASN1_TYPE_new())) {
69                         PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
70                         return 0;
71                 }
72                 if(!(nbit = ASN1_INTEGER_new())) {
73                         PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
74                         return 0;
75                 }
76                 if(!ASN1_INTEGER_set (nbit, arg)) {
77                         PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
78                         return 0;
79                 }
80                 alg->parameter->value.integer = nbit;
81                 alg->parameter->type = V_ASN1_INTEGER;
82         }
83         sk_push (sk, (char *)alg);
84         return 1;
85 }