| Index: openssl/crypto/x509/x509_lu.c
 | 
| ===================================================================
 | 
| --- openssl/crypto/x509/x509_lu.c	(revision 105093)
 | 
| +++ openssl/crypto/x509/x509_lu.c	(working copy)
 | 
| @@ -196,6 +196,8 @@
 | 
|  	ret->get_crl = 0;
 | 
|  	ret->check_crl = 0;
 | 
|  	ret->cert_crl = 0;
 | 
| +	ret->lookup_certs = 0;
 | 
| +	ret->lookup_crls = 0;
 | 
|  	ret->cleanup = 0;
 | 
|  
 | 
|  	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
 | 
| @@ -296,7 +298,7 @@
 | 
|  	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
 | 
|  	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
|  
 | 
| -	if (tmp == NULL)
 | 
| +	if (tmp == NULL || type == X509_LU_CRL)
 | 
|  		{
 | 
|  		for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
 | 
|  			{
 | 
| @@ -421,14 +423,15 @@
 | 
|  		}
 | 
|  	}
 | 
|  
 | 
| -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
 | 
| -	     X509_NAME *name)
 | 
| +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
 | 
| +	     X509_NAME *name, int *pnmatch)
 | 
|  	{
 | 
|  	X509_OBJECT stmp;
 | 
|  	X509 x509_s;
 | 
|  	X509_CINF cinf_s;
 | 
|  	X509_CRL crl_s;
 | 
|  	X509_CRL_INFO crl_info_s;
 | 
| +	int idx;
 | 
|  
 | 
|  	stmp.type=type;
 | 
|  	switch (type)
 | 
| @@ -448,9 +451,31 @@
 | 
|  		return -1;
 | 
|  		}
 | 
|  
 | 
| -	return sk_X509_OBJECT_find(h,&stmp);
 | 
| +	idx = sk_X509_OBJECT_find(h,&stmp);
 | 
| +	if (idx >= 0 && pnmatch)
 | 
| +		{
 | 
| +		int tidx;
 | 
| +		const X509_OBJECT *tobj, *pstmp;
 | 
| +		*pnmatch = 1;
 | 
| +		pstmp = &stmp;
 | 
| +		for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++)
 | 
| +			{
 | 
| +			tobj = sk_X509_OBJECT_value(h, tidx);
 | 
| +			if (x509_object_cmp(&tobj, &pstmp))
 | 
| +				break;
 | 
| +			(*pnmatch)++;
 | 
| +			}
 | 
| +		}
 | 
| +	return idx;
 | 
|  	}
 | 
|  
 | 
| +
 | 
| +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
 | 
| +	     X509_NAME *name)
 | 
| +	{
 | 
| +	return x509_object_idx_cnt(h, type, name, NULL);
 | 
| +	}
 | 
| +
 | 
|  X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
 | 
|  	     X509_NAME *name)
 | 
|  	{
 | 
| @@ -460,19 +485,125 @@
 | 
|  	return sk_X509_OBJECT_value(h, idx);
 | 
|  	}
 | 
|  
 | 
| +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
 | 
| +	{
 | 
| +	int i, idx, cnt;
 | 
| +	STACK_OF(X509) *sk;
 | 
| +	X509 *x;
 | 
| +	X509_OBJECT *obj;
 | 
| +	sk = sk_X509_new_null();
 | 
| +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
 | 
| +	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
 | 
| +	if (idx < 0)
 | 
| +		{
 | 
| +		/* Nothing found in cache: do lookup to possibly add new
 | 
| +		 * objects to cache
 | 
| +		 */
 | 
| +		X509_OBJECT xobj;
 | 
| +		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +		if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
 | 
| +			{
 | 
| +			sk_X509_free(sk);
 | 
| +			return NULL;
 | 
| +			}
 | 
| +		X509_OBJECT_free_contents(&xobj);
 | 
| +		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
 | 
| +		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
 | 
| +		if (idx < 0)
 | 
| +			{
 | 
| +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +			sk_X509_free(sk);
 | 
| +			return NULL;
 | 
| +			}
 | 
| +		}
 | 
| +	for (i = 0; i < cnt; i++, idx++)
 | 
| +		{
 | 
| +		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
 | 
| +		x = obj->data.x509;
 | 
| +		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
 | 
| +		if (!sk_X509_push(sk, x))
 | 
| +			{
 | 
| +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +			X509_free(x);
 | 
| +			sk_X509_pop_free(sk, X509_free);
 | 
| +			return NULL;
 | 
| +			}
 | 
| +		}
 | 
| +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +	return sk;
 | 
| +
 | 
| +	}
 | 
| +
 | 
| +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
 | 
| +	{
 | 
| +	int i, idx, cnt;
 | 
| +	STACK_OF(X509_CRL) *sk;
 | 
| +	X509_CRL *x;
 | 
| +	X509_OBJECT *obj, xobj;
 | 
| +	sk = sk_X509_CRL_new_null();
 | 
| +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
 | 
| +	/* Check cache first */
 | 
| +	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
 | 
| +
 | 
| +	/* Always do lookup to possibly add new CRLs to cache
 | 
| +	 */
 | 
| +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +	if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
 | 
| +		{
 | 
| +		sk_X509_CRL_free(sk);
 | 
| +		return NULL;
 | 
| +		}
 | 
| +	X509_OBJECT_free_contents(&xobj);
 | 
| +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
 | 
| +	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
 | 
| +	if (idx < 0)
 | 
| +		{
 | 
| +		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +		sk_X509_CRL_free(sk);
 | 
| +		return NULL;
 | 
| +		}
 | 
| +
 | 
| +	for (i = 0; i < cnt; i++, idx++)
 | 
| +		{
 | 
| +		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
 | 
| +		x = obj->data.crl;
 | 
| +		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
 | 
| +		if (!sk_X509_CRL_push(sk, x))
 | 
| +			{
 | 
| +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +			X509_CRL_free(x);
 | 
| +			sk_X509_CRL_pop_free(sk, X509_CRL_free);
 | 
| +			return NULL;
 | 
| +			}
 | 
| +		}
 | 
| +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 | 
| +	return sk;
 | 
| +	}
 | 
| +
 | 
|  X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
 | 
|  	{
 | 
|  	int idx, i;
 | 
|  	X509_OBJECT *obj;
 | 
|  	idx = sk_X509_OBJECT_find(h, x);
 | 
|  	if (idx == -1) return NULL;
 | 
| -	if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx);
 | 
| +	if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
 | 
| +		return sk_X509_OBJECT_value(h, idx);
 | 
|  	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
 | 
|  		{
 | 
|  		obj = sk_X509_OBJECT_value(h, i);
 | 
|  		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
 | 
|  			return NULL;
 | 
| -		if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509))
 | 
| +		if (x->type == X509_LU_X509)
 | 
| +			{
 | 
| +			if (!X509_cmp(obj->data.x509, x->data.x509))
 | 
| +				return obj;
 | 
| +			}
 | 
| +		else if (x->type == X509_LU_CRL)
 | 
| +			{
 | 
| +			if (!X509_CRL_match(obj->data.crl, x->data.crl))
 | 
| +				return obj;
 | 
| +			}
 | 
| +		else
 | 
|  			return obj;
 | 
|  		}
 | 
|  	return NULL;
 | 
| @@ -575,5 +706,11 @@
 | 
|  	return X509_VERIFY_PARAM_set1(ctx->param, param);
 | 
|  	}
 | 
|  
 | 
| +void X509_STORE_set_verify_cb(X509_STORE *ctx,
 | 
| +				  int (*verify_cb)(int, X509_STORE_CTX *))
 | 
| +	{
 | 
| +	ctx->verify_cb = verify_cb;
 | 
| +	}
 | 
| +
 | 
|  IMPLEMENT_STACK_OF(X509_LOOKUP)
 | 
|  IMPLEMENT_STACK_OF(X509_OBJECT)
 | 
| 
 |