Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some clients accept SSL cert; others reject it

Some HTTP clients accept this certificate, and others do not. What could make the difference?

Java rejects it.

((javax.net.ssl.HttpsURLConnection)new java.net.URL("https://www.lucidpress.com")
    .openConnection())
    .getInputStream()

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching www.lucidpress.com found. at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1715) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:257) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:251) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1168) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609) at sun.security.ssl.Handshaker.process_record(Handshaker.java:545) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:963) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1208) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1235) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1219) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:440) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)

Python requests rejects it.

import requests
requests.get('https://www.lucidpress.com')

Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 55, in get
    return request('get', url, **kwargs)   File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)   File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 456, in request
    resp = self.send(prep, **send_kwargs)   File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 559, in send
    r = adapter.send(request, **kwargs)   File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 382, in send
    raise SSLError(e, request=request) requests.exceptions.SSLError: hostname 'www.lucidpress.com' doesn't match either of '*.lucidchart.com', 'lucidchart.com'

cURL accepts it.

$ curl -v https://www.lucidpress.com
  • About to connect() to www.lucidpress.com port 443 (#0)
  • Trying 54.236.129.63... connected
  • successfully set certificate verify locations:
  • CAfile: none CApath: /etc/ssl/certs
  • SSLv3, TLS handshake, Client hello (1):
  • SSLv3, TLS handshake, Server hello (2):
  • SSLv3, TLS handshake, CERT (11):
  • SSLv3, TLS handshake, Server key exchange (12):
  • SSLv3, TLS handshake, Server finished (14):
  • SSLv3, TLS handshake, Client key exchange (16):
  • SSLv3, TLS change cipher, Client hello (1):
  • SSLv3, TLS handshake, Finished (20):
  • SSLv3, TLS change cipher, Client hello (1):
  • SSLv3, TLS handshake, Finished (20):
  • SSL connection using DHE-RSA-AES256-SHA
  • Server certificate:
  • subject: OU=Domain Control Validated; CN=*.lucidpress.com
  • start date: 2014-05-12 16:20:34 GMT
  • expire date: 2015-07-09 22:19:45 GMT
  • subjectAltName: www.lucidpress.com matched
  • issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
  • SSL certificate verify ok.

wget rejects it.

wget https://www.lucidpress.com

--2014-08-09 19:55:41-- https://www.lucidpress.com/ Resolving www.lucidpress.com (www.lucidpress.com)... 107.23.98.6, 54.236.129.63, 54.88.154.168 Connecting to www.lucidpress.com (www.lucidpress.com)|107.23.98.6|:443... connected. ERROR: no certificate subject alternative name matches requested host name 'www.lucidpress.com'. To connect to www.lucidpress.com insecurely, use '--no-check-certificate'.

Chrome, FF, and IE accept it.

Why is the behavior different?

like image 454
Paul Draper Avatar asked Aug 10 '14 02:08

Paul Draper


1 Answers

Some HTTP clients accept this certificate, and others do not. What could make the difference?

The short answer: load balancing, virtual hosting and SNI.

The long answer... first, here's an analysis of the certificate. We need to go though this to ensure there's no obvious mistakes.

From the dump below, there's a wildcard DNS name in the Common Name. Placing a DNS name in the CN is deprecated by both the IETF and the CA/Browser Forums. A "friendly name" should be placed in the CN because its displayed to the user. While its deprecated, its not forbidden.

Instead, DNS names should go in the Subject Alternate Name. There should be two of them. The first would be lucidpress.com and the second would be *.lucidpress.com. You need just lucidpress.com because the wildcard needs to match a label.

For reference, the IETF deprecates a DNS name in the CN in RFC 6125 Section 3.1 Server Identity; and Section 6.4.4 Checking of Common Names.

The CA/Browser Forums deprecates a DNS name in the CN in Baseline Requirements (BR) Section 9.2.2 Subject Common Name Field. Also, according to the CA/B, the Subject Alternate Name is required. See Section 9.2.1 Subject Alternative Name Extension.

Related: RFC 6125, Section 6.4.3, also does not allow the matching of *.lucidpress.com to lucidpress.com. The CA/B BR covers wildcards in Section 11.1.3, but it does not discuss matching rules.


With the background information above and the certificate below, here's what is going on.

You have 2 names in the default certificate. Its served by default by Apache because its the first virtual host in the configuration file.

  • lucidchart.com
  • *.lucidchart.com

You have 2 names in the Lucid Press' certificate.

  • lucidpress.com
  • *.lucidpress.com

I think the difference is Server Name Indication (SNI). Its a TLS extension, so you need TLS 1.0 or above. Those that have no trouble get the Lucid Press certifcate and use TLS 1.0 or above with SNI; those that have trouble get the default certificate and use SSLv3 or no SNI. Windows XP will use TLS 1.0 but not SNI, so its experienced often in the field due to the deployment base.

The browsers accept it because they are using TLS 1.0 or above and sending the SNI extension. Because SNI allows your Apache server to select the proper certificate during the handshake, there are no name matching problems.

Java rejects it because it uses SSLv3, even when you say SSLContext.getInstance("TLS");. You have to jump through some hoops to ensure you really get TLS 1.0 and above. There's a few questions on Stack Overflow about it. See, for example, Which Cipher Suites to enable for SSL Socket?.

Python rejects it because I'm guessing you are using 2.x, or you are allowing SSLv3. You need 3.0 or above to get SNI. See Python 3 Support? on the Python FAQ.

wget added support for SNI in version 1.14. I suspect wget is not enabling its or using SSLv3.

cURL likely ensures SNI is used if available. Daniel is very thorough, and he tries to ensure a trouble free experience and secure posture out of the box.


In the OpenSSL dump, the options of interest are -tls1 -servername. You can get TLS without SNI by omitting -servername. So you need both tls1 and -servername <host>.

$ openssl s_client -tls1 -servername www.lucidpress.com \
     -connect www.lucidpress.com:443 | openssl x509 -text -noout
depth=3 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 12250220837273305 (0x2b8582cd6cfed9)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
        Validity
            Not Before: May 12 16:20:34 2014 GMT
            Not After : Jul  9 22:19:45 2015 GMT
        Subject: OU=Domain Control Validated, CN=*.lucidpress.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c8:e0:f6:77:03:c9:5e:cb:51:e3:d3:7a:b6:60:
                    d9:3d:60:26:9c:4b:00:c5:cb:b1:55:2e:d9:ee:f5:
                    08:8d:b7:64:e9:31:2e:83:e4:24:f3:89:4e:46:87:
                    b8:55:b6:34:0a:c9:3b:55:08:10:77:13:7e:85:d6:
                    8c:fa:06:dd:c1:7f:fa:9e:13:c8:1a:d8:36:22:3c:
                    cb:16:9f:cb:c7:5b:7c:7c:0b:6d:c3:ef:24:45:15:
                    5a:7a:38:dd:df:83:eb:c3:ea:9b:57:d5:8f:d8:6c:
                    ff:33:4a:21:02:2a:92:9a:e0:5d:58:51:75:07:b6:
                    ad:21:8c:34:91:20:f5:00:9e:f6:dd:90:7e:a8:60:
                    0e:14:73:de:90:a1:f4:29:83:a0:d8:9d:29:e5:de:
                    c5:cb:b5:36:84:ba:30:d4:a9:9f:b9:bf:89:26:e5:
                    80:5a:f6:3b:27:cc:6d:3f:31:1e:cc:51:09:12:73:
                    a6:de:da:b9:a4:19:86:68:7f:e6:2b:c7:3b:a6:ce:
                    6a:5a:dd:c9:ac:61:18:80:f5:d4:f1:6a:70:2c:9f:
                    8f:af:a6:c5:1d:78:97:97:90:92:6c:21:61:39:ce:
                    f8:c9:99:e2:02:b5:ce:ba:dc:f4:46:ba:e3:1f:ec:
                    ce:a5:e4:6b:56:1e:e6:20:89:44:7b:2c:9f:3a:c4:
                    33:f1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://crl.godaddy.com/gdig2s1-59.crl

            X509v3 Certificate Policies: 
                Policy: 2.16.840.1.114413.1.7.23.1
                  CPS: http://certificates.godaddy.com/repository/

            Authority Information Access: 
                OCSP - URI:http://ocsp.godaddy.com/
                CA Issuers - URI:http://certificates.godaddy.com/repository/gdig2.crt

            X509v3 Authority Key Identifier: 
                keyid:40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE

            X509v3 Subject Alternative Name: 
                DNS:*.lucidpress.com, DNS:lucidpress.com
            X509v3 Subject Key Identifier: 
                CA:97:CC:32:09:20:3E:5F:23:05:4C:DD:F2:DA:4B:1C:E5:02:E8:69
    Signature Algorithm: sha256WithRSAEncryption
         4e:0c:8e:af:d5:c7:06:9e:b9:2c:36:97:d0:9e:1c:84:e8:e1:
         69:5a:36:a3:4f:9f:81:c9:78:5d:ca:35:df:63:be:23:88:4c:
         ba:eb:17:15:22:78:96:5d:5f:dc:3b:fa:cf:14:b6:e9:3a:fe:
         28:19:1c:85:d2:1b:23:b3:79:6d:b2:1d:76:6b:84:97:80:43:
         1b:c0:b7:14:78:75:f9:47:31:6e:21:56:0d:5e:73:ed:d3:b2:
         4b:ab:dc:b0:af:18:ee:2d:bb:65:ff:c7:cb:ff:53:64:8f:a5:
         e8:aa:45:da:fc:0f:b5:8f:da:0f:3e:b1:3b:d0:47:49:52:af:
         8d:f7:a3:42:3b:d3:a1:f4:a1:22:d5:fe:2f:4c:59:b4:18:3f:
         62:1e:4e:56:65:9b:2b:d6:76:cd:29:74:d6:74:a4:7b:bb:6f:
         b2:1d:45:12:67:14:b3:06:a7:36:ee:3a:48:d1:d6:80:2b:fa:
         6d:8b:64:01:0f:1e:51:48:0f:8b:e3:7d:13:86:79:a2:b2:04:
         05:cb:8d:07:35:d9:fa:7e:6d:5d:42:c0:a5:f4:b2:8e:57:53:
         24:b3:aa:e6:92:b1:70:07:73:98:00:91:9b:0f:3e:6e:fe:1d:
         78:7c:57:68:47:d7:8e:6f:1a:64:26:7b:69:f5:b1:13:c2:71:
         2d:ac:56:b6

$ dig www.lucidchart.com

; <<>> DiG 9.8.5-P1 <<>> www.lucidchart.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19608
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.lucidchart.com.        IN  A

;; ANSWER SECTION:
www.lucidchart.com. 8   IN  CNAME   chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com.
chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com. 10 IN A 107.23.98.6
chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com. 10 IN A 54.236.129.63
chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com. 10 IN A 54.88.154.168

;; Query time: 23 msec
;; SERVER: 172.16.1.10#53(172.16.1.10)
;; WHEN: Sun Aug 10 00:02:52 EDT 2014
;; MSG SIZE  rcvd: 160

$ dig www.lucidpress.com

; <<>> DiG 9.8.5-P1 <<>> www.lucidpress.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34260
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.lucidpress.com.        IN  A

;; ANSWER SECTION:
www.lucidpress.com. 599 IN  CNAME   chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com.
chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com. 59 IN A 54.88.154.168
chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com. 59 IN A 107.23.98.6
chart-production-webserver-1858537325.us-east-1.elb.amazonaws.com. 59 IN A 54.236.129.63

;; Query time: 48 msec
;; SERVER: 172.16.1.10#53(172.16.1.10)
;; WHEN: Sun Aug 10 00:02:38 EDT 2014
;; MSG SIZE  rcvd: 160

If interested, this is from sslscan:

  Prefered Server Cipher(s):
    SSLv3  256 bits  DHE-RSA-AES256-SHA
    TLSv1  256 bits  DHE-RSA-AES256-SHA
    TLSv1.1  256 bits  DHE-RSA-AES256-SHA
    TLSv1.2  256 bits  DHE-RSA-AES256-GCM-SHA384
like image 171
jww Avatar answered Oct 04 '22 20:10

jww