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?
certificate Error SSL_connect returned=1 errno=0 state=error: certificate verify failed
As per the documentation of Rest-Client gem
RestClient::Resource.new(
'https://example.com',
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read("cert.pem")),
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
:ssl_ca_file => "ca_certificate.pem",
:verify_ssl => OpenSSL::SSL::VERIFY_PEER
).get
can be used to specify ca-certificate and verify them. In case you do not want to verify it, modify the verify-ssl
key to OpenSSL::SSL::VERIFY_NONE
As per the RestClient gem source code for RestClient.get() and RestClient::Resource.new(...).get, both these methods call Request.execute(). Therefore your arguments will remain the same except you'll need to pass authorized url to the .new
's argument. So your code will become like this:
my_client = RestClient::Resource.new(
authorized_url,
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read("cert.pem")),
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
:ssl_ca_file => "ca_certificate.pem",
:verify_ssl => OpenSSL::SSL::VERIFY_PEER
)
my_client.get({ accept: :json }) { |response, request, result, &block|
raise SparcApiError unless response.code == 200
@response = response
}
This way, you can re-use the my_client
object to send GET/POST/PUT/PATCH/DELETE
requests with same ssl options and url. e.g. my_client.post(...){...}
NOTE:
- Verifying ssl certificate shouldn't be skipped in production. This should be used in dev/test environment only, otherwise you will be susceptible to the man in the middle attacks.
- If you trust the CA certificate then you should add it to your host's installed certificates bundle.
Always getting: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
The IDP side certificate expires, they fix it and the error in question stopped.
Related Topics
What Are Some Good Role Authorization Solutions Used with Authlogic
What Are the Steps Needed to Create and Publish a Rubygem of Your Own
How to Change Passenger Ruby Version Without Recompiling
Why Do Ruby Procs/Blocks with Splat Arguments Behave Differently Than Methods and Lambdas
Problem with Rspec Test, Undefined Method 'Post'
Why Is Bigdecimal Returning a Weird Value
How to Shorten a Uuid to a Specific Length
Authlogic Perishable_Token Resets on Every Request
Ruby Mailer Is Coming Up with an Eoferror
Ruby Scope of Data After _End_
How to Delete a Range of Values from an Array
Ruby on Rails Add a Column After a Specific Column Name
Activeadmin Custom Views Which Retain the Activeadmin Layout