Search code examples
rubysslrest-client

Ruby client for 2-way ssl authentication


I have java web service supports 2-way ssl auth. So I have client key store (client.p12) with server certificate in trusted store and server key store with client cert in trusted store.

I can easily call my service using browser or postman (just need importing client.p12 in browser certificates management) but I have problems with ruby client.

My current version:

require 'rest_client'

p12 = OpenSSL::PKCS12.new(File.read('client.p12'), 'password')

client = RestClient::Resource.new('https://localhost:8080/service',
                                  :ssl_client_cert => p12.certificate,
                                  :ssl_cert_key => p12.key,
                                  :verify_ssl => OpenSSL::SSL::VERIFY_NONE,
                                  :ssl_version => 'TLSv1_2',
                                  :ssl_ciphers => 'ECDHE-RSA-AES128-GCM-SHA256').get

fails with:

connect_nonblock': SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)

What is wrong with my client code?

openssl s_client output:

$ openssl s_client -connect localhost:8080
....
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
...

Solution

  • You need to import your client.p12 file into your nssdb location.

    mkdir /root/nssdb
    pk12util -i /path-to/your/client.p12 -d /root/nssdb
    certutil -L -d /root/nssdb/
    export SSL_DIR = /root/nssdb
    
    curl -X POST -H "Content-Type: text/xml" --data "#{xml}" --cert cert:password "https://localhost:8080/service" -v -k
    chmod -R 777 /root/nssdb
    chown -R user /root/nssdb
    

    Embed this curl call in your ruby client. It will work.

    Note: If you are using a different ssl version you need to add --tlsv1.0 to the curl command