1/*
2 * Copyright 2000-2023 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/objects.h>
13#include <openssl/x509.h>
14#include <openssl/ocsp.h>
15#include "ocsp_local.h"
16#include <openssl/rand.h>
17#include <openssl/x509v3.h>
18
19/* Standard wrapper functions for extensions */
20
21/* OCSP request extensions */
22
23int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
24{
25    return X509v3_get_ext_count(x->tbsRequest.requestExtensions);
26}
27
28int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
29{
30    return (X509v3_get_ext_by_NID
31            (x->tbsRequest.requestExtensions, nid, lastpos));
32}
33
34int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj,
35                                int lastpos)
36{
37    return (X509v3_get_ext_by_OBJ
38            (x->tbsRequest.requestExtensions, obj, lastpos));
39}
40
41int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
42{
43    return (X509v3_get_ext_by_critical
44            (x->tbsRequest.requestExtensions, crit, lastpos));
45}
46
47X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
48{
49    return X509v3_get_ext(x->tbsRequest.requestExtensions, loc);
50}
51
52X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
53{
54    return X509v3_delete_ext(x->tbsRequest.requestExtensions, loc);
55}
56
57void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
58{
59    return X509V3_get_d2i(x->tbsRequest.requestExtensions, nid, crit, idx);
60}
61
62int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
63                              unsigned long flags)
64{
65    return X509V3_add1_i2d(&x->tbsRequest.requestExtensions, nid, value,
66                           crit, flags);
67}
68
69int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
70{
71    return (X509v3_add_ext(&(x->tbsRequest.requestExtensions), ex, loc) !=
72            NULL);
73}
74
75/* Single extensions */
76
77int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
78{
79    return X509v3_get_ext_count(x->singleRequestExtensions);
80}
81
82int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
83{
84    return X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos);
85}
86
87int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj,
88                               int lastpos)
89{
90    return X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos);
91}
92
93int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
94{
95    return (X509v3_get_ext_by_critical
96            (x->singleRequestExtensions, crit, lastpos));
97}
98
99X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
100{
101    return X509v3_get_ext(x->singleRequestExtensions, loc);
102}
103
104X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
105{
106    return X509v3_delete_ext(x->singleRequestExtensions, loc);
107}
108
109void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
110{
111    return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
112}
113
114int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
115                             unsigned long flags)
116{
117    return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
118                           flags);
119}
120
121int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
122{
123    return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL);
124}
125
126/* OCSP Basic response */
127
128int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
129{
130    return X509v3_get_ext_count(x->tbsResponseData.responseExtensions);
131}
132
133int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
134{
135    return (X509v3_get_ext_by_NID
136            (x->tbsResponseData.responseExtensions, nid, lastpos));
137}
138
139int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj,
140                                  int lastpos)
141{
142    return (X509v3_get_ext_by_OBJ
143            (x->tbsResponseData.responseExtensions, obj, lastpos));
144}
145
146int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
147                                       int lastpos)
148{
149    return (X509v3_get_ext_by_critical
150            (x->tbsResponseData.responseExtensions, crit, lastpos));
151}
152
153X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
154{
155    return X509v3_get_ext(x->tbsResponseData.responseExtensions, loc);
156}
157
158X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
159{
160    return X509v3_delete_ext(x->tbsResponseData.responseExtensions, loc);
161}
162
163void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
164                                  int *idx)
165{
166    return X509V3_get_d2i(x->tbsResponseData.responseExtensions, nid, crit,
167                          idx);
168}
169
170int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
171                                int crit, unsigned long flags)
172{
173    return X509V3_add1_i2d(&x->tbsResponseData.responseExtensions, nid,
174                           value, crit, flags);
175}
176
177int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
178{
179    return (X509v3_add_ext(&(x->tbsResponseData.responseExtensions), ex, loc)
180            != NULL);
181}
182
183/* OCSP single response extensions */
184
185int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
186{
187    return X509v3_get_ext_count(x->singleExtensions);
188}
189
190int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
191{
192    return X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos);
193}
194
195int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj,
196                                   int lastpos)
197{
198    return X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos);
199}
200
201int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
202                                        int lastpos)
203{
204    return X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos);
205}
206
207X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
208{
209    return X509v3_get_ext(x->singleExtensions, loc);
210}
211
212X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
213{
214    return X509v3_delete_ext(x->singleExtensions, loc);
215}
216
217void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
218                                   int *idx)
219{
220    return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
221}
222
223int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
224                                 int crit, unsigned long flags)
225{
226    return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
227}
228
229int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
230{
231    return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL);
232}
233
234/* also CRL Entry Extensions */
235
236/* Nonce handling functions */
237
238/*
239 * Add a nonce to an extension stack. A nonce can be specified or if NULL a
240 * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an
241 * OCTET STRING containing the nonce, previous versions used the raw nonce.
242 */
243
244static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
245                           unsigned char *val, int len)
246{
247    unsigned char *tmpval;
248    ASN1_OCTET_STRING os;
249    int ret = 0;
250    if (len <= 0)
251        len = OCSP_DEFAULT_NONCE_LENGTH;
252    /*
253     * Create the OCTET STRING manually by writing out the header and
254     * appending the content octets. This avoids an extra memory allocation
255     * operation in some cases. Applications should *NOT* do this because it
256     * relies on library internals.
257     */
258    os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
259    if (os.length < 0)
260        return 0;
261
262    os.data = OPENSSL_malloc(os.length);
263    if (os.data == NULL)
264        goto err;
265    tmpval = os.data;
266    ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
267    if (val)
268        memcpy(tmpval, val, len);
269    else if (RAND_bytes(tmpval, len) <= 0)
270        goto err;
271    if (X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
272                         &os, 0, X509V3_ADD_REPLACE) <= 0)
273        goto err;
274    ret = 1;
275 err:
276    OPENSSL_free(os.data);
277    return ret;
278}
279
280/* Add nonce to an OCSP request */
281
282int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
283{
284    return ocsp_add1_nonce(&req->tbsRequest.requestExtensions, val, len);
285}
286
287/* Same as above but for a response */
288
289int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
290{
291    return ocsp_add1_nonce(&resp->tbsResponseData.responseExtensions, val,
292                           len);
293}
294
295/*-
296 * Check nonce validity in a request and response.
297 * Return value reflects result:
298 *  1: nonces present and equal.
299 *  2: nonces both absent.
300 *  3: nonce present in response only.
301 *  0: nonces both present and not equal.
302 * -1: nonce in request only.
303 *
304 *  For most responders clients can check return > 0.
305 *  If responder doesn't handle nonces return != 0 may be
306 *  necessary. return == 0 is always an error.
307 */
308
309int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
310{
311    /*
312     * Since we are only interested in the presence or absence of
313     * the nonce and comparing its value there is no need to use
314     * the X509V3 routines: this way we can avoid them allocating an
315     * ASN1_OCTET_STRING structure for the value which would be
316     * freed immediately anyway.
317     */
318
319    int req_idx, resp_idx;
320    X509_EXTENSION *req_ext, *resp_ext;
321    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
322    resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
323    /* Check both absent */
324    if ((req_idx < 0) && (resp_idx < 0))
325        return 2;
326    /* Check in request only */
327    if ((req_idx >= 0) && (resp_idx < 0))
328        return -1;
329    /* Check in response but not request */
330    if ((req_idx < 0) && (resp_idx >= 0))
331        return 3;
332    /*
333     * Otherwise nonce in request and response so retrieve the extensions
334     */
335    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
336    resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
337    if (ASN1_OCTET_STRING_cmp(X509_EXTENSION_get_data(req_ext),
338                              X509_EXTENSION_get_data(resp_ext)))
339        return 0;
340    return 1;
341}
342
343/*
344 * Copy the nonce value (if any) from an OCSP request to a response.
345 */
346
347int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
348{
349    X509_EXTENSION *req_ext;
350    int req_idx;
351    /* Check for nonce in request */
352    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
353    /* If no nonce that's OK */
354    if (req_idx < 0)
355        return 2;
356    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
357    return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
358}
359
360X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim)
361{
362    X509_EXTENSION *x = NULL;
363    OCSP_CRLID *cid = NULL;
364
365    if ((cid = OCSP_CRLID_new()) == NULL)
366        goto err;
367    if (url) {
368        if ((cid->crlUrl = ASN1_IA5STRING_new()) == NULL)
369            goto err;
370        if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
371            goto err;
372    }
373    if (n) {
374        if ((cid->crlNum = ASN1_INTEGER_new()) == NULL)
375            goto err;
376        if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
377            goto err;
378    }
379    if (tim) {
380        if ((cid->crlTime = ASN1_GENERALIZEDTIME_new()) == NULL)
381            goto err;
382        if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
383            goto err;
384    }
385    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
386 err:
387    OCSP_CRLID_free(cid);
388    return x;
389}
390
391/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
392X509_EXTENSION *OCSP_accept_responses_new(char **oids)
393{
394    int nid;
395    STACK_OF(ASN1_OBJECT) *sk = NULL;
396    ASN1_OBJECT *o = NULL;
397    X509_EXTENSION *x = NULL;
398
399    if ((sk = sk_ASN1_OBJECT_new_null()) == NULL)
400        goto err;
401    while (oids && *oids) {
402        if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid)))
403            sk_ASN1_OBJECT_push(sk, o);
404        oids++;
405    }
406    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
407 err:
408    sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
409    return x;
410}
411
412/*  ArchiveCutoff ::= GeneralizedTime */
413X509_EXTENSION *OCSP_archive_cutoff_new(char *tim)
414{
415    X509_EXTENSION *x = NULL;
416    ASN1_GENERALIZEDTIME *gt = NULL;
417
418    if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL)
419        goto err;
420    if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
421        goto err;
422    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
423 err:
424    ASN1_GENERALIZEDTIME_free(gt);
425    return x;
426}
427
428/*
429 * per ACCESS_DESCRIPTION parameter are oids, of which there are currently
430 * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This method
431 * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
432 */
433X509_EXTENSION *OCSP_url_svcloc_new(const X509_NAME *issuer, const char **urls)
434{
435    X509_EXTENSION *x = NULL;
436    ASN1_IA5STRING *ia5 = NULL;
437    OCSP_SERVICELOC *sloc = NULL;
438    ACCESS_DESCRIPTION *ad = NULL;
439
440    if ((sloc = OCSP_SERVICELOC_new()) == NULL)
441        goto err;
442    X509_NAME_free(sloc->issuer);
443    if ((sloc->issuer = X509_NAME_dup(issuer)) == NULL)
444        goto err;
445    if (urls && *urls
446        && (sloc->locator = sk_ACCESS_DESCRIPTION_new_null()) == NULL)
447        goto err;
448    while (urls && *urls) {
449        if ((ad = ACCESS_DESCRIPTION_new()) == NULL)
450            goto err;
451        if ((ad->method = OBJ_nid2obj(NID_ad_OCSP)) == NULL)
452            goto err;
453        if ((ia5 = ASN1_IA5STRING_new()) == NULL)
454            goto err;
455        if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1))
456            goto err;
457        /* ad->location is allocated inside ACCESS_DESCRIPTION_new */
458        ad->location->type = GEN_URI;
459        ad->location->d.ia5 = ia5;
460        ia5 = NULL;
461        if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
462            goto err;
463        ad = NULL;
464        urls++;
465    }
466    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
467 err:
468    ASN1_IA5STRING_free(ia5);
469    ACCESS_DESCRIPTION_free(ad);
470    OCSP_SERVICELOC_free(sloc);
471    return x;
472}
473