195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* crypto/x509/x509_lu.c */
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved.
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com).
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL.
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to.  The following conditions
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA,
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in
1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed.
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used.
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package.
2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met:
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer.
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer in the
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    documentation and/or other materials provided with the distribution.
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    must display the following acknowledgement:
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes cryptographic software written by
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Eric Young (eay@cryptsoft.com)"
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    The word 'cryptographic' can be left out if the rouines from the library
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    being used are not cryptographic related :-).
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    the apps directory (application code) you must include an acknowledgement:
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE.
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed.  i.e. this code cannot simply be
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h>
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/lhash.h>
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h>
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509.h>
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509v3.h>
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_LOOKUP *ret;
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ret == NULL) return NULL;
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->init=0;
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->skip=0;
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->method=method;
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->method_data=NULL;
7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->store_ctx=NULL;
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((method->new_item != NULL) && !method->new_item(ret))
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_free(ret);
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ret;
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_LOOKUP_free(X509_LOOKUP *ctx)
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx == NULL) return;
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (	(ctx->method != NULL) &&
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(ctx->method->free != NULL))
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(*ctx->method->free)(ctx);
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	OPENSSL_free(ctx);
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_init(X509_LOOKUP *ctx)
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->method == NULL) return 0;
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->method->init != NULL)
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return ctx->method->init(ctx);
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 1;
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->method == NULL) return 0;
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->method->shutdown != NULL)
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return ctx->method->shutdown(ctx);
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 1;
11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     char **ret)
11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->method == NULL) return -1;
11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->method->ctrl != NULL)
11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 1;
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     X509_OBJECT *ret)
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return X509_LU_FAIL;
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->skip) return 0;
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ctx->method->get_by_subject(ctx,type,name,ret);
12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     ASN1_INTEGER *serial, X509_OBJECT *ret)
13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((ctx->method == NULL) ||
13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(ctx->method->get_by_issuer_serial == NULL))
13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return X509_LU_FAIL;
13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     unsigned char *bytes, int len, X509_OBJECT *ret)
14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return X509_LU_FAIL;
14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     X509_OBJECT *ret)
15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return X509_LU_FAIL;
15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ctx->method->get_by_alias(ctx,type,str,len,ret);
15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b)
15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  	{
15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 	int ret;
16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 	ret=((*a)->type - (*b)->type);
16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 	if (ret) return ret;
16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 	switch ((*a)->type)
16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 		{
16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 	case X509_LU_X509:
16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 		ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 		break;
16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 	case X509_LU_CRL:
16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 		ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 		break;
17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	default:
17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* abort(); */
17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ret;
17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_STORE *X509_STORE_new(void)
17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_STORE *ret;
18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
18461b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	memset(ret, 0, sizeof(*ret));
18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
18661b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	ret->cache = 1;
18761b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	ret->get_cert_methods = sk_X509_LOOKUP_new_null();
18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
19061b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin		goto err;
19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
19361b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin		goto err;
19461b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin
19561b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	ret->references = 1;
19661b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	return ret;
19761b66ffcc29f28900db4b037865a2206eb62242eDavid Benjaminerr:
19861b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	if (ret)
19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
20061b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin		if (ret->param)
20161b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin			X509_VERIFY_PARAM_free(ret->param);
20261b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin		if (ret->get_cert_methods)
20361b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin			sk_X509_LOOKUP_free(ret->get_cert_methods);
20461b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin		if (ret->objs)
20561b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin			sk_X509_OBJECT_free(ret->objs);
20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_free(ret);
20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
20861b66ffcc29f28900db4b037865a2206eb62242eDavid Benjamin	return NULL;
20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void cleanup(X509_OBJECT *a)
21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (a->type == X509_LU_X509)
21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_free(a->data.x509);
21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else if (a->type == X509_LU_CRL)
21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_CRL_free(a->data.crl);
22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* abort(); */
22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	OPENSSL_free(a);
22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_STORE_free(X509_STORE *vfy)
23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i;
23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t j;
23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(X509_LOOKUP) *sk;
23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_LOOKUP *lu;
23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (vfy == NULL)
23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	    return;
23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	i=CRYPTO_add(&vfy->references,-1,CRYPTO_LOCK_X509_STORE);
24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifdef REF_PRINT
24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	REF_PRINT("X509_STORE",vfy);
24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (i > 0) return;
24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#ifdef REF_CHECK
24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (i < 0)
24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		fprintf(stderr,"X509_STORE_free, bad reference count\n");
24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		abort(); /* ok */
24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk=vfy->get_cert_methods;
25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (j=0; j<sk_X509_LOOKUP_num(sk); j++)
25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		lu=sk_X509_LOOKUP_value(sk,j);
25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_LOOKUP_shutdown(lu);
25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_LOOKUP_free(lu);
25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk_X509_LOOKUP_free(sk);
26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (vfy->param)
26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_VERIFY_PARAM_free(vfy->param);
26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	OPENSSL_free(vfy);
26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
26895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(X509_LOOKUP) *sk;
27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_LOOKUP *lu;
27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk=v->get_cert_methods;
27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		lu=sk_X509_LOOKUP_value(sk,i);
27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (m == lu->method)
27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return lu;
28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* a new one */
28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	lu=X509_LOOKUP_new(m);
28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (lu == NULL)
28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		lu->store_ctx=v;
29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return lu;
29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_LOOKUP_free(lu);
29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return NULL;
29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     X509_OBJECT *ret)
30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_STORE *ctx=vs->ctx;
30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_LOOKUP *lu;
30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT stmp,*tmp;
30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i,j;
30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (tmp == NULL || type == X509_LU_CRL)
31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		for (i=vs->current_method; i<(int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (j < 0)
31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				vs->current_method=j;
32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return j;
32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			else if (j)
32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				tmp= &stmp;
32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				break;
32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		vs->current_method=0;
33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (tmp == NULL)
33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return 0;
33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/*	if (ret->data.ptr != NULL)
33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_OBJECT_free_contents(ret); */
33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->type=tmp->type;
33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret->data.ptr=tmp->data.ptr;
33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT_up_ref_count(ret);
34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT *obj;
34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int ret=1;
34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (x == NULL) return 0;
35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (obj == NULL)
35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, ERR_R_MALLOC_FAILURE);
35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	obj->type=X509_LU_X509;
35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	obj->data.x509=x;
35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT_up_ref_count(obj);
36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_OBJECT_free_contents(obj);
36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_free(obj);
36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, X509_R_CERT_ALREADY_IN_HASH_TABLE);
36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ret=0;
37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else sk_X509_OBJECT_push(ctx->objs, obj);
37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ret;
37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT *obj;
38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int ret=1;
38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (x == NULL) return 0;
38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (obj == NULL)
38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, ERR_R_MALLOC_FAILURE);
38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	obj->type=X509_LU_CRL;
39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	obj->data.crl=x;
39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT_up_ref_count(obj);
39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_OBJECT_free_contents(obj);
40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_free(obj);
40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, X509_R_CERT_ALREADY_IN_HASH_TABLE);
40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ret=0;
40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else sk_X509_OBJECT_push(ctx->objs, obj);
40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ret;
40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_OBJECT_up_ref_count(X509_OBJECT *a)
41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	switch (a->type)
41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case X509_LU_X509:
416150c617cfce408faf1274a60e5db194595cb4473David Benjamin		X509_up_ref(a->data.x509);
41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case X509_LU_CRL:
41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_OBJECT_free_contents(X509_OBJECT *a)
42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	switch (a->type)
42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case X509_LU_X509:
42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_free(a->data.x509);
43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case X509_LU_CRL:
43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_CRL_free(a->data.crl);
43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     X509_NAME *name, int *pnmatch)
43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT stmp;
44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509 x509_s;
44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_CINF cinf_s;
44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_CRL crl_s;
44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_CRL_INFO crl_info_s;
44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t idx;
44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	stmp.type=type;
44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	switch (type)
44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case X509_LU_X509:
45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		stmp.data.x509= &x509_s;
45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		x509_s.cert_info= &cinf_s;
45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		cinf_s.subject=name;
45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	case X509_LU_CRL:
45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		stmp.data.crl= &crl_s;
45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		crl_s.crl= &crl_info_s;
45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		crl_info_s.issuer=name;
45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	default:
46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* abort(); */
46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return -1;
46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idx = -1;
46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (sk_X509_OBJECT_find(h, &idx, &stmp) && pnmatch)
46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		int tidx;
46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		const X509_OBJECT *tobj, *pstmp;
47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		*pnmatch = 1;
47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		pstmp = &stmp;
47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++)
47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			tobj = sk_X509_OBJECT_value(h, tidx);
47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (x509_object_cmp(&tobj, &pstmp))
47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				break;
47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			(*pnmatch)++;
47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return idx;
48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     X509_NAME *name)
48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return x509_object_idx_cnt(h, type, name, NULL);
48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
49195c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	     X509_NAME *name)
49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int idx;
49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idx = X509_OBJECT_idx_by_subject(h, type, name);
49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idx==-1) return NULL;
49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return sk_X509_OBJECT_value(h, idx);
49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
50095c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleySTACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i, idx, cnt;
50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(X509) *sk;
50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509 *x;
50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT *obj;
50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk = sk_X509_new_null();
50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idx < 0)
51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Nothing found in cache: do lookup to possibly add new
51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * objects to cache
51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 */
51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_OBJECT xobj;
51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			sk_X509_free(sk);
51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return NULL;
52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_OBJECT_free_contents(&xobj);
52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (idx < 0)
52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			sk_X509_free(sk);
52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return NULL;
52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < cnt; i++, idx++)
53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		x = obj->data.x509;
535150c617cfce408faf1274a60e5db194595cb4473David Benjamin		if (!sk_X509_push(sk, X509_up_ref(x)))
53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_free(x);
53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			sk_X509_pop_free(sk, X509_free);
54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return NULL;
54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return sk;
54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
54895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleySTACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int i, idx, cnt;
55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(X509_CRL) *sk;
55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_CRL *x;
55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT *obj, xobj;
55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk = sk_X509_CRL_new_null();
55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Check cache first */
55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Always do lookup to possibly add new CRLs to cache
56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	 */
56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		sk_X509_CRL_free(sk);
56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT_free_contents(&xobj);
56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idx < 0)
57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		sk_X509_CRL_free(sk);
57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < cnt; i++, idx++)
57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		x = obj->data.crl;
58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!sk_X509_CRL_push(sk, x))
58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_CRL_free(x);
58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			sk_X509_CRL_pop_free(sk, X509_CRL_free);
58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return NULL;
58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return sk;
59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
59495c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t idx, i;
59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT *obj;
59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!sk_X509_OBJECT_find(h, &idx, x)) {
60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return sk_X509_OBJECT_value(h, idx);
60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		obj = sk_X509_OBJECT_value(h, i);
60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return NULL;
60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (x->type == X509_LU_X509)
61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!X509_cmp(obj->data.x509, x->data.x509))
61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return obj;
61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (x->type == X509_LU_CRL)
61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
61695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!X509_CRL_match(obj->data.crl, x->data.crl))
61795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				return obj;
61895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
61995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
62095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return obj;
62195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
62295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return NULL;
62395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
62495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
62595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
62695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Try to get issuer certificate from store. Due to limitations
62795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * of the API this can only retrieve a single certificate matching
62895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * a given subject name. However it will fill the cache with all
62995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * matching certificates, so we can examine the cache for all
63095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * matches.
63195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
63295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Return values are:
63395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *  1 lookup successful.
63495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *  0 certificate not found.
63595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * -1 some other error.
63695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
63795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
63895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
63995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_NAME *xn;
64095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT obj, *pobj;
64195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int ok, idx, ret;
64295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
64395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	xn=X509_get_issuer_name(x);
64495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
64595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ok != X509_LU_X509)
64695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
64795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ok == X509_LU_RETRY)
64895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
64995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_OBJECT_free_contents(&obj);
65095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_get1_issuer, X509_R_SHOULD_RETRY);
65195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return -1;
65295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
65395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (ok != X509_LU_FAIL)
65495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
65595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_OBJECT_free_contents(&obj);
65695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* not good :-(, break anyway */
65795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return -1;
65895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
65995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
66095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
66195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* If certificate matches all OK */
66295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (ctx->check_issued(ctx, x, obj.data.x509))
66395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
66495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		*issuer = obj.data.x509;
66595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 1;
66695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
66795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_OBJECT_free_contents(&obj);
66895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
66995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* Else find index of first cert accepted by 'check_issued' */
67095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret = 0;
67195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
67295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
67395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idx != -1) /* should be true as we've had at least one match */
67495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
67595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Look through all matching certs for suitable issuer */
67695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
67795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
67895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
67995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			/* See if we've run past the matches */
68095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (pobj->type != X509_LU_X509)
68195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				break;
68295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
68395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				break;
68495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (ctx->check_issued(ctx, x, pobj->data.x509))
68595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
68695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				*issuer = pobj->data.x509;
68795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				X509_OBJECT_up_ref_count(pobj);
68895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				ret = 1;
68995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				break;
69095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
69195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
69295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
69395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
69495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ret;
69595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
69695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
69795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
69895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
69995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
70095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
70195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
70295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_set_depth(X509_STORE *ctx, int depth)
70395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
70495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
70595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
70695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
70795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
70895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
70995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
71095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
71195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
71295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
71395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_set_trust(X509_STORE *ctx, int trust)
71495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
71595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
71695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
71795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
71895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
71995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
72095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return X509_VERIFY_PARAM_set1(ctx->param, param);
72195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
72295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
72395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_STORE_set_verify_cb(X509_STORE *ctx,
72495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				  int (*verify_cb)(int, X509_STORE_CTX *))
72595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
72695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ctx->verify_cb = verify_cb;
72795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
72895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
72995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
73095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm))
73195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
73295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ctx->lookup_crls = cb;
73395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
73495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
73595c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyX509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
73695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
73795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ctx->ctx;
73895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
739