libressl / openbsd

Source code pulled from OpenBSD for LibreSSL - this includes most of the library and supporting code. The place to contribute to this code is via the OpenBSD CVS tree. Please mail patches to tech@openbsd.org, instead of submitting pull requests, since this tree is often rebased.
231 stars 92 forks source link

s_client ignores CA files in openssldir #62

Closed DomT4 closed 8 years ago

DomT4 commented 8 years ago

This was tested initially on LibreSSL Portable but reproduces with the system LibreSSL on OpenBSD 5.9, hence the report here. That it reproduces on OpenBSD makes me wonder if this is a "feature" rather than a "bug". This doesn't reproduce on a current OpenSSL, either the latest 1.0.1 or 1.0.2 releases, for what that's worth.

LibreSSL built with a custom --with-openssldir=/usr/local/etc/libressl doesn't propagate to s_client, and you have to pass the -CAfile manually to create an error-free connection.

openssl s_client -connect github.com:443

CONNECTED(00000003)
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 Extended Validation Server CA
verify error:num=20:unable to get local issuer certificate
verify return:0

---
[snip]

---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: xyz
    Session-ID-ctx:
    Master-Key: xyz
    Start Time: 1466208586
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)

---

Passing the -CAfile manually does produce the expected end result:

openssl s_client -connect github.com:443 -CAfile /usr/local/etc/libressl/cert.pem

CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 Extended Validation Server CA
verify return:1
depth=0 businessCategory = Private Organization, 1.3.6.1.4.1.311.60.2.1.3 = US, 1.3.6.1.4.1.311.60.2.1.2 = Delaware, serialNumber = 5157550, street = "88 Colin P Kelly, Jr Street", postalCode = 94107, C = US, ST = California, L = San Francisco, O = "GitHub, Inc.", CN = github.com
verify return:1

---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: xyz
    Session-ID-ctx:
    Master-Key: xyz
    Start Time: 1466208734
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

Unsure if related but a grep for OPENSSLDIR in OpenSSL 1.0.2h & LibreSSL 2.3.6 shows OpenSSL stores the custom openssldir passed during configure but LibreSSL seems to have discarded it in favour of the default path:

/usr/local/opt/openssl/include/openssl/opensslconf.h:#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
/usr/local/opt/openssl/include/openssl/opensslconf.h:#define OPENSSLDIR "/usr/local/etc/openssl"
/usr/local/opt/libressl/include/openssl/opensslconf.h:#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
/usr/local/opt/libressl/include/openssl/opensslconf.h:#define OPENSSLDIR "/etc/ssl"
kinichiro commented 8 years ago

Hi,

If you move /usr/local/etc/libressl/cert.pem to /usr/local/etc/libressl/certs/, this issue will be solved.

The cert.pem should be placed into $OPENSSLDIR/certs/ .

In my CentOS7, with OpenSSL 1.0.2, OPENSSLDIR is set to /usr/lib/ssl/ and this directory and certs/ under this directory contain like this.

$ ls /usr/lib/ssl/
certs  misc  openssl.cnf  private
$
ls /usr/lib/ssl/certs/
00673b5b.0
02265526.0
...
9f533518.0
ACCVRAIZ1.pem
ACEDICOM_Root.pem
... (many *.pem files are listed) ...
thawte_Primary_Root_CA.pem
thawte_Primary_Root_CA_-_G2.pem
thawte_Primary_Root_CA_-_G3.pem
$

It seems that both OpenSSL and LibreSSL search CA files from $OPENSSLDIR/certs/.

BTW, according to tls/Makefile.am, libtls expect cert.pem is placed under the OPENSSLDIR

...
Makefile.am:libtls_la_CPPFLAGS += -D_PATH_SSL_CA_FILE=\"@OPENSSLDIR@/cert.pem\"
...

This might be a conflict between openssl command and libtls API.

Best Regards,

kinichiro commented 8 years ago

OpenSSL had fixed this by this commit. https://github.com/openssl/openssl/commit/fe9b85c3cb79f1e29e61f01de105b34ce8177190

busterb commented 8 years ago

Thanks, I forwarded the patch for this to tech@openbsd.org for review.

busterb commented 8 years ago

Fix applied, thanks! https://github.com/libressl-portable/openbsd/commit/c69dd72aa32f7a51c866e935403d6b336c45ed18