But many website operators don't, and I've had a tough time in the past reporting chain cert issues because website operators insist nothing's wrong since their site works for them (due to chain cert caching). I've already successfully reported a chain cert issue this week by including a link to the whatsmychaincert.com test result.
Nice work; this is a good tool to have in the world. The Qualys test[1] may be more comprehensive, but it is also much slower if you only need to examine certificate chain issues.
Yes, the SSL Labs test is way more comprehensive. I think a single-purpose tool is still valuable because it provides background about chain certs, and if it detects a misconfiguration, it provides a link to download the correct chain.
I actually have a few questions about cert chains: Is it necessary to have the entire chain? Or only the last few certificates (closest to the site certificate)? Is it any faster to have a shorter cert chain, or are there ways to optimize the cert chain for speed? (encodings? compression?) A small FAQ on cert chain background would be a nice addition to the site.
Would it be make sense to add a quick check for OCSP Stapling too, since that is related to the cert chain setup?
Your chain should start with the certificate that signs your server's certificate and continue up to, but not including, a root certificate that's trusted in all browsers.
Certificates can have multiple chains to a root certificate, some longer than the others, so to optimize you should pick the shortest chain. There's a trade-off to be made with browser support, because a short chain might be to a root that's not trusted in all browsers. The chain cert generator[1] picks the shortest chain that's to a root that's trusted in all reasonably recent browsers (basically everything you're likely to encounter today except Android 2.2, which is woefully lacking in both root certificates and modern TLS support).
An FAQ is a good idea; OCSP stapling seems a little out-of-scope but I'll think about it.
That would support any number of intermediates and remove the need to concatenate certificates into a single file. Terminating with the root certificate would be optional, but if present the server could perform a check to verify the chain to the very end when starting.
Honestly, all credit is due to CloudFlare. They get this stuff right and you need to worry much less about it. Not that the HN server tests poorly, but I can't check since they started disallowing IPs.
Just as an aside: the SSL Labs test is slow on purpose -- that's how we stay under the radar and avoid too many complaints from server operators. That said, it's a common complaint and I intend to optimize some operations in the next major version.
Sorry, an error occurred when building the chain for this certificate. This could mean that the certificate is malformed or that its certificate authority is not functioning properly.
Yeah, I'm seeing some certificate authorities which are serving their certificates in formats that I wasn't expecting. All the errors are being logged and I'm working on adding support for these formats.
Edit: These errors should now be fixed; thanks for your patience!
At some point in the last ten years, most browser vendors enabled a feature that will do automatic discovery of an intermediate certificate.
The most noteworthy exception to this is the builtin Android browser in the 2.x (and possibly later) series. As a result, failure to include the intermediate certificate on the server quite frequently goes unnoticed.
This also fails with many non-browser applications. For example, if Murmur (the server for the Mumble VOIP application) does not detect your certificate is correctly chained, your server won't even start.
That's nice to see. I was working on exactly the same thing before realizing all the corner cases and manual work involved...
Unfortunately this service fails exactly on those cases. For example certificates signed by "/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO High-Assurance Secure Server CA" (b4c66180c520bad688470ef80bb22beba8391c22) actually have two chains. (or more) Each leads to a different CA. Each CA is included in different OS/browsers combinations, so actually you need both intermediate certs to pass validation on all current systems.
I guess you're checking the certificate against your local /etc/ssl/certs/ca-certificates.crt, which is not enough if you want to serve traffic to every OS/browser. To do that, you'd have to have a database of trusted CAs for each of them - generate the shortest chain for each, then dedup the chains, then sort the intermediates and return the chain.
I stopped at the database of trusted CAs. Without actually owning each system, it's almost impossible to obtain the certs. For example Apple provides the list for each version, but names only - without fingerprints that means hunting down CAs from foreign sites going only by names.
I'm using a database of CA certificates that should contain the lowest common denominator of CA certs among different OS/browsers, and picking the shortest chain that leads to these roots. I may not have given sufficient thought to cases where the chain branches and you end up with multiple roots though.
However, as far as I can tell b4c66180c520bad688470ef80bb22beba8391c22 is signed by a root that's in platforms as old as Android 2.2, so a further chain from it shouldn't be necessary unless you need to support even more ancient platforms (in which case you're probably going to run into other problems with SHA-2 support, SNI, etc.).
I can't remember exactly which one failed, but between Android 2.x, 4.x, iOS, OSX/safari, ubuntu/ff, win7/chrome, win7/ie both chains were needed - customers noticed ssl errors. Some systems knew only about 58119f0e128287ea50fdd987456f4f78dcfad6d4 (UTN - DATACorp SGC), but comodo provided only b4c66180c520bad688470ef80bb22beba8391c22 in the intermediates package.
Ssllabs website detects this and tells you both chains are required to support all browsers.
For your multiple chains, is this the case where the chain is
example.org is signed by
New CA intermediate is signed by
New CA root is signed by
Old CA root
So agents with New CA will stop at New CA, and agents without continue on to Old CA? Or do you have an example where you have more choices than stop or continue?
This is how I understand chains to work in practice, and it's what the chain cert generator assumes. However, the SSL certificate ecosystem is so vast there may well be a case of chains ending up at different roots. I'd love to see an example of this. Even the cert given by viraptor, though it has two chains, ultimately ends up at a common root, "/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC".
I meant the second case - one intermediate is signed by 2 "different" certs. (they have the same key of course) One is a CA, the other is intermediate itself.
These are the valid chains:
my cert
b4c66180c520bad688470ef80bb22beba8391c22 - COMODO SSL CA
02faf3e291435468607857694df5e45b68851868 - AddTrust External CA Root
Another chain. Watch out - different cert with CA in name, that is not actually a CA. It's also got the same name as the one above, but is not self-signed:
my cert
b4c66180c520bad688470ef80bb22beba8391c22 - COMODO SSL CA
53845e9fd070b7aa36976f536ff1441c578c63d2 - AddTrust External CA Root
58119f0e128287ea50fdd987456f4f78dcfad6d4 - UTN - DATACorp SGC
From the link, it looks like the AddTrust External CA is cross-signed by two different UTN Roots?
UTN - DATACorp SGC and
UTN-USERFirst-Hardware
This is more of what I was looking for, rather than the case where you have a self-signed CA, but also a cross-signed CA. Is there a way you can create a certificate chain that you could send to two clients, one with the SGC and one with the UserFirst, and both would accept the chain as valid? (I think the answer is no, but it would be super awesome if the answer was yes)
Yes, that's what I'm doing now. My chain has the intermediate from the first chain and the "intermediate-called-ca" from the second chain. All clients are happy with that.
I looked in the logs, and determined that the server in question has a variety of issues, including intolerance to TLS 1.1 and TLS 1.2. For more details, try testing it here:
31 comments
[ 3.6 ms ] story [ 67.2 ms ] threadBut many website operators don't, and I've had a tough time in the past reporting chain cert issues because website operators insist nothing's wrong since their site works for them (due to chain cert caching). I've already successfully reported a chain cert issue this week by including a link to the whatsmychaincert.com test result.
1. ex, albeit cached: https://www.ssllabs.com/ssltest/analyze.html?d=news.ycombina...
Yes, the SSL Labs test is way more comprehensive. I think a single-purpose tool is still valuable because it provides background about chain certs, and if it detects a misconfiguration, it provides a link to download the correct chain.
I actually have a few questions about cert chains: Is it necessary to have the entire chain? Or only the last few certificates (closest to the site certificate)? Is it any faster to have a shorter cert chain, or are there ways to optimize the cert chain for speed? (encodings? compression?) A small FAQ on cert chain background would be a nice addition to the site.
Would it be make sense to add a quick check for OCSP Stapling too, since that is related to the cert chain setup?
Certificates can have multiple chains to a root certificate, some longer than the others, so to optimize you should pick the shortest chain. There's a trade-off to be made with browser support, because a short chain might be to a root that's not trusted in all browsers. The chain cert generator[1] picks the shortest chain that's to a root that's trusted in all reasonably recent browsers (basically everything you're likely to encounter today except Android 2.2, which is woefully lacking in both root certificates and modern TLS support).
An FAQ is a good idea; OCSP stapling seems a little out-of-scope but I'll think about it.
[1] source code here = https://github.com/SSLMate/mkcertchain
Sorry, an error occurred when building the chain for this certificate. This could mean that the certificate is malformed or that its certificate authority is not functioning properly.
Is this normal?
Edit: These errors should now be fixed; thanks for your patience!
[1] https://community.qualys.com/thread/11026
The most noteworthy exception to this is the builtin Android browser in the 2.x (and possibly later) series. As a result, failure to include the intermediate certificate on the server quite frequently goes unnoticed.
Best to set it up correctly in any case.
Many QA engineers are ambushed by this new "edge" case. This change in browser behavior has made it easier for the problem to go undetected.
https://bugzilla.mozilla.org/show_bug.cgi?id=399324
https://bugzilla.mozilla.org/show_bug.cgi?id=245609
Chain cert problems can still go unnoticed in Firefox, however, because Firefox does cache chain certificates that it encounters browsing other sites.
In any case, the relevant RFCs require servers to send a complete chain.
ssl.pemfile = "/path/to/pemfile.pem"
ssl.ca-file = "/path/to/chain.crt"
Unfortunately this service fails exactly on those cases. For example certificates signed by "/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO High-Assurance Secure Server CA" (b4c66180c520bad688470ef80bb22beba8391c22) actually have two chains. (or more) Each leads to a different CA. Each CA is included in different OS/browsers combinations, so actually you need both intermediate certs to pass validation on all current systems.
I guess you're checking the certificate against your local /etc/ssl/certs/ca-certificates.crt, which is not enough if you want to serve traffic to every OS/browser. To do that, you'd have to have a database of trusted CAs for each of them - generate the shortest chain for each, then dedup the chains, then sort the intermediates and return the chain.
I stopped at the database of trusted CAs. Without actually owning each system, it's almost impossible to obtain the certs. For example Apple provides the list for each version, but names only - without fingerprints that means hunting down CAs from foreign sites going only by names.
I'm using a database of CA certificates that should contain the lowest common denominator of CA certs among different OS/browsers, and picking the shortest chain that leads to these roots. I may not have given sufficient thought to cases where the chain branches and you end up with multiple roots though.
However, as far as I can tell b4c66180c520bad688470ef80bb22beba8391c22 is signed by a root that's in platforms as old as Android 2.2, so a further chain from it shouldn't be necessary unless you need to support even more ancient platforms (in which case you're probably going to run into other problems with SHA-2 support, SNI, etc.).
Ssllabs website detects this and tells you both chains are required to support all browsers.
These are the valid chains:
Another chain. Watch out - different cert with CA in name, that is not actually a CA. It's also got the same name as the one above, but is not self-signed: You can see its interesting/messy details at https://ssl-tools.net/certificates/5yf351-addtrust-external-...UTN - DATACorp SGC and UTN-USERFirst-Hardware
This is more of what I was looking for, rather than the case where you have a self-signed CA, but also a cross-signed CA. Is there a way you can create a certificate chain that you could send to two clients, one with the SGC and one with the UserFirst, and both would accept the chain as valid? (I think the answer is no, but it would be super awesome if the answer was yes)
TLS handshake error: error:140773E8:SSL routines:SSL23_GET_SERVER_HELLO:reason(1000)
I looked in the logs, and determined that the server in question has a variety of issues, including intolerance to TLS 1.1 and TLS 1.2. For more details, try testing it here:
https://www.ssllabs.com/ssltest/