1*75e21034Sbeck /* $OpenBSD: ocsp_vfy.c,v 1.24 2024/07/12 18:15:10 beck Exp $ */
2e6841c1dSdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3da347917Sbeck * project 2000.
4da347917Sbeck */
5da347917Sbeck /* ====================================================================
6720b416eSmarkus * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
7da347917Sbeck *
8da347917Sbeck * Redistribution and use in source and binary forms, with or without
9da347917Sbeck * modification, are permitted provided that the following conditions
10da347917Sbeck * are met:
11da347917Sbeck *
12da347917Sbeck * 1. Redistributions of source code must retain the above copyright
13da347917Sbeck * notice, this list of conditions and the following disclaimer.
14da347917Sbeck *
15da347917Sbeck * 2. Redistributions in binary form must reproduce the above copyright
16da347917Sbeck * notice, this list of conditions and the following disclaimer in
17da347917Sbeck * the documentation and/or other materials provided with the
18da347917Sbeck * distribution.
19da347917Sbeck *
20da347917Sbeck * 3. All advertising materials mentioning features or use of this
21da347917Sbeck * software must display the following acknowledgment:
22da347917Sbeck * "This product includes software developed by the OpenSSL Project
23da347917Sbeck * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24da347917Sbeck *
25da347917Sbeck * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26da347917Sbeck * endorse or promote products derived from this software without
27da347917Sbeck * prior written permission. For written permission, please contact
28da347917Sbeck * licensing@OpenSSL.org.
29da347917Sbeck *
30da347917Sbeck * 5. Products derived from this software may not be called "OpenSSL"
31da347917Sbeck * nor may "OpenSSL" appear in their names without prior written
32da347917Sbeck * permission of the OpenSSL Project.
33da347917Sbeck *
34da347917Sbeck * 6. Redistributions of any form whatsoever must retain the following
35da347917Sbeck * acknowledgment:
36da347917Sbeck * "This product includes software developed by the OpenSSL Project
37da347917Sbeck * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38da347917Sbeck *
39da347917Sbeck * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40da347917Sbeck * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41da347917Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42da347917Sbeck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43da347917Sbeck * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44da347917Sbeck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45da347917Sbeck * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46da347917Sbeck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47da347917Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48da347917Sbeck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49da347917Sbeck * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50da347917Sbeck * OF THE POSSIBILITY OF SUCH DAMAGE.
51da347917Sbeck * ====================================================================
52da347917Sbeck *
53da347917Sbeck * This product includes cryptographic software written by Eric Young
54da347917Sbeck * (eay@cryptsoft.com). This product includes software written by Tim
55da347917Sbeck * Hudson (tjh@cryptsoft.com).
56da347917Sbeck *
57da347917Sbeck */
58da347917Sbeck
59da347917Sbeck #include <openssl/ocsp.h>
60da347917Sbeck #include <openssl/err.h>
61da347917Sbeck #include <string.h>
62da347917Sbeck
639f44a700Stb #include "ocsp_local.h"
64c9675a23Stb #include "x509_local.h"
65838f0b6dStb
662d2941d0Smiod static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
672d2941d0Smiod STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags);
68da347917Sbeck static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
692d2941d0Smiod static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain,
702d2941d0Smiod unsigned long flags);
71da347917Sbeck static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret);
722d2941d0Smiod static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
732d2941d0Smiod STACK_OF(OCSP_SINGLERESP) *sresp);
74da347917Sbeck static int ocsp_check_delegated(X509 *x, int flags);
752d2941d0Smiod static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
762d2941d0Smiod X509_NAME *nm, STACK_OF(X509) *certs, X509_STORE *st,
772d2941d0Smiod unsigned long flags);
78da347917Sbeck
79da347917Sbeck /* Verify a basic response message */
802d2941d0Smiod int
OCSP_basic_verify(OCSP_BASICRESP * bs,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)812d2941d0Smiod OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st,
822d2941d0Smiod unsigned long flags)
83da347917Sbeck {
84da347917Sbeck X509 *signer, *x;
85da347917Sbeck STACK_OF(X509) *chain = NULL;
86ac6b1dd5Sbeck STACK_OF(X509) *untrusted = NULL;
87da347917Sbeck X509_STORE_CTX ctx;
88da347917Sbeck int i, ret = 0;
892d2941d0Smiod
90da347917Sbeck ret = ocsp_find_signer(&signer, bs, certs, st, flags);
912d2941d0Smiod if (!ret) {
925067ae9fSbeck OCSPerror(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
93da347917Sbeck goto end;
94da347917Sbeck }
95da347917Sbeck if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
96da347917Sbeck flags |= OCSP_NOVERIFY;
972d2941d0Smiod if (!(flags & OCSP_NOSIGS)) {
98da347917Sbeck EVP_PKEY *skey;
992d2941d0Smiod
1001b78ce04Stb skey = X509_get0_pubkey(signer);
1012d2941d0Smiod if (skey) {
102da347917Sbeck ret = OCSP_BASICRESP_verify(bs, skey, 0);
103c5957159Smarkus }
1042d2941d0Smiod if (!skey || ret <= 0) {
1055067ae9fSbeck OCSPerror(OCSP_R_SIGNATURE_FAILURE);
106da347917Sbeck goto end;
107da347917Sbeck }
108da347917Sbeck }
1092d2941d0Smiod if (!(flags & OCSP_NOVERIFY)) {
110da347917Sbeck int init_res;
1112d2941d0Smiod
112ac6b1dd5Sbeck if (flags & OCSP_NOCHAIN) {
113ac6b1dd5Sbeck untrusted = NULL;
114ac6b1dd5Sbeck } else if (bs->certs && certs) {
115ac6b1dd5Sbeck untrusted = sk_X509_dup(bs->certs);
116ac6b1dd5Sbeck for (i = 0; i < sk_X509_num(certs); i++) {
117ac6b1dd5Sbeck if (!sk_X509_push(untrusted,
118ac6b1dd5Sbeck sk_X509_value(certs, i))) {
1195067ae9fSbeck OCSPerror(ERR_R_MALLOC_FAILURE);
120ac6b1dd5Sbeck goto end;
121ac6b1dd5Sbeck }
122ac6b1dd5Sbeck }
1232b1ad87fStb } else if (certs != NULL) {
1242b1ad87fStb untrusted = certs;
1252b1ad87fStb } else {
126ac6b1dd5Sbeck untrusted = bs->certs;
1272b1ad87fStb }
128ac6b1dd5Sbeck init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted);
1292d2941d0Smiod if (!init_res) {
13097222eddSmiod ret = -1;
1315067ae9fSbeck OCSPerror(ERR_R_X509_LIB);
132da347917Sbeck goto end;
133da347917Sbeck }
134da347917Sbeck
135c602b0f2Smiod if (X509_STORE_CTX_set_purpose(&ctx,
136c602b0f2Smiod X509_PURPOSE_OCSP_HELPER) == 0) {
137c602b0f2Smiod X509_STORE_CTX_cleanup(&ctx);
138c602b0f2Smiod ret = -1;
139c602b0f2Smiod goto end;
140c602b0f2Smiod }
141da347917Sbeck ret = X509_verify_cert(&ctx);
142da347917Sbeck chain = X509_STORE_CTX_get1_chain(&ctx);
143da347917Sbeck X509_STORE_CTX_cleanup(&ctx);
1442d2941d0Smiod if (ret <= 0) {
145da347917Sbeck i = X509_STORE_CTX_get_error(&ctx);
1465067ae9fSbeck OCSPerror(OCSP_R_CERTIFICATE_VERIFY_ERROR);
1470f637b92Sbeck ERR_asprintf_error_data("Verify error:%s",
148da347917Sbeck X509_verify_cert_error_string(i));
149da347917Sbeck goto end;
150da347917Sbeck }
1512d2941d0Smiod if (flags & OCSP_NOCHECKS) {
152da347917Sbeck ret = 1;
153da347917Sbeck goto end;
154da347917Sbeck }
155da347917Sbeck /* At this point we have a valid certificate chain
156da347917Sbeck * need to verify it against the OCSP issuer criteria.
157da347917Sbeck */
158da347917Sbeck ret = ocsp_check_issuer(bs, chain, flags);
159da347917Sbeck
160da347917Sbeck /* If fatal error or valid match then finish */
1612d2941d0Smiod if (ret != 0)
1622d2941d0Smiod goto end;
163da347917Sbeck
164da347917Sbeck /* Easy case: explicitly trusted. Get root CA and
165da347917Sbeck * check for explicit trust
166da347917Sbeck */
1672d2941d0Smiod if (flags & OCSP_NOEXPLICIT)
1682d2941d0Smiod goto end;
169da347917Sbeck
170da347917Sbeck x = sk_X509_value(chain, sk_X509_num(chain) - 1);
171*75e21034Sbeck if (X509_check_trust(x, X509_TRUST_OCSP_SIGN, 0) !=
1722d2941d0Smiod X509_TRUST_TRUSTED) {
1735067ae9fSbeck OCSPerror(OCSP_R_ROOT_CA_NOT_TRUSTED);
174da347917Sbeck goto end;
175da347917Sbeck }
176da347917Sbeck ret = 1;
177da347917Sbeck }
178da347917Sbeck
179da347917Sbeck end:
1802d2941d0Smiod if (chain)
1812d2941d0Smiod sk_X509_pop_free(chain, X509_free);
182ac6b1dd5Sbeck if (bs->certs && certs)
183ac6b1dd5Sbeck sk_X509_free(untrusted);
184da347917Sbeck return ret;
185da347917Sbeck }
186a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_basic_verify);
187da347917Sbeck
188d779a45bStb int
OCSP_resp_get0_signer(OCSP_BASICRESP * bs,X509 ** signer,STACK_OF (X509)* extra_certs)189d779a45bStb OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer,
190d779a45bStb STACK_OF(X509) *extra_certs)
191d779a45bStb {
192d779a45bStb return ocsp_find_signer(signer, bs, extra_certs, NULL, 0) > 0;
193d779a45bStb }
194a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_resp_get0_signer);
195d779a45bStb
1962d2941d0Smiod static int
ocsp_find_signer(X509 ** psigner,OCSP_BASICRESP * bs,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)1972d2941d0Smiod ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
198da347917Sbeck X509_STORE *st, unsigned long flags)
199da347917Sbeck {
200da347917Sbeck X509 *signer;
201da347917Sbeck OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2022d2941d0Smiod
2032d2941d0Smiod if ((signer = ocsp_find_signer_sk(certs, rid))) {
204da347917Sbeck *psigner = signer;
205da347917Sbeck return 2;
206da347917Sbeck }
207da347917Sbeck if (!(flags & OCSP_NOINTERN) &&
2082d2941d0Smiod (signer = ocsp_find_signer_sk(bs->certs, rid))) {
209da347917Sbeck *psigner = signer;
210da347917Sbeck return 1;
211da347917Sbeck }
212da347917Sbeck /* Maybe lookup from store if by subject name */
213da347917Sbeck
214da347917Sbeck *psigner = NULL;
215da347917Sbeck return 0;
216da347917Sbeck }
217da347917Sbeck
2182d2941d0Smiod static X509 *
ocsp_find_signer_sk(STACK_OF (X509)* certs,OCSP_RESPID * id)2192d2941d0Smiod ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
220da347917Sbeck {
221da347917Sbeck int i;
222da347917Sbeck unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
223da347917Sbeck X509 *x;
224da347917Sbeck
225da347917Sbeck /* Easy if lookup by name */
226da347917Sbeck if (id->type == V_OCSP_RESPID_NAME)
227da347917Sbeck return X509_find_by_subject(certs, id->value.byName);
228da347917Sbeck
229da347917Sbeck /* Lookup by key hash */
230da347917Sbeck
231da347917Sbeck /* If key hash isn't SHA1 length then forget it */
2322d2941d0Smiod if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2332d2941d0Smiod return NULL;
234da347917Sbeck keyhash = id->value.byKey->data;
235da347917Sbeck /* Calculate hash of each key and compare */
2362d2941d0Smiod for (i = 0; i < sk_X509_num(certs); i++) {
237da347917Sbeck x = sk_X509_value(certs, i);
238da347917Sbeck X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
239da347917Sbeck if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
240da347917Sbeck return x;
241da347917Sbeck }
242da347917Sbeck return NULL;
243da347917Sbeck }
244da347917Sbeck
2452d2941d0Smiod static int
ocsp_check_issuer(OCSP_BASICRESP * bs,STACK_OF (X509)* chain,unsigned long flags)2462d2941d0Smiod ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain,
2472d2941d0Smiod unsigned long flags)
248da347917Sbeck {
249da347917Sbeck STACK_OF(OCSP_SINGLERESP) *sresp;
250da347917Sbeck X509 *signer, *sca;
251da347917Sbeck OCSP_CERTID *caid = NULL;
252da347917Sbeck int i;
2532d2941d0Smiod
254da347917Sbeck sresp = bs->tbsResponseData->responses;
255da347917Sbeck
2562d2941d0Smiod if (sk_X509_num(chain) <= 0) {
2575067ae9fSbeck OCSPerror(OCSP_R_NO_CERTIFICATES_IN_CHAIN);
258da347917Sbeck return -1;
259da347917Sbeck }
260da347917Sbeck
261da347917Sbeck /* See if the issuer IDs match. */
262da347917Sbeck i = ocsp_check_ids(sresp, &caid);
263da347917Sbeck
264da347917Sbeck /* If ID mismatch or other error then return */
2652d2941d0Smiod if (i <= 0)
2662d2941d0Smiod return i;
267da347917Sbeck
268da347917Sbeck signer = sk_X509_value(chain, 0);
269da347917Sbeck /* Check to see if OCSP responder CA matches request CA */
2702d2941d0Smiod if (sk_X509_num(chain) > 1) {
271da347917Sbeck sca = sk_X509_value(chain, 1);
272da347917Sbeck i = ocsp_match_issuerid(sca, caid, sresp);
2732d2941d0Smiod if (i < 0)
2742d2941d0Smiod return i;
2752d2941d0Smiod if (i) {
276da347917Sbeck /* We have a match, if extensions OK then success */
2772d2941d0Smiod if (ocsp_check_delegated(signer, flags))
2782d2941d0Smiod return 1;
279da347917Sbeck return 0;
280da347917Sbeck }
281da347917Sbeck }
282da347917Sbeck
283da347917Sbeck /* Otherwise check if OCSP request signed directly by request CA */
284da347917Sbeck return ocsp_match_issuerid(signer, caid, sresp);
285da347917Sbeck }
286da347917Sbeck
287da347917Sbeck /* Check the issuer certificate IDs for equality. If there is a mismatch with the same
288da347917Sbeck * algorithm then there's no point trying to match any certificates against the issuer.
289da347917Sbeck * If the issuer IDs all match then we just need to check equality against one of them.
290da347917Sbeck */
2912d2941d0Smiod static int
ocsp_check_ids(STACK_OF (OCSP_SINGLERESP)* sresp,OCSP_CERTID ** ret)2922d2941d0Smiod ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
293da347917Sbeck {
294da347917Sbeck OCSP_CERTID *tmpid, *cid;
295da347917Sbeck int i, idcount;
296da347917Sbeck
297da347917Sbeck idcount = sk_OCSP_SINGLERESP_num(sresp);
2982d2941d0Smiod if (idcount <= 0) {
2995067ae9fSbeck OCSPerror(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
300da347917Sbeck return -1;
301da347917Sbeck }
302da347917Sbeck
303da347917Sbeck cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
304da347917Sbeck
305da347917Sbeck *ret = NULL;
306da347917Sbeck
3072d2941d0Smiod for (i = 1; i < idcount; i++) {
308720b416eSmarkus tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
309da347917Sbeck /* Check to see if IDs match */
3102d2941d0Smiod if (OCSP_id_issuer_cmp(cid, tmpid)) {
311da347917Sbeck return 0;
312da347917Sbeck }
313da347917Sbeck }
314da347917Sbeck
315da347917Sbeck /* All IDs match: only need to check one ID */
316da347917Sbeck *ret = cid;
317da347917Sbeck return 1;
318da347917Sbeck }
319da347917Sbeck
3202d2941d0Smiod static int
ocsp_match_issuerid(X509 * cert,OCSP_CERTID * cid,STACK_OF (OCSP_SINGLERESP)* sresp)3212d2941d0Smiod ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
322da347917Sbeck STACK_OF(OCSP_SINGLERESP) *sresp)
323da347917Sbeck {
324da347917Sbeck /* If only one ID to match then do it */
3252d2941d0Smiod if (cid) {
326da347917Sbeck const EVP_MD *dgst;
327da347917Sbeck X509_NAME *iname;
328da347917Sbeck int mdlen;
329da347917Sbeck unsigned char md[EVP_MAX_MD_SIZE];
3302d2941d0Smiod
3312d2941d0Smiod if (!(dgst =
3322d2941d0Smiod EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) {
3335067ae9fSbeck OCSPerror(OCSP_R_UNKNOWN_MESSAGE_DIGEST);
334da347917Sbeck return -1;
335da347917Sbeck }
336da347917Sbeck
337da347917Sbeck mdlen = EVP_MD_size(dgst);
3380a5d6edeSdjm if (mdlen < 0)
3390a5d6edeSdjm return -1;
3402d2941d0Smiod if (cid->issuerNameHash->length != mdlen ||
3412d2941d0Smiod cid->issuerKeyHash->length != mdlen)
342da347917Sbeck return 0;
343da347917Sbeck iname = X509_get_subject_name(cert);
344da347917Sbeck if (!X509_NAME_digest(iname, dgst, md, NULL))
345da347917Sbeck return -1;
346da347917Sbeck if (memcmp(md, cid->issuerNameHash->data, mdlen))
347da347917Sbeck return 0;
3480a5d6edeSdjm X509_pubkey_digest(cert, dgst, md, NULL);
349da347917Sbeck if (memcmp(md, cid->issuerKeyHash->data, mdlen))
350da347917Sbeck return 0;
351da347917Sbeck
352da347917Sbeck return 1;
3532d2941d0Smiod } else {
354da347917Sbeck /* We have to match the whole lot */
355da347917Sbeck int i, ret;
356da347917Sbeck OCSP_CERTID *tmpid;
3572d2941d0Smiod
3582d2941d0Smiod for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
359720b416eSmarkus tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
360da347917Sbeck ret = ocsp_match_issuerid(cert, tmpid, NULL);
3612d2941d0Smiod if (ret <= 0)
3622d2941d0Smiod return ret;
363da347917Sbeck }
364da347917Sbeck return 1;
365da347917Sbeck }
366da347917Sbeck }
367da347917Sbeck
3682d2941d0Smiod static int
ocsp_check_delegated(X509 * x,int flags)3692d2941d0Smiod ocsp_check_delegated(X509 *x, int flags)
370da347917Sbeck {
371da347917Sbeck X509_check_purpose(x, -1, 0);
3722d2941d0Smiod if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN))
373da347917Sbeck return 1;
3745067ae9fSbeck OCSPerror(OCSP_R_MISSING_OCSPSIGNING_USAGE);
375da347917Sbeck return 0;
376da347917Sbeck }
377da347917Sbeck
378da347917Sbeck /* Verify an OCSP request. This is fortunately much easier than OCSP
379da347917Sbeck * response verify. Just find the signers certificate and verify it
380da347917Sbeck * against a given trust value.
381da347917Sbeck */
3822d2941d0Smiod int
OCSP_request_verify(OCSP_REQUEST * req,STACK_OF (X509)* certs,X509_STORE * store,unsigned long flags)3832d2941d0Smiod OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store,
3842d2941d0Smiod unsigned long flags)
385da347917Sbeck {
386da347917Sbeck X509 *signer;
387da347917Sbeck X509_NAME *nm;
388da347917Sbeck GENERAL_NAME *gen;
389da347917Sbeck int ret;
390da347917Sbeck X509_STORE_CTX ctx;
3912d2941d0Smiod
3922d2941d0Smiod if (!req->optionalSignature) {
3935067ae9fSbeck OCSPerror(OCSP_R_REQUEST_NOT_SIGNED);
394da347917Sbeck return 0;
395da347917Sbeck }
396da347917Sbeck gen = req->tbsRequest->requestorName;
3972d2941d0Smiod if (!gen || gen->type != GEN_DIRNAME) {
3985067ae9fSbeck OCSPerror(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
399da347917Sbeck return 0;
400da347917Sbeck }
401da347917Sbeck nm = gen->d.directoryName;
402da347917Sbeck ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags);
4032d2941d0Smiod if (ret <= 0) {
4045067ae9fSbeck OCSPerror(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
405da347917Sbeck return 0;
406da347917Sbeck }
407da347917Sbeck if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
408da347917Sbeck flags |= OCSP_NOVERIFY;
4092d2941d0Smiod if (!(flags & OCSP_NOSIGS)) {
410da347917Sbeck EVP_PKEY *skey;
4112d2941d0Smiod
41299804f43Sinoguchi if ((skey = X509_get0_pubkey(signer)) == NULL)
41399804f43Sinoguchi return 0;
414da347917Sbeck ret = OCSP_REQUEST_verify(req, skey);
4152d2941d0Smiod if (ret <= 0) {
4165067ae9fSbeck OCSPerror(OCSP_R_SIGNATURE_FAILURE);
417da347917Sbeck return 0;
418da347917Sbeck }
419da347917Sbeck }
4202d2941d0Smiod if (!(flags & OCSP_NOVERIFY)) {
421da347917Sbeck int init_res;
4222d2941d0Smiod
423da347917Sbeck if (flags & OCSP_NOCHAIN)
4242d2941d0Smiod init_res = X509_STORE_CTX_init(&ctx, store, signer,
4252d2941d0Smiod NULL);
426da347917Sbeck else
427da347917Sbeck init_res = X509_STORE_CTX_init(&ctx, store, signer,
428da347917Sbeck req->optionalSignature->certs);
4292d2941d0Smiod if (!init_res) {
4305067ae9fSbeck OCSPerror(ERR_R_X509_LIB);
431da347917Sbeck return 0;
432da347917Sbeck }
433da347917Sbeck
434c602b0f2Smiod if (X509_STORE_CTX_set_purpose(&ctx,
435c602b0f2Smiod X509_PURPOSE_OCSP_HELPER) == 0 ||
436c602b0f2Smiod X509_STORE_CTX_set_trust(&ctx,
437c602b0f2Smiod X509_TRUST_OCSP_REQUEST) == 0) {
438c602b0f2Smiod X509_STORE_CTX_cleanup(&ctx);
439c602b0f2Smiod return 0;
440c602b0f2Smiod }
441da347917Sbeck ret = X509_verify_cert(&ctx);
442da347917Sbeck X509_STORE_CTX_cleanup(&ctx);
4432d2941d0Smiod if (ret <= 0) {
444da347917Sbeck ret = X509_STORE_CTX_get_error(&ctx);
4455067ae9fSbeck OCSPerror(OCSP_R_CERTIFICATE_VERIFY_ERROR);
4460f637b92Sbeck ERR_asprintf_error_data("Verify error:%s",
447da347917Sbeck X509_verify_cert_error_string(ret));
448da347917Sbeck return 0;
449da347917Sbeck }
450da347917Sbeck }
451da347917Sbeck return 1;
452da347917Sbeck }
453a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_request_verify);
454da347917Sbeck
4552d2941d0Smiod static int
ocsp_req_find_signer(X509 ** psigner,OCSP_REQUEST * req,X509_NAME * nm,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)4562d2941d0Smiod ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm,
4572d2941d0Smiod STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags)
458da347917Sbeck {
459da347917Sbeck X509 *signer;
4602d2941d0Smiod
4612d2941d0Smiod if (!(flags & OCSP_NOINTERN)) {
462ac6b1dd5Sbeck signer = X509_find_by_subject(req->optionalSignature->certs, nm);
463ac6b1dd5Sbeck if (signer) {
464da347917Sbeck *psigner = signer;
465da347917Sbeck return 1;
466da347917Sbeck }
467ac6b1dd5Sbeck }
468da347917Sbeck
469da347917Sbeck signer = X509_find_by_subject(certs, nm);
4702d2941d0Smiod if (signer) {
471da347917Sbeck *psigner = signer;
472da347917Sbeck return 2;
473da347917Sbeck }
474da347917Sbeck return 0;
475da347917Sbeck }
476