commit e4363c70386e3e1216d64ef507127484b1298e98 Author: John Denker Date: Tue Sep 9 11:08:47 2014 -0700 fix bypass bug diff --git a/crypto/x509v3/v3_ncons.c b/crypto/x509v3/v3_ncons.c index 257d3d2..c3f36fd 100644 --- a/crypto/x509v3/v3_ncons.c +++ b/crypto/x509v3/v3_ncons.c @@ -239,6 +239,7 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) { int r, i; + int num_altnames; /* number of subject_alt_names in x */ X509_NAME *nm; nm = X509_get_subject_name(x); @@ -280,7 +281,12 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) } - for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) + num_altnames = sk_GENERAL_NAME_num(x->altname); + +/* Normally there are altnames, + * in which case we should process them. + */ + for (i = 0; i < num_altnames; i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); r = nc_match(gen, nc); @@ -288,6 +294,48 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) return r; } +/* If num_altnames is zero, it means there was a zero-length + * subjectAltNames section, and we have done all that we should. + * However, if it is -1, it means there was no subjectAltName + * section at all, in which case we should process the + * common name as found in subject name + */ + if (num_altnames < 0) + { + int tmp, idx = -1; + if(!nm) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + +/* get idx of the last common name */ + while((tmp = X509_NAME_get_index_by_NID(nm, NID_commonName, idx)) >= 0) + idx=tmp; + if (idx >= 0) + { + X509_NAME_ENTRY* ne = X509_NAME_get_entry(nm, idx); + GENERAL_NAME gntmp; + gntmp.type = GEN_DNS; + gntmp.d.dNSName = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.dNSName->type != V_ASN1_PRINTABLESTRING) + { + /* Can this ever happen? */ + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + r = nc_match(&gntmp, nc); + if (r != X509_V_OK) + return r; + } + else + { +/* No altnames and no common name. + * Could happen for an email-signing-only certificate. + * In cases where it would be a problem, + * it would presumably be caught by /other/ checks, + * such as non-matching name, + * so we don't worry about it here. + */ + } + } + return X509_V_OK; }