11cb0ef41Sopenharmony_ci/*
21cb0ef41Sopenharmony_ci * Copyright 2001-2021 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 <time.h>
121cb0ef41Sopenharmony_ci#include "internal/cryptlib.h"
131cb0ef41Sopenharmony_ci#include <openssl/asn1.h>
141cb0ef41Sopenharmony_ci#include <openssl/objects.h>
151cb0ef41Sopenharmony_ci#include <openssl/x509.h>
161cb0ef41Sopenharmony_ci#include <openssl/pem.h>
171cb0ef41Sopenharmony_ci#include <openssl/x509v3.h>
181cb0ef41Sopenharmony_ci#include <openssl/ocsp.h>
191cb0ef41Sopenharmony_ci#include "ocsp_local.h"
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci/*
221cb0ef41Sopenharmony_ci * Utility functions related to sending OCSP requests and extracting relevant
231cb0ef41Sopenharmony_ci * information from the response.
241cb0ef41Sopenharmony_ci */
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci/*
271cb0ef41Sopenharmony_ci * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer:
281cb0ef41Sopenharmony_ci * useful if we want to add extensions.
291cb0ef41Sopenharmony_ci */
301cb0ef41Sopenharmony_ciOCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
311cb0ef41Sopenharmony_ci{
321cb0ef41Sopenharmony_ci    OCSP_ONEREQ *one = NULL;
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci    if ((one = OCSP_ONEREQ_new()) == NULL)
351cb0ef41Sopenharmony_ci        return NULL;
361cb0ef41Sopenharmony_ci    OCSP_CERTID_free(one->reqCert);
371cb0ef41Sopenharmony_ci    one->reqCert = cid;
381cb0ef41Sopenharmony_ci    if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one)) {
391cb0ef41Sopenharmony_ci        one->reqCert = NULL; /* do not free on error */
401cb0ef41Sopenharmony_ci        OCSP_ONEREQ_free(one);
411cb0ef41Sopenharmony_ci        return NULL;
421cb0ef41Sopenharmony_ci    }
431cb0ef41Sopenharmony_ci    return one;
441cb0ef41Sopenharmony_ci}
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci/* Set requestorName from an X509_NAME structure */
471cb0ef41Sopenharmony_ciint OCSP_request_set1_name(OCSP_REQUEST *req, const X509_NAME *nm)
481cb0ef41Sopenharmony_ci{
491cb0ef41Sopenharmony_ci    GENERAL_NAME *gen = GENERAL_NAME_new();
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci    if (gen == NULL)
521cb0ef41Sopenharmony_ci        return 0;
531cb0ef41Sopenharmony_ci    if (!X509_NAME_set(&gen->d.directoryName, nm)) {
541cb0ef41Sopenharmony_ci        GENERAL_NAME_free(gen);
551cb0ef41Sopenharmony_ci        return 0;
561cb0ef41Sopenharmony_ci    }
571cb0ef41Sopenharmony_ci    gen->type = GEN_DIRNAME;
581cb0ef41Sopenharmony_ci    GENERAL_NAME_free(req->tbsRequest.requestorName);
591cb0ef41Sopenharmony_ci    req->tbsRequest.requestorName = gen;
601cb0ef41Sopenharmony_ci    return 1;
611cb0ef41Sopenharmony_ci}
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci/* Add a certificate to an OCSP request */
641cb0ef41Sopenharmony_ciint OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
651cb0ef41Sopenharmony_ci{
661cb0ef41Sopenharmony_ci    if (req->optionalSignature == NULL
671cb0ef41Sopenharmony_ci            && (req->optionalSignature = OCSP_SIGNATURE_new()) == NULL)
681cb0ef41Sopenharmony_ci        return 0;
691cb0ef41Sopenharmony_ci    if (cert == NULL)
701cb0ef41Sopenharmony_ci        return 1;
711cb0ef41Sopenharmony_ci    return ossl_x509_add_cert_new(&req->optionalSignature->certs, cert,
721cb0ef41Sopenharmony_ci                                  X509_ADD_FLAG_UP_REF);
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci/*
761cb0ef41Sopenharmony_ci * Sign an OCSP request set the requestorName to the subject name of an
771cb0ef41Sopenharmony_ci * optional signers certificate and include one or more optional certificates
781cb0ef41Sopenharmony_ci * in the request. Behaves like PKCS7_sign().
791cb0ef41Sopenharmony_ci */
801cb0ef41Sopenharmony_ciint OCSP_request_sign(OCSP_REQUEST *req,
811cb0ef41Sopenharmony_ci                      X509 *signer,
821cb0ef41Sopenharmony_ci                      EVP_PKEY *key,
831cb0ef41Sopenharmony_ci                      const EVP_MD *dgst,
841cb0ef41Sopenharmony_ci                      STACK_OF(X509) *certs, unsigned long flags)
851cb0ef41Sopenharmony_ci{
861cb0ef41Sopenharmony_ci    if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
871cb0ef41Sopenharmony_ci        goto err;
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci    if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL)
901cb0ef41Sopenharmony_ci        goto err;
911cb0ef41Sopenharmony_ci    if (key != NULL) {
921cb0ef41Sopenharmony_ci        if (!X509_check_private_key(signer, key)) {
931cb0ef41Sopenharmony_ci            ERR_raise(ERR_LIB_OCSP,
941cb0ef41Sopenharmony_ci                      OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
951cb0ef41Sopenharmony_ci            goto err;
961cb0ef41Sopenharmony_ci        }
971cb0ef41Sopenharmony_ci        if (!OCSP_REQUEST_sign(req, key, dgst, signer->libctx, signer->propq))
981cb0ef41Sopenharmony_ci            goto err;
991cb0ef41Sopenharmony_ci    }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci    if ((flags & OCSP_NOCERTS) == 0) {
1021cb0ef41Sopenharmony_ci        if (!OCSP_request_add1_cert(req, signer)
1031cb0ef41Sopenharmony_ci            || !X509_add_certs(req->optionalSignature->certs, certs,
1041cb0ef41Sopenharmony_ci                               X509_ADD_FLAG_UP_REF))
1051cb0ef41Sopenharmony_ci            goto err;
1061cb0ef41Sopenharmony_ci    }
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci    return 1;
1091cb0ef41Sopenharmony_ci err:
1101cb0ef41Sopenharmony_ci    OCSP_SIGNATURE_free(req->optionalSignature);
1111cb0ef41Sopenharmony_ci    req->optionalSignature = NULL;
1121cb0ef41Sopenharmony_ci    return 0;
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci/* Get response status */
1161cb0ef41Sopenharmony_ciint OCSP_response_status(OCSP_RESPONSE *resp)
1171cb0ef41Sopenharmony_ci{
1181cb0ef41Sopenharmony_ci    return ASN1_ENUMERATED_get(resp->responseStatus);
1191cb0ef41Sopenharmony_ci}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci/*
1221cb0ef41Sopenharmony_ci * Extract basic response from OCSP_RESPONSE or NULL if no basic response
1231cb0ef41Sopenharmony_ci * present.
1241cb0ef41Sopenharmony_ci */
1251cb0ef41Sopenharmony_ciOCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
1261cb0ef41Sopenharmony_ci{
1271cb0ef41Sopenharmony_ci    OCSP_RESPBYTES *rb = resp->responseBytes;
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci    if (rb == NULL) {
1301cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA);
1311cb0ef41Sopenharmony_ci        return NULL;
1321cb0ef41Sopenharmony_ci    }
1331cb0ef41Sopenharmony_ci    if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
1341cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE);
1351cb0ef41Sopenharmony_ci        return NULL;
1361cb0ef41Sopenharmony_ci    }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci    return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
1391cb0ef41Sopenharmony_ci}
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ciconst ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs)
1421cb0ef41Sopenharmony_ci{
1431cb0ef41Sopenharmony_ci    return bs->signature;
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciconst X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs)
1471cb0ef41Sopenharmony_ci{
1481cb0ef41Sopenharmony_ci    return &bs->signatureAlgorithm;
1491cb0ef41Sopenharmony_ci}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ciconst OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs)
1521cb0ef41Sopenharmony_ci{
1531cb0ef41Sopenharmony_ci    return &bs->tbsResponseData;
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci/* Return number of OCSP_SINGLERESP responses present in a basic response */
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ciint OCSP_resp_count(OCSP_BASICRESP *bs)
1591cb0ef41Sopenharmony_ci{
1601cb0ef41Sopenharmony_ci    if (bs == NULL)
1611cb0ef41Sopenharmony_ci        return -1;
1621cb0ef41Sopenharmony_ci    return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses);
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci/* Extract an OCSP_SINGLERESP response with a given index */
1661cb0ef41Sopenharmony_ciOCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
1671cb0ef41Sopenharmony_ci{
1681cb0ef41Sopenharmony_ci    if (bs == NULL)
1691cb0ef41Sopenharmony_ci        return NULL;
1701cb0ef41Sopenharmony_ci    return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx);
1711cb0ef41Sopenharmony_ci}
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ciconst ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP *bs)
1741cb0ef41Sopenharmony_ci{
1751cb0ef41Sopenharmony_ci    return bs->tbsResponseData.producedAt;
1761cb0ef41Sopenharmony_ci}
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ciconst STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs)
1791cb0ef41Sopenharmony_ci{
1801cb0ef41Sopenharmony_ci    return bs->certs;
1811cb0ef41Sopenharmony_ci}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ciint OCSP_resp_get0_id(const OCSP_BASICRESP *bs,
1841cb0ef41Sopenharmony_ci                      const ASN1_OCTET_STRING **pid,
1851cb0ef41Sopenharmony_ci                      const X509_NAME **pname)
1861cb0ef41Sopenharmony_ci{
1871cb0ef41Sopenharmony_ci    const OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci    if (rid->type == V_OCSP_RESPID_NAME) {
1901cb0ef41Sopenharmony_ci        *pname = rid->value.byName;
1911cb0ef41Sopenharmony_ci        *pid = NULL;
1921cb0ef41Sopenharmony_ci    } else if (rid->type == V_OCSP_RESPID_KEY) {
1931cb0ef41Sopenharmony_ci        *pid = rid->value.byKey;
1941cb0ef41Sopenharmony_ci        *pname = NULL;
1951cb0ef41Sopenharmony_ci    } else {
1961cb0ef41Sopenharmony_ci        return 0;
1971cb0ef41Sopenharmony_ci    }
1981cb0ef41Sopenharmony_ci    return 1;
1991cb0ef41Sopenharmony_ci}
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ciint OCSP_resp_get1_id(const OCSP_BASICRESP *bs,
2021cb0ef41Sopenharmony_ci                      ASN1_OCTET_STRING **pid,
2031cb0ef41Sopenharmony_ci                      X509_NAME **pname)
2041cb0ef41Sopenharmony_ci{
2051cb0ef41Sopenharmony_ci    const OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci    if (rid->type == V_OCSP_RESPID_NAME) {
2081cb0ef41Sopenharmony_ci        *pname = X509_NAME_dup(rid->value.byName);
2091cb0ef41Sopenharmony_ci        *pid = NULL;
2101cb0ef41Sopenharmony_ci    } else if (rid->type == V_OCSP_RESPID_KEY) {
2111cb0ef41Sopenharmony_ci        *pid = ASN1_OCTET_STRING_dup(rid->value.byKey);
2121cb0ef41Sopenharmony_ci        *pname = NULL;
2131cb0ef41Sopenharmony_ci    } else {
2141cb0ef41Sopenharmony_ci        return 0;
2151cb0ef41Sopenharmony_ci    }
2161cb0ef41Sopenharmony_ci    if (*pname == NULL && *pid == NULL)
2171cb0ef41Sopenharmony_ci        return 0;
2181cb0ef41Sopenharmony_ci    return 1;
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci/* Look single response matching a given certificate ID */
2221cb0ef41Sopenharmony_ciint OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
2231cb0ef41Sopenharmony_ci{
2241cb0ef41Sopenharmony_ci    int i;
2251cb0ef41Sopenharmony_ci    STACK_OF(OCSP_SINGLERESP) *sresp;
2261cb0ef41Sopenharmony_ci    OCSP_SINGLERESP *single;
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci    if (bs == NULL)
2291cb0ef41Sopenharmony_ci        return -1;
2301cb0ef41Sopenharmony_ci    if (last < 0)
2311cb0ef41Sopenharmony_ci        last = 0;
2321cb0ef41Sopenharmony_ci    else
2331cb0ef41Sopenharmony_ci        last++;
2341cb0ef41Sopenharmony_ci    sresp = bs->tbsResponseData.responses;
2351cb0ef41Sopenharmony_ci    for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
2361cb0ef41Sopenharmony_ci        single = sk_OCSP_SINGLERESP_value(sresp, i);
2371cb0ef41Sopenharmony_ci        if (!OCSP_id_cmp(id, single->certId))
2381cb0ef41Sopenharmony_ci            return i;
2391cb0ef41Sopenharmony_ci    }
2401cb0ef41Sopenharmony_ci    return -1;
2411cb0ef41Sopenharmony_ci}
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci/*
2441cb0ef41Sopenharmony_ci * Extract status information from an OCSP_SINGLERESP structure. Note: the
2451cb0ef41Sopenharmony_ci * revtime and reason values are only set if the certificate status is
2461cb0ef41Sopenharmony_ci * revoked. Returns numerical value of status.
2471cb0ef41Sopenharmony_ci */
2481cb0ef41Sopenharmony_ciint OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
2491cb0ef41Sopenharmony_ci                            ASN1_GENERALIZEDTIME **revtime,
2501cb0ef41Sopenharmony_ci                            ASN1_GENERALIZEDTIME **thisupd,
2511cb0ef41Sopenharmony_ci                            ASN1_GENERALIZEDTIME **nextupd)
2521cb0ef41Sopenharmony_ci{
2531cb0ef41Sopenharmony_ci    int ret;
2541cb0ef41Sopenharmony_ci    OCSP_CERTSTATUS *cst;
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci    if (single == NULL)
2571cb0ef41Sopenharmony_ci        return -1;
2581cb0ef41Sopenharmony_ci    cst = single->certStatus;
2591cb0ef41Sopenharmony_ci    ret = cst->type;
2601cb0ef41Sopenharmony_ci    if (ret == V_OCSP_CERTSTATUS_REVOKED) {
2611cb0ef41Sopenharmony_ci        OCSP_REVOKEDINFO *rev = cst->value.revoked;
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci        if (revtime)
2641cb0ef41Sopenharmony_ci            *revtime = rev->revocationTime;
2651cb0ef41Sopenharmony_ci        if (reason) {
2661cb0ef41Sopenharmony_ci            if (rev->revocationReason)
2671cb0ef41Sopenharmony_ci                *reason = ASN1_ENUMERATED_get(rev->revocationReason);
2681cb0ef41Sopenharmony_ci            else
2691cb0ef41Sopenharmony_ci                *reason = -1;
2701cb0ef41Sopenharmony_ci        }
2711cb0ef41Sopenharmony_ci    }
2721cb0ef41Sopenharmony_ci    if (thisupd != NULL)
2731cb0ef41Sopenharmony_ci        *thisupd = single->thisUpdate;
2741cb0ef41Sopenharmony_ci    if (nextupd != NULL)
2751cb0ef41Sopenharmony_ci        *nextupd = single->nextUpdate;
2761cb0ef41Sopenharmony_ci    return ret;
2771cb0ef41Sopenharmony_ci}
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci/*
2801cb0ef41Sopenharmony_ci * This function combines the previous ones: look up a certificate ID and if
2811cb0ef41Sopenharmony_ci * found extract status information. Return 0 is successful.
2821cb0ef41Sopenharmony_ci */
2831cb0ef41Sopenharmony_ciint OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
2841cb0ef41Sopenharmony_ci                          int *reason,
2851cb0ef41Sopenharmony_ci                          ASN1_GENERALIZEDTIME **revtime,
2861cb0ef41Sopenharmony_ci                          ASN1_GENERALIZEDTIME **thisupd,
2871cb0ef41Sopenharmony_ci                          ASN1_GENERALIZEDTIME **nextupd)
2881cb0ef41Sopenharmony_ci{
2891cb0ef41Sopenharmony_ci    int i = OCSP_resp_find(bs, id, -1);
2901cb0ef41Sopenharmony_ci    OCSP_SINGLERESP *single;
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci    /* Maybe check for multiple responses and give an error? */
2931cb0ef41Sopenharmony_ci    if (i < 0)
2941cb0ef41Sopenharmony_ci        return 0;
2951cb0ef41Sopenharmony_ci    single = OCSP_resp_get0(bs, i);
2961cb0ef41Sopenharmony_ci    i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
2971cb0ef41Sopenharmony_ci    if (status != NULL)
2981cb0ef41Sopenharmony_ci        *status = i;
2991cb0ef41Sopenharmony_ci    return 1;
3001cb0ef41Sopenharmony_ci}
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci/*
3031cb0ef41Sopenharmony_ci * Check validity of thisUpdate and nextUpdate fields. It is possible that
3041cb0ef41Sopenharmony_ci * the request will take a few seconds to process and/or the time won't be
3051cb0ef41Sopenharmony_ci * totally accurate. Therefore to avoid rejecting otherwise valid time we
3061cb0ef41Sopenharmony_ci * allow the times to be within 'nsec' of the current time. Also to avoid
3071cb0ef41Sopenharmony_ci * accepting very old responses without a nextUpdate field an optional maxage
3081cb0ef41Sopenharmony_ci * parameter specifies the maximum age the thisUpdate field can be.
3091cb0ef41Sopenharmony_ci */
3101cb0ef41Sopenharmony_ciint OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
3111cb0ef41Sopenharmony_ci                        ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
3121cb0ef41Sopenharmony_ci{
3131cb0ef41Sopenharmony_ci    int ret = 1;
3141cb0ef41Sopenharmony_ci    time_t t_now, t_tmp;
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci    time(&t_now);
3171cb0ef41Sopenharmony_ci    /* Check thisUpdate is valid and not more than nsec in the future */
3181cb0ef41Sopenharmony_ci    if (!ASN1_GENERALIZEDTIME_check(thisupd)) {
3191cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
3201cb0ef41Sopenharmony_ci        ret = 0;
3211cb0ef41Sopenharmony_ci    } else {
3221cb0ef41Sopenharmony_ci        t_tmp = t_now + nsec;
3231cb0ef41Sopenharmony_ci        if (X509_cmp_time(thisupd, &t_tmp) > 0) {
3241cb0ef41Sopenharmony_ci            ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID);
3251cb0ef41Sopenharmony_ci            ret = 0;
3261cb0ef41Sopenharmony_ci        }
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci        /*
3291cb0ef41Sopenharmony_ci         * If maxsec specified check thisUpdate is not more than maxsec in
3301cb0ef41Sopenharmony_ci         * the past
3311cb0ef41Sopenharmony_ci         */
3321cb0ef41Sopenharmony_ci        if (maxsec >= 0) {
3331cb0ef41Sopenharmony_ci            t_tmp = t_now - maxsec;
3341cb0ef41Sopenharmony_ci            if (X509_cmp_time(thisupd, &t_tmp) < 0) {
3351cb0ef41Sopenharmony_ci                ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD);
3361cb0ef41Sopenharmony_ci                ret = 0;
3371cb0ef41Sopenharmony_ci            }
3381cb0ef41Sopenharmony_ci        }
3391cb0ef41Sopenharmony_ci    }
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_ci    if (nextupd == NULL)
3421cb0ef41Sopenharmony_ci        return ret;
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci    /* Check nextUpdate is valid and not more than nsec in the past */
3451cb0ef41Sopenharmony_ci    if (!ASN1_GENERALIZEDTIME_check(nextupd)) {
3461cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
3471cb0ef41Sopenharmony_ci        ret = 0;
3481cb0ef41Sopenharmony_ci    } else {
3491cb0ef41Sopenharmony_ci        t_tmp = t_now - nsec;
3501cb0ef41Sopenharmony_ci        if (X509_cmp_time(nextupd, &t_tmp) < 0) {
3511cb0ef41Sopenharmony_ci            ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED);
3521cb0ef41Sopenharmony_ci            ret = 0;
3531cb0ef41Sopenharmony_ci        }
3541cb0ef41Sopenharmony_ci    }
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci    /* Also don't allow nextUpdate to precede thisUpdate */
3571cb0ef41Sopenharmony_ci    if (ASN1_STRING_cmp(nextupd, thisupd) < 0) {
3581cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
3591cb0ef41Sopenharmony_ci        ret = 0;
3601cb0ef41Sopenharmony_ci    }
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci    return ret;
3631cb0ef41Sopenharmony_ci}
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ciconst OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single)
3661cb0ef41Sopenharmony_ci{
3671cb0ef41Sopenharmony_ci    return single->certId;
3681cb0ef41Sopenharmony_ci}
369