Http Library for Ruby with Https, Ssl Client Certificate and Keep-Alive Support

HTTP library for Ruby with HTTPS, SSL Client Certificate and Keep-Alive support?

Is there something that already works?

I believe the HTTP client library Faraday is focus of more Ruby community action is these days.

It comes with a :net_http_persistent adapter, which supports SSL client certificates. You can probably do something like this:

ssl_options = {
cert: OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
key: OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), 'mypassword')
}
conn = Faraday.new(url: 'https://example.com', ssl: ssl_options) do |faraday|
faraday.adapter = Faraday::Adapter::NetHttpPersistent
end

conn.get '/my-resource'

HTTParty

According to the specs:

... the resulting connection when providing PEM certificates when scheme is https

  • uses the provided PEM certificate
  • will verify the certificate

You can use the pem classmethod to provide a client certificate in PEM format.

REST Client

It's not as dead as all that -- Larry Gilbert (@L2G) is still merging in pull requests and keeping the lights on. He's nodded his general approval in the issue tracker. I suspect it's just not at the top of his priority queue at the moment.

The guy who sent in that pull request, @byroot, has been keeping his code up to date so you shouldn't need to do much at all while you wait.

How to use a client certificate with HTTPS?

Okay, so I looked all over and found bits and pieces of what I needed. I want to provide this for anyone else that is struggling. All of the files were put in a PEM format. I used the client.key file to create a CSR that was given to the server administrator. In return I got a P7B file that I then needed to be convert into PEM files. The root.cer and client.cer file came from the P7b.

  uri = URI.parse(my_url_stril)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.cert = OpenSSL::X509::Certificate.new(File.read("client.cer"))
http.ca_file = 'root.cer'
http.key = OpenSSL::PKey::RSA.new(File.read("client.key"))
request = Net::HTTP::Post.new(uri.request_uri)
request.body = body
response = http.request(request)

Let me know if you need more details!

How to mimic browser X509 client certificate verification without access to HTTP layer

Your app stack isn't able to control SSL cause it's terminated on the web server. All the verification stuff is done by the web server and then only SSL_* headers go to the app server (look for Apache's SSLOptions for example). If you can't control web server you probably cant even turn on client certificate requirement. And i can't find any options to turn this requirement on via heroku: https://devcenter.heroku.com/articles/ssl#customdomain-ssl

If you've got SSL_* headers somehow then, regardless of web-server-side verification, you can verify certificate (commonly in the SSL_CLIENT_CERT header) using openssl as an army knife. See this for example in ruby: OpenSSL verify certificate from own CA

Also keep in mind that certificate verification is the process of checking certificate sign and other properties e.g. formal checking. To authenticate user you have to link that verified certificate to user by DN or E field, for example.

SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)

After lots of testing, I found the correct solution. The problem was with the cert file declaration.

I tried sending the post request using the bundled cert files (example.com.pem)

http.ca_file = File.read(File.join(Rails.root, "/crt/example.com.pem"))

So, I changed the above declaration with the each crt and key files

http.cert = OpenSSL::X509::Certificate.new(File.read(File.join(Rails.root, "/crt/example.com.crt")))
http.key = OpenSSL::PKey::RSA.new(File.read(File.join(Rails.root, "/crt/example.com.key")))
req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/xml'}).

It now worked.

Complete code

uri = URI("https://test.compassplus.com:8444/Exec")
xml = "
<TKKPG>
<Request>
<Operation>CreateOrder</Operation>
<Language></Language>
<Order>
<OrderType>Purchase</OrderType>
<Merchant>99999</Merchant>
<Amount>10000</Amount>
<Currency>524</Currency>
<Description>Tour Purchase</Description>
<ApproveURL>/approve.html</ApproveURL>
<CancelURL>/cancel.html</CancelURL>
<DeclineURL></DeclineURL>
<email></email>
<phone></phone>
<AddParams>
<FA-DATA></FA-DATA>
<SenderPostalCode></SenderPostalCode>
<AcctType></AcctType>
<TranAddendums></TranAddendums>
<TranAddendumsVISA></TranAddendumsVISA>
<TranAddendumsMC></TranAddendumsMC>
<TranAddendumsAMEX></TranAddendumsAMEX>
<TranAddendumsJCB></TranAddendumsJCB>
<OrderExpirationPeriod></OrderExpirationPeriod>
<OrigAmount></OrigAmount>
<OrigCurrency></OrigCurrency>
</AddParams>
<Fee></Fee>
</Order>
</Request>
</TKKPG>
"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :TLSv1_2
http.cert = OpenSSL::X509::Certificate.new(File.read(File.join(Rails.root, "/crt/example.com.crt")))
http.key = OpenSSL::PKey::RSA.new(File.read(File.join(Rails.root, "/crt/example.com.key")))
req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/xml'})
@res = http.request(req, xml)

Reference.

HTTP library for Ruby with HTTPS, SSL Client Certificate and Keep-Alive support?



Related Topics



Leave a reply



Submit