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.
This commit is contained in:
Dr. Stephen Henson
2008-07-13 14:25:36 +00:00
parent f9afd9f861
commit db50661fce
7 changed files with 40 additions and 15 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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))
{

View File

@@ -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 */

View File

@@ -388,6 +388,8 @@ struct ISSUING_DIST_POINT_st
#define EXFLAG_NSCERT 0x8
#define EXFLAG_CA 0x10
/* Really self issued not necessarily self signed */
#define EXFLAG_SI 0x20
#define EXFLAG_SS 0x20
#define EXFLAG_V1 0x40
#define EXFLAG_INVALID 0x80