6

I'm trying to generate a certificate with the following subjectAltName:

hostname
*.hostname
hostname.mydomain.local
*.hostname.mydomain.local

I generate the CSR via OpenSSL and then get the certificate from Microsoft Active Directory Certificate Services. Certificate works OK for the following alternative names:

hostname
hostname.mydomain.local
*.hostname.mydomain.local

But, *.hostname just doesn't work. Testing with Curl, I get the following output:

% curl https://m.example/
curl: (51) SSL: certificate subject name '*.example' does not match target host name 'm.example'

If, on the other hand, I add 'm.example' as a subjectAltName, then it works. So, wildcard with shortened hostname just refuses to work.

10

Personal Experience

A while back I had a similar issue.

I had set up a local DNS for Windows and Linux servers with .staging as the TLD. To save on creating and signing certificates for each virtual host and avoid having to configure new IP addresses (non-SNI web servers), I created a key and cert for *.staging but all the clients I tried (including curl) only reported that certificate subject name *.staging does not match target host name whenever I tried loading virtual hosts on our Staging server using TLS.

Relevant RFCs

I spent ages trying to figure out why the wildcard certificate I had generated for *.staging wouldn’t work. I had read all the relevant RFCs but none of them specifically stated that such a wildcard certificate was invalid or illegal.

Security Stack Exchange Answers

I was eventually enlightened after reading this excellent Security Stack Exchange answer.

What matters is what SSL clients will accept as a "valid certificate", i.e. a certificate including a name which "matches" the intended server name (the one included in the URL). This is nominally specified in RFC 2818, section 3.1, and it allows many kinds of wildcard names, including things like "www.*.*c*", matching (theoretically) any server name containing three components, the first being "www" and the third containing at least one "c".

...

So browser vendors made their own schemes and restrictions. Much later, a new RFC (6125, from March 2011) was published, with section 6.4.3 dedicated to the processing of wildcard names in certificates. What RFC 6125 describes is more in tune with the reality, and is a "proposed standard", so there is at least some will, at some level, to make it happen. However, nothing in RFC 6125 mandates rejection of *.com; yet browsers do reject it.

The accepted answer to Can a wildcard SSL certificate be issued for a second level domain? also deserved an up-vote.

Edit

I figured that aside from recounting personal frustration, my answer doesn’t really add a lot other than linking to the RFCs and the relevant answers on Security Stack Exchange; I thought I’d put more effort in and search for the current relevant source code used by Chromium and Firefox.

Note that the comments in the Chromium source code explicitly mention that unknown top-level domains (such as *.intranet) are disallowed.

Also: there’s no reference to a user-configurable option that can override this behaviour.

Mozilla source code

From mozilla-central Mercurial Repository

Like NSS, require at least two labels to follow the wildcard label.

if (isWildcard) {
  // If the DNS ID ends with a dot, the last dot signifies an absolute ID.
  size_t labelCount = (labelLength == 0) ? dotCount : (dotCount + 1);

  // Like NSS, require at least two labels to follow the wildcard label.
  //
  // TODO(bug XXXXXXX): Allow the TrustDomain to control this on a
  // per-eTLD+1 basis, similar to Chromium. Even then, it might be better to
  // still enforce that there are at least two labels after the wildcard.
  if (labelCount < 3) {
    return false;
  }
  // XXX: RFC6125 says that we shouldn't accept wildcards within an IDN
  // A-Label. The consequence of this is that we effectively discriminate
  // against users of languages that cannot be encoded with ASCII.
  if (StartsWithIDNALabel(hostname)) {
    return false;
  }

  // TODO(bug XXXXXXX): Wildcards are not allowed for EV certificates.
  // Provide an option to indicate whether wildcards should be matched, for
  // the purpose of helping the application enforce this.
}

Chromium source code

From Chromium Git Repository

Do not allow wildcards for public/ICANN registry controlled domains - that is, prevent *.com or *.co.uk as valid presented names

In addition, unknown top-level domains (such as 'intranet' domains or new TLDs/gTLDs not yet added to the registry controlled domain dataset) are also implicitly prevented.

if (!reference_domain.empty()) {
  DCHECK(reference_domain.starts_with("."));

  // Do not allow wildcards for public/ICANN registry controlled domains -
  // that is, prevent *.com or *.co.uk as valid presented names, but do not
  // prevent *.appspot.com (a private registry controlled domain).
  // In addition, unknown top-level domains (such as 'intranet' domains or
  // new TLDs/gTLDs not yet added to the registry controlled domain dataset)
  // are also implicitly prevented.
  // Because |reference_domain| must contain at least one name component that
  // is not registry controlled, this ensures that all reference domains
  // contain at least three domain components when using wildcards.
  size_t registry_length =
      registry_controlled_domains::GetRegistryLength(
          reference_name,
          registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
          registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);

  // Because |reference_name| was already canonicalized, the following
  // should never happen.
  CHECK_NE(std::string::npos, registry_length);

  // Account for the leading dot in |reference_domain|.
  bool is_registry_controlled =
      registry_length != 0 &&
      registry_length == (reference_domain.size() - 1);

  // Additionally, do not attempt wildcard matching for purely numeric
  // hostnames.
  allow_wildcards =
      !is_registry_controlled &&
      reference_name.find_first_not_of("0123456789.") != std::string::npos;
}

The comments in registry_controlled_domain.h are also relevant:

The RegistryControlledDomainService examines the hostname of a GURL passed to it and determines the longest portion that is controlled by a registrar. Although technically the top-level domain (TLD) for a hostname is the last dot-portion of the name (such as .com or .org), many domains (such as co.uk) function as though they were TLDs, allocating any number of more specific, essentially unrelated names beneath them. For example, .uk is a TLD, but nobody is allowed to register a domain directly under .uk; the "effective" TLDs are ac.uk, co.uk, and so on. We wouldn't want to allow any site in *.co.uk to set a cookie for the entire co.uk domain, so it's important to be able to identify which higher-level domains function as effective TLDs and which can be registered.

Both the Chromium and Mozilla projects base their definition of an effective TLD on the Public Suffix List as published by Mozilla.

6

HTTPS clients should refuse to match TLD wildcards like *.com or *.net (or even *) for security reasons: No single certificate should claim authority over a whole TLD.

Now how is the client supposed to find out whether .example is a TLD (matching *.example forbidden) or a short form (matching allowed)? Particularly considering that new TLDs pop up every other day and any static TLD list would soon be outdated.

So clients simply refuse to match any wildcard *.XYZ and expect to see at least two dots in a wildcard.

Note that they should still maintain wildcard blacklists like *.co.uk *.co.jp etc.

  • Is there a way to disable this check for particular TL domains in most popular browsers like FF and Chrome? – Jakov Sosic Mar 13 '15 at 15:48
  • 1
    @JakovSosic I'm afraid not. You'd have to edit the source and rebuild; I've edited my answer with the relevant sections of code for both browsers. – Anthony Geoghegan Mar 15 '15 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.