The majority of the OCSP code from CertCo.
[openssl.git] / crypto / ocsp / ocsp_res.c
1 /* ocsp_req.c */
2 /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
3  * project. */
4
5 /* History:
6    This file was originally part of ocsp.c and was transfered to Richard
7    Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included
8    in OpenSSL or released as a patch kit. */
9
10 /* ====================================================================
11  * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer. 
19  *
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in
22  *    the documentation and/or other materials provided with the
23  *    distribution.
24  *
25  * 3. All advertising materials mentioning features or use of this
26  *    software must display the following acknowledgment:
27  *    "This product includes software developed by the OpenSSL Project
28  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
29  *
30  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
31  *    endorse or promote products derived from this software without
32  *    prior written permission. For written permission, please contact
33  *    openssl-core@openssl.org.
34  *
35  * 5. Products derived from this software may not be called "OpenSSL"
36  *    nor may "OpenSSL" appear in their names without prior written
37  *    permission of the OpenSSL Project.
38  *
39  * 6. Redistributions of any form whatsoever must retain the following
40  *    acknowledgment:
41  *    "This product includes software developed by the OpenSSL Project
42  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
45  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
48  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55  * OF THE POSSIBILITY OF SUCH DAMAGE.
56  * ====================================================================
57  *
58  * This product includes cryptographic software written by Eric Young
59  * (eay@cryptsoft.com).  This product includes software written by Tim
60  * Hudson (tjh@cryptsoft.com).
61  *
62  */
63
64 #include <openssl/err.h>
65 #include <openssl/objects.h>
66 #include <openssl/asn1_mac.h>
67 #include <openssl/ocsp.h>
68 #include <openssl/x509.h>
69 #include <openssl/x509v3.h>
70
71 /* Make sure we work well with older variants of OpenSSL */
72 #ifndef OPENSSL_malloc
73 #define OPENSSL_malloc Malloc
74 #endif
75 #ifndef OPENSSL_realloc
76 #define OPENSSL_realloc Realloc
77 #endif
78 #ifndef OPENSSL_free
79 #define OPENSSL_free Free
80 #endif
81
82 IMPLEMENT_STACK_OF(OCSP_SINGLERESP)
83 IMPLEMENT_ASN1_SET_OF(OCSP_SINGLERESP)
84
85 OCSP_RESPBYTES *OCSP_RESPBYTES_new(void)
86         {
87         ASN1_CTX c;
88         OCSP_RESPBYTES *ret=NULL;
89
90         M_ASN1_New_Malloc(ret, OCSP_RESPBYTES);
91         M_ASN1_New(ret->responseType, ASN1_OBJECT_new);
92         M_ASN1_New(ret->response, ASN1_OCTET_STRING_new);
93         return(ret);
94         M_ASN1_New_Error(ASN1_F_OCSP_RESPBYTES_NEW);
95         }
96         
97 void OCSP_RESPBYTES_free(OCSP_RESPBYTES *a)
98         {
99         if (a == NULL) return;
100         ASN1_OBJECT_free(a->responseType);
101         ASN1_OCTET_STRING_free(a->response);
102         OPENSSL_free((char *)a);
103         }
104
105 int i2d_OCSP_RESPBYTES(OCSP_RESPBYTES *a,
106                        unsigned char **pp)
107         {
108         M_ASN1_I2D_vars(a);
109
110         M_ASN1_I2D_len(a->responseType, i2d_ASN1_OBJECT);
111         M_ASN1_I2D_len(a->response, i2d_ASN1_OCTET_STRING);
112         M_ASN1_I2D_seq_total();
113         M_ASN1_I2D_put(a->responseType, i2d_ASN1_OBJECT);
114         M_ASN1_I2D_put(a->response, i2d_ASN1_OCTET_STRING);
115         M_ASN1_I2D_finish();
116         }
117
118 OCSP_RESPBYTES *d2i_OCSP_RESPBYTES(OCSP_RESPBYTES **a,
119                                    unsigned char **pp,
120                                    long length)
121         {
122         M_ASN1_D2I_vars(a,OCSP_RESPBYTES *,OCSP_RESPBYTES_new);
123
124         M_ASN1_D2I_Init();
125         M_ASN1_D2I_start_sequence();
126         M_ASN1_D2I_get(ret->responseType, d2i_ASN1_OBJECT);
127         M_ASN1_D2I_get(ret->response, d2i_ASN1_OCTET_STRING);
128         M_ASN1_D2I_Finish(a,OCSP_RESPBYTES_free,ASN1_F_D2I_OCSP_RESPBYTES);
129         }
130
131 int i2a_OCSP_RESPBYTES(BIO *bp,
132                        OCSP_RESPBYTES* a)
133         {
134         i2a_ASN1_OBJECT(bp, a->responseType);
135         i2a_ASN1_STRING(bp, a->response, V_ASN1_OCTET_STRING);
136         return 2;
137         }
138
139 OCSP_RESPONSE *OCSP_RESPONSE_new(void)
140         {
141         ASN1_CTX c;
142         OCSP_RESPONSE *ret=NULL;
143
144         M_ASN1_New_Malloc(ret, OCSP_RESPONSE);
145         M_ASN1_New(ret->responseStatus, ASN1_ENUMERATED_new);
146         ret->responseBytes = NULL;
147         return(ret);
148         M_ASN1_New_Error(ASN1_F_OCSP_RESPONSE_NEW);
149         }
150         
151 void OCSP_RESPONSE_free(OCSP_RESPONSE *a)
152         {
153         if (a == NULL) return;
154         ASN1_ENUMERATED_free(a->responseStatus);
155         OCSP_RESPBYTES_free(a->responseBytes);
156         OPENSSL_free((char *)a);
157         }
158
159 int i2d_OCSP_RESPONSE(OCSP_RESPONSE *a,
160                       unsigned char **pp)
161         {
162         int v=0;
163         M_ASN1_I2D_vars(a);
164
165         M_ASN1_I2D_len(a->responseStatus, i2d_ASN1_ENUMERATED);
166         M_ASN1_I2D_len_EXP_opt(a->responseBytes, i2d_OCSP_RESPBYTES, 0, v);
167         M_ASN1_I2D_seq_total();
168         M_ASN1_I2D_put(a->responseStatus, i2d_ASN1_ENUMERATED);
169         M_ASN1_I2D_put_EXP_opt(a->responseBytes, i2d_OCSP_RESPBYTES, 0, v);
170         M_ASN1_I2D_finish();
171         }
172
173 OCSP_RESPONSE *d2i_OCSP_RESPONSE(OCSP_RESPONSE **a,
174                                  unsigned char **pp,
175                                  long length)
176         {
177         M_ASN1_D2I_vars(a,OCSP_RESPONSE *,OCSP_RESPONSE_new);
178
179         M_ASN1_D2I_Init();
180         M_ASN1_D2I_start_sequence();
181         M_ASN1_D2I_get(ret->responseStatus, d2i_ASN1_ENUMERATED);
182         M_ASN1_D2I_get_EXP_opt(ret->responseBytes, d2i_OCSP_RESPBYTES, 0);
183         M_ASN1_D2I_Finish(a,OCSP_RESPONSE_free,ASN1_F_D2I_OCSP_RESPONSE);
184         }
185
186 int i2a_OCSP_RESPONSE(BIO *bp, OCSP_RESPONSE* a)
187         {
188         i2a_ASN1_STRING(bp, a->responseStatus, V_ASN1_ENUMERATED);
189         i2a_OCSP_RESPBYTES(bp, a->responseBytes);
190         return a->responseBytes ? 2 : 1;
191         }
192
193 OCSP_RESPID *OCSP_RESPID_new(void)
194         {
195         ASN1_CTX c;
196         OCSP_RESPID *ret=NULL;
197
198         M_ASN1_New_Malloc(ret, OCSP_RESPID);
199         ret->tag = -1;
200         ret->value.byName = NULL;
201         return(ret);
202         M_ASN1_New_Error(ASN1_F_OCSP_RESPID_NEW);
203         }
204         
205 void OCSP_RESPID_free(OCSP_RESPID *a)
206         {
207         if (a == NULL) return;
208         switch (a->tag)
209                 {
210                 case V_OCSP_RESPID_NAME:
211                         X509_NAME_free(a->value.byName);
212                         break;
213                 case V_OCSP_RESPID_KEY:
214                         ASN1_OCTET_STRING_free(a->value.byKey);
215                         break;
216                 }
217         OPENSSL_free((char *)a);
218         }
219
220 int i2d_OCSP_RESPID(OCSP_RESPID *a, unsigned char **pp)
221         {
222         int v=0;
223         M_ASN1_I2D_vars(a);
224         switch (a->tag)
225                 {
226                 case V_OCSP_RESPID_NAME:
227                         v = i2d_X509_NAME(a->value.byName,NULL);
228                         ret += ASN1_object_size(1, v, V_OCSP_RESPID_NAME);
229                         if (pp==NULL) return ret;
230                         p=*pp;
231                         ASN1_put_object(&p, 1, v, 
232                                         V_OCSP_RESPID_NAME,
233                                         V_ASN1_CONTEXT_SPECIFIC);
234                         i2d_X509_NAME(a->value.byName,&p);
235                         break;
236                 case V_OCSP_RESPID_KEY:
237                         v = i2d_ASN1_OCTET_STRING(a->value.byKey,NULL);
238                         ret += ASN1_object_size(1, v, V_OCSP_RESPID_KEY);
239                         if (pp==NULL) return ret;
240                         p=*pp;
241                         ASN1_put_object(&p, 1, v, 
242                                         V_OCSP_RESPID_KEY,
243                                         V_ASN1_CONTEXT_SPECIFIC);
244                         i2d_ASN1_OCTET_STRING(a->value.byKey,&p);
245                         break;
246                 }
247         if (pp && *pp) *pp=p;
248         return(r);
249         }
250
251 OCSP_RESPID *d2i_OCSP_RESPID(OCSP_RESPID **a,
252                              unsigned char **pp,
253                              long length)
254         {
255         int inf,xclass;
256         M_ASN1_D2I_vars(a,OCSP_RESPID *,OCSP_RESPID_new);
257
258         M_ASN1_D2I_Init();
259         c.slen = length; /* simulate sequence */
260         inf=ASN1_get_object(&c.p,&c.slen,&ret->tag,&xclass,c.slen);
261         if (inf & 0x80) goto err;
262         switch (ret->tag)
263                 {
264                 case V_OCSP_RESPID_NAME:
265                         M_ASN1_D2I_get(ret->value.byName, d2i_X509_NAME);
266                         break;
267                 case V_OCSP_RESPID_KEY:
268                         M_ASN1_D2I_get(ret->value.byKey, d2i_ASN1_OCTET_STRING);
269                         break;
270                 default:
271                         ASN1err(ASN1_F_D2I_OCSP_RESPID,ASN1_R_BAD_TYPE);
272                         break;
273                 }
274         M_ASN1_D2I_Finish(a,OCSP_RESPID_free,ASN1_F_D2I_OCSP_RESPID);
275         }
276
277 int i2a_OCSP_RESPID(BIO *bp, OCSP_RESPID* a)
278         {
279         switch (a->tag)
280                 {
281                 case V_OCSP_RESPID_NAME:
282                         X509_NAME_print(bp, a->value.byName, 16);
283                         break;
284                 case V_OCSP_RESPID_KEY:
285                         i2a_ASN1_STRING(bp, a->value.byKey, V_ASN1_OCTET_STRING);
286                         break;
287                 }
288
289         return 1;
290         }
291
292 OCSP_RESPDATA *OCSP_RESPDATA_new(void)
293         {
294         ASN1_CTX c;
295         OCSP_RESPDATA *ret=NULL;
296
297         M_ASN1_New_Malloc(ret, OCSP_RESPDATA);
298         ret->version = NULL;
299         M_ASN1_New(ret->responderId, OCSP_RESPID_new);
300         M_ASN1_New(ret->producedAt, ASN1_GENERALIZEDTIME_new);
301         ret->responses = NULL;
302         ret->responseExtensions = NULL;
303         return(ret);
304         M_ASN1_New_Error(ASN1_F_OCSP_RESPDATA_NEW);
305         }
306         
307 void OCSP_RESPDATA_free(OCSP_RESPDATA *a)
308         {
309         if (a == NULL) return;
310         ASN1_INTEGER_free(a->version);
311         OCSP_RESPID_free(a->responderId);
312         ASN1_GENERALIZEDTIME_free(a->producedAt);
313         sk_OCSP_SINGLERESP_pop_free(a->responses, OCSP_SINGLERESP_free);
314         sk_X509_EXTENSION_pop_free(a->responseExtensions, X509_EXTENSION_free);
315         OPENSSL_free((char *)a);
316         }
317
318 int i2d_OCSP_RESPDATA(OCSP_RESPDATA *a,
319                       unsigned char **pp)
320         {
321         int v1=0,v2=0;
322         M_ASN1_I2D_vars(a);
323
324         M_ASN1_I2D_len_EXP_opt(a->version, i2d_ASN1_INTEGER, 0, v1);
325         M_ASN1_I2D_len(a->responderId, i2d_OCSP_RESPID);
326         M_ASN1_I2D_len(a->producedAt, i2d_ASN1_GENERALIZEDTIME);
327         M_ASN1_I2D_len_SEQUENCE_type(OCSP_SINGLERESP, a->responses, 
328                                 i2d_OCSP_SINGLERESP);
329         M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(X509_EXTENSION,
330              a->responseExtensions, i2d_X509_EXTENSION, 1,
331              V_ASN1_SEQUENCE, v2);
332         M_ASN1_I2D_seq_total();
333         M_ASN1_I2D_put_EXP_opt(a->version, i2d_ASN1_INTEGER, 0, v1);
334         M_ASN1_I2D_put(a->responderId, i2d_OCSP_RESPID);
335         M_ASN1_I2D_put(a->producedAt, i2d_ASN1_GENERALIZEDTIME);
336         M_ASN1_I2D_put_SEQUENCE_type(OCSP_SINGLERESP, a->responses,
337                                      i2d_OCSP_SINGLERESP);
338         M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(X509_EXTENSION,
339              a->responseExtensions, i2d_X509_EXTENSION, 1,
340              V_ASN1_SEQUENCE, v2);
341         M_ASN1_I2D_finish();
342         }
343
344 OCSP_RESPDATA *d2i_OCSP_RESPDATA(OCSP_RESPDATA **a,
345                                  unsigned char **pp,
346                                  long length)
347         {
348         M_ASN1_D2I_vars(a,OCSP_RESPDATA *,OCSP_RESPDATA_new);
349
350         M_ASN1_D2I_Init();
351         M_ASN1_D2I_start_sequence();
352         /* we have the optional version field */
353         if (M_ASN1_next == (V_ASN1_CONTEXT_SPECIFIC | V_ASN1_CONSTRUCTED | 0))
354                 { M_ASN1_D2I_get_EXP_opt(ret->version,d2i_ASN1_INTEGER,0);}
355         else
356                 {
357                 if (ret->version != NULL)
358                         {
359                         ASN1_INTEGER_free(ret->version);
360                         ret->version=NULL;
361                         }
362                 }
363         M_ASN1_D2I_get(ret->responderId, d2i_OCSP_RESPID);
364         M_ASN1_D2I_get(ret->producedAt, d2i_ASN1_GENERALIZEDTIME);
365         M_ASN1_D2I_get_seq_type(OCSP_SINGLERESP, ret->responses,
366                         d2i_OCSP_SINGLERESP, OCSP_SINGLERESP_free);
367         /* there is no M_ASN1_D2I_get_EXP_seq* code, so
368            we're using the set version */
369         M_ASN1_D2I_get_EXP_set_opt_type(X509_EXTENSION,
370                 ret->responseExtensions, d2i_X509_EXTENSION, 
371                 X509_EXTENSION_free, 1, V_ASN1_SEQUENCE);
372         M_ASN1_D2I_Finish(a,OCSP_RESPDATA_free,ASN1_F_D2I_OCSP_RESPDATA);
373         }
374
375 int i2a_OCSP_RESPDATA(BIO *bp, OCSP_RESPDATA* a)
376         {
377         int i, j=2;
378         if (a->version == NULL) BIO_puts(bp, "0");
379         else i2a_ASN1_INTEGER(bp, a->version);
380         i2a_OCSP_RESPID(bp, a->responderId);
381         if (!ASN1_GENERALIZEDTIME_print(bp, a->producedAt)) return 0;
382         if (a->responses != NULL)
383                 {
384                 for (i=0; i<sk_OCSP_SINGLERESP_num(a->responses); i++)
385                         if (sk_OCSP_SINGLERESP_value(a->responses,i) != NULL)
386                                 i2a_OCSP_SINGLERESP(bp, 
387                                       sk_OCSP_SINGLERESP_value(a->responses,i));
388                 j+=sk_OCSP_SINGLERESP_num(a->responses);
389                 }
390 #ifdef UNDEF
391         /* XXX need generic extension print method or need to register
392          * ocsp extensions with existing extension handler mechanism,
393          * invoke i2a callbacks.
394          */
395         if (a->responseExtensions != NULL)
396                 {
397                 for (i=0; i<sk_X509_EXTENSION_num(a->responseExtensions); i++)
398                         if (sk_X509_EXTENSION_value(a->responseExtensions,i) != NULL)
399                                 i2a_X509_EXTENSION(bp, 
400                                    sk_X509_EXTENSION_value(a->responseExtensions,i));
401                 j+=sk_X509_EXTENSION_num(a->responseExtensions);
402                 }
403 #endif
404         return j;
405         }
406
407 OCSP_BASICRESP *OCSP_BASICRESP_new(void)
408         {
409         ASN1_CTX c;
410         OCSP_BASICRESP *ret=NULL;
411
412         M_ASN1_New_Malloc(ret, OCSP_BASICRESP);
413         M_ASN1_New(ret->tbsResponseData, OCSP_RESPDATA_new);
414         M_ASN1_New(ret->signatureAlgorithm, X509_ALGOR_new);
415         M_ASN1_New(ret->signature, ASN1_BIT_STRING_new);
416         ret->certs = NULL;
417         return(ret);
418         M_ASN1_New_Error(ASN1_F_OCSP_BASICRESP_NEW);
419         }
420         
421 void OCSP_BASICRESP_free(OCSP_BASICRESP *a)
422         {
423         if (a == NULL) return;
424         OCSP_RESPDATA_free(a->tbsResponseData);
425         X509_ALGOR_free(a->signatureAlgorithm);
426         ASN1_BIT_STRING_free(a->signature);
427         sk_X509_pop_free(a->certs, X509_free);
428         OPENSSL_free((char *)a);
429         }
430
431 int i2d_OCSP_BASICRESP(OCSP_BASICRESP *a, unsigned char **pp)
432         {
433         int v=0;
434         M_ASN1_I2D_vars(a);
435
436         M_ASN1_I2D_len(a->tbsResponseData, i2d_OCSP_RESPDATA);
437         M_ASN1_I2D_len(a->signatureAlgorithm, i2d_X509_ALGOR);
438         M_ASN1_I2D_len(a->signature, i2d_ASN1_BIT_STRING);
439         M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(X509, a->certs, 
440                              i2d_X509, 0, V_ASN1_SEQUENCE, v);
441         M_ASN1_I2D_seq_total();
442         M_ASN1_I2D_put(a->tbsResponseData, i2d_OCSP_RESPDATA);
443         M_ASN1_I2D_put(a->signatureAlgorithm, i2d_X509_ALGOR);
444         M_ASN1_I2D_put(a->signature, i2d_ASN1_BIT_STRING);
445         M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(X509, a->certs,
446                              i2d_X509, 0, V_ASN1_SEQUENCE, v);
447         M_ASN1_I2D_finish();
448         }
449
450 OCSP_BASICRESP *d2i_OCSP_BASICRESP(OCSP_BASICRESP **a,
451                                    unsigned char **pp,
452                                    long length)
453         {
454         M_ASN1_D2I_vars(a,OCSP_BASICRESP *,OCSP_BASICRESP_new);
455
456         M_ASN1_D2I_Init();
457         M_ASN1_D2I_start_sequence();
458         M_ASN1_D2I_get(ret->tbsResponseData, d2i_OCSP_RESPDATA);
459         M_ASN1_D2I_get(ret->signatureAlgorithm, d2i_X509_ALGOR);
460         M_ASN1_D2I_get(ret->signature, d2i_ASN1_BIT_STRING);
461         /* there is no M_ASN1_D2I_get_EXP_seq* code, so
462            we're using the set version */
463         M_ASN1_D2I_get_EXP_set_opt_type(X509, ret->certs, d2i_X509, 
464                                    X509_free, 0, V_ASN1_SEQUENCE);
465         M_ASN1_D2I_Finish(a,OCSP_BASICRESP_free,ASN1_F_D2I_OCSP_BASICRESP);
466         }
467
468 int i2a_OCSP_BASICRESP(BIO *bp, OCSP_BASICRESP* a)
469         {
470         int i, j=3;
471         i2a_OCSP_RESPDATA(bp, a->tbsResponseData);
472 #ifdef UNDEF
473         /* XXX this guy isn't implemented. */
474         i2a_X509_ALGOR(bp, a->signatureAlgorithm);
475 #else   /* instead, just show OID, not param */
476         i2a_ASN1_OBJECT(bp, a->signatureAlgorithm->algorithm);
477 #endif
478         i2a_ASN1_STRING(bp, a->signature, V_ASN1_BIT_STRING);
479         if (a->certs != NULL)
480                 {
481                 for (i=0; i<sk_X509_num(a->certs); i++)
482                         if (sk_X509_value(a->certs,i) != NULL)
483                                 X509_print(bp, sk_X509_value(a->certs,i));
484                 j+=sk_X509_num(a->certs);
485                 }
486         return j;
487         }
488
489 OCSP_REVOKEDINFO *OCSP_REVOKEDINFO_new(void)
490         {
491         ASN1_CTX c;
492         OCSP_REVOKEDINFO *ret=NULL;
493
494         M_ASN1_New_Malloc(ret, OCSP_REVOKEDINFO);
495         M_ASN1_New(ret->revocationTime, ASN1_GENERALIZEDTIME_new);
496         ret->revocationReason = NULL;
497         return(ret);
498         M_ASN1_New_Error(ASN1_F_OCSP_REVOKEDINFO_NEW);
499         }
500         
501 void OCSP_REVOKEDINFO_free(OCSP_REVOKEDINFO *a)
502         {
503         if (a == NULL) return;
504         ASN1_GENERALIZEDTIME_free(a->revocationTime);
505         ASN1_ENUMERATED_free(a->revocationReason);
506         OPENSSL_free((char *)a);
507         }
508
509 int i2d_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO *a, unsigned char **pp)
510         {
511         int v=0;
512         M_ASN1_I2D_vars(a);
513
514         M_ASN1_I2D_len(a->revocationTime, i2d_ASN1_GENERALIZEDTIME);
515         M_ASN1_I2D_len_EXP_opt(a->revocationReason, i2d_ASN1_ENUMERATED, 0, v);
516         M_ASN1_I2D_seq_total();
517         M_ASN1_I2D_put(a->revocationTime, i2d_ASN1_GENERALIZEDTIME); 
518         M_ASN1_I2D_put_EXP_opt(a->revocationReason, i2d_ASN1_ENUMERATED, 0, v);
519         M_ASN1_I2D_finish();
520         }
521
522 OCSP_REVOKEDINFO *d2i_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO **a,
523                                        unsigned char **pp,
524                                        long length)
525         {
526         M_ASN1_D2I_vars(a,OCSP_REVOKEDINFO *,OCSP_REVOKEDINFO_new);
527
528         M_ASN1_D2I_Init();
529         M_ASN1_D2I_start_sequence();
530         M_ASN1_D2I_get(ret->revocationTime, d2i_ASN1_GENERALIZEDTIME);
531         M_ASN1_D2I_get_EXP_opt(ret->revocationReason, d2i_ASN1_ENUMERATED, 0);
532         M_ASN1_D2I_Finish(a,OCSP_REVOKEDINFO_free,ASN1_F_D2I_OCSP_REVOKEDINFO);
533         }
534
535 int i2a_OCSP_REVOKEDINFO(BIO *bp, OCSP_REVOKEDINFO* a)
536         {
537         int i=0; 
538         if (!ASN1_GENERALIZEDTIME_print(bp, a->revocationTime)) return 0;
539         if (a->revocationReason)
540                 {
541                 i2a_ASN1_STRING(bp, a->revocationReason, V_ASN1_ENUMERATED);
542                 i++;
543                 }
544         return i;
545         }
546
547 OCSP_CERTSTATUS *OCSP_CERTSTATUS_new(void)
548
549         {
550         ASN1_CTX c;
551         OCSP_CERTSTATUS *ret=NULL;
552
553         M_ASN1_New_Malloc(ret, OCSP_CERTSTATUS);
554         ret->tag = -1;
555         ret->revoked = NULL;
556         return(ret);
557         M_ASN1_New_Error(ASN1_F_OCSP_CERTSTATUS_NEW);
558         }
559         
560 void OCSP_CERTSTATUS_free(OCSP_CERTSTATUS *a)
561         {
562         if (a == NULL) return;
563         OCSP_REVOKEDINFO_free(a->revoked);
564         OPENSSL_free((char *)a);
565         }
566
567 int i2d_OCSP_CERTSTATUS(OCSP_CERTSTATUS *a, unsigned char **pp)
568         {
569         unsigned char *qq;
570         M_ASN1_I2D_vars(a);
571         ret += 0; /* shush, compiler, shush... */
572         if (a == NULL) return(0);
573         switch (a->tag)
574                 {
575                 case V_OCSP_CERTSTATUS_GOOD:
576                 case V_OCSP_CERTSTATUS_UNKNOWN:
577                         r = 2;
578                         if (pp)
579                                 {
580                                 qq=p=*pp;
581                                 ASN1_put_object(&p,0,0,
582                                                 V_ASN1_NULL,V_ASN1_UNIVERSAL);
583                                 *qq=(V_ASN1_CONTEXT_SPECIFIC|a->tag|
584                                                    (*qq&V_ASN1_CONSTRUCTED));
585                                 }
586                         break;
587                 case V_OCSP_CERTSTATUS_REVOKED:
588                         r = i2d_OCSP_REVOKEDINFO(a->revoked,NULL);
589                         if (pp)
590                                 {
591                                 p=*pp;
592                                 M_ASN1_I2D_put_IMP_opt(a->revoked,
593                                                        i2d_OCSP_REVOKEDINFO, 
594                                                        a->tag);
595                                 }
596                         break;
597
598                 }
599         if (pp && *pp) *pp=p;
600         return(r);
601         }
602
603 OCSP_CERTSTATUS *d2i_OCSP_CERTSTATUS(OCSP_CERTSTATUS **a,
604                                      unsigned char **pp,
605                                      long length)
606         {
607         int tag, xclass, error=0;
608         long len;
609         unsigned char *p, *q, t;
610         OCSP_CERTSTATUS* ret=NULL;
611
612         if ((a == NULL) || ((*a) == NULL))
613                 { 
614                 if ((ret=(OCSP_CERTSTATUS*)OCSP_CERTSTATUS_new()) == NULL) 
615                         goto err; 
616                 }
617         else    ret=(*a);
618         p=*pp;
619         ret->tag = (*p & ~(V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC));
620         switch (ret->tag)
621                 {
622                 case V_OCSP_CERTSTATUS_GOOD:
623                 case V_OCSP_CERTSTATUS_UNKNOWN:
624                         ret->revoked = NULL;
625                         q=p;
626                         ASN1_get_object(&p,&len,&tag,&xclass,length);
627                         if (len) 
628                                 {
629                                 error = ASN1_R_BAD_TYPE;
630                                 goto err;
631                                 }
632                         break;
633                 case V_OCSP_CERTSTATUS_REVOKED:
634                         q=p;
635                         ASN1_get_object(&q,&len,&tag,&xclass,length);
636                         t=*p;
637                         *p=(t&~V_ASN1_PRIMATIVE_TAG)|V_ASN1_SEQUENCE;
638                         q=p; 
639                         if (d2i_OCSP_REVOKEDINFO(&ret->revoked,
640                                                  &p,length) == NULL)
641                                 goto err;
642                         *q=t;
643                         if ((p-q) != (len+2))
644                                 {
645                                 error = ASN1_R_BAD_TYPE;
646                                 goto err;
647                                 }
648                         break;
649                 default:
650                         ASN1err(ASN1_F_D2I_OCSP_CERTSTATUS,ASN1_R_BAD_TYPE);
651                         break;
652                 }
653         *pp=p;
654         if (a != NULL) (*a)=ret;
655         return(ret);
656 err:
657         ASN1err(ASN1_F_D2I_OCSP_CERTSTATUS,error); 
658         asn1_add_error(*pp,(int)(q- *pp)); 
659         if ((ret != NULL) && ((a == NULL) || (*a != ret))) 
660                 OCSP_CERTSTATUS_free(ret); 
661         return(NULL);
662         }
663
664 int i2a_OCSP_CERTSTATUS(BIO *bp, OCSP_CERTSTATUS* a)
665         {
666         switch (a->tag)
667                 {
668                 case V_OCSP_CERTSTATUS_GOOD:
669                         BIO_puts(bp, "CertStatus: good");
670                         break;
671                 case V_OCSP_CERTSTATUS_REVOKED:
672                         BIO_puts(bp, "CertStatus: revoked");
673                         i2a_OCSP_REVOKEDINFO(bp, a->revoked);
674                         break;
675                 case V_OCSP_CERTSTATUS_UNKNOWN:
676                         BIO_puts(bp, "CertStatus: unknown");
677                         break;
678                 }
679         return 1;
680         }
681
682 OCSP_SINGLERESP *OCSP_SINGLERESP_new(void)
683         {
684         ASN1_CTX c;
685         OCSP_SINGLERESP *ret=NULL;
686
687         M_ASN1_New_Malloc(ret, OCSP_SINGLERESP);
688         M_ASN1_New(ret->certId, OCSP_CERTID_new);
689         M_ASN1_New(ret->certStatus, OCSP_CERTSTATUS_new);
690         M_ASN1_New(ret->thisUpdate, ASN1_GENERALIZEDTIME_new);
691         ret->nextUpdate = NULL;
692         ret->singleExtensions = NULL;
693         return(ret);
694         M_ASN1_New_Error(ASN1_F_OCSP_SINGLERESP_NEW);
695         }
696         
697 void OCSP_SINGLERESP_free(OCSP_SINGLERESP *a)
698         {
699         if (a == NULL) return;
700         OCSP_CERTID_free(a->certId);
701         OCSP_CERTSTATUS_free(a->certStatus);
702         ASN1_GENERALIZEDTIME_free(a->thisUpdate);
703         ASN1_GENERALIZEDTIME_free(a->nextUpdate);
704         sk_X509_EXTENSION_pop_free(a->singleExtensions, X509_EXTENSION_free);
705         OPENSSL_free((char *)a);
706         }
707
708 int i2d_OCSP_SINGLERESP(OCSP_SINGLERESP *a, unsigned char **pp)
709         {
710         int v1=0,v2=0;
711         M_ASN1_I2D_vars(a);
712
713         M_ASN1_I2D_len(a->certId, i2d_OCSP_CERTID);
714         M_ASN1_I2D_len(a->certStatus, i2d_OCSP_CERTSTATUS);
715         M_ASN1_I2D_len(a->thisUpdate, i2d_ASN1_GENERALIZEDTIME);
716         M_ASN1_I2D_len_EXP_opt(a->nextUpdate, i2d_ASN1_GENERALIZEDTIME, 0, v1);
717         M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(X509_EXTENSION,
718              a->singleExtensions, i2d_X509_EXTENSION, 1, V_ASN1_SEQUENCE, v2);
719         M_ASN1_I2D_seq_total();
720         M_ASN1_I2D_put(a->certId, i2d_OCSP_CERTID);
721         M_ASN1_I2D_put(a->certStatus, i2d_OCSP_CERTSTATUS);
722         M_ASN1_I2D_put(a->thisUpdate, i2d_ASN1_GENERALIZEDTIME);
723         M_ASN1_I2D_put_EXP_opt(a->nextUpdate, i2d_ASN1_GENERALIZEDTIME, 0, v1);
724         M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(X509_EXTENSION,
725              a->singleExtensions, i2d_X509_EXTENSION, 1, V_ASN1_SEQUENCE, v2);
726         M_ASN1_I2D_finish();
727         }
728
729 OCSP_SINGLERESP *d2i_OCSP_SINGLERESP(OCSP_SINGLERESP **a,
730                                      unsigned char **pp,
731                                      long length)
732         {
733         M_ASN1_D2I_vars(a,OCSP_SINGLERESP *,OCSP_SINGLERESP_new);
734
735         M_ASN1_D2I_Init();
736         M_ASN1_D2I_start_sequence();
737         M_ASN1_D2I_get(ret->certId, d2i_OCSP_CERTID);
738         M_ASN1_D2I_get(ret->certStatus, d2i_OCSP_CERTSTATUS);
739         M_ASN1_D2I_get(ret->thisUpdate, d2i_ASN1_GENERALIZEDTIME);
740         M_ASN1_D2I_get_EXP_opt(ret->nextUpdate, d2i_ASN1_GENERALIZEDTIME, 0);
741         /* there is no M_ASN1_D2I_get_EXP_seq*, so had to use set here*/
742         M_ASN1_D2I_get_EXP_set_opt_type(X509_EXTENSION, ret->singleExtensions, 
743            d2i_X509_EXTENSION, X509_EXTENSION_free, 1, V_ASN1_SEQUENCE);
744         M_ASN1_D2I_Finish(a,OCSP_SINGLERESP_free,ASN1_F_D2I_OCSP_SINGLERESP);
745         }
746
747 int i2a_OCSP_SINGLERESP(BIO *bp, OCSP_SINGLERESP* a)
748         {
749         int /* XXX i, */ j=3;
750         i2a_OCSP_CERTID(bp, a->certId);
751         i2a_OCSP_CERTSTATUS(bp, a->certStatus);
752         if (!ASN1_GENERALIZEDTIME_print(bp, a->thisUpdate)) return 0;
753         if (a->nextUpdate) 
754                 {
755                 if (!ASN1_GENERALIZEDTIME_print(bp, a->nextUpdate)) return 0;
756                 j++;
757                 }
758 #ifdef UNDEF
759         /* XXX need generic extension print method or need to register
760          * ocsp extensions with existing extension handler mechanism,
761          * invoke i2a callbacks.
762          */
763         if (a->singleExtensions != NULL)
764                 {
765                 for (i=0; i<sk_X509_EXTENSION_num(a->singleExtensions); i++)
766                         if (sk_X509_EXTENSION_value(a->singleExtensions,i) != NULL)
767                                 i2a_X509_EXTENSION(bp, 
768                                   sk_X509_EXTENSION_value(a->singleExtensions,i));
769                 j+=sk_X509_EXTENSION_num(a->singleExtensions);
770                 }
771 #endif
772         return j;
773         }
774
775 OCSP_CRLID *OCSP_CRLID_new(void)
776         {
777         ASN1_CTX c;
778         OCSP_CRLID *ret=NULL;
779
780         M_ASN1_New_Malloc(ret, OCSP_CRLID);
781         ret->crlUrl = NULL;
782         ret->crlNum = NULL;
783         ret->crlTime = NULL;
784         return(ret);
785         M_ASN1_New_Error(ASN1_F_OCSP_CRLID_NEW);
786         }
787         
788 void OCSP_CRLID_free(OCSP_CRLID *a)
789         {
790         if (a == NULL) return;
791         ASN1_IA5STRING_free(a->crlUrl);
792         ASN1_INTEGER_free(a->crlNum);
793         ASN1_GENERALIZEDTIME_free(a->crlTime);
794         OPENSSL_free((char *)a);
795         }
796
797 int i2d_OCSP_CRLID(OCSP_CRLID *a,
798                    unsigned char **pp)
799         {
800         int v1=0,v2=0,v3=0;
801         M_ASN1_I2D_vars(a);
802
803         M_ASN1_I2D_len_EXP_opt(a->crlUrl, i2d_ASN1_IA5STRING, 0, v1);
804         M_ASN1_I2D_len_EXP_opt(a->crlNum, i2d_ASN1_INTEGER, 1, v2);
805         M_ASN1_I2D_len_EXP_opt(a->crlTime, i2d_ASN1_GENERALIZEDTIME, 2, v3);
806         M_ASN1_I2D_seq_total();
807         M_ASN1_I2D_put_EXP_opt(a->crlUrl, i2d_ASN1_IA5STRING, 0, v1);
808         M_ASN1_I2D_put_EXP_opt(a->crlNum, i2d_ASN1_INTEGER, 1, v2);
809         M_ASN1_I2D_put_EXP_opt(a->crlTime, i2d_ASN1_GENERALIZEDTIME, 2, v3);
810         M_ASN1_I2D_finish();
811         }
812
813 OCSP_CRLID *d2i_OCSP_CRLID(OCSP_CRLID **a,
814                            unsigned char **pp,
815                            long length)
816         {
817         M_ASN1_D2I_vars(a,OCSP_CRLID *,OCSP_CRLID_new);
818
819         M_ASN1_D2I_Init();
820         M_ASN1_D2I_start_sequence();
821         M_ASN1_D2I_get_EXP_opt(ret->crlUrl, d2i_ASN1_IA5STRING, 0);
822         M_ASN1_D2I_get_EXP_opt(ret->crlNum, d2i_ASN1_INTEGER, 1);
823         M_ASN1_D2I_get_EXP_opt(ret->crlTime, d2i_ASN1_GENERALIZEDTIME, 2);
824         M_ASN1_D2I_Finish(a,OCSP_CRLID_free,ASN1_F_D2I_OCSP_CRLID);
825         }
826
827 int i2a_OCSP_CRLID(BIO *bp, OCSP_CRLID* a)
828         {
829         int i = 0;
830         char buf[1024];
831         if (a->crlUrl && ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) i++;
832         if (a->crlNum && a2i_ASN1_INTEGER(bp, a->crlNum, buf, sizeof buf)) i++;
833         if (a->crlTime && ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) i++;
834         return i;
835         }
836
837 OCSP_SERVICELOC *OCSP_SERVICELOC_new(void)
838         {
839         ASN1_CTX c;
840         OCSP_SERVICELOC *ret=NULL;
841
842         M_ASN1_New_Malloc(ret, OCSP_SERVICELOC);
843         M_ASN1_New(ret->issuer, X509_NAME_new);
844         ret->locator = NULL;
845         return(ret);
846         M_ASN1_New_Error(ASN1_F_OCSP_SERVICELOC_NEW);
847         }
848         
849 void OCSP_SERVICELOC_free(OCSP_SERVICELOC *a)
850         {
851         if (a == NULL) return;
852         X509_NAME_free(a->issuer);
853         sk_ACCESS_DESCRIPTION_pop_free(a->locator, ACCESS_DESCRIPTION_free);
854         OPENSSL_free((char *)a);
855         }
856
857 int i2d_OCSP_SERVICELOC(OCSP_SERVICELOC *a,
858                         unsigned char **pp)
859         {
860         M_ASN1_I2D_vars(a);
861
862         M_ASN1_I2D_len(a->issuer, i2d_X509_NAME);
863         M_ASN1_I2D_len_SEQUENCE_opt_type(ACCESS_DESCRIPTION, 
864                          a->locator, i2d_ACCESS_DESCRIPTION);
865         M_ASN1_I2D_seq_total();
866         M_ASN1_I2D_put(a->issuer, i2d_X509_NAME);
867         M_ASN1_I2D_put_SEQUENCE_opt_type(ACCESS_DESCRIPTION,
868                          a->locator, i2d_ACCESS_DESCRIPTION);
869         M_ASN1_I2D_finish();
870         }
871
872 OCSP_SERVICELOC *d2i_OCSP_SERVICELOC(OCSP_SERVICELOC **a,
873                                      unsigned char **pp,
874                                      long length)
875         {
876         M_ASN1_D2I_vars(a,OCSP_SERVICELOC *,OCSP_SERVICELOC_new);
877
878         M_ASN1_D2I_Init();
879         M_ASN1_D2I_start_sequence();
880         M_ASN1_D2I_get(ret->issuer, d2i_X509_NAME);
881         M_ASN1_D2I_get_seq_opt_type(ACCESS_DESCRIPTION, ret->locator,
882                     d2i_ACCESS_DESCRIPTION,ACCESS_DESCRIPTION_free);
883         M_ASN1_D2I_Finish(a,OCSP_SERVICELOC_free,ASN1_F_D2I_OCSP_SERVICELOC);
884         }
885
886 int i2a_OCSP_SERVICELOC(BIO *bp,
887                         OCSP_SERVICELOC* a)
888         {
889         int i;
890         X509_NAME_print(bp, a->issuer, 16);
891         if (!a->locator) return 1;
892         for (i=0; i<sk_ACCESS_DESCRIPTION_num(a->locator); i++)
893                 i2a_ACCESS_DESCRIPTION(bp,
894                              sk_ACCESS_DESCRIPTION_value(a->locator,i));
895         return i+2;
896         }