xref: /openssl/crypto/ocsp/v3_ocsp.c (revision e077455e)
1 /*
2  * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/conf.h>
13 #include <openssl/asn1.h>
14 #include <openssl/ocsp.h>
15 #include "ocsp_local.h"
16 #include <openssl/x509v3.h>
17 #include "../x509/ext_dat.h"
18 
19 /*
20  * OCSP extensions and a couple of CRL entry extensions
21  */
22 
23 static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
24                           BIO *out, int indent);
25 static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
26                             BIO *out, int indent);
27 static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
28                       int indent);
29 
30 static void *ocsp_nonce_new(void);
31 static int i2d_ocsp_nonce(const void *a, unsigned char **pp);
32 static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
33 static void ocsp_nonce_free(void *a);
34 static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
35                           BIO *out, int indent);
36 
37 static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
38                             void *nocheck, BIO *out, int indent);
39 static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
40                               X509V3_CTX *ctx, const char *str);
41 static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
42                                BIO *bp, int ind);
43 
44 const X509V3_EXT_METHOD ossl_v3_ocsp_crlid = {
45     NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
46     0, 0, 0, 0,
47     0, 0,
48     0, 0,
49     i2r_ocsp_crlid, 0,
50     NULL
51 };
52 
53 const X509V3_EXT_METHOD ossl_v3_ocsp_acutoff = {
54     NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
55     0, 0, 0, 0,
56     0, 0,
57     0, 0,
58     i2r_ocsp_acutoff, 0,
59     NULL
60 };
61 
62 const X509V3_EXT_METHOD ossl_v3_crl_invdate = {
63     NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
64     0, 0, 0, 0,
65     0, 0,
66     0, 0,
67     i2r_ocsp_acutoff, 0,
68     NULL
69 };
70 
71 const X509V3_EXT_METHOD ossl_v3_crl_hold = {
72     NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
73     0, 0, 0, 0,
74     0, 0,
75     0, 0,
76     i2r_object, 0,
77     NULL
78 };
79 
80 const X509V3_EXT_METHOD ossl_v3_ocsp_nonce = {
81     NID_id_pkix_OCSP_Nonce, 0, NULL,
82     ocsp_nonce_new,
83     ocsp_nonce_free,
84     d2i_ocsp_nonce,
85     i2d_ocsp_nonce,
86     0, 0,
87     0, 0,
88     i2r_ocsp_nonce, 0,
89     NULL
90 };
91 
92 const X509V3_EXT_METHOD ossl_v3_ocsp_nocheck = {
93     NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
94     0, 0, 0, 0,
95     0, s2i_ocsp_nocheck,
96     0, 0,
97     i2r_ocsp_nocheck, 0,
98     NULL
99 };
100 
101 const X509V3_EXT_METHOD ossl_v3_ocsp_serviceloc = {
102     NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
103     0, 0, 0, 0,
104     0, 0,
105     0, 0,
106     i2r_ocsp_serviceloc, 0,
107     NULL
108 };
109 
i2r_ocsp_crlid(const X509V3_EXT_METHOD * method,void * in,BIO * bp,int ind)110 static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
111                           int ind)
112 {
113     OCSP_CRLID *a = in;
114     if (a->crlUrl) {
115         if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0)
116             goto err;
117         if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl))
118             goto err;
119         if (BIO_write(bp, "\n", 1) <= 0)
120             goto err;
121     }
122     if (a->crlNum) {
123         if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0)
124             goto err;
125         if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0)
126             goto err;
127         if (BIO_write(bp, "\n", 1) <= 0)
128             goto err;
129     }
130     if (a->crlTime) {
131         if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0)
132             goto err;
133         if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime))
134             goto err;
135         if (BIO_write(bp, "\n", 1) <= 0)
136             goto err;
137     }
138     return 1;
139  err:
140     return 0;
141 }
142 
i2r_ocsp_acutoff(const X509V3_EXT_METHOD * method,void * cutoff,BIO * bp,int ind)143 static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
144                             BIO *bp, int ind)
145 {
146     if (BIO_printf(bp, "%*s", ind, "") <= 0)
147         return 0;
148     if (!ASN1_GENERALIZEDTIME_print(bp, cutoff))
149         return 0;
150     return 1;
151 }
152 
i2r_object(const X509V3_EXT_METHOD * method,void * oid,BIO * bp,int ind)153 static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
154                       int ind)
155 {
156     if (BIO_printf(bp, "%*s", ind, "") <= 0)
157         return 0;
158     if (i2a_ASN1_OBJECT(bp, oid) <= 0)
159         return 0;
160     return 1;
161 }
162 
163 /*
164  * OCSP nonce. This is needs special treatment because it doesn't have an
165  * ASN1 encoding at all: it just contains arbitrary data.
166  */
167 
ocsp_nonce_new(void)168 static void *ocsp_nonce_new(void)
169 {
170     return ASN1_OCTET_STRING_new();
171 }
172 
i2d_ocsp_nonce(const void * a,unsigned char ** pp)173 static int i2d_ocsp_nonce(const void *a, unsigned char **pp)
174 {
175     const ASN1_OCTET_STRING *os = a;
176     if (pp) {
177         memcpy(*pp, os->data, os->length);
178         *pp += os->length;
179     }
180     return os->length;
181 }
182 
d2i_ocsp_nonce(void * a,const unsigned char ** pp,long length)183 static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
184 {
185     ASN1_OCTET_STRING *os, **pos;
186     pos = a;
187     if (pos == NULL || *pos == NULL) {
188         os = ASN1_OCTET_STRING_new();
189         if (os == NULL)
190             goto err;
191     } else {
192         os = *pos;
193     }
194     if (!ASN1_OCTET_STRING_set(os, *pp, length))
195         goto err;
196 
197     *pp += length;
198 
199     if (pos)
200         *pos = os;
201     return os;
202 
203  err:
204     if ((pos == NULL) || (*pos != os))
205         ASN1_OCTET_STRING_free(os);
206     ERR_raise(ERR_LIB_OCSP, ERR_R_ASN1_LIB);
207     return NULL;
208 }
209 
ocsp_nonce_free(void * a)210 static void ocsp_nonce_free(void *a)
211 {
212     ASN1_OCTET_STRING_free(a);
213 }
214 
i2r_ocsp_nonce(const X509V3_EXT_METHOD * method,void * nonce,BIO * out,int indent)215 static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
216                           BIO *out, int indent)
217 {
218     if (BIO_printf(out, "%*s", indent, "") <= 0)
219         return 0;
220     if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0)
221         return 0;
222     return 1;
223 }
224 
225 /* Nocheck is just a single NULL. Don't print anything and always set it */
226 
i2r_ocsp_nocheck(const X509V3_EXT_METHOD * method,void * nocheck,BIO * out,int indent)227 static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
228                             BIO *out, int indent)
229 {
230     return 1;
231 }
232 
s2i_ocsp_nocheck(const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,const char * str)233 static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
234                               X509V3_CTX *ctx, const char *str)
235 {
236     return ASN1_NULL_new();
237 }
238 
i2r_ocsp_serviceloc(const X509V3_EXT_METHOD * method,void * in,BIO * bp,int ind)239 static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
240                                BIO *bp, int ind)
241 {
242     int i;
243     OCSP_SERVICELOC *a = in;
244     ACCESS_DESCRIPTION *ad;
245 
246     if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0)
247         goto err;
248     if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0)
249         goto err;
250     for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) {
251         ad = sk_ACCESS_DESCRIPTION_value(a->locator, i);
252         if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0)
253             goto err;
254         if (i2a_ASN1_OBJECT(bp, ad->method) <= 0)
255             goto err;
256         if (BIO_puts(bp, " - ") <= 0)
257             goto err;
258         if (GENERAL_NAME_print(bp, ad->location) <= 0)
259             goto err;
260     }
261     return 1;
262  err:
263     return 0;
264 }
265