1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include <time.h> 12e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 13e1051a39Sopenharmony_ci#include <openssl/asn1.h> 14e1051a39Sopenharmony_ci#include <openssl/objects.h> 15e1051a39Sopenharmony_ci#include <openssl/x509.h> 16e1051a39Sopenharmony_ci#include <openssl/pem.h> 17e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 18e1051a39Sopenharmony_ci#include <openssl/ocsp.h> 19e1051a39Sopenharmony_ci#include "ocsp_local.h" 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci/* 22e1051a39Sopenharmony_ci * Utility functions related to sending OCSP requests and extracting relevant 23e1051a39Sopenharmony_ci * information from the response. 24e1051a39Sopenharmony_ci */ 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci/* 27e1051a39Sopenharmony_ci * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer: 28e1051a39Sopenharmony_ci * useful if we want to add extensions. 29e1051a39Sopenharmony_ci */ 30e1051a39Sopenharmony_ciOCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) 31e1051a39Sopenharmony_ci{ 32e1051a39Sopenharmony_ci OCSP_ONEREQ *one = NULL; 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci if ((one = OCSP_ONEREQ_new()) == NULL) 35e1051a39Sopenharmony_ci return NULL; 36e1051a39Sopenharmony_ci OCSP_CERTID_free(one->reqCert); 37e1051a39Sopenharmony_ci one->reqCert = cid; 38e1051a39Sopenharmony_ci if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one)) { 39e1051a39Sopenharmony_ci one->reqCert = NULL; /* do not free on error */ 40e1051a39Sopenharmony_ci OCSP_ONEREQ_free(one); 41e1051a39Sopenharmony_ci return NULL; 42e1051a39Sopenharmony_ci } 43e1051a39Sopenharmony_ci return one; 44e1051a39Sopenharmony_ci} 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ci/* Set requestorName from an X509_NAME structure */ 47e1051a39Sopenharmony_ciint OCSP_request_set1_name(OCSP_REQUEST *req, const X509_NAME *nm) 48e1051a39Sopenharmony_ci{ 49e1051a39Sopenharmony_ci GENERAL_NAME *gen = GENERAL_NAME_new(); 50e1051a39Sopenharmony_ci 51e1051a39Sopenharmony_ci if (gen == NULL) 52e1051a39Sopenharmony_ci return 0; 53e1051a39Sopenharmony_ci if (!X509_NAME_set(&gen->d.directoryName, nm)) { 54e1051a39Sopenharmony_ci GENERAL_NAME_free(gen); 55e1051a39Sopenharmony_ci return 0; 56e1051a39Sopenharmony_ci } 57e1051a39Sopenharmony_ci gen->type = GEN_DIRNAME; 58e1051a39Sopenharmony_ci GENERAL_NAME_free(req->tbsRequest.requestorName); 59e1051a39Sopenharmony_ci req->tbsRequest.requestorName = gen; 60e1051a39Sopenharmony_ci return 1; 61e1051a39Sopenharmony_ci} 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ci/* Add a certificate to an OCSP request */ 64e1051a39Sopenharmony_ciint OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) 65e1051a39Sopenharmony_ci{ 66e1051a39Sopenharmony_ci if (req->optionalSignature == NULL 67e1051a39Sopenharmony_ci && (req->optionalSignature = OCSP_SIGNATURE_new()) == NULL) 68e1051a39Sopenharmony_ci return 0; 69e1051a39Sopenharmony_ci if (cert == NULL) 70e1051a39Sopenharmony_ci return 1; 71e1051a39Sopenharmony_ci return ossl_x509_add_cert_new(&req->optionalSignature->certs, cert, 72e1051a39Sopenharmony_ci X509_ADD_FLAG_UP_REF); 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci/* 76e1051a39Sopenharmony_ci * Sign an OCSP request set the requestorName to the subject name of an 77e1051a39Sopenharmony_ci * optional signers certificate and include one or more optional certificates 78e1051a39Sopenharmony_ci * in the request. Behaves like PKCS7_sign(). 79e1051a39Sopenharmony_ci */ 80e1051a39Sopenharmony_ciint OCSP_request_sign(OCSP_REQUEST *req, 81e1051a39Sopenharmony_ci X509 *signer, 82e1051a39Sopenharmony_ci EVP_PKEY *key, 83e1051a39Sopenharmony_ci const EVP_MD *dgst, 84e1051a39Sopenharmony_ci STACK_OF(X509) *certs, unsigned long flags) 85e1051a39Sopenharmony_ci{ 86e1051a39Sopenharmony_ci if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) 87e1051a39Sopenharmony_ci goto err; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL) 90e1051a39Sopenharmony_ci goto err; 91e1051a39Sopenharmony_ci if (key != NULL) { 92e1051a39Sopenharmony_ci if (!X509_check_private_key(signer, key)) { 93e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, 94e1051a39Sopenharmony_ci OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 95e1051a39Sopenharmony_ci goto err; 96e1051a39Sopenharmony_ci } 97e1051a39Sopenharmony_ci if (!OCSP_REQUEST_sign(req, key, dgst, signer->libctx, signer->propq)) 98e1051a39Sopenharmony_ci goto err; 99e1051a39Sopenharmony_ci } 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci if ((flags & OCSP_NOCERTS) == 0) { 102e1051a39Sopenharmony_ci if (!OCSP_request_add1_cert(req, signer) 103e1051a39Sopenharmony_ci || !X509_add_certs(req->optionalSignature->certs, certs, 104e1051a39Sopenharmony_ci X509_ADD_FLAG_UP_REF)) 105e1051a39Sopenharmony_ci goto err; 106e1051a39Sopenharmony_ci } 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci return 1; 109e1051a39Sopenharmony_ci err: 110e1051a39Sopenharmony_ci OCSP_SIGNATURE_free(req->optionalSignature); 111e1051a39Sopenharmony_ci req->optionalSignature = NULL; 112e1051a39Sopenharmony_ci return 0; 113e1051a39Sopenharmony_ci} 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci/* Get response status */ 116e1051a39Sopenharmony_ciint OCSP_response_status(OCSP_RESPONSE *resp) 117e1051a39Sopenharmony_ci{ 118e1051a39Sopenharmony_ci return ASN1_ENUMERATED_get(resp->responseStatus); 119e1051a39Sopenharmony_ci} 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci/* 122e1051a39Sopenharmony_ci * Extract basic response from OCSP_RESPONSE or NULL if no basic response 123e1051a39Sopenharmony_ci * present. 124e1051a39Sopenharmony_ci */ 125e1051a39Sopenharmony_ciOCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) 126e1051a39Sopenharmony_ci{ 127e1051a39Sopenharmony_ci OCSP_RESPBYTES *rb = resp->responseBytes; 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci if (rb == NULL) { 130e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA); 131e1051a39Sopenharmony_ci return NULL; 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { 134e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE); 135e1051a39Sopenharmony_ci return NULL; 136e1051a39Sopenharmony_ci } 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP)); 139e1051a39Sopenharmony_ci} 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ciconst ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs) 142e1051a39Sopenharmony_ci{ 143e1051a39Sopenharmony_ci return bs->signature; 144e1051a39Sopenharmony_ci} 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ciconst X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs) 147e1051a39Sopenharmony_ci{ 148e1051a39Sopenharmony_ci return &bs->signatureAlgorithm; 149e1051a39Sopenharmony_ci} 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ciconst OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs) 152e1051a39Sopenharmony_ci{ 153e1051a39Sopenharmony_ci return &bs->tbsResponseData; 154e1051a39Sopenharmony_ci} 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci/* Return number of OCSP_SINGLERESP responses present in a basic response */ 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ciint OCSP_resp_count(OCSP_BASICRESP *bs) 159e1051a39Sopenharmony_ci{ 160e1051a39Sopenharmony_ci if (bs == NULL) 161e1051a39Sopenharmony_ci return -1; 162e1051a39Sopenharmony_ci return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses); 163e1051a39Sopenharmony_ci} 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci/* Extract an OCSP_SINGLERESP response with a given index */ 166e1051a39Sopenharmony_ciOCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) 167e1051a39Sopenharmony_ci{ 168e1051a39Sopenharmony_ci if (bs == NULL) 169e1051a39Sopenharmony_ci return NULL; 170e1051a39Sopenharmony_ci return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx); 171e1051a39Sopenharmony_ci} 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ciconst ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP *bs) 174e1051a39Sopenharmony_ci{ 175e1051a39Sopenharmony_ci return bs->tbsResponseData.producedAt; 176e1051a39Sopenharmony_ci} 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ciconst STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) 179e1051a39Sopenharmony_ci{ 180e1051a39Sopenharmony_ci return bs->certs; 181e1051a39Sopenharmony_ci} 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ciint OCSP_resp_get0_id(const OCSP_BASICRESP *bs, 184e1051a39Sopenharmony_ci const ASN1_OCTET_STRING **pid, 185e1051a39Sopenharmony_ci const X509_NAME **pname) 186e1051a39Sopenharmony_ci{ 187e1051a39Sopenharmony_ci const OCSP_RESPID *rid = &bs->tbsResponseData.responderId; 188e1051a39Sopenharmony_ci 189e1051a39Sopenharmony_ci if (rid->type == V_OCSP_RESPID_NAME) { 190e1051a39Sopenharmony_ci *pname = rid->value.byName; 191e1051a39Sopenharmony_ci *pid = NULL; 192e1051a39Sopenharmony_ci } else if (rid->type == V_OCSP_RESPID_KEY) { 193e1051a39Sopenharmony_ci *pid = rid->value.byKey; 194e1051a39Sopenharmony_ci *pname = NULL; 195e1051a39Sopenharmony_ci } else { 196e1051a39Sopenharmony_ci return 0; 197e1051a39Sopenharmony_ci } 198e1051a39Sopenharmony_ci return 1; 199e1051a39Sopenharmony_ci} 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ciint OCSP_resp_get1_id(const OCSP_BASICRESP *bs, 202e1051a39Sopenharmony_ci ASN1_OCTET_STRING **pid, 203e1051a39Sopenharmony_ci X509_NAME **pname) 204e1051a39Sopenharmony_ci{ 205e1051a39Sopenharmony_ci const OCSP_RESPID *rid = &bs->tbsResponseData.responderId; 206e1051a39Sopenharmony_ci 207e1051a39Sopenharmony_ci if (rid->type == V_OCSP_RESPID_NAME) { 208e1051a39Sopenharmony_ci *pname = X509_NAME_dup(rid->value.byName); 209e1051a39Sopenharmony_ci *pid = NULL; 210e1051a39Sopenharmony_ci } else if (rid->type == V_OCSP_RESPID_KEY) { 211e1051a39Sopenharmony_ci *pid = ASN1_OCTET_STRING_dup(rid->value.byKey); 212e1051a39Sopenharmony_ci *pname = NULL; 213e1051a39Sopenharmony_ci } else { 214e1051a39Sopenharmony_ci return 0; 215e1051a39Sopenharmony_ci } 216e1051a39Sopenharmony_ci if (*pname == NULL && *pid == NULL) 217e1051a39Sopenharmony_ci return 0; 218e1051a39Sopenharmony_ci return 1; 219e1051a39Sopenharmony_ci} 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci/* Look single response matching a given certificate ID */ 222e1051a39Sopenharmony_ciint OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) 223e1051a39Sopenharmony_ci{ 224e1051a39Sopenharmony_ci int i; 225e1051a39Sopenharmony_ci STACK_OF(OCSP_SINGLERESP) *sresp; 226e1051a39Sopenharmony_ci OCSP_SINGLERESP *single; 227e1051a39Sopenharmony_ci 228e1051a39Sopenharmony_ci if (bs == NULL) 229e1051a39Sopenharmony_ci return -1; 230e1051a39Sopenharmony_ci if (last < 0) 231e1051a39Sopenharmony_ci last = 0; 232e1051a39Sopenharmony_ci else 233e1051a39Sopenharmony_ci last++; 234e1051a39Sopenharmony_ci sresp = bs->tbsResponseData.responses; 235e1051a39Sopenharmony_ci for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) { 236e1051a39Sopenharmony_ci single = sk_OCSP_SINGLERESP_value(sresp, i); 237e1051a39Sopenharmony_ci if (!OCSP_id_cmp(id, single->certId)) 238e1051a39Sopenharmony_ci return i; 239e1051a39Sopenharmony_ci } 240e1051a39Sopenharmony_ci return -1; 241e1051a39Sopenharmony_ci} 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci/* 244e1051a39Sopenharmony_ci * Extract status information from an OCSP_SINGLERESP structure. Note: the 245e1051a39Sopenharmony_ci * revtime and reason values are only set if the certificate status is 246e1051a39Sopenharmony_ci * revoked. Returns numerical value of status. 247e1051a39Sopenharmony_ci */ 248e1051a39Sopenharmony_ciint OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, 249e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME **revtime, 250e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME **thisupd, 251e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME **nextupd) 252e1051a39Sopenharmony_ci{ 253e1051a39Sopenharmony_ci int ret; 254e1051a39Sopenharmony_ci OCSP_CERTSTATUS *cst; 255e1051a39Sopenharmony_ci 256e1051a39Sopenharmony_ci if (single == NULL) 257e1051a39Sopenharmony_ci return -1; 258e1051a39Sopenharmony_ci cst = single->certStatus; 259e1051a39Sopenharmony_ci ret = cst->type; 260e1051a39Sopenharmony_ci if (ret == V_OCSP_CERTSTATUS_REVOKED) { 261e1051a39Sopenharmony_ci OCSP_REVOKEDINFO *rev = cst->value.revoked; 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci if (revtime) 264e1051a39Sopenharmony_ci *revtime = rev->revocationTime; 265e1051a39Sopenharmony_ci if (reason) { 266e1051a39Sopenharmony_ci if (rev->revocationReason) 267e1051a39Sopenharmony_ci *reason = ASN1_ENUMERATED_get(rev->revocationReason); 268e1051a39Sopenharmony_ci else 269e1051a39Sopenharmony_ci *reason = -1; 270e1051a39Sopenharmony_ci } 271e1051a39Sopenharmony_ci } 272e1051a39Sopenharmony_ci if (thisupd != NULL) 273e1051a39Sopenharmony_ci *thisupd = single->thisUpdate; 274e1051a39Sopenharmony_ci if (nextupd != NULL) 275e1051a39Sopenharmony_ci *nextupd = single->nextUpdate; 276e1051a39Sopenharmony_ci return ret; 277e1051a39Sopenharmony_ci} 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci/* 280e1051a39Sopenharmony_ci * This function combines the previous ones: look up a certificate ID and if 281e1051a39Sopenharmony_ci * found extract status information. Return 0 is successful. 282e1051a39Sopenharmony_ci */ 283e1051a39Sopenharmony_ciint OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, 284e1051a39Sopenharmony_ci int *reason, 285e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME **revtime, 286e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME **thisupd, 287e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME **nextupd) 288e1051a39Sopenharmony_ci{ 289e1051a39Sopenharmony_ci int i = OCSP_resp_find(bs, id, -1); 290e1051a39Sopenharmony_ci OCSP_SINGLERESP *single; 291e1051a39Sopenharmony_ci 292e1051a39Sopenharmony_ci /* Maybe check for multiple responses and give an error? */ 293e1051a39Sopenharmony_ci if (i < 0) 294e1051a39Sopenharmony_ci return 0; 295e1051a39Sopenharmony_ci single = OCSP_resp_get0(bs, i); 296e1051a39Sopenharmony_ci i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); 297e1051a39Sopenharmony_ci if (status != NULL) 298e1051a39Sopenharmony_ci *status = i; 299e1051a39Sopenharmony_ci return 1; 300e1051a39Sopenharmony_ci} 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_ci/* 303e1051a39Sopenharmony_ci * Check validity of thisUpdate and nextUpdate fields. It is possible that 304e1051a39Sopenharmony_ci * the request will take a few seconds to process and/or the time won't be 305e1051a39Sopenharmony_ci * totally accurate. Therefore to avoid rejecting otherwise valid time we 306e1051a39Sopenharmony_ci * allow the times to be within 'nsec' of the current time. Also to avoid 307e1051a39Sopenharmony_ci * accepting very old responses without a nextUpdate field an optional maxage 308e1051a39Sopenharmony_ci * parameter specifies the maximum age the thisUpdate field can be. 309e1051a39Sopenharmony_ci */ 310e1051a39Sopenharmony_ciint OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, 311e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) 312e1051a39Sopenharmony_ci{ 313e1051a39Sopenharmony_ci int ret = 1; 314e1051a39Sopenharmony_ci time_t t_now, t_tmp; 315e1051a39Sopenharmony_ci 316e1051a39Sopenharmony_ci time(&t_now); 317e1051a39Sopenharmony_ci /* Check thisUpdate is valid and not more than nsec in the future */ 318e1051a39Sopenharmony_ci if (!ASN1_GENERALIZEDTIME_check(thisupd)) { 319e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD); 320e1051a39Sopenharmony_ci ret = 0; 321e1051a39Sopenharmony_ci } else { 322e1051a39Sopenharmony_ci t_tmp = t_now + nsec; 323e1051a39Sopenharmony_ci if (X509_cmp_time(thisupd, &t_tmp) > 0) { 324e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID); 325e1051a39Sopenharmony_ci ret = 0; 326e1051a39Sopenharmony_ci } 327e1051a39Sopenharmony_ci 328e1051a39Sopenharmony_ci /* 329e1051a39Sopenharmony_ci * If maxsec specified check thisUpdate is not more than maxsec in 330e1051a39Sopenharmony_ci * the past 331e1051a39Sopenharmony_ci */ 332e1051a39Sopenharmony_ci if (maxsec >= 0) { 333e1051a39Sopenharmony_ci t_tmp = t_now - maxsec; 334e1051a39Sopenharmony_ci if (X509_cmp_time(thisupd, &t_tmp) < 0) { 335e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD); 336e1051a39Sopenharmony_ci ret = 0; 337e1051a39Sopenharmony_ci } 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci } 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ci if (nextupd == NULL) 342e1051a39Sopenharmony_ci return ret; 343e1051a39Sopenharmony_ci 344e1051a39Sopenharmony_ci /* Check nextUpdate is valid and not more than nsec in the past */ 345e1051a39Sopenharmony_ci if (!ASN1_GENERALIZEDTIME_check(nextupd)) { 346e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); 347e1051a39Sopenharmony_ci ret = 0; 348e1051a39Sopenharmony_ci } else { 349e1051a39Sopenharmony_ci t_tmp = t_now - nsec; 350e1051a39Sopenharmony_ci if (X509_cmp_time(nextupd, &t_tmp) < 0) { 351e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED); 352e1051a39Sopenharmony_ci ret = 0; 353e1051a39Sopenharmony_ci } 354e1051a39Sopenharmony_ci } 355e1051a39Sopenharmony_ci 356e1051a39Sopenharmony_ci /* Also don't allow nextUpdate to precede thisUpdate */ 357e1051a39Sopenharmony_ci if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { 358e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); 359e1051a39Sopenharmony_ci ret = 0; 360e1051a39Sopenharmony_ci } 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci return ret; 363e1051a39Sopenharmony_ci} 364e1051a39Sopenharmony_ci 365e1051a39Sopenharmony_ciconst OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) 366e1051a39Sopenharmony_ci{ 367e1051a39Sopenharmony_ci return single->certId; 368e1051a39Sopenharmony_ci} 369