edea2359b3db6c9ee24d4e08b94f2214e768756c
[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_OF(X509_ALGOR) *cap)
18 {
19         ASN1_STRING *seq;
20         unsigned char *p, *pp;
21         int len;
22         len=i2d_ASN1_SET_OF_X509_ALGOR(cap,NULL,i2d_X509_ALGOR,
23                                        V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL,
24                                        IS_SEQUENCE);
25         if(!(pp=(unsigned char *)Malloc(len))) {
26                 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
27                 return 0;
28         }
29         p=pp;
30         i2d_ASN1_SET_OF_X509_ALGOR(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
31                                    V_ASN1_UNIVERSAL, IS_SEQUENCE);
32         if(!(seq = ASN1_STRING_new())) {
33                 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
34                 return 0;
35         }
36         if(!ASN1_STRING_set (seq, pp, len)) {
37                 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
38                 return 0;
39         }
40         Free (pp);
41         return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
42                                                         V_ASN1_SEQUENCE, seq);
43 }
44
45 STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
46 {
47         ASN1_TYPE *cap;
48         unsigned char *p;
49         cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
50         if (!cap) return NULL;
51         p = cap->value.sequence->data;
52         return d2i_ASN1_SET (NULL, &p, cap->value.sequence->length, 
53                 (char *(*)())d2i_X509_ALGOR, X509_ALGOR_free, V_ASN1_SEQUENCE,
54                                                          V_ASN1_UNIVERSAL);
55 }
56
57 /* Basic smime-capabilities OID and optional integer arg */
58 int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
59 {
60         X509_ALGOR *alg;
61
62         if(!(alg = X509_ALGOR_new())) {
63                 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
64                 return 0;
65         }
66         ASN1_OBJECT_free(alg->algorithm);
67         alg->algorithm = OBJ_nid2obj (nid);
68         if (arg > 0) {
69                 ASN1_INTEGER *nbit;
70                 if(!(alg->parameter = ASN1_TYPE_new())) {
71                         PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
72                         return 0;
73                 }
74                 if(!(nbit = ASN1_INTEGER_new())) {
75                         PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
76                         return 0;
77                 }
78                 if(!ASN1_INTEGER_set (nbit, arg)) {
79                         PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
80                         return 0;
81                 }
82                 alg->parameter->value.integer = nbit;
83                 alg->parameter->type = V_ASN1_INTEGER;
84         }
85         sk_X509_ALGOR_push (sk, alg);
86         return 1;
87 }