Ssl_Connect Returned=1 Errno=0 State=Error: Certificate Verify Failed (Unable to Get Local Issuer Certificate)

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:

  1. 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.
  2. 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



Leave a reply



Submit