On Debian Jessie 8.4 GNU/Linux, I am experiencing a certificate validation inconsistency between Iceweasel (Debian's derivative of Firefox) and cURL in relation to the URL https://profile.mensa.org.uk/contact.aspx .
Iceweasel
Visiting https://profile.mensa.org.uk/contact.aspx using Iceweasel results in no errors or warnings. Clicking on the padlock icon at the left of the address bar, and then clicking the "More Information..." button, yields a window saying, among other things:
Web Site Identity
Web site: profile.mensa.org.uk
Owner: This web site does not supply ownership information.
Verified by: GeoTrust Inc.
Clicking the "View Certificate" button yields a window with two tabs, "General" and "Details". The General tab says:
This certificate has been verified for the following uses:
SSL Client Certificate
SSL Server Certificate
Issued To
Common Name (CN) profile.mensa.org.uk
Organisation (O) <Not Part Of Certificate>
Organisational Unit (OU) GT91227394
Serial Number 06:26:4F
Issued By
Common Name (CN) RapidSSL SHA256 CA - G3
Organisation (O) GeoTrust Inc.
Organisational Unit (OU) <Not Part Of Certificate>
Period of Validity
Begins On 05/08/15
Expires On 06/09/16
Fingerprints
SHA-256 Fingerprint 9C:F3:D7:B8:96:D6:A5:BC:98:9E:F0:DE:26:63:BD:17:
C5:29:24:C9:02:A9:90:D3:A5:49:AB:10:5D:E8:C0:3C
SHA1 Fingerprint
Clicking on the Details tab shows a three-level hierarchy in the Certificate Hierarchy field:
GeoTrust Global CA
RapidSSL SHA256 CA - G3
profile.mensa.org.uk
Selecting the GeoTrust Global CA
item in that field, then clicking the "Export..." button, and then saving as the file ~/Documents/organisations/mensa/geotrust_global_ca.pem
works as expected. Here is the fingerprint:
$ openssl x509 -noout -in ~/Documents/organisations/mensa/geotrust_global_ca.pem -fingerprint
SHA1 Fingerprint=DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12
Let's compare this with cURL.
cURL
Visiting https://profile.mensa.org.uk/contact.aspx using cURL results in a certificate error. Here is the verbose output, attempting to fetch only header information:
$ curl -v --head https://profile.mensa.org.uk/contact.aspx
* Hostname was NOT found in DNS cache
* Trying 93.159.201.114...
* Connected to profile.mensa.org.uk (93.159.201.114) port 443 (#0)
* 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 alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
cURL works OK for this URL over HTTP, and also for other domains over HTTPS:
$ curl --head http://profile.mensa.org.uk/contact.aspx
HTTP/1.1 302 Found
Date: Sat, 28 May 2016 14:30:56 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Location: /login.aspx?target=%2fcontact.aspx
Set-Cookie: ASP.NET_SessionId=axylcyf2cep2lq4e3brkggln; path=/; HttpOnly
Set-Cookie: WebToolsParam= ; path=/; HttpOnly
Cache-Control: no-cache, no-store
Pragma: no-cache
Expires: -1
Content-Type: text/html; charset=utf-8
Content-Length: 151
$ curl --head https://www.mensa.org.uk
HTTP/1.1 200 OK
Date: Sat, 28 May 2016 12:39:56 GMT
Server: Apache
Pragma: no-cache
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: store, no-cache, must-revalidate, post-check=0, pre-check=0
Set-Cookie: SESS4b296932593725667cea89bf7eb4e462=d10lbmrpju03rccsaftdemiai6; path=/; domain=.mensa.org.uk
Last-Modified: Sat, 28 May 2016 12:39:56 GMT
Content-Type: text/html; charset=utf-8
Here is information about the current version of cURL:
$ curl -V
curl 7.38.0 (i586-pc-linux-gnu) libcurl/7.38.0 OpenSSL/1.0.1k zlib/1.2.8 libidn/1.29 libssh2/1.4.3 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API SPNEGO NTLM NTLM_WB SSL libz TLS-SRP
I believe that whereas Iceweasel has its own CA store, cURL looks for certificate authority certificates in /etc/ssl/certs
, as shown in the verbose output above. So, my first thought was that the error cURL experienced in visiting https://profile.mensa.org.uk/contact.aspx must be due to /etc/ssl/certs
being devoid of a certificate for the CA that Iceweasel identified: GeoTrust Global CA
. However, I found that /etc/ssl/certs
does contain a suitable certificate:
$ openssl x509 -noout -in /etc/ssl/certs/GeoTrust_Global_CA.pem -fingerprint
SHA1 Fingerprint=DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12
As you can see, this is the same fingerprint as for ~/Documents/organisations/mensa/geotrust_global_ca.pem
above.
So, something else must be going on. I tried forcing cURL to use each of these two certificates, via the --cacert
option, but that didn't yield success:
$ curl --cacert ~/Documents/organisations/mensa/geotrust_global_ca.pem --head https://profile.mensa.org.uk/contact.aspx
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
$ curl --cacert /etc/ssl/certs/GeoTrust_Global_CA.pem --head https://profile.mensa.org.uk/contact.aspx
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
My primary question is: what is causing this inconsistency between cURL and Iceweasel?
My secondary question is: does this inconsistency mean that there is a bug in Iceweasel and/or a bug in cURL?