Access server with client certificate using s_client but not curl?
I am using nginx for my web server with client certificate authentication. Relevant part of the configuration:
ssl_certificate /usr/local/etc/nginx/certs/ssl.crt;
ssl_certificate_key /usr/local/etc/nginx/certs/ssl.key;
ssl_client_certificate /usr/local/etc/nginx/certs/server_chain.crt;
ssl_verify_client on;
ssl_verify_depth 2;
Client certificates are signed by another server that has a certificate from the root CA. Ie, I want to accept clients having a certificate chain like this:
CA -> intermediate CA -> client
Therefore, the server_chain.crt file is created:
cat intermediate_ca.crt root_ca.crt > server_chain.crt
Now I can successfully access the server by running the command:
openssl s_client -connect localhost:443 -tls1 -cert client.crt \
-key client.key -CApath root_ca.crt -state -debug`
and then enter GET /api
But if I try to achieve the same service using:
curl -v -s -k --key client.key --cert client.crt https://localhost/api
I get:
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.6.0</center>
</body>
</html>
I also cannot access the page localhost/api
from the web browser with the client certificate installed. Something that works if I disable client validation.
Any ideas on what is wrong?
source to share
This may have changed since then, but as of today, the curl installed can use client side certificates. But since this is linking to Mac OS SSL libraries, there are a couple of errors:
- The certificate must be in PKCS12 format. You can convert what you have with the following:
cat client.key client.crt intermediate_ca.crt > bundle.pem
openssl pkcs12 -export -in bundle.pem -out bundle.p12
Run curl with the option
--cert bundle.p12:*password*
Showtopper got caught. Either curl or the core libraries are NOT sending intermediate certificates correctly: only the client-side certificate is sent. You can verify this by capturing packets on the packets going to the server: the issuer and subject names are displayed in clear text.
source to share