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

15,137

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?

Share:
15,137
Santosh Aryal
Author by

Santosh Aryal

Programming is my passion. Though I am not a good programmer, everyday I am trying to gain more skills and knowledge.

Updated on June 17, 2022

Comments

  • Santosh Aryal
    Santosh Aryal almost 2 years

    I am trying to post to a web service from my app and I am getting the following error frequently.

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

    I send post request with the crt file issued by compassplus and key file generated by myself.

    def payment
        @booking = 12
    
        uri = URI("https://test.compassplus.com:8444/Exec")
        xml = Builder::XmlMarkup.new
        xml.instruct! :xml, :version => '1.0'
        xml.TKKPG {
            xml.Request {
                xml.Operation("CreateOrder")
                xml.language("EN")
                xml.Order {
                    xml.OrderType("Purchase")
                    xml.Merchant("123456")
                    xml.Amount("10000")
                    xml.Currency("840")
                    xml.Description("Tour Purchase")
                    xml.ApproveURL("/thankyou.html")
                    xml.CancelURL("/error.html")
                    xml.DeclineURL("/declined.html")
                    xml.email("")
                    xml.phone("")
                    xml.AddParams {
                        xml.FADATA("")
                        xml.SenderPostalCode("")
                        xml.AcctType("")
                        xml.TranAddendums("")
                        xml.TranAdddendumsVISA("")
                        xml.TranAdddendumsMC("")
                        xml.TranAdddendumsAMEX("")
                        xml.TranAdddendumsJCB("")
                        xml.OrderExpirationPeriod("")
                        xml.OrigAmount("")
                        xml.OrigCurrency("")
                    }
                }
            }
        }
        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl  = true
        http.ssl_version = :TLSv1_2
        http.verify_mode  = OpenSSL::SSL::VERIFY_PEER
        http.ca_file = File.read(File.join(Rails.root, "/crt/gvtrek.com.pem"))
    
        @request = http.post(uri, xml)
    end
    

    I am getting SSL error when I send post request from localhost and timeout when I send it from production. I couldn't figure out the problem. Help me to get it fix. I am working on macOS Mojave.