os/ossrv/ssl/libcrypto/src/crypto/x509/x509_lu.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/x509/x509_lu.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,567 @@
     1.4 +/* crypto/x509/x509_lu.c */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 +
    1.62 +#include <stdio.h>
    1.63 +#include "cryptlib.h"
    1.64 +#include <openssl/lhash.h>
    1.65 +#include <openssl/x509.h>
    1.66 +#include <openssl/x509v3.h>
    1.67 +
    1.68 +EXPORT_C X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
    1.69 +	{
    1.70 +	X509_LOOKUP *ret;
    1.71 +
    1.72 +	ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
    1.73 +	if (ret == NULL) return NULL;
    1.74 +
    1.75 +	ret->init=0;
    1.76 +	ret->skip=0;
    1.77 +	ret->method=method;
    1.78 +	ret->method_data=NULL;
    1.79 +	ret->store_ctx=NULL;
    1.80 +	if ((method->new_item != NULL) && !method->new_item(ret))
    1.81 +		{
    1.82 +		OPENSSL_free(ret);
    1.83 +		return NULL;
    1.84 +		}
    1.85 +	return ret;
    1.86 +	}
    1.87 +
    1.88 +EXPORT_C void X509_LOOKUP_free(X509_LOOKUP *ctx)
    1.89 +	{
    1.90 +	if (ctx == NULL) return;
    1.91 +	if (	(ctx->method != NULL) &&
    1.92 +		(ctx->method->free != NULL))
    1.93 +		ctx->method->free(ctx);
    1.94 +	OPENSSL_free(ctx);
    1.95 +	}
    1.96 +
    1.97 +EXPORT_C int X509_LOOKUP_init(X509_LOOKUP *ctx)
    1.98 +	{
    1.99 +	if (ctx->method == NULL) return 0;
   1.100 +	if (ctx->method->init != NULL)
   1.101 +		return ctx->method->init(ctx);
   1.102 +	else
   1.103 +		return 1;
   1.104 +	}
   1.105 +
   1.106 +EXPORT_C int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
   1.107 +	{
   1.108 +	if (ctx->method == NULL) return 0;
   1.109 +	if (ctx->method->shutdown != NULL)
   1.110 +		return ctx->method->shutdown(ctx);
   1.111 +	else
   1.112 +		return 1;
   1.113 +	}
   1.114 +
   1.115 +EXPORT_C int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
   1.116 +	     char **ret)
   1.117 +	{
   1.118 +	if (ctx->method == NULL) return -1;
   1.119 +	if (ctx->method->ctrl != NULL)
   1.120 +		return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
   1.121 +	else
   1.122 +		return 1;
   1.123 +	}
   1.124 +
   1.125 +EXPORT_C int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
   1.126 +	     X509_OBJECT *ret)
   1.127 +	{
   1.128 +	if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
   1.129 +		return X509_LU_FAIL;
   1.130 +	if (ctx->skip) return 0;
   1.131 +	return ctx->method->get_by_subject(ctx,type,name,ret);
   1.132 +	}
   1.133 +
   1.134 +EXPORT_C int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
   1.135 +	     ASN1_INTEGER *serial, X509_OBJECT *ret)
   1.136 +	{
   1.137 +	if ((ctx->method == NULL) ||
   1.138 +		(ctx->method->get_by_issuer_serial == NULL))
   1.139 +		return X509_LU_FAIL;
   1.140 +	return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
   1.141 +	}
   1.142 +
   1.143 +EXPORT_C int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
   1.144 +	     unsigned char *bytes, int len, X509_OBJECT *ret)
   1.145 +	{
   1.146 +	if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
   1.147 +		return X509_LU_FAIL;
   1.148 +	return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
   1.149 +	}
   1.150 +
   1.151 +EXPORT_C int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
   1.152 +	     X509_OBJECT *ret)
   1.153 +	{
   1.154 +	if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
   1.155 +		return X509_LU_FAIL;
   1.156 +	return ctx->method->get_by_alias(ctx,type,str,len,ret);
   1.157 +	}
   1.158 +
   1.159 +  
   1.160 +static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
   1.161 +  	{
   1.162 + 	int ret;
   1.163 +
   1.164 + 	ret=((*a)->type - (*b)->type);
   1.165 + 	if (ret) return ret;
   1.166 + 	switch ((*a)->type)
   1.167 + 		{
   1.168 + 	case X509_LU_X509:
   1.169 + 		ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
   1.170 + 		break;
   1.171 + 	case X509_LU_CRL:
   1.172 + 		ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
   1.173 + 		break;
   1.174 +	default:
   1.175 +		/* abort(); */
   1.176 +		return 0;
   1.177 +		}
   1.178 +	return ret;
   1.179 +	}
   1.180 +
   1.181 +EXPORT_C X509_STORE *X509_STORE_new(void)
   1.182 +	{
   1.183 +	X509_STORE *ret;
   1.184 +
   1.185 +	if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
   1.186 +		return NULL;
   1.187 +	ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
   1.188 +	ret->cache=1;
   1.189 +	ret->get_cert_methods=sk_X509_LOOKUP_new_null();
   1.190 +	ret->verify=0;
   1.191 +	ret->verify_cb=0;
   1.192 +
   1.193 +	if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
   1.194 +		return NULL;
   1.195 +
   1.196 +	ret->get_issuer = 0;
   1.197 +	ret->check_issued = 0;
   1.198 +	ret->check_revocation = 0;
   1.199 +	ret->get_crl = 0;
   1.200 +	ret->check_crl = 0;
   1.201 +	ret->cert_crl = 0;
   1.202 +	ret->cleanup = 0;
   1.203 +
   1.204 +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data);
   1.205 +	ret->references=1;
   1.206 +	return ret;
   1.207 +	}
   1.208 +
   1.209 +static void cleanup(X509_OBJECT *a)
   1.210 +	{
   1.211 +	if (a->type == X509_LU_X509)
   1.212 +		{
   1.213 +		X509_free(a->data.x509);
   1.214 +		}
   1.215 +	else if (a->type == X509_LU_CRL)
   1.216 +		{
   1.217 +		X509_CRL_free(a->data.crl);
   1.218 +		}
   1.219 +	else
   1.220 +		{
   1.221 +		/* abort(); */
   1.222 +		}
   1.223 +
   1.224 +	OPENSSL_free(a);
   1.225 +	}
   1.226 +
   1.227 +EXPORT_C void X509_STORE_free(X509_STORE *vfy)
   1.228 +	{
   1.229 +	int i;
   1.230 +	STACK_OF(X509_LOOKUP) *sk;
   1.231 +	X509_LOOKUP *lu;
   1.232 +
   1.233 +	if (vfy == NULL)
   1.234 +	    return;
   1.235 +
   1.236 +	sk=vfy->get_cert_methods;
   1.237 +	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
   1.238 +		{
   1.239 +		lu=sk_X509_LOOKUP_value(sk,i);
   1.240 +		X509_LOOKUP_shutdown(lu);
   1.241 +		X509_LOOKUP_free(lu);
   1.242 +		}
   1.243 +	sk_X509_LOOKUP_free(sk);
   1.244 +	sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
   1.245 +
   1.246 +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
   1.247 +	if (vfy->param)
   1.248 +		X509_VERIFY_PARAM_free(vfy->param);
   1.249 +	OPENSSL_free(vfy);
   1.250 +	}
   1.251 +
   1.252 +EXPORT_C X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
   1.253 +	{
   1.254 +	int i;
   1.255 +	STACK_OF(X509_LOOKUP) *sk;
   1.256 +	X509_LOOKUP *lu;
   1.257 +
   1.258 +	sk=v->get_cert_methods;
   1.259 +	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
   1.260 +		{
   1.261 +		lu=sk_X509_LOOKUP_value(sk,i);
   1.262 +		if (m == lu->method)
   1.263 +			{
   1.264 +			return lu;
   1.265 +			}
   1.266 +		}
   1.267 +	/* a new one */
   1.268 +	lu=X509_LOOKUP_new(m);
   1.269 +	if (lu == NULL)
   1.270 +		return NULL;
   1.271 +	else
   1.272 +		{
   1.273 +		lu->store_ctx=v;
   1.274 +		if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
   1.275 +			return lu;
   1.276 +		else
   1.277 +			{
   1.278 +			X509_LOOKUP_free(lu);
   1.279 +			return NULL;
   1.280 +			}
   1.281 +		}
   1.282 +	}
   1.283 +
   1.284 +EXPORT_C int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
   1.285 +	     X509_OBJECT *ret)
   1.286 +	{
   1.287 +	X509_STORE *ctx=vs->ctx;
   1.288 +	X509_LOOKUP *lu;
   1.289 +	X509_OBJECT stmp,*tmp;
   1.290 +	int i,j;
   1.291 +
   1.292 +	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
   1.293 +
   1.294 +	if (tmp == NULL)
   1.295 +		{
   1.296 +		for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
   1.297 +			{
   1.298 +			lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
   1.299 +			j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
   1.300 +			if (j < 0)
   1.301 +				{
   1.302 +				vs->current_method=j;
   1.303 +				return j;
   1.304 +				}
   1.305 +			else if (j)
   1.306 +				{
   1.307 +				tmp= &stmp;
   1.308 +				break;
   1.309 +				}
   1.310 +			}
   1.311 +		vs->current_method=0;
   1.312 +		if (tmp == NULL)
   1.313 +			return 0;
   1.314 +		}
   1.315 +
   1.316 +/*	if (ret->data.ptr != NULL)
   1.317 +		X509_OBJECT_free_contents(ret); */
   1.318 +
   1.319 +	ret->type=tmp->type;
   1.320 +	ret->data.ptr=tmp->data.ptr;
   1.321 +
   1.322 +	X509_OBJECT_up_ref_count(ret);
   1.323 +
   1.324 +	return 1;
   1.325 +	}
   1.326 +
   1.327 +EXPORT_C int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
   1.328 +	{
   1.329 +	X509_OBJECT *obj;
   1.330 +	int ret=1;
   1.331 +
   1.332 +	if (x == NULL) return 0;
   1.333 +	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
   1.334 +	if (obj == NULL)
   1.335 +		{
   1.336 +		X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE);
   1.337 +		return 0;
   1.338 +		}
   1.339 +	obj->type=X509_LU_X509;
   1.340 +	obj->data.x509=x;
   1.341 +
   1.342 +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
   1.343 +
   1.344 +	X509_OBJECT_up_ref_count(obj);
   1.345 +
   1.346 +
   1.347 +	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
   1.348 +		{
   1.349 +		X509_OBJECT_free_contents(obj);
   1.350 +		OPENSSL_free(obj);
   1.351 +		X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE);
   1.352 +		ret=0;
   1.353 +		} 
   1.354 +	else sk_X509_OBJECT_push(ctx->objs, obj);
   1.355 +
   1.356 +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
   1.357 +
   1.358 +	return ret;
   1.359 +	}
   1.360 +
   1.361 +EXPORT_C int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
   1.362 +	{
   1.363 +	X509_OBJECT *obj;
   1.364 +	int ret=1;
   1.365 +
   1.366 +	if (x == NULL) return 0;
   1.367 +	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
   1.368 +	if (obj == NULL)
   1.369 +		{
   1.370 +		X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE);
   1.371 +		return 0;
   1.372 +		}
   1.373 +	obj->type=X509_LU_CRL;
   1.374 +	obj->data.crl=x;
   1.375 +
   1.376 +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
   1.377 +
   1.378 +	X509_OBJECT_up_ref_count(obj);
   1.379 +
   1.380 +	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
   1.381 +		{
   1.382 +		X509_OBJECT_free_contents(obj);
   1.383 +		OPENSSL_free(obj);
   1.384 +		X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE);
   1.385 +		ret=0;
   1.386 +		}
   1.387 +	else sk_X509_OBJECT_push(ctx->objs, obj);
   1.388 +
   1.389 +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
   1.390 +
   1.391 +	return ret;
   1.392 +	}
   1.393 +
   1.394 +EXPORT_C void X509_OBJECT_up_ref_count(X509_OBJECT *a)
   1.395 +	{
   1.396 +	switch (a->type)
   1.397 +		{
   1.398 +	case X509_LU_X509:
   1.399 +		CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
   1.400 +		break;
   1.401 +	case X509_LU_CRL:
   1.402 +		CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
   1.403 +		break;
   1.404 +		}
   1.405 +	}
   1.406 +
   1.407 +EXPORT_C void X509_OBJECT_free_contents(X509_OBJECT *a)
   1.408 +	{
   1.409 +	switch (a->type)
   1.410 +		{
   1.411 +	case X509_LU_X509:
   1.412 +		X509_free(a->data.x509);
   1.413 +		break;
   1.414 +	case X509_LU_CRL:
   1.415 +		X509_CRL_free(a->data.crl);
   1.416 +		break;
   1.417 +		}
   1.418 +	}
   1.419 +
   1.420 +EXPORT_C int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
   1.421 +	     X509_NAME *name)
   1.422 +	{
   1.423 +	X509_OBJECT stmp;
   1.424 +	X509 x509_s;
   1.425 +	X509_CINF cinf_s;
   1.426 +	X509_CRL crl_s;
   1.427 +	X509_CRL_INFO crl_info_s;
   1.428 +
   1.429 +	stmp.type=type;
   1.430 +	switch (type)
   1.431 +		{
   1.432 +	case X509_LU_X509:
   1.433 +		stmp.data.x509= &x509_s;
   1.434 +		x509_s.cert_info= &cinf_s;
   1.435 +		cinf_s.subject=name;
   1.436 +		break;
   1.437 +	case X509_LU_CRL:
   1.438 +		stmp.data.crl= &crl_s;
   1.439 +		crl_s.crl= &crl_info_s;
   1.440 +		crl_info_s.issuer=name;
   1.441 +		break;
   1.442 +	default:
   1.443 +		/* abort(); */
   1.444 +		return -1;
   1.445 +		}
   1.446 +
   1.447 +	return sk_X509_OBJECT_find(h,&stmp);
   1.448 +	}
   1.449 +
   1.450 +EXPORT_C X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
   1.451 +	     X509_NAME *name)
   1.452 +{
   1.453 +	int idx;
   1.454 +	idx = X509_OBJECT_idx_by_subject(h, type, name);
   1.455 +	if (idx==-1) return NULL;
   1.456 +	return sk_X509_OBJECT_value(h, idx);
   1.457 +}
   1.458 +
   1.459 +EXPORT_C X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
   1.460 +{
   1.461 +	int idx, i;
   1.462 +	X509_OBJECT *obj;
   1.463 +	idx = sk_X509_OBJECT_find(h, x);
   1.464 +	if (idx == -1) return NULL;
   1.465 +	if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx);
   1.466 +	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
   1.467 +		{
   1.468 +		obj = sk_X509_OBJECT_value(h, i);
   1.469 +		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
   1.470 +			return NULL;
   1.471 +		if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509))
   1.472 +			return obj;
   1.473 +		}
   1.474 +	return NULL;
   1.475 +}
   1.476 +
   1.477 +
   1.478 +/* Try to get issuer certificate from store. Due to limitations
   1.479 + * of the API this can only retrieve a single certificate matching
   1.480 + * a given subject name. However it will fill the cache with all
   1.481 + * matching certificates, so we can examine the cache for all 
   1.482 + * matches.
   1.483 + *
   1.484 + * Return values are:
   1.485 + *  1 lookup successful.
   1.486 + *  0 certificate not found.
   1.487 + * -1 some other error.
   1.488 + */
   1.489 +
   1.490 +
   1.491 +EXPORT_C int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
   1.492 +{
   1.493 +	X509_NAME *xn;
   1.494 +	X509_OBJECT obj, *pobj;
   1.495 +	int i, ok, idx;
   1.496 +	xn=X509_get_issuer_name(x);
   1.497 +	ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
   1.498 +	if (ok != X509_LU_X509)
   1.499 +		{
   1.500 +		if (ok == X509_LU_RETRY)
   1.501 +			{
   1.502 +			X509_OBJECT_free_contents(&obj);
   1.503 +			X509err(X509_F_X509_STORE_CTX_GET1_ISSUER,X509_R_SHOULD_RETRY);
   1.504 +			return -1;
   1.505 +			}
   1.506 +		else if (ok != X509_LU_FAIL)
   1.507 +			{
   1.508 +			X509_OBJECT_free_contents(&obj);
   1.509 +			/* not good :-(, break anyway */
   1.510 +			return -1;
   1.511 +			}
   1.512 +		return 0;
   1.513 +		}
   1.514 +	/* If certificate matches all OK */
   1.515 +	if (ctx->check_issued(ctx, x, obj.data.x509))
   1.516 +		{
   1.517 +		*issuer = obj.data.x509;
   1.518 +		return 1;
   1.519 +		}
   1.520 +	X509_OBJECT_free_contents(&obj);
   1.521 +	/* Else find index of first matching cert */
   1.522 +	idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
   1.523 +	/* This shouldn't normally happen since we already have one match */
   1.524 +	if (idx == -1) return 0;
   1.525 +
   1.526 +	/* Look through all matching certificates for a suitable issuer */
   1.527 +	for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
   1.528 +		{
   1.529 +		pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
   1.530 +		/* See if we've ran out of matches */
   1.531 +		if (pobj->type != X509_LU_X509) return 0;
   1.532 +		if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0;
   1.533 +		if (ctx->check_issued(ctx, x, pobj->data.x509))
   1.534 +			{
   1.535 +			*issuer = pobj->data.x509;
   1.536 +			X509_OBJECT_up_ref_count(pobj);
   1.537 +			return 1;
   1.538 +			}
   1.539 +		}
   1.540 +	return 0;
   1.541 +}
   1.542 +
   1.543 +EXPORT_C int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
   1.544 +	{
   1.545 +	return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
   1.546 +	}
   1.547 +
   1.548 +EXPORT_C int X509_STORE_set_depth(X509_STORE *ctx, int depth)
   1.549 +	{
   1.550 +	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
   1.551 +	return 1;
   1.552 +	}
   1.553 +
   1.554 +EXPORT_C int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
   1.555 +	{
   1.556 +	return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
   1.557 +	}
   1.558 +
   1.559 +EXPORT_C int X509_STORE_set_trust(X509_STORE *ctx, int trust)
   1.560 +	{
   1.561 +	return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
   1.562 +	}
   1.563 +
   1.564 +EXPORT_C int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
   1.565 +	{
   1.566 +	return X509_VERIFY_PARAM_set1(ctx->param, param);
   1.567 +	}
   1.568 +
   1.569 +IMPLEMENT_STACK_OF(X509_LOOKUP)
   1.570 +IMPLEMENT_STACK_OF(X509_OBJECT)