Warning! I am about to bring up a topic that others have talked about before: Name Constraints (as it applies to SSL, that is). Name Constraints is a way for a Certificate Authority (a CA) to say “All of the certificates issued by me should only be used for these domains (x.net, or y.z.com, or all of .org, etc.). Any other certificate should not be trusted.”
Name Constraints are not supported by everything yet, but they are supported in some places. Not only would Name Constraints make things easier for sysadmins, it would give a new revenue stream for CAs, browsers would have an easier time accepting them, and it would “streamline the user experience” (whatever that means).
While I was doing through the iOS 8.0 CA list, I came across one certificate authority which included something I hadn’t seen before. Here’s the CA certificate details, with the raw key and signature info removed.
Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: sha1WithRSAEncryption Issuer: C=GR, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2011 Trust: Always Validity Not Before: Dec 6 13:49:52 2011 GMT Not After : Dec 1 13:49:52 2031 GMT Subject: C=GR, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2011 Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign, CRL Sign X509v3 Subject Key Identifier: A6:91:42:FD:13:61:4A:23:9E:08:A4:29:E5:D8:13:04:23:EE:41:25 X509v3 Name Constraints: Permitted: DNS:.gr DNS:.eu DNS:.edu DNS:.org email:.gr email:.eu email:.edu email:.org
What caught my eye (it’s not easy to miss!) were the X509v3 Name Constraints. Name Constraints (also written “nameConstraints”, OID 126.96.36.199) are defined in RFC 3280 section 188.8.131.52. If you decide to read through the RFC, you should probably first read section 184.108.40.206, because that defines the term GeneralName, which plays an important part in in the definition of the Name Constraints extension.
Basically, the Name Constraints is an extension, something that is not part of the core SSL Certificate specification. They are entirely optional, but if used they may only be present in CA certificates (they can be in root CAs or in intermediate CAs), and they do not apply to the CA itself. If a Name Constraint extension is present in CA, it will apply to all certificates that are issued by the CA. If the CA with name constraints is a root CA, and the root CA has intermediate CAs, then the constraints from the root CA are applied to certificates issued by the intermediate CAs. The standard does not explicitly say what happens if both a root CA and one of its intermediates both have name constraints.
The Hellenic Academic & Research Institutions Certification Authority (HARICA) made a great statement in the CA shown above: The HARICA has stated that the certificates they issue will only be used for web sites and email addresses whose domains end in .gr (Greece), .eu (the European Union), .edu, or .org. If HARICA’s CA issues a certificate for any other domain name (such as a .com domain), the holder of that certificate runs the risk of browsers not accepting it.
Although this is a great gesture, it is somewhat moot, because support for Name Constraints, as applied to DNS (www.example.com) and email (email@example.com) is not fully supported. Firefox supports it, but Apple (iOS and Mac OS X) does not. Proper OpenSSL support started in version 1. For more details, see the Testing section at the end of this post. The HARICA has given themselves an out here by not marking the Name Constraints extension as critical. If a client encounters something in a certificate that is marked critical, but the client does not know how to understand what it is seeing, then the client must drop the connection with an error. If a client encounters The HARICA’s CA, but the client does not understand the Name Constraints section, that’s OK with the client, because that section is not marked critical.
Of course, I’m not the first person to bring up Name Constraints! This topic has been covered before. The same can be said for HTTP Strict Transport Security, and OCSP Pinning: In order for it to be useful, people need to see that there would be a clear benefit to its implementation. If more clients would support the Name Constraints extension, concerned users would benefit (by limiting internal corporate and government CAs), corporations would benefit (by making SSL easier to use internally), and even CAs would benefit (with a new revenue stream)!
“Limiting” Governmental Influence
In a previous post, I mentioned how many government CAs existed in iOS 8.0. All of the government CAs, which exist in mobile AND desktop OSes and browsers (not just in iOS) can be used to issue certificates that apply to any domain. Yes, certificate and key pinning can be used to catch this, but that is not being done very much right now, and I wonder how well it would scale (but that’s a different topic), and how much power it would give to CAs (again, different topic).
If government CAs were to use the Name Constraints extension, with the extension marked as critical (because browser and OS makers would require it), then the CA’s sphere of influence would be limited to just the domains that are directly tied to the particular government. For example:
- The DoD CAs could be limited to .mil and .us.
- The China CA could be limited to .cn (and most likely also .hk and .tw).
- And so on.
Of course, even with those limits in place, it doesn’t really matter: As long as a government is able to lean on a CA to issue said government an unrestricted intermediate certificate, there will still be concerns. Problems like that are definitely beyond the scope of this post!
Anyway, where I really see the Name Constraints extension being useful is in the corporate world.
A New Opportunity for CAs
Most corporations, especially those using Active Directory, have an internal CA. That internal CA is linked to the corporate Active Directory domain, and (among other things) can be used to issue certificates for internal use. That is really nice, because it allows you to use HTTPS for internal sites, and it allows people to have client certificates for authentication on internal sites. It means that you don’t have to go around using self-signed certificates for the places where you want to use SSL. The problem is, you have an internal CA.
If your users are only using Windows, and all of those Windows machines are on the domain, and they are only using IE or Chrome, then maybe you’ll be fine. You can let Active Directory and AD Group Policies take care of pushing out the root to client systems. However, as soon as you introduce something else, like a smartphone, or a Linux box, then you really have to start thinking about distributing your CA. For example, for the iPhone (assuming you don’t use MDM) you’ll need to have people install your CA certificate. If you have Android users, starting with Android 4.4 KitKat, users may start seeing scary warnings if you install your CA onto an Android device. Firefox users will also need special handholding. Savvy users will start asking if you are planning on using this CA to watch their SSL traffic.
It would be much easier if sysadmins could issue certificates that link back to an existing trusted root, and with Name Constraints, I think you would be able to do so! Here’s what I’m thinking:
- A Certificate Authority would take an existing well-known root, creating a new intermediate.
- The new intermediate would have a path-length constraint of 1, meaning that there can only be up to one more intermediate certificate between this new intermediate and the end entity certificate (that is, the web server or the user).
- The new intermediate would have a critical Name Constraints section, limiting certificates to sub-domains of .local, .internal, .corp, etc., for email and web site use.
- When a corporate customer places an order, the CA would use their new intermediate to create yet another intermediate (let’s call this one the CorpCA).
- The CA would perform the same level of validation as it does when a customer orders an EV certificate, even though (to be clear) this is not an EV cert (or an EV intermediate).
- If possible (this could be a requirement), the CA would place a critical Name Constraints extension into CorpCA when it is issued, limiting CorpCA to the internal domains that the company uses (for example, widget.internal).
- The customer installs CorpCA as the CA for their Active Directory domain (if they have one), and they use it to issue certificates for all their internal needs. If an admin is configuring a server for SSL, they would include both the CA’s intermediate, as well as CorpCA, as the intermediates.
- Users work as normal, without having to do anything special:
- Since the resources users are accessing are secured using a certificate that chains up to a trusted root, they get a warning-free secure connection without needing to install any CAs on their device.
- BYOD (Bring Your Own Device) environments are a little easier to configure, because there are no CAs that need to be installed.
- Android will not complain, because no non-standard CAs needed to be installed.
- Concerned users will be mollified, because the critical Name Constraints extension on the intermediates prevent the company from using their intermediate to do man-in-the-middle attacks.
- Users of older software (older browsers, older phones, etc.) will encounter errors when they encounter an intermediate that has a critical Name Constraints extension.
Especially as companies move away from Windows XP and Server 2003, I see this becoming more and more doable.
One note on the domains I mentioned in #1: I picked those top-level domains at random, except for .local. I would really like to suggest using .local, but that domain is reserved for multicast DNS (see RFC 6762), and I don’t want to step on it. Both .internal and .corp are candidates, because they do not exist as top-level domains today. Whichever domain(s) are chosen would need to be registered as a special-use domain name (see RFC 6761, and the current list); then it would be safe. That being said, even though the .local domain is used by mDNS, I would still suggest CAs include that in their Name Constraints section, since I expect many corporations use it.
The Name Constraints extension is 12 years old, and it has started to be supported in important places. If the Name Constraints extension would get better support, then there would be visible benefits for all:
- Browsers (who are making CA installation harder) would automatically trust these new restricted CA.
- Users (who are slowly learning to take browser warnings seriously) would have a better experience when accessing internal corporate stuff.
- Sysadmins would have an easier time setting up and maintaining their environment.
- Certificate Authorities would have a new revenue stream.
Is this the push necessary to get Name Constraints implemented? I certainly hope so!
In order to test how browsers handle the Name Constraints extension, I created my own CA that has a critical Name Constraints extension. The test CA’s nameConstraint is such that only subdomains of karl.kornel.us are valid. Next, I set up two web sites:
- buttonmash.karl.kornel.us should work (assuming you trust the test CA), because the FQDN is a subdomain of karl.kornel.us.
- buttonmash.karl.kornel.name should fail.
The test for browsers is simple: Trust the CA (signature), and then try going to each web site. On site #1 (the .us domain), you should see a YouTube video. On site #2 (the .name domain), your web browser should give you an error.
- The OpenSSL configuration file.
- The OpenSSL CA directory.
- The directory of certs/CRLs/etc. that I used when making the two test web sites.
The CA and the web servers use 4096-bit RSA keys. SHA-256 is used as the hash on all the certificates. Here’s me creating the CA:
Macintosh-5:ca akkornel$ ~/openssl-1.0.1i/apps/openssl req -config ~/buttonmash/openssl.cnf -new -x509 -out cacert.pem -key private/key.pem -extensions req_extensions_ca -days 180 WARNING: can't open config file: /usr/local/ssl/openssl.cnf You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- 2-letter Country Code :EQ State or Province Name :. City Name :Ponyville Organization or Person Name :Button Mash Awesome CA, Inc., Ltd., LOL Organization Unit (optional) :CA Division Server FQDN :Button Mash CA Email Address :.
Generating the client certificate request:
Macintosh-5:cert akkornel$ ~/openssl-1.0.1i/apps/openssl req -config ~/buttonmash/openssl.cnf -new -out us_req.pem -key key.pem WARNING: can't open config file: /usr/local/ssl/openssl.cnf You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- 2-letter Country Code :US State or Province Name :California City Name :Newport Beach Organization or Person Name :A. Karl Kornel Organization Unit (optional) :. Server FQDN :buttonmash.karl.kornel.us Email Address :firstname.lastname@example.org
I made the .name CSR with a similar command, replacing the instances of .us with .name (except for in the email address).
Issuing the certificate from the CSR:
Macintosh-5:cert akkornel$ ~/openssl-1.0.1i/apps/openssl ca -config ~/buttonmash/openssl.cnf -in name_req.pem -out name_cert.pem WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from /Users/akkornel/buttonmash/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'US' stateOrProvinceName :ASN.1 12:'California' localityName :ASN.1 12:'Newport Beach' organizationName :ASN.1 12:'A. Karl Kornel' commonName :ASN.1 12:'buttonmash.karl.kornel.name' emailAddress :IA5STRING:'email@example.com' Certificate is to be certified until Oct 25 07:47:24 2014 GMT (30 days) Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
The .us certificate was created similarly.
Finally, a CRL needed to be generated:
Macintosh-5:ca akkornel$ ~/openssl-1.0.1i/apps/openssl ca -config ~/buttonmash/openssl.cnf -gencrl -crldays 90 > ~/Dropbox/Public/Blog/buttonmash_crl.pem WARNING: can't open config file: /usr/local/ssl/openssl.cnf Using configuration from /Users/akkornel/buttonmash/openssl.cnf
Once the CA, server certs, and CRL were generated, I made a simple HTML page (the same on both sites). To test on the client side, it’s simply a matter of installing the CA (signature) locally and then going to the two test web sites (the good site and the bad site).
Here’s what I found in my testing:
- Firefox (NSS) works fine: If the Name Constraints are not met, the connection is never allowed to complete.
- iOS 8.0 fails badly: As long as the root is trusted, the web page is displayed, even if the name constraint is not met. It’s possible that iOS is ignoring the Name Constraint entirely, even if it’s marked critical. I’ve filed this as issue #18461300 on Radar.
- Mac OS X 10.8 fails: As recently confirmed by the Chromium team, Mac OS X does not recognize Name Constraints. Even if the root is trusted, Safari brings up the certificate warning. You can still choose to trust the certificate, which will allow pages to load.
- OpenSSL’s s_client ???? (I’m testing this, but I’m led to believe it doesn’t work until OpenSSL 1)
Android and Windows have not been tested, because I don’t have any of those available to test on.
Internet Explorer, Opera, and Safari are not listed above because they all rely on the local OS for CAs and certificate validation. Chrome will use the local OS for CAs and certificate validation on Android, OS X, and Windows; either NSS (what Firefox uses) or OpenSSL is used elsewhere.