RestClient failing to GET resource using SSL client certificate
Asked Answered
B

1

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 :(

Bunchy answered 23/5, 2013 at 13:40 Comment(0)
S
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.

Spangler answered 25/5, 2013 at 16:17 Comment(4)
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?Kindergartner
@JarmoPertman VERIFY_NONE is useful when developing locally against a server with a self-signed certificate.Prompter
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.Kindergartner
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_PEERDrypoint

© 2022 - 2024 — McMap. All rights reserved.