Update PKCS#7 enveloped data to new API.
[openssl.git] / crypto / pkcs7 / example.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <openssl/pkcs7.h>
5 #include <openssl/asn1_mac.h>
6 #include <openssl/x509.h>
7
8 int add_signed_time(PKCS7_SIGNER_INFO *si)
9         {
10         ASN1_UTCTIME *sign_time;
11
12         /* The last parameter is the amount to add/subtract from the current
13          * time (in seconds) */
14         sign_time=X509_gmtime_adj(NULL,0);
15         PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime,
16                 V_ASN1_UTCTIME,(char *)sign_time);
17         return(1);
18         }
19
20 ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
21         {
22         ASN1_TYPE *so;
23
24         so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
25         if (so->type == V_ASN1_UTCTIME)
26             return so->value.utctime;
27         return NULL;
28         }
29         
30 static int signed_string_nid= -1;
31
32 void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
33         {
34         ASN1_OCTET_STRING *os;
35
36         /* To a an object of OID 1.2.3.4.5, which is an octet string */
37         if (signed_string_nid == -1)
38                 signed_string_nid=
39                         OBJ_create("1.2.3.4.5","OID_example","Our example OID");
40         os=ASN1_OCTET_STRING_new();
41         ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
42         /* When we add, we do not free */
43         PKCS7_add_signed_attribute(si,signed_string_nid,
44                 V_ASN1_OCTET_STRING,(char *)os);
45         }
46
47 int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
48         {
49         ASN1_TYPE *so;
50         ASN1_OCTET_STRING *os;
51         int i;
52
53         if (signed_string_nid == -1)
54                 signed_string_nid=
55                         OBJ_create("1.2.3.4.5","OID_example","Our example OID");
56         /* To retrieve */
57         so=PKCS7_get_signed_attribute(si,signed_string_nid);
58         if (so != NULL)
59                 {
60                 if (so->type == V_ASN1_OCTET_STRING)
61                         {
62                         os=so->value.octet_string;
63                         i=os->length;
64                         if ((i+1) > len)
65                                 i=len-1;
66                         memcpy(buf,os->data,i);
67                         return(i);
68                         }
69                 }
70         return(0);
71         }
72
73 static int signed_seq2string_nid= -1;
74 /* ########################################### */
75 int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
76         {
77         /* To add an object of OID 1.9.999, which is a sequence containing
78          * 2 octet strings */
79         unsigned char *p;
80         ASN1_OCTET_STRING *os1,*os2;
81         ASN1_STRING *seq;
82         unsigned char *data;
83         int i,total;
84
85         if (signed_seq2string_nid == -1)
86                 signed_seq2string_nid=
87                         OBJ_create("1.9.9999","OID_example","Our example OID");
88
89         os1=ASN1_OCTET_STRING_new();
90         os2=ASN1_OCTET_STRING_new();
91         ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
92         ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
93         i =i2d_ASN1_OCTET_STRING(os1,NULL);
94         i+=i2d_ASN1_OCTET_STRING(os2,NULL);
95         total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
96
97         data=malloc(total);
98         p=data;
99         ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
100         i2d_ASN1_OCTET_STRING(os1,&p);
101         i2d_ASN1_OCTET_STRING(os2,&p);
102
103         seq=ASN1_STRING_new();
104         ASN1_STRING_set(seq,data,total);
105         free(data);
106         ASN1_OCTET_STRING_free(os1);
107         ASN1_OCTET_STRING_free(os2);
108
109         PKCS7_add_signed_attribute(si,signed_seq2string_nid,
110                 V_ASN1_SEQUENCE,(char *)seq);
111         return(1);
112         }
113
114 /* For this case, I will malloc the return strings */
115 int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
116         {
117         ASN1_TYPE *so;
118
119         if (signed_seq2string_nid == -1)
120                 signed_seq2string_nid=
121                         OBJ_create("1.9.9999","OID_example","Our example OID");
122         /* To retrieve */
123         so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
124         if (so && (so->type == V_ASN1_SEQUENCE))
125                 {
126                 ASN1_const_CTX c;
127                 ASN1_STRING *s;
128                 long length;
129                 ASN1_OCTET_STRING *os1,*os2;
130
131                 s=so->value.sequence;
132                 c.p=ASN1_STRING_data(s);
133                 c.max=c.p+ASN1_STRING_length(s);
134                 if (!asn1_GetSequence(&c,&length)) goto err;
135                 /* Length is the length of the seqence */
136
137                 c.q=c.p;
138                 if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
139                         goto err;
140                 c.slen-=(c.p-c.q);
141
142                 c.q=c.p;
143                 if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
144                         goto err;
145                 c.slen-=(c.p-c.q);
146
147                 if (!asn1_const_Finish(&c)) goto err;
148                 *str1=malloc(os1->length+1);
149                 *str2=malloc(os2->length+1);
150                 memcpy(*str1,os1->data,os1->length);
151                 memcpy(*str2,os2->data,os2->length);
152                 (*str1)[os1->length]='\0';
153                 (*str2)[os2->length]='\0';
154                 ASN1_OCTET_STRING_free(os1);
155                 ASN1_OCTET_STRING_free(os2);
156                 return(1);
157                 }
158 err:
159         return(0);
160         }
161
162
163 /* #######################################
164  * THE OTHER WAY TO DO THINGS
165  * #######################################
166  */
167 X509_ATTRIBUTE *create_time(void)
168         {
169         ASN1_UTCTIME *sign_time;
170         X509_ATTRIBUTE *ret;
171
172         /* The last parameter is the amount to add/subtract from the current
173          * time (in seconds) */
174         sign_time=X509_gmtime_adj(NULL,0);
175         ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime,
176                 V_ASN1_UTCTIME,(char *)sign_time);
177         return(ret);
178         }
179
180 ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk)
181         {
182         ASN1_TYPE *so;
183         PKCS7_SIGNER_INFO si;
184
185         si.auth_attr=sk;
186         so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
187         if (so->type == V_ASN1_UTCTIME)
188             return so->value.utctime;
189         return NULL;
190         }
191         
192 X509_ATTRIBUTE *create_string(char *str)
193         {
194         ASN1_OCTET_STRING *os;
195         X509_ATTRIBUTE *ret;
196
197         /* To a an object of OID 1.2.3.4.5, which is an octet string */
198         if (signed_string_nid == -1)
199                 signed_string_nid=
200                         OBJ_create("1.2.3.4.5","OID_example","Our example OID");
201         os=ASN1_OCTET_STRING_new();
202         ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
203         /* When we add, we do not free */
204         ret=X509_ATTRIBUTE_create(signed_string_nid,
205                 V_ASN1_OCTET_STRING,(char *)os);
206         return(ret);
207         }
208
209 int sk_get_string(STACK_OF(X509_ATTRIBUTE) *sk, char *buf, int len)
210         {
211         ASN1_TYPE *so;
212         ASN1_OCTET_STRING *os;
213         int i;
214         PKCS7_SIGNER_INFO si;
215
216         si.auth_attr=sk;
217
218         if (signed_string_nid == -1)
219                 signed_string_nid=
220                         OBJ_create("1.2.3.4.5","OID_example","Our example OID");
221         /* To retrieve */
222         so=PKCS7_get_signed_attribute(&si,signed_string_nid);
223         if (so != NULL)
224                 {
225                 if (so->type == V_ASN1_OCTET_STRING)
226                         {
227                         os=so->value.octet_string;
228                         i=os->length;
229                         if ((i+1) > len)
230                                 i=len-1;
231                         memcpy(buf,os->data,i);
232                         return(i);
233                         }
234                 }
235         return(0);
236         }
237
238 X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
239         {
240         /* To add an object of OID 1.9.999, which is a sequence containing
241          * 2 octet strings */
242         unsigned char *p;
243         ASN1_OCTET_STRING *os1,*os2;
244         ASN1_STRING *seq;
245         X509_ATTRIBUTE *ret;
246         unsigned char *data;
247         int i,total;
248
249         if (signed_seq2string_nid == -1)
250                 signed_seq2string_nid=
251                         OBJ_create("1.9.9999","OID_example","Our example OID");
252
253         os1=ASN1_OCTET_STRING_new();
254         os2=ASN1_OCTET_STRING_new();
255         ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
256         ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
257         i =i2d_ASN1_OCTET_STRING(os1,NULL);
258         i+=i2d_ASN1_OCTET_STRING(os2,NULL);
259         total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
260
261         data=malloc(total);
262         p=data;
263         ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
264         i2d_ASN1_OCTET_STRING(os1,&p);
265         i2d_ASN1_OCTET_STRING(os2,&p);
266
267         seq=ASN1_STRING_new();
268         ASN1_STRING_set(seq,data,total);
269         free(data);
270         ASN1_OCTET_STRING_free(os1);
271         ASN1_OCTET_STRING_free(os2);
272
273         ret=X509_ATTRIBUTE_create(signed_seq2string_nid,
274                 V_ASN1_SEQUENCE,(char *)seq);
275         return(ret);
276         }
277
278 /* For this case, I will malloc the return strings */
279 int sk_get_seq2string(STACK_OF(X509_ATTRIBUTE) *sk, char **str1, char **str2)
280         {
281         ASN1_TYPE *so;
282         PKCS7_SIGNER_INFO si;
283
284         if (signed_seq2string_nid == -1)
285                 signed_seq2string_nid=
286                         OBJ_create("1.9.9999","OID_example","Our example OID");
287
288         si.auth_attr=sk;
289         /* To retrieve */
290         so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid);
291         if (so->type == V_ASN1_SEQUENCE)
292                 {
293                 ASN1_const_CTX c;
294                 ASN1_STRING *s;
295                 long length;
296                 ASN1_OCTET_STRING *os1,*os2;
297
298                 s=so->value.sequence;
299                 c.p=ASN1_STRING_data(s);
300                 c.max=c.p+ASN1_STRING_length(s);
301                 if (!asn1_GetSequence(&c,&length)) goto err;
302                 /* Length is the length of the seqence */
303
304                 c.q=c.p;
305                 if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
306                         goto err;
307                 c.slen-=(c.p-c.q);
308
309                 c.q=c.p;
310                 if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
311                         goto err;
312                 c.slen-=(c.p-c.q);
313
314                 if (!asn1_const_Finish(&c)) goto err;
315                 *str1=malloc(os1->length+1);
316                 *str2=malloc(os2->length+1);
317                 memcpy(*str1,os1->data,os1->length);
318                 memcpy(*str2,os2->data,os2->length);
319                 (*str1)[os1->length]='\0';
320                 (*str2)[os2->length]='\0';
321                 ASN1_OCTET_STRING_free(os1);
322                 ASN1_OCTET_STRING_free(os2);
323                 return(1);
324                 }
325 err:
326         return(0);
327         }
328
329