Commit 4d50a2b4 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add verify callback functions to lookup a STACK of matching certs or CRLs

based on subject name.

New thread safe functions to retrieve matching STACK from X509_STORE.

Cache some IDP components.
parent 7f430166
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@

static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
				const X509_REVOKED * const *b);
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);

ASN1_SEQUENCE(X509_REVOKED) = {
	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
@@ -116,6 +117,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
		case ASN1_OP_NEW_POST:
		crl->idp = NULL;
		crl->akid = NULL;
		crl->flags = 0;
		crl->idp_flags = 0;
		break;

		case ASN1_OP_D2I_POST:
@@ -124,6 +127,9 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
#endif
		crl->idp = X509_CRL_get_ext_d2i(crl,
				NID_issuing_distribution_point, NULL, NULL);
		if (crl->idp)
			setup_idp(crl, crl->idp);

		crl->akid = X509_CRL_get_ext_d2i(crl,
				NID_authority_key_identifier, NULL, NULL);	
		break;
@@ -138,6 +144,46 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
	return 1;
	}

/* Convert IDP into a more convenient form */

static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
	{
	int idp_only = 0;
	/* Set various flags according to IDP */
	crl->idp_flags |= IDP_PRESENT;
	if (idp->onlyuser > 0)
		{
		idp_only++;
		crl->idp_flags |= IDP_ONLYUSER;
		}
	if (idp->onlyCA > 0)
		{
		idp_only++;
		crl->idp_flags |= IDP_ONLYCA;
		}
	if (idp->onlyattr > 0)
		{
		idp_only++;
		crl->idp_flags |= IDP_ONLYATTR;
		}

	if (idp_only > 1)
		crl->idp_flags |= IDP_INVALID;

	if (idp->indirectCRL > 0)
		crl->idp_flags |= IDP_INDIRECT;

	if (idp->onlysomereasons)
		{
		crl->idp_flags |= IDP_REASONS;
		if (idp->onlysomereasons->length > 0)
			crl->idp_reasons = idp->onlysomereasons->data[0];
		if (idp->onlysomereasons->length > 1)
			crl->idp_reasons |=
				(idp->onlysomereasons->data[1] << 8);
		}
	}

ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
+3 −0
Original line number Diff line number Diff line
@@ -454,6 +454,9 @@ struct X509_crl_st
	/* Copies of various extensions */
	AUTHORITY_KEYID *akid;
	ISSUING_DIST_POINT *idp;
	/* Convenient breakdown of IDP */
	int idp_flags;
	int idp_reasons;
#ifndef OPENSSL_NO_SHA
	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
#endif
+92 −3
Original line number Diff line number Diff line
@@ -414,14 +414,15 @@ void X509_OBJECT_free_contents(X509_OBJECT *a)
		}
	}

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)
@@ -441,7 +442,29 @@ int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
		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,
@@ -453,6 +476,72 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
	return sk_X509_OBJECT_value(h, idx);
}

STACK_OF(X509)* X509_STORE_get_certs(X509_STORE *st, X509_NAME *nm)
	{
	int i, idx, cnt;
	STACK_OF(X509) *sk;
	X509 *x;
	X509_OBJECT *obj;
	sk = sk_X509_new_null();
	CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
	idx = x509_object_idx_cnt(st->objs, X509_LU_X509, nm, &cnt);
	if (idx < 0)
		{
		CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
		sk_X509_free(sk);
		return NULL;
		}
	for (i = 0; i < cnt; i++, idx++)
		{
		obj = sk_X509_OBJECT_value(st->objs, i);
		x = obj->data.x509;
		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
		if (!sk_X509_push(sk, x))
			{
			CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
			X509_free(x);
			sk_X509_pop_free(sk, X509_free);
			return NULL;
			}
		}
	CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
	return sk;

	}

STACK_OF(X509_CRL)* X509_STORE_get_crls(X509_STORE *st, X509_NAME *nm)
	{
	int i, idx, cnt;
	STACK_OF(X509_CRL) *sk;
	X509_CRL *x;
	X509_OBJECT *obj;
	sk = sk_X509_CRL_new_null();
	CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
	idx = x509_object_idx_cnt(st->objs, X509_LU_CRL, nm, &cnt);
	if (idx < 0)
		{
		CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
		sk_X509_CRL_free(sk);
		return NULL;
		}
	for (i = 0; i < cnt; i++, idx++)
		{
		obj = sk_X509_OBJECT_value(st->objs, i);
		x = obj->data.crl;
		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
		if (!sk_X509_CRL_push(sk, x))
			{
			CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
			X509_CRL_free(x);
			sk_X509_CRL_pop_free(sk, X509_CRL_free);
			return NULL;
			}
		}
	CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
	return sk;

	}

X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
{
	int idx, i;
+23 −1
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ static int check_revocation(X509_STORE_CTX *ctx);
static int check_cert(X509_STORE_CTX *ctx);
static int check_policy(X509_STORE_CTX *ctx);
static int internal_verify(X509_STORE_CTX *ctx);
static STACK_OF(X509) * lookup_certs(X509_STORE_CTX *ctx, X509_NAME *nm);
static STACK_OF(X509_CRL) * lookup_crls(X509_STORE_CTX *ctx, X509_NAME *nm);
const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;


@@ -669,7 +671,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl,
		if (check_crl_time(ctx, crl, 0))
			{
			*pcrl = crl;
			CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509);
			CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
			return 1;
			}
		best_crl = crl;
@@ -874,6 +876,16 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
	return 1;
	}

static STACK_OF(X509) * lookup_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
	{
	return X509_STORE_get_certs(ctx->ctx, nm);
	}

static STACK_OF(X509_CRL) * lookup_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
	{
	return X509_STORE_get_crls(ctx->ctx, nm);
	}

static int check_policy(X509_STORE_CTX *ctx)
	{
	int ret;
@@ -1461,6 +1473,16 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
	else
		ctx->cert_crl = cert_crl;

	if (store && store->lookup_certs)
		ctx->lookup_certs = store->lookup_certs;
	else
		ctx->lookup_certs = lookup_certs;

	if (store && store->lookup_crls)
		ctx->lookup_crls = store->lookup_crls;
	else
		ctx->lookup_crls = lookup_crls;

	ctx->check_policy = check_policy;


+6 −0
Original line number Diff line number Diff line
@@ -198,6 +198,8 @@ struct x509_store_st
	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
	int (*cleanup)(X509_STORE_CTX *ctx);

	CRYPTO_EX_DATA ex_data;
@@ -246,6 +248,8 @@ struct x509_store_ctx_st /* X509_STORE_CTX */
	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
	int (*check_policy)(X509_STORE_CTX *ctx);
	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
	int (*cleanup)(X509_STORE_CTX *ctx);

	/* The following is built up */
@@ -383,6 +387,8 @@ void X509_OBJECT_free_contents(X509_OBJECT *a);
X509_STORE *X509_STORE_new(void );
void X509_STORE_free(X509_STORE *v);

STACK_OF(X509)* X509_STORE_get_certs(X509_STORE *st, X509_NAME *nm);
STACK_OF(X509_CRL)* X509_STORE_get_crls(X509_STORE *st, X509_NAME *nm);
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
int X509_STORE_set_trust(X509_STORE *ctx, int trust);
Loading