os/ossrv/ssl/libcrypto/src/crypto/ocsp/ocsp_vfy.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* ocsp_vfy.c */
sl@0
     2
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
sl@0
     3
 * project 2000.
sl@0
     4
 */
sl@0
     5
/* ====================================================================
sl@0
     6
 * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
sl@0
     7
 *
sl@0
     8
 * Redistribution and use in source and binary forms, with or without
sl@0
     9
 * modification, are permitted provided that the following conditions
sl@0
    10
 * are met:
sl@0
    11
 *
sl@0
    12
 * 1. Redistributions of source code must retain the above copyright
sl@0
    13
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    14
 *
sl@0
    15
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    16
 *    notice, this list of conditions and the following disclaimer in
sl@0
    17
 *    the documentation and/or other materials provided with the
sl@0
    18
 *    distribution.
sl@0
    19
 *
sl@0
    20
 * 3. All advertising materials mentioning features or use of this
sl@0
    21
 *    software must display the following acknowledgment:
sl@0
    22
 *    "This product includes software developed by the OpenSSL Project
sl@0
    23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
sl@0
    24
 *
sl@0
    25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    26
 *    endorse or promote products derived from this software without
sl@0
    27
 *    prior written permission. For written permission, please contact
sl@0
    28
 *    licensing@OpenSSL.org.
sl@0
    29
 *
sl@0
    30
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    31
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    32
 *    permission of the OpenSSL Project.
sl@0
    33
 *
sl@0
    34
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    35
 *    acknowledgment:
sl@0
    36
 *    "This product includes software developed by the OpenSSL Project
sl@0
    37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
sl@0
    38
 *
sl@0
    39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
    48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
    49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
    50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
    51
 * ====================================================================
sl@0
    52
 *
sl@0
    53
 * This product includes cryptographic software written by Eric Young
sl@0
    54
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
    55
 * Hudson (tjh@cryptsoft.com).
sl@0
    56
 *
sl@0
    57
 */
sl@0
    58
sl@0
    59
#include <openssl/ocsp.h>
sl@0
    60
#include <openssl/err.h>
sl@0
    61
#include <string.h>
sl@0
    62
sl@0
    63
static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
sl@0
    64
				X509_STORE *st, unsigned long flags);
sl@0
    65
static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
sl@0
    66
static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags);
sl@0
    67
static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret);
sl@0
    68
static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp);
sl@0
    69
static int ocsp_check_delegated(X509 *x, int flags);
sl@0
    70
static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
sl@0
    71
				X509_STORE *st, unsigned long flags);
sl@0
    72
sl@0
    73
/* Verify a basic response message */
sl@0
    74
sl@0
    75
EXPORT_C int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
sl@0
    76
				X509_STORE *st, unsigned long flags)
sl@0
    77
	{
sl@0
    78
	X509 *signer, *x;
sl@0
    79
	STACK_OF(X509) *chain = NULL;
sl@0
    80
	X509_STORE_CTX ctx;
sl@0
    81
	int i, ret = 0;
sl@0
    82
	ret = ocsp_find_signer(&signer, bs, certs, st, flags);
sl@0
    83
	if (!ret)
sl@0
    84
		{
sl@0
    85
		OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
sl@0
    86
		goto end;
sl@0
    87
		}
sl@0
    88
	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
sl@0
    89
		flags |= OCSP_NOVERIFY;
sl@0
    90
	if (!(flags & OCSP_NOSIGS))
sl@0
    91
		{
sl@0
    92
		EVP_PKEY *skey;
sl@0
    93
		skey = X509_get_pubkey(signer);
sl@0
    94
		ret = OCSP_BASICRESP_verify(bs, skey, 0);
sl@0
    95
		EVP_PKEY_free(skey);
sl@0
    96
		if(ret <= 0)
sl@0
    97
			{
sl@0
    98
			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
sl@0
    99
			goto end;
sl@0
   100
			}
sl@0
   101
		}
sl@0
   102
	if (!(flags & OCSP_NOVERIFY))
sl@0
   103
		{
sl@0
   104
		int init_res;
sl@0
   105
		if(flags & OCSP_NOCHAIN)
sl@0
   106
			init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL);
sl@0
   107
		else
sl@0
   108
			init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
sl@0
   109
		if(!init_res)
sl@0
   110
			{
sl@0
   111
			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
sl@0
   112
			goto end;
sl@0
   113
			}
sl@0
   114
sl@0
   115
		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
sl@0
   116
		ret = X509_verify_cert(&ctx);
sl@0
   117
		chain = X509_STORE_CTX_get1_chain(&ctx);
sl@0
   118
		X509_STORE_CTX_cleanup(&ctx);
sl@0
   119
                if (ret <= 0)
sl@0
   120
			{
sl@0
   121
			i = X509_STORE_CTX_get_error(&ctx);	
sl@0
   122
			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR);
sl@0
   123
			ERR_add_error_data(2, "Verify error:",
sl@0
   124
					X509_verify_cert_error_string(i));
sl@0
   125
                        goto end;
sl@0
   126
                	}
sl@0
   127
		if(flags & OCSP_NOCHECKS)
sl@0
   128
			{
sl@0
   129
			ret = 1;
sl@0
   130
			goto end;
sl@0
   131
			}
sl@0
   132
		/* At this point we have a valid certificate chain
sl@0
   133
		 * need to verify it against the OCSP issuer criteria.
sl@0
   134
		 */
sl@0
   135
		ret = ocsp_check_issuer(bs, chain, flags);
sl@0
   136
sl@0
   137
		/* If fatal error or valid match then finish */
sl@0
   138
		if (ret != 0) goto end;
sl@0
   139
sl@0
   140
		/* Easy case: explicitly trusted. Get root CA and
sl@0
   141
		 * check for explicit trust
sl@0
   142
		 */
sl@0
   143
		if(flags & OCSP_NOEXPLICIT) goto end;
sl@0
   144
sl@0
   145
		x = sk_X509_value(chain, sk_X509_num(chain) - 1);
sl@0
   146
		if(X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED)
sl@0
   147
			{
sl@0
   148
			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_ROOT_CA_NOT_TRUSTED);
sl@0
   149
			goto end;
sl@0
   150
			}
sl@0
   151
		ret = 1;
sl@0
   152
		}
sl@0
   153
sl@0
   154
sl@0
   155
sl@0
   156
	end:
sl@0
   157
	if(chain) sk_X509_pop_free(chain, X509_free);
sl@0
   158
	return ret;
sl@0
   159
	}
sl@0
   160
sl@0
   161
sl@0
   162
static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
sl@0
   163
				X509_STORE *st, unsigned long flags)
sl@0
   164
	{
sl@0
   165
	X509 *signer;
sl@0
   166
	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
sl@0
   167
	if ((signer = ocsp_find_signer_sk(certs, rid)))
sl@0
   168
		{
sl@0
   169
		*psigner = signer;
sl@0
   170
		return 2;
sl@0
   171
		}
sl@0
   172
	if(!(flags & OCSP_NOINTERN) &&
sl@0
   173
	    (signer = ocsp_find_signer_sk(bs->certs, rid)))
sl@0
   174
		{
sl@0
   175
		*psigner = signer;
sl@0
   176
		return 1;
sl@0
   177
		}
sl@0
   178
	/* Maybe lookup from store if by subject name */
sl@0
   179
sl@0
   180
	*psigner = NULL;
sl@0
   181
	return 0;
sl@0
   182
	}
sl@0
   183
sl@0
   184
sl@0
   185
static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
sl@0
   186
	{
sl@0
   187
	int i;
sl@0
   188
	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
sl@0
   189
	X509 *x;
sl@0
   190
sl@0
   191
	/* Easy if lookup by name */
sl@0
   192
	if (id->type == V_OCSP_RESPID_NAME)
sl@0
   193
		return X509_find_by_subject(certs, id->value.byName);
sl@0
   194
sl@0
   195
	/* Lookup by key hash */
sl@0
   196
sl@0
   197
	/* If key hash isn't SHA1 length then forget it */
sl@0
   198
	if (id->value.byKey->length != SHA_DIGEST_LENGTH) return NULL;
sl@0
   199
	keyhash = id->value.byKey->data;
sl@0
   200
	/* Calculate hash of each key and compare */
sl@0
   201
	for (i = 0; i < sk_X509_num(certs); i++)
sl@0
   202
		{
sl@0
   203
		x = sk_X509_value(certs, i);
sl@0
   204
		X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
sl@0
   205
		if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
sl@0
   206
			return x;
sl@0
   207
		}
sl@0
   208
	return NULL;
sl@0
   209
	}
sl@0
   210
sl@0
   211
sl@0
   212
static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags)
sl@0
   213
	{
sl@0
   214
	STACK_OF(OCSP_SINGLERESP) *sresp;
sl@0
   215
	X509 *signer, *sca;
sl@0
   216
	OCSP_CERTID *caid = NULL;
sl@0
   217
	int i;
sl@0
   218
	sresp = bs->tbsResponseData->responses;
sl@0
   219
sl@0
   220
	if (sk_X509_num(chain) <= 0)
sl@0
   221
		{
sl@0
   222
		OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
sl@0
   223
		return -1;
sl@0
   224
		}
sl@0
   225
sl@0
   226
	/* See if the issuer IDs match. */
sl@0
   227
	i = ocsp_check_ids(sresp, &caid);
sl@0
   228
sl@0
   229
	/* If ID mismatch or other error then return */
sl@0
   230
	if (i <= 0) return i;
sl@0
   231
sl@0
   232
	signer = sk_X509_value(chain, 0);
sl@0
   233
	/* Check to see if OCSP responder CA matches request CA */
sl@0
   234
	if (sk_X509_num(chain) > 1)
sl@0
   235
		{
sl@0
   236
		sca = sk_X509_value(chain, 1);
sl@0
   237
		i = ocsp_match_issuerid(sca, caid, sresp);
sl@0
   238
		if (i < 0) return i;
sl@0
   239
		if (i)
sl@0
   240
			{
sl@0
   241
			/* We have a match, if extensions OK then success */
sl@0
   242
			if (ocsp_check_delegated(signer, flags)) return 1;
sl@0
   243
			return 0;
sl@0
   244
			}
sl@0
   245
		}
sl@0
   246
sl@0
   247
	/* Otherwise check if OCSP request signed directly by request CA */
sl@0
   248
	return ocsp_match_issuerid(signer, caid, sresp);
sl@0
   249
	}
sl@0
   250
sl@0
   251
sl@0
   252
/* Check the issuer certificate IDs for equality. If there is a mismatch with the same
sl@0
   253
 * algorithm then there's no point trying to match any certificates against the issuer.
sl@0
   254
 * If the issuer IDs all match then we just need to check equality against one of them.
sl@0
   255
 */
sl@0
   256
	
sl@0
   257
static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
sl@0
   258
	{
sl@0
   259
	OCSP_CERTID *tmpid, *cid;
sl@0
   260
	int i, idcount;
sl@0
   261
sl@0
   262
	idcount = sk_OCSP_SINGLERESP_num(sresp);
sl@0
   263
	if (idcount <= 0)
sl@0
   264
		{
sl@0
   265
		OCSPerr(OCSP_F_OCSP_CHECK_IDS, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
sl@0
   266
		return -1;
sl@0
   267
		}
sl@0
   268
sl@0
   269
	cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
sl@0
   270
sl@0
   271
	*ret = NULL;
sl@0
   272
sl@0
   273
	for (i = 1; i < idcount; i++)
sl@0
   274
		{
sl@0
   275
		tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
sl@0
   276
		/* Check to see if IDs match */
sl@0
   277
		if (OCSP_id_issuer_cmp(cid, tmpid))
sl@0
   278
			{
sl@0
   279
			/* If algoritm mismatch let caller deal with it */
sl@0
   280
			if (OBJ_cmp(tmpid->hashAlgorithm->algorithm,
sl@0
   281
					cid->hashAlgorithm->algorithm))
sl@0
   282
					return 2;
sl@0
   283
			/* Else mismatch */
sl@0
   284
			return 0;
sl@0
   285
			}
sl@0
   286
		}
sl@0
   287
sl@0
   288
	/* All IDs match: only need to check one ID */
sl@0
   289
	*ret = cid;
sl@0
   290
	return 1;
sl@0
   291
	}
sl@0
   292
sl@0
   293
sl@0
   294
static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
sl@0
   295
			STACK_OF(OCSP_SINGLERESP) *sresp)
sl@0
   296
	{
sl@0
   297
	/* If only one ID to match then do it */
sl@0
   298
	if(cid)
sl@0
   299
		{
sl@0
   300
		const EVP_MD *dgst;
sl@0
   301
		X509_NAME *iname;
sl@0
   302
		int mdlen;
sl@0
   303
		unsigned char md[EVP_MAX_MD_SIZE];
sl@0
   304
		if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm)))
sl@0
   305
			{
sl@0
   306
			OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, OCSP_R_UNKNOWN_MESSAGE_DIGEST);
sl@0
   307
			return -1;
sl@0
   308
			}
sl@0
   309
sl@0
   310
		mdlen = EVP_MD_size(dgst);
sl@0
   311
		if ((cid->issuerNameHash->length != mdlen) ||
sl@0
   312
		   (cid->issuerKeyHash->length != mdlen))
sl@0
   313
			return 0;
sl@0
   314
		iname = X509_get_subject_name(cert);
sl@0
   315
		if (!X509_NAME_digest(iname, dgst, md, NULL))
sl@0
   316
			return -1;
sl@0
   317
		if (memcmp(md, cid->issuerNameHash->data, mdlen))
sl@0
   318
			return 0;
sl@0
   319
		X509_pubkey_digest(cert, EVP_sha1(), md, NULL);
sl@0
   320
		if (memcmp(md, cid->issuerKeyHash->data, mdlen))
sl@0
   321
			return 0;
sl@0
   322
sl@0
   323
		return 1;
sl@0
   324
sl@0
   325
		}
sl@0
   326
	else
sl@0
   327
		{
sl@0
   328
		/* We have to match the whole lot */
sl@0
   329
		int i, ret;
sl@0
   330
		OCSP_CERTID *tmpid;
sl@0
   331
		for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++)
sl@0
   332
			{
sl@0
   333
			tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
sl@0
   334
			ret = ocsp_match_issuerid(cert, tmpid, NULL);
sl@0
   335
			if (ret <= 0) return ret;
sl@0
   336
			}
sl@0
   337
		return 1;
sl@0
   338
		}
sl@0
   339
			
sl@0
   340
	}
sl@0
   341
sl@0
   342
static int ocsp_check_delegated(X509 *x, int flags)
sl@0
   343
	{
sl@0
   344
	X509_check_purpose(x, -1, 0);
sl@0
   345
	if ((x->ex_flags & EXFLAG_XKUSAGE) &&
sl@0
   346
	    (x->ex_xkusage & XKU_OCSP_SIGN))
sl@0
   347
		return 1;
sl@0
   348
	OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
sl@0
   349
	return 0;
sl@0
   350
	}
sl@0
   351
sl@0
   352
/* Verify an OCSP request. This is fortunately much easier than OCSP
sl@0
   353
 * response verify. Just find the signers certificate and verify it
sl@0
   354
 * against a given trust value.
sl@0
   355
 */
sl@0
   356
sl@0
   357
EXPORT_C int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags)
sl@0
   358
        {
sl@0
   359
	X509 *signer;
sl@0
   360
	X509_NAME *nm;
sl@0
   361
	GENERAL_NAME *gen;
sl@0
   362
	int ret;
sl@0
   363
	X509_STORE_CTX ctx;
sl@0
   364
	if (!req->optionalSignature) 
sl@0
   365
		{
sl@0
   366
		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
sl@0
   367
		return 0;
sl@0
   368
		}
sl@0
   369
	gen = req->tbsRequest->requestorName;
sl@0
   370
	if (!gen || gen->type != GEN_DIRNAME)
sl@0
   371
		{
sl@0
   372
		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
sl@0
   373
		return 0;
sl@0
   374
		}
sl@0
   375
	nm = gen->d.directoryName;
sl@0
   376
	ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags);
sl@0
   377
	if (ret <= 0)
sl@0
   378
		{
sl@0
   379
		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
sl@0
   380
		return 0;
sl@0
   381
		}
sl@0
   382
	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
sl@0
   383
		flags |= OCSP_NOVERIFY;
sl@0
   384
	if (!(flags & OCSP_NOSIGS))
sl@0
   385
		{
sl@0
   386
		EVP_PKEY *skey;
sl@0
   387
		skey = X509_get_pubkey(signer);
sl@0
   388
		ret = OCSP_REQUEST_verify(req, skey);
sl@0
   389
		EVP_PKEY_free(skey);
sl@0
   390
		if(ret <= 0)
sl@0
   391
			{
sl@0
   392
			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
sl@0
   393
			return 0;
sl@0
   394
			}
sl@0
   395
		}
sl@0
   396
	if (!(flags & OCSP_NOVERIFY))
sl@0
   397
		{
sl@0
   398
		int init_res;
sl@0
   399
		if(flags & OCSP_NOCHAIN)
sl@0
   400
			init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL);
sl@0
   401
		else
sl@0
   402
			init_res = X509_STORE_CTX_init(&ctx, store, signer,
sl@0
   403
					req->optionalSignature->certs);
sl@0
   404
		if(!init_res)
sl@0
   405
			{
sl@0
   406
			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,ERR_R_X509_LIB);
sl@0
   407
			return 0;
sl@0
   408
			}
sl@0
   409
sl@0
   410
		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
sl@0
   411
		X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST);
sl@0
   412
		ret = X509_verify_cert(&ctx);
sl@0
   413
		X509_STORE_CTX_cleanup(&ctx);
sl@0
   414
                if (ret <= 0)
sl@0
   415
			{
sl@0
   416
			ret = X509_STORE_CTX_get_error(&ctx);	
sl@0
   417
			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR);
sl@0
   418
			ERR_add_error_data(2, "Verify error:",
sl@0
   419
					X509_verify_cert_error_string(ret));
sl@0
   420
                        return 0;
sl@0
   421
                	}
sl@0
   422
		}
sl@0
   423
	return 1;
sl@0
   424
        }
sl@0
   425
sl@0
   426
static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
sl@0
   427
				X509_STORE *st, unsigned long flags)
sl@0
   428
	{
sl@0
   429
	X509 *signer;
sl@0
   430
	if(!(flags & OCSP_NOINTERN))
sl@0
   431
		{
sl@0
   432
		signer = X509_find_by_subject(req->optionalSignature->certs, nm);
sl@0
   433
		*psigner = signer;
sl@0
   434
		return 1;
sl@0
   435
		}
sl@0
   436
sl@0
   437
	signer = X509_find_by_subject(certs, nm);
sl@0
   438
	if (signer)
sl@0
   439
		{
sl@0
   440
		*psigner = signer;
sl@0
   441
		return 2;
sl@0
   442
		}
sl@0
   443
	return 0;
sl@0
   444
	}