7

I'm trying to use RestClient to retrieve a page that's secured using an SSL client certificate. My code is as follows:

require 'restclient'

p12 = OpenSSL::PKCS12.new(File.read('client.p12'), 'password')
client = RestClient::Resource.new('https://example.com/',
                                  :ssl_client_key => p12.key,
                                  :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
client.get

When I run it, I see the following failure:

1.9.3-p374 :007 > client.get
RestClient::BadRequest: 400 Bad Request
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/abstract_response.rb:48:in `return!'
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/request.rb:230:in `process_result'
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/request.rb:178:in `block in transmit'
    from /home/duncan/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/net/http.rb:745:in `start'
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/request.rb:172:in `transmit'
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/request.rb:64:in `execute'
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/request.rb:33:in `execute'
    from /home/duncan/.rvm/gems/ruby-1.9.3-p374/gems/rest-client-1.6.7/lib/restclient/resource.rb:51:in `get'
    from (irb):7
    from /home/duncan/.rvm/rubies/ruby-1.9.3-p374/bin/irb:13:in `<main>'

I'm fairly sure this is a failure to authenticate, as I get the same error in a browser if I don't install the client certificate.

I'm using OpenSSL::SSL::VERIFY_NONE because the server has a self-signed certificate, and I believe this is the correct value to pass to ignore that.

Any suggestions on how to get this working would be greatly appreciated - even a pointer to some detailed documentation, or a suggestion of a different Gem could work. I've not had much luck with either the Gem docs or Google :(

Duncan Bayne
  • 3,870
  • 4
  • 39
  • 64

1 Answers1

7

Your HTTPS request is going to need the client certificate as well as the key. Try:

client = RestClient::Resource.new('https://example.com/',
                                  :ssl_client_cert => p12.certificate,
                                  :ssl_client_key => p12.key,
                                  :verify_ssl => OpenSSL::SSL::VERIFY_NONE)

If that doesn't work you can try capturing the handshake packets (e.g. with WireShark) to verify that the API is offering the certificate.

rhashimoto
  • 15,650
  • 2
  • 52
  • 80
  • 7
    Having a solution with `VERIFY_NONE` is so wrong in so many levels... What's the point of using ssl when you do not verify the certificate? – Jarmo Pertman Nov 15 '14 at 11:07
  • 2
    @JarmoPertman `VERIFY_NONE` is useful when developing locally against a server with a self-signed certificate. – WildlyInaccurate Aug 27 '15 at 12:17
  • 4
    Yeah, but when SO is full of accepted answers with `VERIFY_NONE` without any explanation of what it actually might do, then it's highly likely that code like this will end up everywhere and no certificates will be verified. – Jarmo Pertman Aug 28 '15 at 20:54
  • I agree with @JarmoPertman - there's no reason to set ssl_client_cert & ssl_client_key because of the ```VERIFY_NONE```. Of course it works and let's you override connection problems, but that's not ok on production environment. You should specify ```OpenSSL::SSL::VERIFY_PEER``` – banesto Jan 25 '16 at 11:28