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>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index 01f0bc7..691b452 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -3678,15 +3678,16 @@
           /*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,
diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c
index 7e7c549..474acf8 100644
--- a/crypto/x509v3/v3_utl.c
+++ b/crypto/x509v3/v3_utl.c
@@ -708,44 +708,11 @@
                          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 @@
                       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 @@
     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;
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
index 3e8cf1b..c67dde6 100644
--- a/include/openssl/x509v3.h
+++ b/include/openssl/x509v3.h
@@ -896,15 +896,10 @@
 #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);