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