1109998Smarkm/* ocsp_vfy.c */ 2280304Sjkim/* 3280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280304Sjkim * 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 14280304Sjkim * 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 64280304Sjkimstatic int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, 65280304Sjkim STACK_OF(X509) *certs, X509_STORE *st, 66280304Sjkim unsigned long flags); 67109998Smarkmstatic X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); 68280304Sjkimstatic int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, 69280304Sjkim unsigned long flags); 70280304Sjkimstatic int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, 71280304Sjkim OCSP_CERTID **ret); 72280304Sjkimstatic int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, 73280304Sjkim STACK_OF(OCSP_SINGLERESP) *sresp); 74109998Smarkmstatic int ocsp_check_delegated(X509 *x, int flags); 75280304Sjkimstatic int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, 76280304Sjkim X509_NAME *nm, STACK_OF(X509) *certs, 77280304Sjkim 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, 82280304Sjkim X509_STORE *st, unsigned long flags) 83280304Sjkim{ 84280304Sjkim X509 *signer, *x; 85280304Sjkim STACK_OF(X509) *chain = NULL; 86284285Sjkim STACK_OF(X509) *untrusted = NULL; 87280304Sjkim X509_STORE_CTX ctx; 88280304Sjkim int i, ret = 0; 89280304Sjkim ret = ocsp_find_signer(&signer, bs, certs, st, flags); 90280304Sjkim if (!ret) { 91280304Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, 92280304Sjkim OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); 93280304Sjkim goto end; 94280304Sjkim } 95280304Sjkim if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) 96280304Sjkim flags |= OCSP_NOVERIFY; 97280304Sjkim if (!(flags & OCSP_NOSIGS)) { 98280304Sjkim EVP_PKEY *skey; 99280304Sjkim skey = X509_get_pubkey(signer); 100280304Sjkim if (skey) { 101280304Sjkim ret = OCSP_BASICRESP_verify(bs, skey, 0); 102280304Sjkim EVP_PKEY_free(skey); 103280304Sjkim } 104280304Sjkim if (!skey || ret <= 0) { 105280304Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); 106280304Sjkim goto end; 107280304Sjkim } 108280304Sjkim } 109280304Sjkim if (!(flags & OCSP_NOVERIFY)) { 110280304Sjkim int init_res; 111284285Sjkim if (flags & OCSP_NOCHAIN) { 112284285Sjkim untrusted = NULL; 113284285Sjkim } else if (bs->certs && certs) { 114284285Sjkim untrusted = sk_X509_dup(bs->certs); 115284285Sjkim for (i = 0; i < sk_X509_num(certs); i++) { 116284285Sjkim if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { 117284285Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); 118284285Sjkim goto end; 119284285Sjkim } 120284285Sjkim } 121284285Sjkim } else { 122284285Sjkim untrusted = bs->certs; 123284285Sjkim } 124284285Sjkim init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); 125280304Sjkim if (!init_res) { 126280304Sjkim ret = -1; 127280304Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); 128280304Sjkim goto end; 129280304Sjkim } 130109998Smarkm 131280304Sjkim X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); 132280304Sjkim ret = X509_verify_cert(&ctx); 133280304Sjkim chain = X509_STORE_CTX_get1_chain(&ctx); 134280304Sjkim X509_STORE_CTX_cleanup(&ctx); 135280304Sjkim if (ret <= 0) { 136280304Sjkim i = X509_STORE_CTX_get_error(&ctx); 137280304Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, 138280304Sjkim OCSP_R_CERTIFICATE_VERIFY_ERROR); 139280304Sjkim ERR_add_error_data(2, "Verify error:", 140280304Sjkim X509_verify_cert_error_string(i)); 141280304Sjkim goto end; 142280304Sjkim } 143280304Sjkim if (flags & OCSP_NOCHECKS) { 144280304Sjkim ret = 1; 145280304Sjkim goto end; 146280304Sjkim } 147280304Sjkim /* 148280304Sjkim * At this point we have a valid certificate chain need to verify it 149280304Sjkim * against the OCSP issuer criteria. 150280304Sjkim */ 151280304Sjkim ret = ocsp_check_issuer(bs, chain, flags); 152109998Smarkm 153280304Sjkim /* If fatal error or valid match then finish */ 154280304Sjkim if (ret != 0) 155280304Sjkim goto end; 156109998Smarkm 157280304Sjkim /* 158280304Sjkim * Easy case: explicitly trusted. Get root CA and check for explicit 159280304Sjkim * trust 160280304Sjkim */ 161280304Sjkim if (flags & OCSP_NOEXPLICIT) 162280304Sjkim goto end; 163109998Smarkm 164280304Sjkim x = sk_X509_value(chain, sk_X509_num(chain) - 1); 165280304Sjkim if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { 166280304Sjkim OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); 167280304Sjkim goto end; 168280304Sjkim } 169280304Sjkim ret = 1; 170280304Sjkim } 171109998Smarkm 172280304Sjkim end: 173280304Sjkim if (chain) 174280304Sjkim sk_X509_pop_free(chain, X509_free); 175284285Sjkim if (bs->certs && certs) 176284285Sjkim sk_X509_free(untrusted); 177280304Sjkim return ret; 178280304Sjkim} 179109998Smarkm 180280304Sjkimstatic int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, 181280304Sjkim STACK_OF(X509) *certs, X509_STORE *st, 182280304Sjkim unsigned long flags) 183280304Sjkim{ 184280304Sjkim X509 *signer; 185280304Sjkim OCSP_RESPID *rid = bs->tbsResponseData->responderId; 186280304Sjkim if ((signer = ocsp_find_signer_sk(certs, rid))) { 187280304Sjkim *psigner = signer; 188280304Sjkim return 2; 189280304Sjkim } 190280304Sjkim if (!(flags & OCSP_NOINTERN) && 191280304Sjkim (signer = ocsp_find_signer_sk(bs->certs, rid))) { 192280304Sjkim *psigner = signer; 193280304Sjkim return 1; 194280304Sjkim } 195280304Sjkim /* Maybe lookup from store if by subject name */ 196109998Smarkm 197280304Sjkim *psigner = NULL; 198280304Sjkim return 0; 199280304Sjkim} 200109998Smarkm 201109998Smarkmstatic X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 202280304Sjkim{ 203280304Sjkim int i; 204280304Sjkim unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 205280304Sjkim X509 *x; 206109998Smarkm 207280304Sjkim /* Easy if lookup by name */ 208280304Sjkim if (id->type == V_OCSP_RESPID_NAME) 209280304Sjkim return X509_find_by_subject(certs, id->value.byName); 210109998Smarkm 211280304Sjkim /* Lookup by key hash */ 212109998Smarkm 213280304Sjkim /* If key hash isn't SHA1 length then forget it */ 214280304Sjkim if (id->value.byKey->length != SHA_DIGEST_LENGTH) 215280304Sjkim return NULL; 216280304Sjkim keyhash = id->value.byKey->data; 217280304Sjkim /* Calculate hash of each key and compare */ 218280304Sjkim for (i = 0; i < sk_X509_num(certs); i++) { 219280304Sjkim x = sk_X509_value(certs, i); 220280304Sjkim X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 221280304Sjkim if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 222280304Sjkim return x; 223280304Sjkim } 224280304Sjkim return NULL; 225280304Sjkim} 226109998Smarkm 227280304Sjkimstatic int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, 228280304Sjkim unsigned long flags) 229280304Sjkim{ 230280304Sjkim STACK_OF(OCSP_SINGLERESP) *sresp; 231280304Sjkim X509 *signer, *sca; 232280304Sjkim OCSP_CERTID *caid = NULL; 233280304Sjkim int i; 234280304Sjkim sresp = bs->tbsResponseData->responses; 235109998Smarkm 236280304Sjkim if (sk_X509_num(chain) <= 0) { 237280304Sjkim OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); 238280304Sjkim return -1; 239280304Sjkim } 240109998Smarkm 241280304Sjkim /* See if the issuer IDs match. */ 242280304Sjkim i = ocsp_check_ids(sresp, &caid); 243109998Smarkm 244280304Sjkim /* If ID mismatch or other error then return */ 245280304Sjkim if (i <= 0) 246280304Sjkim return i; 247109998Smarkm 248280304Sjkim signer = sk_X509_value(chain, 0); 249280304Sjkim /* Check to see if OCSP responder CA matches request CA */ 250280304Sjkim if (sk_X509_num(chain) > 1) { 251280304Sjkim sca = sk_X509_value(chain, 1); 252280304Sjkim i = ocsp_match_issuerid(sca, caid, sresp); 253280304Sjkim if (i < 0) 254280304Sjkim return i; 255280304Sjkim if (i) { 256280304Sjkim /* We have a match, if extensions OK then success */ 257280304Sjkim if (ocsp_check_delegated(signer, flags)) 258280304Sjkim return 1; 259280304Sjkim return 0; 260280304Sjkim } 261280304Sjkim } 262109998Smarkm 263280304Sjkim /* Otherwise check if OCSP request signed directly by request CA */ 264280304Sjkim return ocsp_match_issuerid(signer, caid, sresp); 265280304Sjkim} 266109998Smarkm 267280304Sjkim/* 268280304Sjkim * Check the issuer certificate IDs for equality. If there is a mismatch with 269280304Sjkim * the same algorithm then there's no point trying to match any certificates 270280304Sjkim * against the issuer. If the issuer IDs all match then we just need to check 271280304Sjkim * equality against one of them. 272280304Sjkim */ 273109998Smarkm 274109998Smarkmstatic int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) 275280304Sjkim{ 276280304Sjkim OCSP_CERTID *tmpid, *cid; 277280304Sjkim int i, idcount; 278109998Smarkm 279280304Sjkim idcount = sk_OCSP_SINGLERESP_num(sresp); 280280304Sjkim if (idcount <= 0) { 281280304Sjkim OCSPerr(OCSP_F_OCSP_CHECK_IDS, 282280304Sjkim OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); 283280304Sjkim return -1; 284280304Sjkim } 285109998Smarkm 286280304Sjkim cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; 287109998Smarkm 288280304Sjkim *ret = NULL; 289109998Smarkm 290280304Sjkim for (i = 1; i < idcount; i++) { 291280304Sjkim tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; 292280304Sjkim /* Check to see if IDs match */ 293280304Sjkim if (OCSP_id_issuer_cmp(cid, tmpid)) { 294280304Sjkim /* If algoritm mismatch let caller deal with it */ 295280304Sjkim if (OBJ_cmp(tmpid->hashAlgorithm->algorithm, 296280304Sjkim cid->hashAlgorithm->algorithm)) 297280304Sjkim return 2; 298280304Sjkim /* Else mismatch */ 299280304Sjkim return 0; 300280304Sjkim } 301280304Sjkim } 302109998Smarkm 303280304Sjkim /* All IDs match: only need to check one ID */ 304280304Sjkim *ret = cid; 305280304Sjkim return 1; 306280304Sjkim} 307109998Smarkm 308109998Smarkmstatic int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, 309280304Sjkim STACK_OF(OCSP_SINGLERESP) *sresp) 310280304Sjkim{ 311280304Sjkim /* If only one ID to match then do it */ 312280304Sjkim if (cid) { 313280304Sjkim const EVP_MD *dgst; 314280304Sjkim X509_NAME *iname; 315280304Sjkim int mdlen; 316280304Sjkim unsigned char md[EVP_MAX_MD_SIZE]; 317280304Sjkim if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) { 318280304Sjkim OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, 319280304Sjkim OCSP_R_UNKNOWN_MESSAGE_DIGEST); 320280304Sjkim return -1; 321280304Sjkim } 322109998Smarkm 323280304Sjkim mdlen = EVP_MD_size(dgst); 324280304Sjkim if (mdlen < 0) 325280304Sjkim return -1; 326280304Sjkim if ((cid->issuerNameHash->length != mdlen) || 327280304Sjkim (cid->issuerKeyHash->length != mdlen)) 328280304Sjkim return 0; 329280304Sjkim iname = X509_get_subject_name(cert); 330280304Sjkim if (!X509_NAME_digest(iname, dgst, md, NULL)) 331280304Sjkim return -1; 332280304Sjkim if (memcmp(md, cid->issuerNameHash->data, mdlen)) 333280304Sjkim return 0; 334280304Sjkim X509_pubkey_digest(cert, dgst, md, NULL); 335280304Sjkim if (memcmp(md, cid->issuerKeyHash->data, mdlen)) 336280304Sjkim return 0; 337109998Smarkm 338280304Sjkim return 1; 339109998Smarkm 340280304Sjkim } else { 341280304Sjkim /* We have to match the whole lot */ 342280304Sjkim int i, ret; 343280304Sjkim OCSP_CERTID *tmpid; 344280304Sjkim for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { 345280304Sjkim tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; 346280304Sjkim ret = ocsp_match_issuerid(cert, tmpid, NULL); 347280304Sjkim if (ret <= 0) 348280304Sjkim return ret; 349280304Sjkim } 350280304Sjkim return 1; 351280304Sjkim } 352109998Smarkm 353280304Sjkim} 354280304Sjkim 355109998Smarkmstatic int ocsp_check_delegated(X509 *x, int flags) 356280304Sjkim{ 357280304Sjkim X509_check_purpose(x, -1, 0); 358280304Sjkim if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN)) 359280304Sjkim return 1; 360280304Sjkim OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); 361280304Sjkim return 0; 362280304Sjkim} 363109998Smarkm 364280304Sjkim/* 365280304Sjkim * Verify an OCSP request. This is fortunately much easier than OCSP response 366280304Sjkim * verify. Just find the signers certificate and verify it against a given 367280304Sjkim * trust value. 368109998Smarkm */ 369109998Smarkm 370280304Sjkimint OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, 371280304Sjkim X509_STORE *store, unsigned long flags) 372280304Sjkim{ 373280304Sjkim X509 *signer; 374280304Sjkim X509_NAME *nm; 375280304Sjkim GENERAL_NAME *gen; 376280304Sjkim int ret; 377280304Sjkim X509_STORE_CTX ctx; 378280304Sjkim if (!req->optionalSignature) { 379280304Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); 380280304Sjkim return 0; 381280304Sjkim } 382280304Sjkim gen = req->tbsRequest->requestorName; 383280304Sjkim if (!gen || gen->type != GEN_DIRNAME) { 384280304Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, 385280304Sjkim OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); 386280304Sjkim return 0; 387280304Sjkim } 388280304Sjkim nm = gen->d.directoryName; 389280304Sjkim ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); 390280304Sjkim if (ret <= 0) { 391280304Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, 392280304Sjkim OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); 393280304Sjkim return 0; 394280304Sjkim } 395280304Sjkim if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) 396280304Sjkim flags |= OCSP_NOVERIFY; 397280304Sjkim if (!(flags & OCSP_NOSIGS)) { 398280304Sjkim EVP_PKEY *skey; 399280304Sjkim skey = X509_get_pubkey(signer); 400280304Sjkim ret = OCSP_REQUEST_verify(req, skey); 401280304Sjkim EVP_PKEY_free(skey); 402280304Sjkim if (ret <= 0) { 403280304Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); 404280304Sjkim return 0; 405280304Sjkim } 406280304Sjkim } 407280304Sjkim if (!(flags & OCSP_NOVERIFY)) { 408280304Sjkim int init_res; 409280304Sjkim if (flags & OCSP_NOCHAIN) 410280304Sjkim init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); 411280304Sjkim else 412280304Sjkim init_res = X509_STORE_CTX_init(&ctx, store, signer, 413280304Sjkim req->optionalSignature->certs); 414280304Sjkim if (!init_res) { 415280304Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); 416280304Sjkim return 0; 417280304Sjkim } 418109998Smarkm 419280304Sjkim X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); 420280304Sjkim X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); 421280304Sjkim ret = X509_verify_cert(&ctx); 422280304Sjkim X509_STORE_CTX_cleanup(&ctx); 423280304Sjkim if (ret <= 0) { 424280304Sjkim ret = X509_STORE_CTX_get_error(&ctx); 425280304Sjkim OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, 426280304Sjkim OCSP_R_CERTIFICATE_VERIFY_ERROR); 427280304Sjkim ERR_add_error_data(2, "Verify error:", 428280304Sjkim X509_verify_cert_error_string(ret)); 429280304Sjkim return 0; 430109998Smarkm } 431280304Sjkim } 432280304Sjkim return 1; 433280304Sjkim} 434109998Smarkm 435280304Sjkimstatic int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, 436280304Sjkim X509_NAME *nm, STACK_OF(X509) *certs, 437280304Sjkim X509_STORE *st, unsigned long flags) 438280304Sjkim{ 439280304Sjkim X509 *signer; 440280304Sjkim if (!(flags & OCSP_NOINTERN)) { 441280304Sjkim signer = X509_find_by_subject(req->optionalSignature->certs, nm); 442280304Sjkim if (signer) { 443280304Sjkim *psigner = signer; 444280304Sjkim return 1; 445280304Sjkim } 446280304Sjkim } 447109998Smarkm 448280304Sjkim signer = X509_find_by_subject(certs, nm); 449280304Sjkim if (signer) { 450280304Sjkim *psigner = signer; 451280304Sjkim return 2; 452280304Sjkim } 453280304Sjkim return 0; 454280304Sjkim} 455