4

tl;dr: TLS 1.2 between Server 2012 R2 and Chromium based browsers fails when using AD CS issued certs. Works fine on Server 2016+, and on 2012 R2 with Firefox/IE/Cygwin-curl.

We have several internal Server 2012 R2 web servers which we are trying to move off of publicly issued certificates, onto ones issued by our AD integrated CA, and eliminate less secure crypto settings, including CBC MAC. Server 2012 R2 does not support ECDHE_RSA with GCM, which means that we're trying to use an ECDH based cert. We have experienced a similar issue, however, when we allow cipher suites with CBC-MAC, such as TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 with an RSA cert issued from the same CA. Using our public wildcard cert issued by GlobalSign, we're able to connect with all browsers.

The enterprise CA, and the offline root CA are both trusted, and we've verified that this is working properly. Certificates using multiple different templates issued to 2016 and 2019 servers work without issue across all browsers. The ECDH and RSA based templates work equally well on 2016+.

ECDH certificate template crypto: ECDH cert template crypto settings.

RSA certificate template crypto: RSA cert template crypto settings.

Both RSA and ECDH certificates on the 2012 R2 servers are accepted by Firefox (once it's been told to trust them both via policy, and manually setting security.enterprise_roots.enabled), pre-Chromium Edge, IE, and Cygwin's curl and wget. I've confirmed we're using modern ciphers in the registry, re-setting them with IISCrypto, and verified there are compatible available ciphers being offered by the server with OpenSSL, and nmap. Likewise, I've confirmed that clients are actually able to connect using those ciphers.

Firefox shows it's connecting with TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, which according to Qualys is supported in the version of Chrome which we're using.

With the ECDH

PORT    STATE SERVICE
443/tcp open  https
| ciphers:
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: A

Each time we try to connect with Chrome a pair of event 36874/36888 are logged stating there were no supported cipher suites on the client.

A list of the cipher suites we experience the issue with when using an Enterprise CA issued cert, most of which were enabled just for testing (warnings snipped):

PORT    STATE SERVICE
443/tcp open  https
| ciphers:
|   SSLv3:
|     ciphers:
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C
|       TLS_RSA_WITH_RC4_128_MD5 (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: C

My questions are:

  1. Why do Chromium based browsers fail to negotiate a cipher suite when there are compatible cipher suites offered by the server?
  2. What do I need to set in order to allow Server 2012 R2 to use internally issued certs?
  3. Is there a better way to handle what I'm trying to do, aside from upgrading the application servers to 2016/2019? At this point, it seems like disabling TLS completely and putting everything behind a LB/reverse proxy may be a better idea, even if these are single-server solutions.

EDIT: I've opened a bug with Chromium and they have confirmed that the cipher suites being offered by the server should be accepted by Chrome. They are now investigating after I've provided network logging captured via CHROME://Net-Export. This may be related to an old Chrome/2012 bug. Once Google has reported back about what the issue is, I'll update this post again. However, at this point it looks as though there's nothing wrong with the configuration on our side.

Thanks for looking!

RobbieCrash
  • 1,131
  • 7
  • 25
  • What is the error on the browser end? Is the server cipher order the one listed in the question? – Håkan Lindqvist Oct 17 '20 at 15:51
  • The browser just gives ERR_CONNECTION_RESET. The posted order of the cipher suites is how they're offered from the server, depending on if we're using the ECDH certificate, or the RSA cert. Either way, Chromium browsers immediately have their connection reset, while other browsers connect properly. I've raised a bug with Chromium, and it seems like a new version of an old issue which I'm now investigating with them. – RobbieCrash Oct 17 '20 at 23:00
  • 1
    Is the signature hash algorithm used for the root certificate `SHA512`? There was some issue with `2012` and `2012 R2` to do with CPU usage, I think, which caused the `SHA512` to not be supported. IIRC the solution is either a registry edit, or to simply create root certificate based on `SHA 384` or `SHA 256`. Honestly haven't looked at this closely enough to really know if that is your issue, but if it helps .... – Colt Oct 18 '20 at 00:53
  • @Colt great idea, but unfortunately it doesn't seem applicable. Our offline root CA does use SHA512 for its cert. The issue you're referring to was supposed to be fixed with KB2973337, and subsequent update rollups, and the server doesn't die when serving to non-Chromium browsers. – RobbieCrash Oct 18 '20 at 03:07

2 Answers2

1

Please, make sure your certificate signing request (CSR) is not requesting a certificate that is valid for signing only, rather than signing and encryption. If the CSR ask for a certificate valid only for signing and your CA has a policy that allows for encryption even when the request was signing only, then you will likely see this problem... sometimes. Clearly a certificate requested for signature only shouldn't work at all when used for encryption, but if your CA overrides the request to allow for encryption that will create a situation where encryption will work, but only under circumstances when the client supports a couple specific protocol suites. Identifying certificates causing this problem is complicated.

Try to capture the traffic between the W2012 R2 and Chrome using wireshark. If a protocol negotiation is the issue, you'll see the connection reset by the server immediately after the client suggests a list of cipher suites. This packet from the client will have the info of "client hello" followed immediately with a TCP RST (reset) from the server. If you drill into the details of the "client hello" packet you will be able to see the suites the client is proposing.

To remediate this issue you'll need to make sure that certificate ordered is for the correct purpose (https://docs.microsoft.com/en-us/archive/blogs/pki/how-to-create-a-web-server-ssl-certificate-manually). It's critical to ensure your certificate request has the correct parameters including the certificate usage. If you are using Windows PKI with AD integrated templates, you can "hard code" this in the templates if you like.

Jesús Ángel
  • 518
  • 1
  • 6
  • Thanks for your help. Unfortunately we've already done everything you've suggested, and the issue is assuredly with Server 2012 R2, not with the certificates, templates, or cipher suites that the server is offering. The ciphers and the template are being used on 2016/2019 servers without issue. Despite there being matching ciphers, Chrome is refusing to accept them. The same certificate also works in non-Chromium browsers, and validates fine without issue. I've opened an issue with the Chromium team which has now been escalated as a resurfacing of an old bug in Chrome. – RobbieCrash Oct 17 '20 at 23:02
  • Your welcome. Hope they will fix the bug soon. – Jesús Ángel Oct 18 '20 at 09:29
1

Google has confirmed that this is an issue with the way that Chromium handles the ClientHello, how IIS handles things on 2012, and the algorithm used in our root CA's root cert signing.

IIS on 2012r2 performs a check with the ClientHello, against every cert in the chain. Chrome doesn't advertise, but does support, the root CA's SHA-512, ECDH cert. So when IIS performs the check against the entire cert chain, it sees that Chrome offers support for the ciphers from the webserver, the from our intermediate CA, but that it doesn't offer support for the (admittedly overkill), P-521 ECDH curve so IIS resets the connection. Chrome doesn't advertise support for this to handle edge cases in the mess of field mappings that is TLS1.2/1.3.

The recommendation on my bug report with Chromium was to either replace the root CA, or upgrade to 2016/2019 where this is no-longer an issue.

RobbieCrash
  • 1,131
  • 7
  • 25