Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing SSL/TLS Client Authentication with OpenSSL

Tags:

I am developing a client/server application with TLS. My idea is to use a certificate on the client so it is authenticated by the server. Also another certificate on the server so the client is also able to authenticate that it is connecting to the right server.

I want first to test and use openssl s_server and openssl s_client to validate the proposal.

Until now I have created a CA private key on the server, I have created a root certificate. With the root certificate I have signed two CSR, so I get one certificate for the server and one certificate for the client.

I also have installed the client certificate + root certificate on the client, and the server certificate + root certificate on the server.

I want now to try to establish a connection between openssl s_server and openssl s_client and verify that they get both authenticated mutually, but I cannot wrap my mind with the documentation on how to do it. Any help or any guide on that?

Once I have that set up, the next step is to test the own developed client against that server, and our own developed server against the s_client. Can we use that for testing?

Thanks

like image 908
fazineroso Avatar asked Jan 10 '14 17:01

fazineroso


People also ask

How does client verify TLS certificate?

If the SSL or TLS server requires client authentication, the server verifies the client's identity by verifying the client's digital certificate with the public key for the CA that issued the personal certificate to the client, in this case CA X .

How do you test for TLS?

To test that your SSL/TLS configuration works correctly, you can use self-signed certificates. Self-signed certificates are useful in test scenarios so that you can ensure SSL/TLS connectivity without paying a Certificate Authority (CA) for a certificate. See Creating test certificates for details.

How do you check if TLS 1.0 is enabled OpenSSL?

OpenSSL command is the easiest way to check TLS version. The following commands can be used to find TLS version: openssl s_client -connect host.com:443 -tls1. openssl s_client -connect host.com:443 -tls1_1.


2 Answers

It looks like you are trying to set up a root of trust with (1) s_client and s_server for testing; and (2) programmatically within your code using OpenSSL.


To ensure openssl s_client (or openssl s_server) uses your root, use the following options:

  • -CAfile option to specify the root
  • -cert option for the certificate to use
  • -key option for the private key of the certificate

See the docs on s_client(1) and s_server(1) for details.


To do the same programmatically on the client, you would use:

  • SSL_CTX_load_verify_locations to load the trusted root
  • SSL_CTX_use_certificate to specify the client certificate
  • SSL_CTX_use_PrivateKey to load the private key for the client certificate

To do the same programmatically on the server, you would use:

  • SSL_CTX_load_verify_locations to load the trusted root
  • SSL_CTX_use_certificate_chain_file to specify the server certificate
  • SSL_CTX_use_PrivateKey to load the private key for the server certificate
  • SSL_CTX_set_client_CA_list to tell the client to send its client certificate

If you don't want to use the parameters for every connection (i.e. the common context), then set it for each SSL connection with, for example, SSL_use_certificate and SSL_use_PrivateKey.

A lot goes on with SSL_CTX_set_client_CA_list. It (1) loads the CA's to the server uses to verify a client, (2) it causes the server to send a list of CAs it accepts when verifing a client, and (3) it triggers the ClientCertificate message at the client if the client has a certificate that satisfies the server's accepted CAs list.

Also see the docs on SSL_CTX_load_verify_locations(3), SSL_CTX_use_certificate(3), SSL_CTX_set_client_CA_list and friends.


The easiest certificate and key format to use is PEM. PEM is the one that uses, for example, ----- BEGIN CERTIFICATE -----. For the server certificate, be sure the file is a concatenation of the server's certificate and any intermediates needed by the client to build the chain.

Having the server send all required certificates is standard practice for a problem known as the "which directory" problem. Its a well known problem in PKI, and its essentially the problem that clients don't know where to go to fetch missing intermediate certificates.


In general, you now know the functions that you need to use. Download a small server like nginx, and see how a production server uses them in practice. You could even use a SQL server like Postgres since it sets up a SSL/TLS server. Simply search the source files for SSL_CTX_load_verify_locations or SSL_load_verify_locations, and you will find the right place.

Though I don't recommend it, you could even look at s_client.c and s_server.c. They are located in <openssl dir>/apps. But the code can be difficult to read at times.

like image 83
jww Avatar answered Oct 01 '22 12:10

jww


Generate two pairs of certificates/keys, one for the server and one for the client. Also create test.txt with any content.

To set up an SSL server that checks a client certificate, run the following command:

openssl s_server -cert server_cert.pem -key server_key.pem -WWW -port 12345 -CAfile client_cert.pem -verify_return_error -Verify 1 

To test the server with client certificate, run the following command:

echo -e 'GET /test.txt HTTP/1.1\r\n\r\n' | openssl s_client -cert client_cert.pem -key client_key.pem -CAfile server_cert.pem -connect localhost:12345 -quiet 

Alternatively you can use curl command:

curl -k --cert client_cert.pem --key client_key.pem https://localhost:12345/test.txt 
like image 42
anton_rh Avatar answered Oct 01 '22 13:10

anton_rh