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