Remove non-standard wildcard input DNS names.

Update-Note: ".example.com" as an input DNS name will no longer match
"www.example.com" in a certificate. (Note this does not impact wildcard
certificates. Rather, it removes a non-standard "reverse wildcard" that
OpenSSL implemented.)

Fixed: 463
Change-Id: I627e1bd00b8e4b810e9bb756f424f6230a99496e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50726
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
fips-20220613
David Benjamin 3 years ago committed by Boringssl LUCI CQ
parent 405c7888a7
commit 9631bc1041
  1. 11
      crypto/x509/x509_test.cc
  2. 39
      crypto/x509v3/v3_utl.c
  3. 9
      include/openssl/x509v3.h

@ -3678,15 +3678,16 @@ TEST(X509Test, Names) {
/*flags=*/0,
},
// However, OpenSSL has some non-standard behavior that implements this
// with a different syntax.
// TODO(https://crbug.com/boringssl/463): Remove this.
// OpenSSL has some non-standard wildcard syntax for input DNS names. We
// do not support this.
{
/*cert_subject=*/{},
/*cert_dns_names=*/{"www.a.example", "*.b.test"},
/*cert_emails=*/{},
/*valid_dns_names=*/{".a.example", ".b.test", ".example", ".test"},
/*invalid_dns_names=*/{".www.a.example", ".www.b.test"},
/*valid_dns_names=*/{},
/*invalid_dns_names=*/
{".www.a.example", ".www.b.test", ".a.example", ".b.test", ".example",
".test"},
/*valid_emails=*/{},
/*invalid_emails=*/{},
/*flags=*/0,

@ -708,44 +708,11 @@ typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
const unsigned char *subject, size_t subject_len,
unsigned int flags);
/* Skip pattern prefix to match "wildcard" subject */
static void skip_prefix(const unsigned char **p, size_t *plen,
const unsigned char *subject, size_t subject_len,
unsigned int flags)
{
const unsigned char *pattern = *p;
size_t pattern_len = *plen;
/*
* If subject starts with a leading '.' followed by more octets, and
* pattern is longer, compare just an equal-length suffix with the
* full subject (starting at the '.'), provided the prefix contains
* no NULs.
*/
if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
return;
while (pattern_len > subject_len && *pattern) {
if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
*pattern == '.')
break;
++pattern;
--pattern_len;
}
/* Skip if entire prefix acceptable */
if (pattern_len == subject_len) {
*p = pattern;
*plen = pattern_len;
}
}
/* Compare while ASCII ignoring case. */
static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
const unsigned char *subject, size_t subject_len,
unsigned int flags)
{
skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
if (pattern_len != subject_len)
return 0;
while (pattern_len) {
@ -774,7 +741,6 @@ static int equal_case(const unsigned char *pattern, size_t pattern_len,
const unsigned char *subject, size_t subject_len,
unsigned int flags)
{
skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
if (pattern_len != subject_len)
return 0;
return !OPENSSL_memcmp(pattern, subject, pattern_len);
@ -1051,17 +1017,12 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
int rv = 0;
equal_fn equal;
/* See below, this flag is internal-only */
flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
if (check_type == GEN_EMAIL) {
cnid = NID_pkcs9_emailAddress;
alt_type = V_ASN1_IA5STRING;
equal = equal_email;
} else if (check_type == GEN_DNS) {
cnid = NID_commonName;
/* Implicit client-side DNS sub-domain pattern */
if (chklen > 1 && chk[0] == '.')
flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
alt_type = V_ASN1_IA5STRING;
if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
equal = equal_nocase;

@ -896,15 +896,10 @@ OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0
// Deprecated: this flag does nothing
#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0
// Constraint verifier subdomain patterns to match a single labels.
#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10
// Deprecated: this flag does nothing
#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0
// Skip the subject common name fallback if subjectAltNames is missing.
#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20
//
// Match reference identifiers starting with "." to any sub-domain.
// This is a non-public flag, turned on implicitly when the subject
// reference identity is a DNS name.
#define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000
OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen,
unsigned int flags, char **peername);

Loading…
Cancel
Save