1109998Smarkm/* ocsp_vfy.c */ 2280297Sjkim/* 3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280297Sjkim * 2000. 5109998Smarkm */ 6109998Smarkm/* ==================================================================== 7127128Snectar * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 8109998Smarkm * 9109998Smarkm * Redistribution and use in source and binary forms, with or without 10109998Smarkm * modification, are permitted provided that the following conditions 11109998Smarkm * are met: 12109998Smarkm * 13109998Smarkm * 1. Redistributions of source code must retain the above copyright 14280297Sjkim * notice, this list of conditions and the following disclaimer. 15109998Smarkm * 16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 17109998Smarkm * notice, this list of conditions and the following disclaimer in 18109998Smarkm * the documentation and/or other materials provided with the 19109998Smarkm * distribution. 20109998Smarkm * 21109998Smarkm * 3. All advertising materials mentioning features or use of this 22109998Smarkm * software must display the following acknowledgment: 23109998Smarkm * "This product includes software developed by the OpenSSL Project 24109998Smarkm * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25109998Smarkm * 26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27109998Smarkm * endorse or promote products derived from this software without 28109998Smarkm * prior written permission. For written permission, please contact 29109998Smarkm * licensing@OpenSSL.org. 30109998Smarkm * 31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 32109998Smarkm * nor may "OpenSSL" appear in their names without prior written 33109998Smarkm * permission of the OpenSSL Project. 34109998Smarkm * 35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 36109998Smarkm * acknowledgment: 37109998Smarkm * "This product includes software developed by the OpenSSL Project 38109998Smarkm * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39109998Smarkm * 40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 52109998Smarkm * ==================================================================== 53109998Smarkm * 54109998Smarkm * This product includes cryptographic software written by Eric Young 55109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 56109998Smarkm * Hudson (tjh@cryptsoft.com). 57109998Smarkm * 58109998Smarkm */ 59109998Smarkm 60109998Smarkm#include <openssl/ocsp.h> 61109998Smarkm#include <openssl/err.h> 62109998Smarkm#include <string.h> 63109998Smarkm 64280297Sjkimstatic int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, 65280297Sjkim STACK_OF(X509) *certs, X509_STORE *st, 66280297Sjkim unsigned long flags); 67109998Smarkmstatic X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); 68280297Sjkimstatic int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, 69280297Sjkim unsigned long flags); 70280297Sjkimstatic int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, 71280297Sjkim OCSP_CERTID **ret); 72280297Sjkimstatic int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, 73280297Sjkim STACK_OF(OCSP_SINGLERESP) *sresp); 74109998Smarkmstatic int ocsp_check_delegated(X509 *x, int flags); 75280297Sjkimstatic int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, 76280297Sjkim X509_NAME *nm, STACK_OF(X509) *certs, 77280297Sjkim X509_STORE *st, unsigned long flags); 78109998Smarkm 79109998Smarkm/* Verify a basic response message */ 80109998Smarkm 81109998Smarkmint OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 82280297Sjkim X509_STORE *st, unsigned long flags) 83280297Sjkim{ 84280297Sjkim X509 *signer, *x; 85280297Sjkim STACK_OF(X509) *chain = NULL; 86284283Sjkim STACK_OF(X509) *untrusted = NULL; 87280297Sjkim X509_STORE_CTX ctx; 88280297Sjkim int i, ret = 0; 89280297Sjkim ret = ocsp_find_signer(&signer, bs, certs, st, flags); 90280297Sjkim if (!ret) { 91280297Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, 92280297Sjkim OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); 93280297Sjkim goto end; 94280297Sjkim } 95280297Sjkim if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) 96280297Sjkim flags |= OCSP_NOVERIFY; 97280297Sjkim if (!(flags & OCSP_NOSIGS)) { 98280297Sjkim EVP_PKEY *skey; 99280297Sjkim skey = X509_get_pubkey(signer); 100280297Sjkim if (skey) { 101280297Sjkim ret = OCSP_BASICRESP_verify(bs, skey, 0); 102280297Sjkim EVP_PKEY_free(skey); 103280297Sjkim } 104280297Sjkim if (!skey || ret <= 0) { 105280297Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); 106280297Sjkim goto end; 107280297Sjkim } 108280297Sjkim } 109280297Sjkim if (!(flags & OCSP_NOVERIFY)) { 110280297Sjkim int init_res; 111284283Sjkim if (flags & OCSP_NOCHAIN) { 112284283Sjkim untrusted = NULL; 113284283Sjkim } else if (bs->certs && certs) { 114284283Sjkim untrusted = sk_X509_dup(bs->certs); 115284283Sjkim for (i = 0; i < sk_X509_num(certs); i++) { 116284283Sjkim if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { 117284283Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); 118284283Sjkim goto end; 119284283Sjkim } 120284283Sjkim } 121325337Sjkim } else if (certs != NULL) { 122325337Sjkim untrusted = certs; 123284283Sjkim } else { 124284283Sjkim untrusted = bs->certs; 125284283Sjkim } 126284283Sjkim init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); 127280297Sjkim if (!init_res) { 128280297Sjkim ret = -1; 129280297Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); 130280297Sjkim goto end; 131280297Sjkim } 132109998Smarkm 133280297Sjkim X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); 134280297Sjkim ret = X509_verify_cert(&ctx); 135280297Sjkim chain = X509_STORE_CTX_get1_chain(&ctx); 136280297Sjkim X509_STORE_CTX_cleanup(&ctx); 137280297Sjkim if (ret <= 0) { 138280297Sjkim i = X509_STORE_CTX_get_error(&ctx); 139280297Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, 140280297Sjkim OCSP_R_CERTIFICATE_VERIFY_ERROR); 141280297Sjkim ERR_add_error_data(2, "Verify error:", 142280297Sjkim X509_verify_cert_error_string(i)); 143280297Sjkim goto end; 144280297Sjkim } 145280297Sjkim if (flags & OCSP_NOCHECKS) { 146280297Sjkim ret = 1; 147280297Sjkim goto end; 148280297Sjkim } 149280297Sjkim /* 150280297Sjkim * At this point we have a valid certificate chain need to verify it 151280297Sjkim * against the OCSP issuer criteria. 152280297Sjkim */ 153280297Sjkim ret = ocsp_check_issuer(bs, chain, flags); 154109998Smarkm 155280297Sjkim /* If fatal error or valid match then finish */ 156280297Sjkim if (ret != 0) 157280297Sjkim goto end; 158109998Smarkm 159280297Sjkim /* 160280297Sjkim * Easy case: explicitly trusted. Get root CA and check for explicit 161280297Sjkim * trust 162280297Sjkim */ 163280297Sjkim if (flags & OCSP_NOEXPLICIT) 164280297Sjkim goto end; 165109998Smarkm 166280297Sjkim x = sk_X509_value(chain, sk_X509_num(chain) - 1); 167280297Sjkim if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { 168280297Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); 169280297Sjkim goto end; 170280297Sjkim } 171280297Sjkim ret = 1; 172280297Sjkim } 173109998Smarkm 174280297Sjkim end: 175280297Sjkim if (chain) 176280297Sjkim sk_X509_pop_free(chain, X509_free); 177284283Sjkim if (bs->certs && certs) 178284283Sjkim sk_X509_free(untrusted); 179280297Sjkim return ret; 180280297Sjkim} 181109998Smarkm 182280297Sjkimstatic int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, 183280297Sjkim STACK_OF(X509) *certs, X509_STORE *st, 184280297Sjkim unsigned long flags) 185280297Sjkim{ 186280297Sjkim X509 *signer; 187280297Sjkim OCSP_RESPID *rid = bs->tbsResponseData->responderId; 188280297Sjkim if ((signer = ocsp_find_signer_sk(certs, rid))) { 189280297Sjkim *psigner = signer; 190280297Sjkim return 2; 191280297Sjkim } 192280297Sjkim if (!(flags & OCSP_NOINTERN) && 193280297Sjkim (signer = ocsp_find_signer_sk(bs->certs, rid))) { 194280297Sjkim *psigner = signer; 195280297Sjkim return 1; 196280297Sjkim } 197280297Sjkim /* Maybe lookup from store if by subject name */ 198109998Smarkm 199280297Sjkim *psigner = NULL; 200280297Sjkim return 0; 201280297Sjkim} 202109998Smarkm 203109998Smarkmstatic X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 204280297Sjkim{ 205280297Sjkim int i; 206280297Sjkim unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 207280297Sjkim X509 *x; 208109998Smarkm 209280297Sjkim /* Easy if lookup by name */ 210280297Sjkim if (id->type == V_OCSP_RESPID_NAME) 211280297Sjkim return X509_find_by_subject(certs, id->value.byName); 212109998Smarkm 213280297Sjkim /* Lookup by key hash */ 214109998Smarkm 215280297Sjkim /* If key hash isn't SHA1 length then forget it */ 216280297Sjkim if (id->value.byKey->length != SHA_DIGEST_LENGTH) 217280297Sjkim return NULL; 218280297Sjkim keyhash = id->value.byKey->data; 219280297Sjkim /* Calculate hash of each key and compare */ 220280297Sjkim for (i = 0; i < sk_X509_num(certs); i++) { 221280297Sjkim x = sk_X509_value(certs, i); 222280297Sjkim X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 223280297Sjkim if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 224280297Sjkim return x; 225280297Sjkim } 226280297Sjkim return NULL; 227280297Sjkim} 228109998Smarkm 229280297Sjkimstatic int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, 230280297Sjkim unsigned long flags) 231280297Sjkim{ 232280297Sjkim STACK_OF(OCSP_SINGLERESP) *sresp; 233280297Sjkim X509 *signer, *sca; 234280297Sjkim OCSP_CERTID *caid = NULL; 235280297Sjkim int i; 236280297Sjkim sresp = bs->tbsResponseData->responses; 237109998Smarkm 238280297Sjkim if (sk_X509_num(chain) <= 0) { 239280297Sjkim OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); 240280297Sjkim return -1; 241280297Sjkim } 242109998Smarkm 243280297Sjkim /* See if the issuer IDs match. */ 244280297Sjkim i = ocsp_check_ids(sresp, &caid); 245109998Smarkm 246280297Sjkim /* If ID mismatch or other error then return */ 247280297Sjkim if (i <= 0) 248280297Sjkim return i; 249109998Smarkm 250280297Sjkim signer = sk_X509_value(chain, 0); 251280297Sjkim /* Check to see if OCSP responder CA matches request CA */ 252280297Sjkim if (sk_X509_num(chain) > 1) { 253280297Sjkim sca = sk_X509_value(chain, 1); 254280297Sjkim i = ocsp_match_issuerid(sca, caid, sresp); 255280297Sjkim if (i < 0) 256280297Sjkim return i; 257280297Sjkim if (i) { 258280297Sjkim /* We have a match, if extensions OK then success */ 259280297Sjkim if (ocsp_check_delegated(signer, flags)) 260280297Sjkim return 1; 261280297Sjkim return 0; 262280297Sjkim } 263280297Sjkim } 264109998Smarkm 265280297Sjkim /* Otherwise check if OCSP request signed directly by request CA */ 266280297Sjkim return ocsp_match_issuerid(signer, caid, sresp); 267280297Sjkim} 268109998Smarkm 269280297Sjkim/* 270280297Sjkim * Check the issuer certificate IDs for equality. If there is a mismatch with 271280297Sjkim * the same algorithm then there's no point trying to match any certificates 272280297Sjkim * against the issuer. If the issuer IDs all match then we just need to check 273280297Sjkim * equality against one of them. 274280297Sjkim */ 275109998Smarkm 276109998Smarkmstatic int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) 277280297Sjkim{ 278280297Sjkim OCSP_CERTID *tmpid, *cid; 279280297Sjkim int i, idcount; 280109998Smarkm 281280297Sjkim idcount = sk_OCSP_SINGLERESP_num(sresp); 282280297Sjkim if (idcount <= 0) { 283280297Sjkim OCSPerr(OCSP_F_OCSP_CHECK_IDS, 284280297Sjkim OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); 285280297Sjkim return -1; 286280297Sjkim } 287109998Smarkm 288280297Sjkim cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; 289109998Smarkm 290280297Sjkim *ret = NULL; 291109998Smarkm 292280297Sjkim for (i = 1; i < idcount; i++) { 293280297Sjkim tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; 294280297Sjkim /* Check to see if IDs match */ 295280297Sjkim if (OCSP_id_issuer_cmp(cid, tmpid)) { 296280297Sjkim /* If algoritm mismatch let caller deal with it */ 297280297Sjkim if (OBJ_cmp(tmpid->hashAlgorithm->algorithm, 298280297Sjkim cid->hashAlgorithm->algorithm)) 299280297Sjkim return 2; 300280297Sjkim /* Else mismatch */ 301280297Sjkim return 0; 302280297Sjkim } 303280297Sjkim } 304109998Smarkm 305280297Sjkim /* All IDs match: only need to check one ID */ 306280297Sjkim *ret = cid; 307280297Sjkim return 1; 308280297Sjkim} 309109998Smarkm 310109998Smarkmstatic int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, 311280297Sjkim STACK_OF(OCSP_SINGLERESP) *sresp) 312280297Sjkim{ 313280297Sjkim /* If only one ID to match then do it */ 314280297Sjkim if (cid) { 315280297Sjkim const EVP_MD *dgst; 316280297Sjkim X509_NAME *iname; 317280297Sjkim int mdlen; 318280297Sjkim unsigned char md[EVP_MAX_MD_SIZE]; 319280297Sjkim if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) { 320280297Sjkim OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, 321280297Sjkim OCSP_R_UNKNOWN_MESSAGE_DIGEST); 322280297Sjkim return -1; 323280297Sjkim } 324109998Smarkm 325280297Sjkim mdlen = EVP_MD_size(dgst); 326280297Sjkim if (mdlen < 0) 327280297Sjkim return -1; 328280297Sjkim if ((cid->issuerNameHash->length != mdlen) || 329280297Sjkim (cid->issuerKeyHash->length != mdlen)) 330280297Sjkim return 0; 331280297Sjkim iname = X509_get_subject_name(cert); 332280297Sjkim if (!X509_NAME_digest(iname, dgst, md, NULL)) 333280297Sjkim return -1; 334280297Sjkim if (memcmp(md, cid->issuerNameHash->data, mdlen)) 335280297Sjkim return 0; 336280297Sjkim X509_pubkey_digest(cert, dgst, md, NULL); 337280297Sjkim if (memcmp(md, cid->issuerKeyHash->data, mdlen)) 338280297Sjkim return 0; 339109998Smarkm 340280297Sjkim return 1; 341109998Smarkm 342280297Sjkim } else { 343280297Sjkim /* We have to match the whole lot */ 344280297Sjkim int i, ret; 345280297Sjkim OCSP_CERTID *tmpid; 346280297Sjkim for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { 347280297Sjkim tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; 348280297Sjkim ret = ocsp_match_issuerid(cert, tmpid, NULL); 349280297Sjkim if (ret <= 0) 350280297Sjkim return ret; 351280297Sjkim } 352280297Sjkim return 1; 353280297Sjkim } 354109998Smarkm 355280297Sjkim} 356280297Sjkim 357109998Smarkmstatic int ocsp_check_delegated(X509 *x, int flags) 358280297Sjkim{ 359280297Sjkim X509_check_purpose(x, -1, 0); 360280297Sjkim if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN)) 361280297Sjkim return 1; 362280297Sjkim OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); 363280297Sjkim return 0; 364280297Sjkim} 365109998Smarkm 366280297Sjkim/* 367280297Sjkim * Verify an OCSP request. This is fortunately much easier than OCSP response 368280297Sjkim * verify. Just find the signers certificate and verify it against a given 369280297Sjkim * trust value. 370109998Smarkm */ 371109998Smarkm 372280297Sjkimint OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, 373280297Sjkim X509_STORE *store, unsigned long flags) 374280297Sjkim{ 375280297Sjkim X509 *signer; 376280297Sjkim X509_NAME *nm; 377280297Sjkim GENERAL_NAME *gen; 378280297Sjkim int ret; 379280297Sjkim X509_STORE_CTX ctx; 380280297Sjkim if (!req->optionalSignature) { 381280297Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); 382280297Sjkim return 0; 383280297Sjkim } 384280297Sjkim gen = req->tbsRequest->requestorName; 385280297Sjkim if (!gen || gen->type != GEN_DIRNAME) { 386280297Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, 387280297Sjkim OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); 388280297Sjkim return 0; 389280297Sjkim } 390280297Sjkim nm = gen->d.directoryName; 391280297Sjkim ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); 392280297Sjkim if (ret <= 0) { 393280297Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, 394280297Sjkim OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); 395280297Sjkim return 0; 396280297Sjkim } 397280297Sjkim if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) 398280297Sjkim flags |= OCSP_NOVERIFY; 399280297Sjkim if (!(flags & OCSP_NOSIGS)) { 400280297Sjkim EVP_PKEY *skey; 401280297Sjkim skey = X509_get_pubkey(signer); 402280297Sjkim ret = OCSP_REQUEST_verify(req, skey); 403280297Sjkim EVP_PKEY_free(skey); 404280297Sjkim if (ret <= 0) { 405280297Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); 406280297Sjkim return 0; 407280297Sjkim } 408280297Sjkim } 409280297Sjkim if (!(flags & OCSP_NOVERIFY)) { 410280297Sjkim int init_res; 411280297Sjkim if (flags & OCSP_NOCHAIN) 412280297Sjkim init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); 413280297Sjkim else 414280297Sjkim init_res = X509_STORE_CTX_init(&ctx, store, signer, 415280297Sjkim req->optionalSignature->certs); 416280297Sjkim if (!init_res) { 417280297Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); 418280297Sjkim return 0; 419280297Sjkim } 420109998Smarkm 421280297Sjkim X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); 422280297Sjkim X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); 423280297Sjkim ret = X509_verify_cert(&ctx); 424280297Sjkim X509_STORE_CTX_cleanup(&ctx); 425280297Sjkim if (ret <= 0) { 426280297Sjkim ret = X509_STORE_CTX_get_error(&ctx); 427280297Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, 428280297Sjkim OCSP_R_CERTIFICATE_VERIFY_ERROR); 429280297Sjkim ERR_add_error_data(2, "Verify error:", 430280297Sjkim X509_verify_cert_error_string(ret)); 431280297Sjkim return 0; 432109998Smarkm } 433280297Sjkim } 434280297Sjkim return 1; 435280297Sjkim} 436109998Smarkm 437280297Sjkimstatic int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, 438280297Sjkim X509_NAME *nm, STACK_OF(X509) *certs, 439280297Sjkim X509_STORE *st, unsigned long flags) 440280297Sjkim{ 441280297Sjkim X509 *signer; 442280297Sjkim if (!(flags & OCSP_NOINTERN)) { 443280297Sjkim signer = X509_find_by_subject(req->optionalSignature->certs, nm); 444280297Sjkim if (signer) { 445280297Sjkim *psigner = signer; 446280297Sjkim return 1; 447280297Sjkim } 448280297Sjkim } 449109998Smarkm 450280297Sjkim signer = X509_find_by_subject(certs, nm); 451280297Sjkim if (signer) { 452280297Sjkim *psigner = signer; 453280297Sjkim return 2; 454280297Sjkim } 455280297Sjkim return 0; 456280297Sjkim} 457