The SSL specification indicates that the ServerCertificate message should
contain:
certificate_list: This is a sequence (chain) of X.509.v3
certificates, ordered with the sender's certificate first followed
by any certificate authority certificates proceeding sequentially
upward.
The TLS RFC has:
certificate_list
This is a sequence (chain) of X.509v3 certificates. The sender's
certificate must come first in the list. Each following
certificate must directly certify the one preceding it. Because
certificate validation requires that root keys be distributed
independently, the self-signed certificate which specifies the
root certificate authority may optionally be omitted from the
chain, under the assumption that the remote end must already
possess it in order to validate it in any case.
So the web server is sending the list incorrectly. I once used a product that
just sent the certs in the order contained in the configured .PFX file, so the
easiest workaround was to repackage the .PFX.
Erik
....................................
Erik Tkal
Juniper OAC/UAC/Pulse Development
From: [email protected] [mailto:[email protected]]
On Behalf Of Timothy Kay
Sent: Tuesday, February 14, 2012 12:46 PM
To: [email protected]
Subject: cert chain out of order breaks openssl
We have been baffled for a long time that curl cannot access websites that work
just fine in the browser (unless we use --insecure, of course). The curl
documentation points you to http://curl.haxx.se/docs/sslcerts.html, which
explains that your server has out of date certificates. It's not true! The
problem is that the troublesome websites send the certificate chain that is out
of order, and openssl fails to validate these chains, even though
/etc/ssl/certs contains appropriate root certificates.
$ curl -v https://catalog.cincinnatilibrary.org
* About to connect() to
catalog.cincinnatilibrary.org<http://catalog.cincinnatilibrary.org> port 443
(#0)
* Trying 66.213.10.111... connected
* Connected to
catalog.cincinnatilibrary.org<http://catalog.cincinnatilibrary.org>
(66.213.10.111) 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, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify
failed
* Closing connection #0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify
failed
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.
Note that the CA path is set to /etc/ssl/certs. The certificate verification
fails. I will now show that the system is configured correctly, and that the
problem is with openssl.
Searching the web, we find several mentions of out of order certificate chains,
but I have found no mention that openssl is at fault for not handling it
properly regardless.
I am looking to this group to confirm my findings, then we can work to fix
openssl.