drwetter / testssl.sh

Testing TLS/SSL encryption anywhere on any port
https://testssl.sh
GNU General Public License v2.0
7.98k stars 1.02k forks source link

No TLS SNI support for HTTPS certificate checks #447

Closed ogmueller closed 8 years ago

ogmueller commented 8 years ago

Versions:

# ./testssl.sh -b 2>/dev/null | head -4 | tail -1
    (424cf23 2016-08-09 10:35:58 -- 1.531)
# ./testssl.sh -b 2>/dev/null | head -16 | tail -3
 Using "OpenSSL 1.0.2-chacha (1.0.2i-dev)" [~183 ciphers]
 on snell:./bin/openssl.Linux.x86_64
 (built: "Jun 22 19:32:29 2016", platform: "linux-x86_64")
# uname -a
Linux test 4.4.0-34-generic #53-Ubuntu SMP Wed Jul 27 16:06:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Target IP: 78.47.205.213 Target Website: https://ugi.teqneers.de/


The bug we found with testssl is, that it doesn't seem to support SNI (Server Name Indication). So if you connect to ugi.teqneers.de with HTTPS, testssl tells you, that it receives a self-signed certificate. The problem here is, that if you connect to the server using an IP address, it will just give you a self-signed cert, but the website, which i am trying to test does not. so if you use e.g. google chrome and visit https://ugi.teqneers.de the certificate is perfectly fine, because the server delivers different certs depending on the domain name and virtual server settings of the web server.

# ./testssl.sh -S ugi.teqneers.de

...

  Server Certificate #2
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 2048 bits
   Fingerprint / Serial         SHA1 FF5727BB40414B567C0BAE68F752DFBA68697D4F / F90197C8EBFD4004
                                SHA256 23824550CFC6E71A4294909E840271A958B5A1B0E4E489AFE2A68E34930C7B4C
   Common Name (CN)             "ugi.teqneers.de"
   subjectAltName (SAN)         --
   Issuer                       self-signed (NOT ok)
   Trust (hostname)             Ok via CN (works w/o SNI)
   Chain of trust               NOT ok (self signed)
   EV cert (experimental)       no
   Certificate Expiration       3593 >= 60 days (2016-06-20 11:24 --> 2026-06-18 11:24 +0000)
   # of certificates provided   1
   Certificate Revocation List  --
   OCSP URI                     --
   OCSP stapling                --

...
ogmueller commented 8 years ago

I forgot to mention, that if you are using [openssl]((http://blog.chrismeller.com/testing-sni-certificates-with-openssl) to test certificates, the "-servname" option needs to be used.

# openssl s_client -servername ugi.teqneers.de -connect ugi.teqneers.de:443
...
---
Certificate chain
 0 s:/CN=*.teqneers.de
   i:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G4
 1 s:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G4
   i:/C=US/O=GeoTrust Inc./OU=(c) 2008 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G3
---
...
dcooper16 commented 8 years ago

Hello Oliver,

When testssl.sh is run on ugi.teqneers.de, it shows two certificates, but you only showed one of the two above. Below is the complete result of running the -S option on ugi.teqneers.de. testssl.sh does support SNI, and that is why the first certificate return is the one you wanted to see (the one that only appears if SNI is used). The reason that the self-signed certificate is also shown is to address issue #276. There are some servers that will return a different certificate if the client requests TLS version 1.1 or earlier and does not use SNI, and there is a desire for testssl.sh to show those certificates in addition to the ones returned if SNI is used.

In the case of ugi.teqneers.de, testsssl.sh displays the certificate returned without SNI (in addition to the one returned with SNI), since the certificate returned without SNI identifies ugi.teqneers.de in the common name part of the subject. It the certificate that was returned did not identify the server (as is the case with https://testssl.sh), then the certificate would not have been displayed.

 Testing server defaults (Server Hello) 

 TLS extensions (standard)    "server name/#0" "renegotiation info/#65281" "EC point formats/#11" "session ticket/#35" "status request/#5" "heartbeat/#15"
 Session Tickets RFC 5077     300 seconds (PFS requires session ticket keys to be rotated <= daily)
 SSL Session ID support       yes
 TLS clock skew               random values, no fingerprinting possible 

  Server Certificate #1
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 2048 bits
   Fingerprint / Serial         SHA1 32D2D8AB6E32D3876BE2DD0C560463A11B3D3C16 / 534A
                                SHA256 1CD2EAF576134C4BE7B7F211D9A8B0D39F6AB1FD1B752F6EAEDF10CE9A4B4463
   Common Name (CN)             "*.teqneers.de" (CN in response to request w/o SNI: "ugi.teqneers.de")
   subjectAltName (SAN)         "*.teqneers.de" "teqneers.de" 
   Issuer                       "RapidSSL SHA256 CA - G4" ("GeoTrust Inc." from "US")
   Trust (hostname)             Ok via SAN wildcard and CN wildcard (works w/o SNI)
   Chain of trust               Ok   
   EV cert (experimental)       no 
   Certificate Expiration       967 >= 60 days (2016-01-10 15:15 --> 2019-04-10 01:12 -0400)
   # of certificates provided   2
   Certificate Revocation List  http://gz.symcb.com/gz.crl
   OCSP URI                     http://gz.symcd.com
   OCSP stapling                offered

  Server Certificate #2
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 2048 bits
   Fingerprint / Serial         SHA1 FF5727BB40414B567C0BAE68F752DFBA68697D4F / F90197C8EBFD4004
                                SHA256 23824550CFC6E71A4294909E840271A958B5A1B0E4E489AFE2A68E34930C7B4C
   Common Name (CN)             "ugi.teqneers.de"
   subjectAltName (SAN)         -- 
   Issuer                       self-signed (NOT ok)
   Trust (hostname)             Ok via CN (works w/o SNI)
   Chain of trust               NOT ok (self signed)
   EV cert (experimental)       no 
   Certificate Expiration       3593 >= 60 days (2016-06-20 07:24 --> 2026-06-18 07:24 -0400)
   # of certificates provided   1
   Certificate Revocation List  --
   OCSP URI                     --
   OCSP stapling                --
ogmueller commented 8 years ago

ok, that explains a lot. in this case is it possible to mark/describe the second certificate in a better way, so it is better understandable for people like me? :-) when i analyzed this server i was a bit shocked to see that the certificate is "not ok"/self-signed.

thnx for your good explanation on this topic!

drwetter commented 8 years ago

ok, that explains a lot. in this case is it possible to mark/describe the second certificate in a better way,

hmm. difficult... and I am hesitant. Suggestion?

ogmueller commented 8 years ago

Would it be possible to add a line to each of the certs with the request, which was done/used? E.g. the first certificate was done using "https://ugi.teqneers.de", so with domain name and SNI. The second cert though was done with "https://78.47.205.213". At least from the server perspective and that would explain the outcome in an easy way.

drwetter commented 8 years ago

Maybe s.th. similar in the "Server Certificate " head line. I'll check

dcooper16 commented 8 years ago

I just submitted PR #460 in an attempt to (at least partially) address this issue. Below is the output that the PR code produces for ugi.teqneers.de. It now notes that the second certificate was obtained using a request without SNI. In addition, since the "Trust (hostname)" line for the second certificate no longer includes "(works w/o SNI)", since that is redundant (and possibly confusing).

 Testing server defaults (Server Hello) 

 TLS extensions (standard)    "server name/#0" "renegotiation info/#65281" "EC point formats/#11" "session ticket/#35" "status request/#5" "heartbeat/#15"
 Session Tickets RFC 5077     300 seconds (PFS requires session ticket keys to be rotated <= daily)
 SSL Session ID support       yes
 TLS clock skew               random values, no fingerprinting possible 

  Server Certificate #1
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 2048 bits
   Fingerprint / Serial         SHA1 32D2D8AB6E32D3876BE2DD0C560463A11B3D3C16 / 534A
                                SHA256 1CD2EAF576134C4BE7B7F211D9A8B0D39F6AB1FD1B752F6EAEDF10CE9A4B4463
   Common Name (CN)             "*.teqneers.de" (CN in response to request w/o SNI: "ugi.teqneers.de")
   subjectAltName (SAN)         "*.teqneers.de" "teqneers.de" 
   Issuer                       "RapidSSL SHA256 CA - G4" ("GeoTrust Inc." from "US")
   Trust (hostname)             Ok via SAN wildcard and CN wildcard (works w/o SNI)
   Chain of trust               NOT ok: myroot (chain incomplete)
                                OK: Mozilla Microsoft Linux Apple 
   EV cert (experimental)       no 
   Certificate Expiration       952 >= 60 days (2016-01-10 15:15 --> 2019-04-10 01:12 -0400)
   # of certificates provided   2
   Certificate Revocation List  http://gz.symcb.com/gz.crl
   OCSP URI                     http://gz.symcd.com
   OCSP stapling                offered

  Server Certificate #2 (in response to request w/o SNI)
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 2048 bits
   Fingerprint / Serial         SHA1 FF5727BB40414B567C0BAE68F752DFBA68697D4F / F90197C8EBFD4004
                                SHA256 23824550CFC6E71A4294909E840271A958B5A1B0E4E489AFE2A68E34930C7B4C
   Common Name (CN)             "ugi.teqneers.de"
   subjectAltName (SAN)         -- 
   Issuer                       self-signed (NOT ok)
   Trust (hostname)             Ok via CN
   Chain of trust               NOT ok (self signed)
   EV cert (experimental)       no 
   Certificate Expiration       3578 >= 60 days (2016-06-20 07:24 --> 2026-06-18 07:24 -0400)
   # of certificates provided   1
   Certificate Revocation List  --
   OCSP URI                     --
   OCSP stapling                --
ogmueller commented 8 years ago

I like it. It gives a nice hint to why there is a different cert.