cURL / Mailing Lists / curl-library / Single Mail

curl-library

Certificate verificaion fails when using CURLOPT_CAINFO to intermediate

From: Johannes Bauer <Jb.Imm_at_gmx.de>
Date: Wed, 11 Jan 2012 17:11:32 +0100

Hi list,

I have a problem when using libcurl 7.21.3 on Linux. When using
CURLOPT_CAINFO and pointing it to a file which only includes a
intermediate certificate of the server's chain, verification of the
hosts certificate will fail (although I believe it should succeed).

While my actual setting is different, this effect can for example be
seen at accounts.google.com. It uses three certificates: A self-signed
root (A), an intermediate certificate (B) and a leaf server certificate (C).

When I put B in a single file:

$ cat >intermed.crt
-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
-----END CERTIFICATE-----

And then do a connection using openssl without any certificates, it
fails (like it should):

$ touch empty.crt
$ openssl s_client -connect accounts.google.com:443 -CApath /sys -CAfile
empty.crt >/dev/null
depth=1 /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
verify error:num=20:unable to get local issuer certificate
verify return:0

Now when I specify ONLY the intermediate certificate of the chain as
CAfile, it works (like it should):

$ openssl s_client -connect accounts.google.com:443 -CApath /sys -CAfile
intermed.crt >/dev/null

depth=2 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification
Authority
verify return:1
depth=1 /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
verify return:1
depth=0 /C=US/ST=California/L=Mountain View/O=Google
Inc/CN=accounts.google.com
verify return:1

Doing the same thing with curl now:

$ curl --cacert intermed.crt --capath /sys https://accounts.google.com
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate
verify failed

When also putting the root certificate in the CAfile certificate, it
also works with curl (obviously). However, I do not want to put the root
certificate in the CAfile (since I only trust certificates signed by
that specific intermediate and not all children of the root).

Can somebody please enlighten me why the behavior of cURL differs form
that of openssl?

Best regards,
Joe

PS: In some commands I use /sys for the CApath, which obviously does not
contain any certificates and which I specify only for the sole purpose
that openssl does not unexpectedly pull in certificates from
/etc/ssl/certs for verification.
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2012-01-11