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?

+4


source to share


2 answers


Ok, so the error is completely unrelated to nginx. Turns out curl doesn't have a mechanism to run ssl by default on OS X. Therefore curl never sent any certificates to the server.



+3


source


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:

  1. 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

      

  1. Run curl with the option --cert bundle.p12:*password*

  2. 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.

+1


source







All Articles