Ruby Net::HTTP responds with OpenSSL::SSL::SSLError “certificate verify failed” after certificate renewal

こ雲淡風輕ζ 提交于 2019-11-28 01:57:23

I would try to double-check the trusted certificate store if it contains the COMODO_RSA_Certification_Authority.pem certificate. In my (Linux) setup, the site works OK but when I temporarily remove the certificate of the COMODO cert authority from the cert store, I get exactly the same error as you (while in browsers it still works as they have their own cert stores).

BTW, the same error is also recognizable using curl as it also appears to use the same trusted cert store as ruby, so you might first ensure that the site works under curl.

In linux, the cert store is located usually in /etc/ssl/certs whereas under OSX it should probably be /System/Library/OpenSSL (see this article for other options).

You should see something like the following in the cert store directory:

root@apsara:/etc/ssl/certs$ ls -l | grep COMODO_RSA_Certification_Authority.pem
lrwxrwxrwx 1 root root     73 úno 28 10:24 COMODO_RSA_Certification_Authority.pem -> /usr/share/ca-certificates/mozilla/COMODO_RSA_Certification_Authority.crt
lrwxrwxrwx 1 root root     38 úno 28 10:24 d4c339cb.0 -> COMODO_RSA_Certification_Authority.pem
lrwxrwxrwx 1 root root     38 úno 28 10:24 d6325660.0 -> COMODO_RSA_Certification_Authority.pem

The following is a snipped of some attributes of this root CA certificate:

$ openssl x509 -in COMODO_RSA_Certification_Authority.pem -noout -text
Certificate:
Data:
    Version: 3 (0x2)
    Serial Number:
        4c:aa:f9:ca:db:63:6f:e0:1f:f7:4e:d8:5b:03:86:9d
Signature Algorithm: sha384WithRSAEncryption
    Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority
    Validity
        Not Before: Jan 19 00:00:00 2010 GMT
        Not After : Jan 18 23:59:59 2038 GMT
    Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (4096 bit)
            Modulus:
                00:91:e8:54:92:d2:0a:56:b1:ac:0d:24:dd:c5:cf:
                ...
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Key Identifier: 
            BB:AF:7E:02:3D:FA:A6:F1:3C:84:8E:AD:EE:38:98:EC:D9:32:32:D4
        X509v3 Key Usage: critical
            Certificate Sign, CRL Sign
        X509v3 Basic Constraints: critical
            CA:TRUE
Signature Algorithm: sha384WithRSAEncryption
     ...

The certificate can be downloaded from Comodo here (index of all certs is here).

More info: while looking into it, it turns out that there are actually two distinct certification chains for certs by the Comodo CA. One, the older one, is the one with the root CA listed above. The newer validation chain uses "External CA root" certificates in the chain. This forum post explains further, with specific instructions for OSX for marking those certs as trusted.

It sounds like the problem is with your OSX certificates cache. I guess you updated your certificates before the old one has expired?

Try purging your OSX system wide CRL cache by running this command:

crlrefresh rpv

# p - purges cache, r - refreshes them, v - run in verbose mode

This is a built-in command-line tool that updates and maintains system-wide CRL cache. Read more about it in its man page (mand crlrefresh).

I have been pulling my hair out all morning with this error. This question and the answer led me to a solution that works for me. I'm not adding new information here, but just the specifics of what I did in case it's of use to anyone else with this error on a platform similar to mine.

I'm using:

Ubuntu 16.04
ruby 2.3.0
rails 4.2.7.1
HTTParty

I'm accessing an API secured with an COMODO SSL certificate. In my code, when I tried:

HTTParty.get(secured_url).tap{|response| puts response}

I got:

SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)

I, too, used the SSL doctor script noted above. When I ran the script (substituting my actual api server address for host), I got:

$ ruby doctor.rb host:443
/home/<redacted>/.rvm/rubies/ruby-2.3.0/bin/ruby (2.3.0-p0)
OpenSSL 1.0.2g  1 Mar 2016: /usr/lib/ssl
SSL_CERT_DIR=""
SSL_CERT_FILE=""

HEAD https://host:443
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed

The server presented a certificate that could not be verified:
  subject: <redacted>
  issuer: /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
  error code 20: unable to get local issuer certificate

In a separate terminal, I went into my certs directory:

$ cd /etc/ssl/certs

And did (using COMODO_RSA_Organization_Validation_Secure_Server_CA derived from the issuer text, above):

<redacted>:/etc/ssl/certs$ openssl x509 -in COMODO_RSA_Organization_Validation_Secure_Server_CA.pem -noout -text
Error opening Certificate COMODO_RSA_Organization_Validation_Secure_Server_CA.pem
140455648364184:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('COMODO_RSA_Organization_Validation_Secure_Server_CA.pem','r')
140455648364184:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400:
unable to load certificate

I went to the COMODO site where the COMODO RSA Organization Validation Secure Server CA pem is located. I copied the certificate into a new file called COMODO_RSA_Organization_Validation_Secure_Server_CA.crt on my desktop (some instructions say to use crt extension instead of pem even though you need the pem certicate content).

Then, following these instructions, I did:

<redacted>:~/Desktop$ sudo cp COMODO_RSA_Organization_Validation_Secure_Server_CA.crt /usr/share/ca-certificates/COMODO_RSA_Organization_Validation_Secure_Server_CA.crt
<redacted>:~/Desktop$ sudo dpkg-reconfigure ca-certificates

Then I did:

sudo dpkg-reconfigure ca-certificates

And then:

<redacted>:~/Desktop$ ruby doctor.rb host:443
/home/<redacted>/.rvm/rubies/ruby-2.3.0/bin/ruby (2.3.0-p0)
OpenSSL 1.0.2g  1 Mar 2016: /usr/lib/ssl
SSL_CERT_DIR=""
SSL_CERT_FILE=""

HEAD https://host:443
OK

After which my code ran fine. Thank you, thank you, thank you!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!