Search code examples
rubysslcertificatessl-certificatenet-http

Ruby https with ca certification does not work while it worked with curl


In ruby, I try to do a ssl connection to a nginx server I setup locally, with an auto-signed certificate. My code is :

require "net/http"
require "net/https"
require "openssl"
require "uri"
require "pp"

request = Net::HTTP::Get.new("/")
response = Net::HTTP.start(
  "localhost",
  443,
  {
    :use_ssl => true,
    :key => OpenSSL::PKey::RSA.new(File.read("/home/gg/crt/client.key")),
    :cert => OpenSSL::X509::Certificate.new(File.read("/home/gg/crt/client.crt")),
    :ca_file => "/home/gg/crt/ca.pem",
    :verify_mode => OpenSSL::SSL::VERIFY_PEER,
    :verify_depth => 5,
  }
) do |http|
      http.request(request)
end
puts response.inspect
puts response.body

When I run it it return

/home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `connect': SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `block in connect'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/timeout.rb:74:in `timeout'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `connect'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:852:in `start'
    from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:583:in `start'
    from testso.rb:8:in `<main>'

But I have the correct result if I run it with curl:

curl https://localhost --key crt/client.key --cert crt/client.crt --cacert crt/ca.pem

What am i doing wrong?


Solution

  • I feel dumb but figured out the problem.

    When generating the different certificates I left some fields blank. It seems that openssl detected this certificate as "looking" autosigned.

    Thus if we use OpenSSL::SSL::VERIFY_PEER the connection fails

    So to be sure that the certificate is well generated using the CA you can do : openssl verify -CAfile ca.crt server.crt (and same command with client.crt)

    if we get

    error 18 at 0 depth lookup:self signed certificate
    OK
    

    The certificate is detected as autosigned and it fails

    if we get

     Signature ok
    

    It should work