Commit 3e727a3b authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add support for nameRelativeToCRLIssuer field in distribution point name

fields.
parent a9ff742e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -236,6 +236,8 @@ static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
			crl->idp_reasons |=
				(idp->onlysomereasons->data[1] << 8);
		}

	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
	}

ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
+78 −24
Original line number Diff line number Diff line
@@ -780,13 +780,82 @@ static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer)
	return 0;
	}

/* Check for match between two dist point names: three separate cases.
 * 1. Both are relative names and compare X509_NAME types.
 * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
 * 3. Both are full names and compare two GENERAL_NAMES.
 */


static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
	{
	X509_NAME *nm = NULL;
	GENERAL_NAMES *gens = NULL;
	GENERAL_NAME *gena, *genb;
	int i, j;
	if (a->type == 1)
		{
		if (!a->dpname)
			return 0;
		/* Case 1: two X509_NAME */
		if (b->type == 1)
			{
			if (!b->dpname)
				return 0;
			if (!X509_NAME_cmp(a->dpname, b->dpname))
				return 1;
			else
				return 0;
			}
		/* Case 2: set name and GENERAL_NAMES appropriately */
		nm = a->dpname;
		gens = b->name.fullname;
		}
	else if (b->type == 1)
		{
		if (!b->dpname)
			return 0;
		/* Case 2: set name and GENERAL_NAMES appropriately */
		gens = a->name.fullname;
		nm = b->dpname;
		}

	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
	if (nm)
		{
		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
			{
			gena = sk_GENERAL_NAME_value(gens, i);	
			if (gena->type != GEN_DIRNAME)
				continue;
			if (!X509_NAME_cmp(nm, gena->d.directoryName))
				return 1;
			}
		return 0;
		}

	/* Else case 3: two GENERAL_NAMES */

	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
		{
		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
			{
			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
			if (!GENERAL_NAME_cmp(gena, genb))
				return 1;
			}
		}

	return 0;

	}

/* Check IDP name matches at least one CRLDP name */

static int idp_check_scope(X509 *x, X509_CRL *crl)
	{
	int i, j, k;
	GENERAL_NAMES *inames, *dnames;
	int i;
	if (crl->idp_flags & IDP_ONLYATTR)
		return 0;
	if (x->ex_flags & EXFLAG_CA)
@@ -801,32 +870,17 @@ static int idp_check_scope(X509 *x, X509_CRL *crl)
		}
	if (!crl->idp->distpoint)
		return 1;
	if (crl->idp->distpoint->type != 0)
		return 1;
	if (!x->crldp)
		return 0;
	inames = crl->idp->distpoint->name.fullname;
	for (i = 0; i < sk_GENERAL_NAME_num(inames); i++)
	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
		{
		GENERAL_NAME *igen = sk_GENERAL_NAME_value(inames, i);
		for (j = 0; j < sk_DIST_POINT_num(x->crldp); j++)
			{
			DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, j);
		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
		/* We don't handle these at present */
		if (dp->reasons || dp->CRLissuer)
			continue;
			if (!dp->distpoint || (dp->distpoint->type != 0))
				continue;
			dnames = dp->distpoint->name.fullname;
			for (k = 0; k < sk_GENERAL_NAME_num(dnames); k++)
				{
				GENERAL_NAME *cgen =
					sk_GENERAL_NAME_value(dnames, k);
				if (!GENERAL_NAME_cmp(igen, cgen))
		if (idp_check_dp(dp->distpoint, crl->idp->distpoint))
			return 1;
		}
			}
		}
	return 0;
	}

+54 −3
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * project 1999.
 */
/* ====================================================================
 * Copyright (c) 1999, 2005 The OpenSSL Project.  All rights reserved.
 * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -361,11 +361,31 @@ static void *v2i_crld(X509V3_EXT_METHOD *method,
IMPLEMENT_STACK_OF(DIST_POINT)
IMPLEMENT_ASN1_SET_OF(DIST_POINT)

static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
								void *exarg)
	{
	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;

	switch(operation)
		{
		case ASN1_OP_NEW_POST:
		dpn->dpname = NULL;
		break;

ASN1_CHOICE(DIST_POINT_NAME) = {
		case ASN1_OP_FREE_POST:
		if (dpn->dpname)
			X509_NAME_free(dpn->dpname);
		break;
		}
	return 1;
	}


ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
} ASN1_CHOICE_END(DIST_POINT_NAME)
} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)


IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)

@@ -550,3 +570,34 @@ static int i2r_crldp(X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
		}
	return 1;
	}

int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
	{
	int i;
	STACK_OF(X509_NAME_ENTRY) *frag;
	X509_NAME_ENTRY *ne;
	if (!dpn || (dpn->type != 1))
		return 1;
	frag = dpn->name.relativename;
	dpn->dpname = X509_NAME_dup(iname);
	if (!dpn->dpname)
		return 0;
	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
		{
		ne = sk_X509_NAME_ENTRY_value(frag, i);
		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
			{
			X509_NAME_free(dpn->dpname);
			dpn->dpname = NULL;
			return 0;
			}
		}
	/* generate cached encoding of name */
	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
		{
		X509_NAME_free(dpn->dpname);
		dpn->dpname = NULL;
		return 0;
		}
	return 1;
	}
+33 −2
Original line number Diff line number Diff line
@@ -312,6 +312,35 @@ int X509_supported_extension(X509_EXTENSION *ex)
	return 0;
	}

static void setup_dp(X509 *x, DIST_POINT *dp)
	{
	X509_NAME *iname = NULL;
	int i;
	if (!dp->distpoint || (dp->distpoint->type != 1))
		return;
	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
		{
		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
		if (gen->type == GEN_DIRNAME)
			{
			iname = gen->d.directoryName;
			break;
			}
		}
	if (!iname)
		iname = X509_get_issuer_name(x);

	DIST_POINT_set_dpname(dp->distpoint, iname);

	}

static void setup_crldp(X509 *x)
	{
	int i;
	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
	}

static void x509v3_cache_extensions(X509 *x)
{
@@ -419,7 +448,9 @@ static void x509v3_cache_extensions(X509 *x)
	}
	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
	setup_crldp(x);
			
			
#ifndef OPENSSL_NO_RFC3779
 	x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
 	x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
+4 −0
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ union {
	GENERAL_NAMES *fullname;
	STACK_OF(X509_NAME_ENTRY) *relativename;
} name;
/* If relativename then this contains the full distribution point name */
X509_NAME *dpname;
} DIST_POINT_NAME;

struct DIST_POINT_st {
@@ -545,6 +547,8 @@ DECLARE_ASN1_FUNCTIONS(DIST_POINT)
DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)

int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);

DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)