11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 51cb0ef41Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at 71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include <stdio.h> 111cb0ef41Sopenharmony_ci#include "internal/cryptlib.h" 121cb0ef41Sopenharmony_ci#include <openssl/objects.h> 131cb0ef41Sopenharmony_ci#include <openssl/x509.h> 141cb0ef41Sopenharmony_ci#include <openssl/ocsp.h> 151cb0ef41Sopenharmony_ci#include "ocsp_local.h" 161cb0ef41Sopenharmony_ci#include <openssl/rand.h> 171cb0ef41Sopenharmony_ci#include <openssl/x509v3.h> 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci/* Standard wrapper functions for extensions */ 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci/* OCSP request extensions */ 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciint OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) 241cb0ef41Sopenharmony_ci{ 251cb0ef41Sopenharmony_ci return X509v3_get_ext_count(x->tbsRequest.requestExtensions); 261cb0ef41Sopenharmony_ci} 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciint OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) 291cb0ef41Sopenharmony_ci{ 301cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_NID 311cb0ef41Sopenharmony_ci (x->tbsRequest.requestExtensions, nid, lastpos)); 321cb0ef41Sopenharmony_ci} 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciint OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, 351cb0ef41Sopenharmony_ci int lastpos) 361cb0ef41Sopenharmony_ci{ 371cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_OBJ 381cb0ef41Sopenharmony_ci (x->tbsRequest.requestExtensions, obj, lastpos)); 391cb0ef41Sopenharmony_ci} 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ciint OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) 421cb0ef41Sopenharmony_ci{ 431cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_critical 441cb0ef41Sopenharmony_ci (x->tbsRequest.requestExtensions, crit, lastpos)); 451cb0ef41Sopenharmony_ci} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) 481cb0ef41Sopenharmony_ci{ 491cb0ef41Sopenharmony_ci return X509v3_get_ext(x->tbsRequest.requestExtensions, loc); 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) 531cb0ef41Sopenharmony_ci{ 541cb0ef41Sopenharmony_ci return X509v3_delete_ext(x->tbsRequest.requestExtensions, loc); 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_civoid *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) 581cb0ef41Sopenharmony_ci{ 591cb0ef41Sopenharmony_ci return X509V3_get_d2i(x->tbsRequest.requestExtensions, nid, crit, idx); 601cb0ef41Sopenharmony_ci} 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ciint OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, 631cb0ef41Sopenharmony_ci unsigned long flags) 641cb0ef41Sopenharmony_ci{ 651cb0ef41Sopenharmony_ci return X509V3_add1_i2d(&x->tbsRequest.requestExtensions, nid, value, 661cb0ef41Sopenharmony_ci crit, flags); 671cb0ef41Sopenharmony_ci} 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ciint OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) 701cb0ef41Sopenharmony_ci{ 711cb0ef41Sopenharmony_ci return (X509v3_add_ext(&(x->tbsRequest.requestExtensions), ex, loc) != 721cb0ef41Sopenharmony_ci NULL); 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci/* Single extensions */ 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ciint OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) 781cb0ef41Sopenharmony_ci{ 791cb0ef41Sopenharmony_ci return X509v3_get_ext_count(x->singleRequestExtensions); 801cb0ef41Sopenharmony_ci} 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ciint OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) 831cb0ef41Sopenharmony_ci{ 841cb0ef41Sopenharmony_ci return X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos); 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciint OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, 881cb0ef41Sopenharmony_ci int lastpos) 891cb0ef41Sopenharmony_ci{ 901cb0ef41Sopenharmony_ci return X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos); 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ciint OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) 941cb0ef41Sopenharmony_ci{ 951cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_critical 961cb0ef41Sopenharmony_ci (x->singleRequestExtensions, crit, lastpos)); 971cb0ef41Sopenharmony_ci} 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) 1001cb0ef41Sopenharmony_ci{ 1011cb0ef41Sopenharmony_ci return X509v3_get_ext(x->singleRequestExtensions, loc); 1021cb0ef41Sopenharmony_ci} 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) 1051cb0ef41Sopenharmony_ci{ 1061cb0ef41Sopenharmony_ci return X509v3_delete_ext(x->singleRequestExtensions, loc); 1071cb0ef41Sopenharmony_ci} 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_civoid *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) 1101cb0ef41Sopenharmony_ci{ 1111cb0ef41Sopenharmony_ci return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ciint OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, 1151cb0ef41Sopenharmony_ci unsigned long flags) 1161cb0ef41Sopenharmony_ci{ 1171cb0ef41Sopenharmony_ci return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, 1181cb0ef41Sopenharmony_ci flags); 1191cb0ef41Sopenharmony_ci} 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ciint OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) 1221cb0ef41Sopenharmony_ci{ 1231cb0ef41Sopenharmony_ci return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); 1241cb0ef41Sopenharmony_ci} 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci/* OCSP Basic response */ 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ciint OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) 1291cb0ef41Sopenharmony_ci{ 1301cb0ef41Sopenharmony_ci return X509v3_get_ext_count(x->tbsResponseData.responseExtensions); 1311cb0ef41Sopenharmony_ci} 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ciint OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) 1341cb0ef41Sopenharmony_ci{ 1351cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_NID 1361cb0ef41Sopenharmony_ci (x->tbsResponseData.responseExtensions, nid, lastpos)); 1371cb0ef41Sopenharmony_ci} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ciint OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, 1401cb0ef41Sopenharmony_ci int lastpos) 1411cb0ef41Sopenharmony_ci{ 1421cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_OBJ 1431cb0ef41Sopenharmony_ci (x->tbsResponseData.responseExtensions, obj, lastpos)); 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ciint OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, 1471cb0ef41Sopenharmony_ci int lastpos) 1481cb0ef41Sopenharmony_ci{ 1491cb0ef41Sopenharmony_ci return (X509v3_get_ext_by_critical 1501cb0ef41Sopenharmony_ci (x->tbsResponseData.responseExtensions, crit, lastpos)); 1511cb0ef41Sopenharmony_ci} 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) 1541cb0ef41Sopenharmony_ci{ 1551cb0ef41Sopenharmony_ci return X509v3_get_ext(x->tbsResponseData.responseExtensions, loc); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) 1591cb0ef41Sopenharmony_ci{ 1601cb0ef41Sopenharmony_ci return X509v3_delete_ext(x->tbsResponseData.responseExtensions, loc); 1611cb0ef41Sopenharmony_ci} 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_civoid *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, 1641cb0ef41Sopenharmony_ci int *idx) 1651cb0ef41Sopenharmony_ci{ 1661cb0ef41Sopenharmony_ci return X509V3_get_d2i(x->tbsResponseData.responseExtensions, nid, crit, 1671cb0ef41Sopenharmony_ci idx); 1681cb0ef41Sopenharmony_ci} 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ciint OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, 1711cb0ef41Sopenharmony_ci int crit, unsigned long flags) 1721cb0ef41Sopenharmony_ci{ 1731cb0ef41Sopenharmony_ci return X509V3_add1_i2d(&x->tbsResponseData.responseExtensions, nid, 1741cb0ef41Sopenharmony_ci value, crit, flags); 1751cb0ef41Sopenharmony_ci} 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ciint OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) 1781cb0ef41Sopenharmony_ci{ 1791cb0ef41Sopenharmony_ci return (X509v3_add_ext(&(x->tbsResponseData.responseExtensions), ex, loc) 1801cb0ef41Sopenharmony_ci != NULL); 1811cb0ef41Sopenharmony_ci} 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci/* OCSP single response extensions */ 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ciint OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) 1861cb0ef41Sopenharmony_ci{ 1871cb0ef41Sopenharmony_ci return X509v3_get_ext_count(x->singleExtensions); 1881cb0ef41Sopenharmony_ci} 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ciint OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) 1911cb0ef41Sopenharmony_ci{ 1921cb0ef41Sopenharmony_ci return X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos); 1931cb0ef41Sopenharmony_ci} 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ciint OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj, 1961cb0ef41Sopenharmony_ci int lastpos) 1971cb0ef41Sopenharmony_ci{ 1981cb0ef41Sopenharmony_ci return X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos); 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ciint OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, 2021cb0ef41Sopenharmony_ci int lastpos) 2031cb0ef41Sopenharmony_ci{ 2041cb0ef41Sopenharmony_ci return X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos); 2051cb0ef41Sopenharmony_ci} 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) 2081cb0ef41Sopenharmony_ci{ 2091cb0ef41Sopenharmony_ci return X509v3_get_ext(x->singleExtensions, loc); 2101cb0ef41Sopenharmony_ci} 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) 2131cb0ef41Sopenharmony_ci{ 2141cb0ef41Sopenharmony_ci return X509v3_delete_ext(x->singleExtensions, loc); 2151cb0ef41Sopenharmony_ci} 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_civoid *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, 2181cb0ef41Sopenharmony_ci int *idx) 2191cb0ef41Sopenharmony_ci{ 2201cb0ef41Sopenharmony_ci return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); 2211cb0ef41Sopenharmony_ci} 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ciint OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, 2241cb0ef41Sopenharmony_ci int crit, unsigned long flags) 2251cb0ef41Sopenharmony_ci{ 2261cb0ef41Sopenharmony_ci return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); 2271cb0ef41Sopenharmony_ci} 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ciint OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) 2301cb0ef41Sopenharmony_ci{ 2311cb0ef41Sopenharmony_ci return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); 2321cb0ef41Sopenharmony_ci} 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci/* also CRL Entry Extensions */ 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci/* Nonce handling functions */ 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci/* 2391cb0ef41Sopenharmony_ci * Add a nonce to an extension stack. A nonce can be specified or if NULL a 2401cb0ef41Sopenharmony_ci * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an 2411cb0ef41Sopenharmony_ci * OCTET STRING containing the nonce, previous versions used the raw nonce. 2421cb0ef41Sopenharmony_ci */ 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_cistatic int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, 2451cb0ef41Sopenharmony_ci unsigned char *val, int len) 2461cb0ef41Sopenharmony_ci{ 2471cb0ef41Sopenharmony_ci unsigned char *tmpval; 2481cb0ef41Sopenharmony_ci ASN1_OCTET_STRING os; 2491cb0ef41Sopenharmony_ci int ret = 0; 2501cb0ef41Sopenharmony_ci if (len <= 0) 2511cb0ef41Sopenharmony_ci len = OCSP_DEFAULT_NONCE_LENGTH; 2521cb0ef41Sopenharmony_ci /* 2531cb0ef41Sopenharmony_ci * Create the OCTET STRING manually by writing out the header and 2541cb0ef41Sopenharmony_ci * appending the content octets. This avoids an extra memory allocation 2551cb0ef41Sopenharmony_ci * operation in some cases. Applications should *NOT* do this because it 2561cb0ef41Sopenharmony_ci * relies on library internals. 2571cb0ef41Sopenharmony_ci */ 2581cb0ef41Sopenharmony_ci os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); 2591cb0ef41Sopenharmony_ci if (os.length < 0) 2601cb0ef41Sopenharmony_ci return 0; 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci os.data = OPENSSL_malloc(os.length); 2631cb0ef41Sopenharmony_ci if (os.data == NULL) 2641cb0ef41Sopenharmony_ci goto err; 2651cb0ef41Sopenharmony_ci tmpval = os.data; 2661cb0ef41Sopenharmony_ci ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); 2671cb0ef41Sopenharmony_ci if (val) 2681cb0ef41Sopenharmony_ci memcpy(tmpval, val, len); 2691cb0ef41Sopenharmony_ci else if (RAND_bytes(tmpval, len) <= 0) 2701cb0ef41Sopenharmony_ci goto err; 2711cb0ef41Sopenharmony_ci if (X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, 2721cb0ef41Sopenharmony_ci &os, 0, X509V3_ADD_REPLACE) <= 0) 2731cb0ef41Sopenharmony_ci goto err; 2741cb0ef41Sopenharmony_ci ret = 1; 2751cb0ef41Sopenharmony_ci err: 2761cb0ef41Sopenharmony_ci OPENSSL_free(os.data); 2771cb0ef41Sopenharmony_ci return ret; 2781cb0ef41Sopenharmony_ci} 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci/* Add nonce to an OCSP request */ 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_ciint OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) 2831cb0ef41Sopenharmony_ci{ 2841cb0ef41Sopenharmony_ci return ocsp_add1_nonce(&req->tbsRequest.requestExtensions, val, len); 2851cb0ef41Sopenharmony_ci} 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci/* Same as above but for a response */ 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ciint OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) 2901cb0ef41Sopenharmony_ci{ 2911cb0ef41Sopenharmony_ci return ocsp_add1_nonce(&resp->tbsResponseData.responseExtensions, val, 2921cb0ef41Sopenharmony_ci len); 2931cb0ef41Sopenharmony_ci} 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci/*- 2961cb0ef41Sopenharmony_ci * Check nonce validity in a request and response. 2971cb0ef41Sopenharmony_ci * Return value reflects result: 2981cb0ef41Sopenharmony_ci * 1: nonces present and equal. 2991cb0ef41Sopenharmony_ci * 2: nonces both absent. 3001cb0ef41Sopenharmony_ci * 3: nonce present in response only. 3011cb0ef41Sopenharmony_ci * 0: nonces both present and not equal. 3021cb0ef41Sopenharmony_ci * -1: nonce in request only. 3031cb0ef41Sopenharmony_ci * 3041cb0ef41Sopenharmony_ci * For most responders clients can check return > 0. 3051cb0ef41Sopenharmony_ci * If responder doesn't handle nonces return != 0 may be 3061cb0ef41Sopenharmony_ci * necessary. return == 0 is always an error. 3071cb0ef41Sopenharmony_ci */ 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ciint OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) 3101cb0ef41Sopenharmony_ci{ 3111cb0ef41Sopenharmony_ci /* 3121cb0ef41Sopenharmony_ci * Since we are only interested in the presence or absence of 3131cb0ef41Sopenharmony_ci * the nonce and comparing its value there is no need to use 3141cb0ef41Sopenharmony_ci * the X509V3 routines: this way we can avoid them allocating an 3151cb0ef41Sopenharmony_ci * ASN1_OCTET_STRING structure for the value which would be 3161cb0ef41Sopenharmony_ci * freed immediately anyway. 3171cb0ef41Sopenharmony_ci */ 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ci int req_idx, resp_idx; 3201cb0ef41Sopenharmony_ci X509_EXTENSION *req_ext, *resp_ext; 3211cb0ef41Sopenharmony_ci req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 3221cb0ef41Sopenharmony_ci resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); 3231cb0ef41Sopenharmony_ci /* Check both absent */ 3241cb0ef41Sopenharmony_ci if ((req_idx < 0) && (resp_idx < 0)) 3251cb0ef41Sopenharmony_ci return 2; 3261cb0ef41Sopenharmony_ci /* Check in request only */ 3271cb0ef41Sopenharmony_ci if ((req_idx >= 0) && (resp_idx < 0)) 3281cb0ef41Sopenharmony_ci return -1; 3291cb0ef41Sopenharmony_ci /* Check in response but not request */ 3301cb0ef41Sopenharmony_ci if ((req_idx < 0) && (resp_idx >= 0)) 3311cb0ef41Sopenharmony_ci return 3; 3321cb0ef41Sopenharmony_ci /* 3331cb0ef41Sopenharmony_ci * Otherwise nonce in request and response so retrieve the extensions 3341cb0ef41Sopenharmony_ci */ 3351cb0ef41Sopenharmony_ci req_ext = OCSP_REQUEST_get_ext(req, req_idx); 3361cb0ef41Sopenharmony_ci resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); 3371cb0ef41Sopenharmony_ci if (ASN1_OCTET_STRING_cmp(X509_EXTENSION_get_data(req_ext), 3381cb0ef41Sopenharmony_ci X509_EXTENSION_get_data(resp_ext))) 3391cb0ef41Sopenharmony_ci return 0; 3401cb0ef41Sopenharmony_ci return 1; 3411cb0ef41Sopenharmony_ci} 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci/* 3441cb0ef41Sopenharmony_ci * Copy the nonce value (if any) from an OCSP request to a response. 3451cb0ef41Sopenharmony_ci */ 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ciint OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) 3481cb0ef41Sopenharmony_ci{ 3491cb0ef41Sopenharmony_ci X509_EXTENSION *req_ext; 3501cb0ef41Sopenharmony_ci int req_idx; 3511cb0ef41Sopenharmony_ci /* Check for nonce in request */ 3521cb0ef41Sopenharmony_ci req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 3531cb0ef41Sopenharmony_ci /* If no nonce that's OK */ 3541cb0ef41Sopenharmony_ci if (req_idx < 0) 3551cb0ef41Sopenharmony_ci return 2; 3561cb0ef41Sopenharmony_ci req_ext = OCSP_REQUEST_get_ext(req, req_idx); 3571cb0ef41Sopenharmony_ci return OCSP_BASICRESP_add_ext(resp, req_ext, -1); 3581cb0ef41Sopenharmony_ci} 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim) 3611cb0ef41Sopenharmony_ci{ 3621cb0ef41Sopenharmony_ci X509_EXTENSION *x = NULL; 3631cb0ef41Sopenharmony_ci OCSP_CRLID *cid = NULL; 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci if ((cid = OCSP_CRLID_new()) == NULL) 3661cb0ef41Sopenharmony_ci goto err; 3671cb0ef41Sopenharmony_ci if (url) { 3681cb0ef41Sopenharmony_ci if ((cid->crlUrl = ASN1_IA5STRING_new()) == NULL) 3691cb0ef41Sopenharmony_ci goto err; 3701cb0ef41Sopenharmony_ci if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) 3711cb0ef41Sopenharmony_ci goto err; 3721cb0ef41Sopenharmony_ci } 3731cb0ef41Sopenharmony_ci if (n) { 3741cb0ef41Sopenharmony_ci if ((cid->crlNum = ASN1_INTEGER_new()) == NULL) 3751cb0ef41Sopenharmony_ci goto err; 3761cb0ef41Sopenharmony_ci if (!(ASN1_INTEGER_set(cid->crlNum, *n))) 3771cb0ef41Sopenharmony_ci goto err; 3781cb0ef41Sopenharmony_ci } 3791cb0ef41Sopenharmony_ci if (tim) { 3801cb0ef41Sopenharmony_ci if ((cid->crlTime = ASN1_GENERALIZEDTIME_new()) == NULL) 3811cb0ef41Sopenharmony_ci goto err; 3821cb0ef41Sopenharmony_ci if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 3831cb0ef41Sopenharmony_ci goto err; 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); 3861cb0ef41Sopenharmony_ci err: 3871cb0ef41Sopenharmony_ci OCSP_CRLID_free(cid); 3881cb0ef41Sopenharmony_ci return x; 3891cb0ef41Sopenharmony_ci} 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 3921cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_accept_responses_new(char **oids) 3931cb0ef41Sopenharmony_ci{ 3941cb0ef41Sopenharmony_ci int nid; 3951cb0ef41Sopenharmony_ci STACK_OF(ASN1_OBJECT) *sk = NULL; 3961cb0ef41Sopenharmony_ci ASN1_OBJECT *o = NULL; 3971cb0ef41Sopenharmony_ci X509_EXTENSION *x = NULL; 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci if ((sk = sk_ASN1_OBJECT_new_null()) == NULL) 4001cb0ef41Sopenharmony_ci goto err; 4011cb0ef41Sopenharmony_ci while (oids && *oids) { 4021cb0ef41Sopenharmony_ci if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) 4031cb0ef41Sopenharmony_ci sk_ASN1_OBJECT_push(sk, o); 4041cb0ef41Sopenharmony_ci oids++; 4051cb0ef41Sopenharmony_ci } 4061cb0ef41Sopenharmony_ci x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); 4071cb0ef41Sopenharmony_ci err: 4081cb0ef41Sopenharmony_ci sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 4091cb0ef41Sopenharmony_ci return x; 4101cb0ef41Sopenharmony_ci} 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci/* ArchiveCutoff ::= GeneralizedTime */ 4131cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_archive_cutoff_new(char *tim) 4141cb0ef41Sopenharmony_ci{ 4151cb0ef41Sopenharmony_ci X509_EXTENSION *x = NULL; 4161cb0ef41Sopenharmony_ci ASN1_GENERALIZEDTIME *gt = NULL; 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL) 4191cb0ef41Sopenharmony_ci goto err; 4201cb0ef41Sopenharmony_ci if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) 4211cb0ef41Sopenharmony_ci goto err; 4221cb0ef41Sopenharmony_ci x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); 4231cb0ef41Sopenharmony_ci err: 4241cb0ef41Sopenharmony_ci ASN1_GENERALIZEDTIME_free(gt); 4251cb0ef41Sopenharmony_ci return x; 4261cb0ef41Sopenharmony_ci} 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci/* 4291cb0ef41Sopenharmony_ci * per ACCESS_DESCRIPTION parameter are oids, of which there are currently 4301cb0ef41Sopenharmony_ci * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method 4311cb0ef41Sopenharmony_ci * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. 4321cb0ef41Sopenharmony_ci */ 4331cb0ef41Sopenharmony_ciX509_EXTENSION *OCSP_url_svcloc_new(const X509_NAME *issuer, const char **urls) 4341cb0ef41Sopenharmony_ci{ 4351cb0ef41Sopenharmony_ci X509_EXTENSION *x = NULL; 4361cb0ef41Sopenharmony_ci ASN1_IA5STRING *ia5 = NULL; 4371cb0ef41Sopenharmony_ci OCSP_SERVICELOC *sloc = NULL; 4381cb0ef41Sopenharmony_ci ACCESS_DESCRIPTION *ad = NULL; 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci if ((sloc = OCSP_SERVICELOC_new()) == NULL) 4411cb0ef41Sopenharmony_ci goto err; 4421cb0ef41Sopenharmony_ci X509_NAME_free(sloc->issuer); 4431cb0ef41Sopenharmony_ci if ((sloc->issuer = X509_NAME_dup(issuer)) == NULL) 4441cb0ef41Sopenharmony_ci goto err; 4451cb0ef41Sopenharmony_ci if (urls && *urls 4461cb0ef41Sopenharmony_ci && (sloc->locator = sk_ACCESS_DESCRIPTION_new_null()) == NULL) 4471cb0ef41Sopenharmony_ci goto err; 4481cb0ef41Sopenharmony_ci while (urls && *urls) { 4491cb0ef41Sopenharmony_ci if ((ad = ACCESS_DESCRIPTION_new()) == NULL) 4501cb0ef41Sopenharmony_ci goto err; 4511cb0ef41Sopenharmony_ci if ((ad->method = OBJ_nid2obj(NID_ad_OCSP)) == NULL) 4521cb0ef41Sopenharmony_ci goto err; 4531cb0ef41Sopenharmony_ci if ((ia5 = ASN1_IA5STRING_new()) == NULL) 4541cb0ef41Sopenharmony_ci goto err; 4551cb0ef41Sopenharmony_ci if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) 4561cb0ef41Sopenharmony_ci goto err; 4571cb0ef41Sopenharmony_ci /* ad->location is allocated inside ACCESS_DESCRIPTION_new */ 4581cb0ef41Sopenharmony_ci ad->location->type = GEN_URI; 4591cb0ef41Sopenharmony_ci ad->location->d.ia5 = ia5; 4601cb0ef41Sopenharmony_ci ia5 = NULL; 4611cb0ef41Sopenharmony_ci if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) 4621cb0ef41Sopenharmony_ci goto err; 4631cb0ef41Sopenharmony_ci ad = NULL; 4641cb0ef41Sopenharmony_ci urls++; 4651cb0ef41Sopenharmony_ci } 4661cb0ef41Sopenharmony_ci x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); 4671cb0ef41Sopenharmony_ci err: 4681cb0ef41Sopenharmony_ci ASN1_IA5STRING_free(ia5); 4691cb0ef41Sopenharmony_ci ACCESS_DESCRIPTION_free(ad); 4701cb0ef41Sopenharmony_ci OCSP_SERVICELOC_free(sloc); 4711cb0ef41Sopenharmony_ci return x; 4721cb0ef41Sopenharmony_ci} 473