Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#1760 closed defect (invalid)

Client cert verification not working with Openssl 1.1.1b - working on 1.0.2r

Reported by: scaarup@… Owned by:
Priority: major Milestone:
Component: other Version: 1.15.x
Keywords: openssl Cc:
uname -a: Linux ssl-modirum301.dibs.dk 3.10.0-957.10.1.el7.x86_64 #1 SMP Thu Feb 7 07:12:53 UTC 2019
nginx -V: nginx version: nginx/1.15.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.1.1b 26 Feb 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-openssl=/usr/local/development/rpmbuild/rpmbuildnginx/BUILD/openssl-1.1.1b/ --with-http_ssl_module --with-http_stub_status_module --with-debug --with-http_dav_module --with-http_v2_module --with-http_auth_request_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --with-http_realip_module --with-stream --with-stream_ssl_preread_module --with-stream_realip_module --with-openssl-opt=enable-tls1_3 --add-module=/usr/local/development/rpmbuild/rpmbuildnginx/BUILD/ModSecurity-nginx

Description

Hi guys.

If I build Nginx with OpenSSL 1.1.1b, client cert verification is not working. Always resulting in:

2019/04/02 21:18:55 [info] 29916#0: *10 client SSL certificate verify error: (26:unsupported certificate purpose) while reading client request headers, client: <masked ip>, server: <masked-hostname>, request: "POST /endpoint/jokum HTTP/1.1", host: "<masked-hostname>:4000"

nginx -V:

nginx version: nginx/1.15.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.1.1b  26 Feb 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-openssl=/usr/local/development/rpmbuild/rpmbuildnginx/BUILD/openssl-1.1.1b/ --with-http_ssl_module --with-http_stub_status_module --with-debug --with-http_dav_module --with-http_v2_module --with-http_auth_request_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --with-http_realip_module --with-stream --with-stream_ssl_preread_module --with-stream_realip_module --with-openssl-opt=enable-tls1_3 --add-module=/usr/local/development/rpmbuild/rpmbuildnginx/BUILD/ModSecurity-nginx

Configuration:

                ssl_client_certificate /etc/nginx/root.pem;
                ssl_verify_client on;
                ssl_verify_depth 3;

If I then build Nginx with OpenSSL 1.0.2r, it works fine. Same configuration on same server.

nginx -V:

nginx version: nginx/1.15.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2r  26 Feb 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-openssl=/usr/local/development/rpmbuild/rpmbuildnginx/BUILD/openssl-1.0.2r/ --with-http_ssl_module --with-http_stub_status_module --with-debug --with-http_dav_module --with-http_v2_module --with-http_auth_request_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --with-http_realip_module --with-stream --with-stream_ssl_preread_module --with-stream_realip_module --add-module=/usr/local/development/rpmbuild/rpmbuildnginx/BUILD/ModSecurity-nginx

Attachments (2)

root.pem (1.3 KB ) - added by scaarup@… 5 years ago.
root.pem
client.pem (1.4 KB ) - added by scaarup@… 5 years ago.
client.pem

Download all attachments as: .zip

Change History (8)

comment:1 by Maxim Dounin, 5 years ago

There are a lot of changes between OpenSSL 1.0.2 and OpenSSL 1.1.1, and the most likely reason is that it now rejects certificates you are using. Try checking if using openssl verify works for you, i.e., try something like:

openssl verify -CAfile /etc/nginx/root.pem <client.crt>

with different versions of OpenSSL. As long as it works with OpenSSL 1.0.2, but not with OpenSSL 1.1.1, this is clearly not an nginx problem. If it works with both versions, please provide some example certificates here for us to take a look.

comment:2 by scaarup@…, 5 years ago

No matter which openssl I try with, I get

client.pem: OK

comment:3 by Maxim Dounin, 5 years ago

As previously suggested, please provide example certificates which demonstrate the problem.

by scaarup@…, 5 years ago

Attachment: root.pem added

root.pem

by scaarup@…, 5 years ago

Attachment: client.pem added

client.pem

comment:4 by scaarup@…, 5 years ago

sry about that. They are attached now.

comment:5 by Maxim Dounin, 5 years ago

Resolution: invalid
Status: newclosed

The problem is that the root certificate uses the X509v3 Extended Key Usage extension:

$ openssl x509 -text -noout -in root.pem 
Certificate:
...
            X509v3 Extended Key Usage: 
                Any Extended Key Usage
...

While it is set to "Any Extended Key Usage", it doesn't include any other possible key usages. Quoting RFC 5280:

                             Applications that require the presence of a
   particular purpose MAY reject certificates that include the
   anyExtendedKeyUsage OID but not the particular OID expected for the
   application.

On the other hand, Extended Key Usage is checked by OpenSSL since 1.1.0. And OpenSSL does not permit certificates with anyExtendedKeyUsage as long as the particular OID is not specified. Note well that Extended Key Usage as set on a CA certificate also restricts all the certificates issued by this CA. As such, all certificates issued by the root certificate in question won't be trusted unless a particular key usage is not known.

The same failure can be demonstrated by using openssl verify with -purpose sslclient:

$ openssl version
OpenSSL 1.0.2o-freebsd  27 Mar 2018
$ openssl verify -purpose sslclient -CAfile root.pem client.pem
client.pem: OK
$ openssl version
OpenSSL 1.1.0h  27 Mar 2018
$ openssl verify -purpose sslclient -CAfile root.pem client.pem
C = EE, ST = HM, L = Tallinn, O = Scheme Inc, OU = Root CA, CN = Scheme Inc Root CA 2027
error 26 at 1 depth lookup: unsupported certificate purpose
error client.pem: verification failed
$ openssl version            
OpenSSL 1.1.1b  26 Feb 2019
$ openssl verify -purpose sslclient -CAfile root.pem client.pem
C = EE, ST = HM, L = Tallinn, O = Scheme Inc, OU = Root CA, CN = Scheme Inc Root CA 2027
error 26 at 1 depth lookup: unsupported certificate purpose
error client.pem: verification failed

An obvious workaround would be to remove the X509v3 Extended Key Usage extension from the root certificate.

Further reading:

https://serverfault.com/questions/785108/why-does-openvpn-give-the-error-unsupported-certificate-purpose-for-an-interm
https://tools.ietf.org/html/rfc5280#section-4.2.1.12

comment:6 by scaarup@…, 5 years ago

Awesome reply. Thank you very much for investigating this.

Note: See TracTickets for help on using tickets.