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

X509 verification fixes.

Ignore self issued certificates when checking path length constraints.

Duplicate OIDs in policy tree in case they are allocated.

Use anyPolicy from certificate cache and not current tree level.
parent f9afd9f8
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(STRING) *rr_to,
#define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
#define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)

int verify_err = 0;

int MAIN(int, char **);

int MAIN(int argc, char **argv)
@@ -118,6 +120,7 @@ int MAIN(int argc, char **argv)
	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
	int badarg = 0;
	int flags = CMS_DETACHED, noout = 0, print = 0;
	int verify_retcode = 0;
	int rr_print = 0, rr_allorfirst = -1;
	STACK_OF(STRING) *rr_to = NULL, *rr_from = NULL;
	CMS_ReceiptRequest *rr = NULL;
@@ -167,6 +170,8 @@ int MAIN(int argc, char **argv)
			operation = SMIME_RESIGN;
		else if (!strcmp (*args, "-verify"))
			operation = SMIME_VERIFY;
		else if (!strcmp (*args, "-verify_retcode"))
			verify_retcode = 1;
		else if (!strcmp(*args,"-verify_receipt"))
			{
			operation = SMIME_VERIFY_RECEIPT;
@@ -1077,6 +1082,8 @@ int MAIN(int argc, char **argv)
		else
			{
			BIO_printf(bio_err, "Verification failure\n");
			if (verify_retcode)
				ret = verify_err + 32;
			goto end;
			}
		if (signerfile)
@@ -1206,6 +1213,8 @@ static int cms_cb(int ok, X509_STORE_CTX *ctx)

	error = X509_STORE_CTX_get_error(ctx);

	verify_err = error;

	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
		&& ((error != X509_V_OK) || (ok != 2)))
		return ok;
+8 −4
Original line number Diff line number Diff line
@@ -396,7 +396,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
#ifdef OPENSSL_NO_CHAIN_VERIFY
	return 1;
#else
	int i, ok=0, must_be_ca;
	int i, ok=0, must_be_ca, plen = 0;
	X509 *x;
	int (*cb)(int xok,X509_STORE_CTX *xctx);
	int proxy_path_length = 0;
@@ -497,9 +497,10 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
				if (!ok) goto end;
				}
			}
		/* Check pathlen */
		if ((i > 1) && (x->ex_pathlen != -1)
			   && (i > (x->ex_pathlen + proxy_path_length + 1)))
		/* Check pathlen if not self issued */
		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
			   && (x->ex_pathlen != -1)
			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
			{
			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
			ctx->error_depth = i;
@@ -507,6 +508,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
			ok=cb(0,ctx);
			if (!ok) goto end;
			}
		/* Increment path length if not self issued */
		if (!(x->ex_flags & EXFLAG_SI))
			plen++;
		/* If this certificate is a proxy certificate, the next
		   certificate must be another proxy certificate or a EE
		   certificate.  If not, the next certificate must be a
+8 −0
Original line number Diff line number Diff line
@@ -87,6 +87,12 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit)
	X509_POLICY_DATA *ret;
	if (!policy && !id)
		return NULL;
	if (id)
		{
		id = OBJ_dup(id);
		if (!id)
			return NULL;
		}
	ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
	if (!ret)
		return NULL;
@@ -94,6 +100,8 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit)
	if (!ret->expected_policy_set)
		{
		OPENSSL_free(ret);
		if (id)
			ASN1_OBJECT_free(id);
		return NULL;
		}

+4 −3
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
		if (explicit_policy > 0)
			{
			explicit_policy--;
			if (!(x->ex_flags & EXFLAG_SS)
			if (!(x->ex_flags & EXFLAG_SI)
				&& (cache->explicit_skip != -1)
				&& (cache->explicit_skip < explicit_policy))
				explicit_policy = cache->explicit_skip;
@@ -197,7 +197,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
			/* Any matching allowed if certificate is self
			 * issued and not the last in the chain.
			 */
			if (!(x->ex_flags & EXFLAG_SS) || (i == 0))
			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
				level->flags |= X509_V_FLAG_INHIBIT_ANY;
			}
		else
@@ -310,7 +310,8 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,

		if (data == NULL)
			return 0;
		data->qualifier_set = curr->anyPolicy->data->qualifier_set;
		/* Curr may not have anyPolicy */
		data->qualifier_set = cache->anyPolicy->qualifier_set;
		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
		if (!level_add_node(curr, data, node, tree))
			{
+2 −1
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
		NID_sbgp_ipAddrBlock,	/* 290 */
		NID_sbgp_autonomousSysNum, /* 291 */
#endif
		NID_policy_constraints,	/* 401 */
		NID_proxyCertInfo	/* 663 */
	};

@@ -327,7 +328,7 @@ static void x509v3_cache_extensions(X509 *x)
#endif
	/* Does subject name match issuer ? */
	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
			 x->ex_flags |= EXFLAG_SS;
			 x->ex_flags |= EXFLAG_SI;
	/* V1 should mean no extensions ... */
	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
	/* Handle basic constraints */
Loading