Adding a new SSL certificate to solve Verify return code: 20 (unable to get local issuer certificate)?

11,289

You need to add the path where s_client should look for the certificates, because it does not use any default path. This should work:

openssl s_client -CApath /etc/ssl/certs/ -connect api.stripe.com:443

There should be no need to any any certificates to /etc/ssl/certs, because the relevant CA should already be included with (X)ubuntu.

Share:
11,289
ssaeed
Author by

ssaeed

Updated on June 04, 2022

Comments

  • ssaeed
    ssaeed about 2 years

    UPDATE: If I let the API call hang and keyboard interrupt it, here is what it shows it was stuck on:

      File "/usr/lib/python2.7/ssl.py", line 405, in do_handshake
        self._sslobj.do_handshake()
    

    Are you guys sure it is not an SSL related issue?

    I have been getting an error that seems to be somewhat common, that of "Verify return code: 20 (unable to get local issuer certificate)". With the help of this thread I found a certificate that eliminates the error when I pass the path to a file as an arg, as per this thread. Now how do I permanently make this new certificate my like default certificate?

    To be clear, "echo '' | openssl s_client -connect api.stripe.com:443" yields this:

    CONNECTED(00000003)
    depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
    verify error:num=20:unable to get local issuer certificate
    verify return:0
    ---
    Certificate chain
     0 s:/C=US/ST=California/L=San Francisco/O=Stripe, Inc./CN=api.stripe.com
       i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
     1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
       i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
     2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
       i:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIFHDCCBASgAwIBAgIQCBKNwt21MdAyGnD9g/FpLzANBgkqhkiG9w0BAQUFADBm
    MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
    ZSBDQS0zMB4XDTEzMDkyNzAwMDAwMFoXDTE1MDEwODEyMDAwMFowajELMAkGA1UE
    BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lz
    Y28xFTATBgNVBAoTDFN0cmlwZSwgSW5jLjEXMBUGA1UEAxMOYXBpLnN0cmlwZS5j
    b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbC50FiFYms4rUoW7o
    CmW+jw6IUEt1oYyE7bWLMB/rmdGlw3cv7u82WR8HezLH9Fj60NvQhGvAzFYBjRWA
    +VnF5rxEYS05piwvF0jR1QSpeMzId7GOrHKV125pPuYzp+Mj44e3nr/uP91ICMVn
    gz6U39OqiU9aBUTI8bhuiqcWK+4M7yQ5j9DGcq/wJISfLSr9zVYxOH75TqaMDFUh
    EUqaWYpoJatQAYAobATCEVs5uw3T+K0tlRjcxhw5Zx698lajqTGORLwvVcF+ErZ7
    ukVNnStu3LyWaR2pMs8zytlx2nepFjIp7m/SCcxTc9GmRY6zubbfo/ih9sjofv2K
    nye9AgMBAAGjggHAMIIBvDAfBgNVHSMEGDAWgBRQ6nOJ2yn7EI+e5QEg1N55mUiD
        LnN0cmlwZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
        BggrBgEFBQcDAjBhBgNVHR8EWjBYMCqgKKAmhiRodHRwOi8vY3JsMy5kaWdpY2Vy
        dC5jb20vY2EzLWcyNy5jcmwwKqAooCaGJGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv
        bS9jYTMtZzI3LmNybDBCBgNVHSAEOzA5MDcGCWCGSAGG/WwBATAqMCgGCCsGAQUF
        BwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMHsGCCsGAQUFBwEBBG8w
        bTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEUGCCsGAQUF
        BzAChjlodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNz
        dXJhbmNlQ0EtMy5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEA
        j1zUdQBzjpMTeexGYpxMLWW4IYcblZeP03V15WnGnpGq5eaLHKDNJ9K7MRIOtDaw
        K4EVCIO1ru8ojf6eFwcRuozRkbMNSRAYLbFyTS3CWygC1De4vLwuhRxvnpKYcG57
        7kgPx+nxIQtQdauL5AinxXMysY8+GZP1qzc2zlSV0MnvW2p5D3g0lb1ZMFQLpzDm
        ACJcg7xiOrs6lS70EfvcEPrVmRn287aE7b3jEBQ+dkokxNEC0Mi7G4CJQVP1oape
        wtKjWMSeQA/VdUVuoxoUa        gNh7gzLqoc6s7z5HmWVpR1KXiASRFYXsBFeIXnvehJc
        6HeLGqB0qcMYHcE8wmJErA==
    -----END CERTIFICATE-----
    subject=/C=US/ST=California/L=San Francisco/O=Stripe, Inc./CN=api.stripe.com
    issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 4712 bytes and written 443 bytes
    ---
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-RSA-AES128-GCM-SHA256
        Session-ID: F5EA24F3FE87EA6D4D2D5F8EBBD66811BE85116047AB1111F22968B324698D86
        Session-ID-ctx: 
        Master-Key: EEBA4D6255330C751DACE424844778CAA561F9BA339488CB8B32D78047A681B3066DD683A733732AB778EB1C72FB1EE2
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        TLS session ticket lifetime hint: 300 (seconds)
        TLS session ticket:
        0000 - f0 46 61 22 d7 65 e3 95-e7 4b b3 f6 d6 79 9d 69   .Fa".e...K...y.i
        0010 - b1 8d 4a a2 a7 97 ba de-68 1a ff 63 f6 2a 64 34   ..J.....h..c.*d4
        0020 - 44 e6 01 64 d9 a9 ff 26-32 21 be 49 2a fc 85 42   D..d...&2!.I*..B
        0030 - ee eb c8 b1 65 cc 43 be-05 69 e8 d6 5c bd e0 19   ....e.C..i..\...
        0040 - 57 b3 07 5a d4 6b 90 f2-a0 b4 31 96 1f 41 6d 88   W..Z.k....1..Am.
        0050 - e3 23 ea b2 33 e3 33 2e-29 33 ab 30 65 a1 eb 6d   .#..3.3.)3.0e..m
        0060 - 99 66 65 c1 bf 2b e2 25-70 a7 f8 17 c4 4b 8a bd   .fe..+.%p....K..
        0070 - cf 37 6a ee 38 dc 96 c5-24 6b 35 40 1c f1 d6 35   [email protected]
        0080 - 64 0f 78 c7 90 98 f8 08-15 81 73 ce d6 e4 3e 38   d.x.......s...>8
        0090 - af 81 51 ef a1 0b 20 95-09 80 af c8 9d 08 14 e3   ..Q... .........
    
            Start Time: 1404582660
        Timeout   : 300 (sec)
        Verify return code: 20 (unable to get local issuer certificate)
    ---
    DONE
    

    Whereas "echo '' | openssl s_client -CApath ~/Downloads/DigiCertHighAssuranceEVRootCA.crt -connect api.stripe.com:443" yields this:

    CONNECTED(00000003)
    depth=3 C = US, O = GTE Corporation, OU = "GTE CyberTrust Solutions, Inc.", CN = GTE CyberTrust Global Root
    verify return:1
    depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
    verify return:1
    depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance CA-3
    verify return:1
    depth=0 C = US, ST = California, L = San Francisco, O = "Stripe, Inc.", CN = api.stripe.com
    verify return:1
    ---
    Certificate chain
     0 s:/C=US/ST=California/L=San Francisco/O=Stripe, Inc./CN=api.stripe.com
       i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
     1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
       i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
     2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
       i:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIFHDCCBASgAwIBAgIQCBKNwt21MdAyGnD9g/FpLzANBgkqhkiG9w0BAQUFADBm
    MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
    ZSBDQS0zMB4XDTEzMDkyNzAwMDAwMFoXDTE1MDEwODEyMDAwMFowajELMAkGA1UE
    BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lz
    Y28xFTATBgNVBAoTDFN0cmlwZSwgSW5jLjEXMBUGA1UEAxMOYXBpLnN0cmlwZS5j
    b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbC50FiFYms4rUoW7o
    CmW+jw6IUEt1oYyE7bWLMB/rmdGlw3cv7u82WR8HezLH9Fj60NvQhGvAzFYBjRWA
    +VnF5rxEYS05piwvF0jR1QSpeMzId7GOrHKV125pPuYzp+Mj44e3nr/uP91ICMVn
    gz6U39OqiU9aBUTI8bhuiqcWK+4M7yQ5j9DGcq/wJISfLSr9zVYxOH75TqaMDFUh
    EUqaWYpoJatQAYAobATCEVs5uw3T+K0tlRjcxhw5Zx698lajqTGORLwvVcF+ErZ7
    ukVNnStu3LyWaR2pMs8zytlx2nepFjIp7m/SCcxTc9GmRY6zubbfo/ih9sjofv2K
    nye9AgMBAAGjggHAMIIBvDAfBgNVHSMEGDAWgBRQ6nOJ2yn7EI+e5QEg1N55mUiD
    9zAdBgNVHQ4EFgQUgrT82oRIRdlSABFBqltZv7JNDBAwGQYDVR0RBBIwEIIOYXBp
    LnN0cmlwZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
    BggrBgEFBQcDAjBhBgNVHR8EWjBYMCqgKKAmhiRodHRwOi8vY3JsMy5kaWdpY2Vy
    dC5jb20vY2EzLWcyNy5jcmwwKqAooCaGJGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv
    bS9jYTMtZzI3LmNybDBCBgNVHSAEOzA5MDcGCWCGSAGG/WwBATAqMCgGCCsGAQUF
    BwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMHsGCCsGAQUFBwEBBG8w
    bTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEUGCCsGAQUF
    BzAChjlodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNz
    dXJhbmNlQ0EtMy5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEA
    j1zUdQBzjpMTeexGYpxMLWW4IYcblZeP03V15WnGnpGq5eaLHKDNJ9K7MRIOtDaw
    K4EVCIO1ru8ojf6eFwcRuozRkbMNSRAYLbFyTS3CWygC1De4vLwuhRxvnpKYcG57
    7kgPx+nxIQtQdauL5AinxXMysY8+GZP1qzc2zlSV0MnvW2p5D3g0lb1ZMFQLpzDm
    ACJcg7xiOrs6lS70EfvcEPrVmRn287aE7b3jEBQ+dkokxNEC0Mi7G4CJQVP1oape
    wtKjWMSeQA/VdUVuoxoUagNh7gzLqoc6s7z5HmWVpR1KXiASRFYXsBFeIXnvehJc
    6HeLGqB0qcMYHcE8wmJErA==
    -----END CERTIFICATE-----
    subject=/C=US/ST=California/L=San Francisco/O=Stripe, Inc./CN=api.stripe.com
    issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
    ---
        No client certificate CA names sent
    ---
    SSL handshake has read 4712 bytes and written 443 bytes
    ---
    New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-RSA-AES128-GCM-SHA256
        Session-ID: 7ACAFB7EFC59892B2FD356197EE62E8E94F05DA51FAC29C21CA4790D69916169
        Session-ID-ctx: 
        Master-Key: 4E58BAB4E6C5C36BFEE31C5AA49AB8B22C6ADB684C3A7A9FC1FE2D899676C5CDF2823C51E35120E61FA04F2291DBBF0D
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        TLS session ticket lifetime hint: 300 (seconds)
        TLS session ticket:
        0000 - 89 ab 9c 38 a7 3e 8a ae-43 22 63 ea fa 5d db 7e   ...8.>..C"c..].~
        0010 - b8 31 46 06 ba d7 5f ed-0f f4 58 47 ef 18 9c fc   .1F..._...XG....
        0020 - bf a5 ff f0 17 27 15 b0-ab 0e 38 53 6a f2 54 95   .....'....8Sj.T.
        0030 - 7a 68 0a f6 78 2d 30 ec-1b 54 27 3f 58 8f b0 59   zh..x-0..T'?X..Y
        0040 - 95 93 c1 fb 67 8c 1b 94-85 76 74 59 35 f7 c5 06   ....g....vtY5...
        0050 - 2e a1 41 cb 49 c0 6f 3d-77 d5 4b 4a 7f fd 9c d2   ..A.I.o=w.KJ....
        0060 - 07 4a 52 e6 04 8f 63 9b-fd a6 7b 94 5b 1e 3d 50   .JR...c...{.[.=P
        0070 - e3 77 dd b9 da 56 e7 5b-16 09 15 a8 b5 02 b7 07   .w...V.[........
        0080 - 1e 31 39 cb 07 c7 85 45-25 0c a6 d8 10 93 bc 21   .19....E%......!
        0090 - e8 0d b9 3c 08 8a 99 ce-75 eb 41 5e fe 5e af 8e   ...<....u.A^.^..
    
        Start Time: 1404583006
        Timeout   : 300 (sec)
        Verify return code: 0 (ok)
    ---
    DONE
    

    And the latter seems to me to solve this problem, if only I could make that "permanent". Would the solution be to convert it to PEM and put it in /usr/lib/ssl/certs/ ?

    If so, I am having trouble converting the certificate to PEM. I get the following, which I am currently "researching":

    $ openssl x509 -in DigiCertHighAssuranceEVRootCA.crt  -out  DigiCertHighAssuranceEVRootCA.pem -outform PEM
    unable to load certificate
    3074123452:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE
    

    EDIT: argh, successfully converted to .pem and moved it to that dir and it didn't make a difference.

    For background, this isn't on a like a production server or anything, this is just on my computer, which runs Xubuntu. I ran into this problem out of the blue while trying to run a script to interact with Stripe's API. The same script was running fine as wine the day before. Then all of the sudden the API calls started timing out. I contacted Stripe support, which was uncharacteristically slow, and the guy gave me some commands to run which brought to light this issue. Still waiting on a response back from them, but this seems to be the problem. I am hoping that using the certificate I downloaded all the time will allow me to once again interact with the Stripe API when I do things other than "echo '' | openssl s_client -connect api.stripe.com:443"

    if anyone has any guesses as to what I might have inadvertently done to cause this problem all of the sudden, I would really appreciate. Been kind of flabbergasted as to why this occurred.

    EDIT:

    I have been asked for the Stripe script itself.

    import stripe
    
    STRIPE_SECRET = "mys3cretkey"
    STRIPE_PUBLISHABLE = "testkeypublishable"
    
    stripe.api_key = STRIPE_SECRET
    customer = stripe.Customer.retrieve('cus_4FJ2a8cSopzrwQ')
    print customer['created']
    

    However, I would like to reiterate that this and every other Stripe related script and action were working just fine until a few days ago. I have been making Stripe API calls and web scraping and all sorts of other stuff blissfully oblivious to certs and ssl handshakes for months before this problem arose a few days ago. Also, Stripe's doc provide examples of API calls with your key and test info on the right, so you can just copy that and play around with it. Copying that doesn't work either. Making test transactions on our "site" on my local environment doesn't work either.

    But, ha, it has worked like 1/12 times since the problem started...it's weird...

    I tried echo '' | openssl s_client -connect google.com:443 as well and I got the same issue. So that is reason to think this problem is not Stripe-specific, though they did have some trouble with people connecting to their API they day these problems arose for me, trouble they said on Twitter was resolved. (And our production site is fine).

    Edit: Been asked to provide a little more info.

    1. Things that may have changed. The only thing that comes to mind as possibly affecting this is that I have started using my VM more. Note "more"--I was using it before and running these scripts just fine. It is a Windows 7 VM I use for .NET work. (For the curious, it runs poorly).

    2. Errors from Stripe. If I let the script hang long enough, I get a traceback the end of witch is this:

        File "/usr/local/lib/python2.7/dist-packages/stripe/http_client.py", line 140, in     _handle_request_error
      raise error.APIConnectionError(msg)
      stripe.error.APIConnectionError: Unexpected error communicating with Stripe.  If this problem persists,
      let us know at [email protected].
      
      (Network error: Timeout: HTTPSConnectionPool(host='api.stripe.com', port=443): Read timed out.)
      
    3. The scripts and openssl tests are both just on my local machine here, my laptop. When I referenced test transactions on our site, that was localhost here, with the same Stripe test API key as the scripts.

    Thanks

  • ssaeed
    ssaeed almost 10 years
    Thanks @Steffen, that does yield a return code of 0. However, that doesn't solve the problem--running the script afterwards does not work, still. If only there was a way to "permanently apply" that CApath, that seems like the solution. Or am I missing the mark?
  • Steffen Ullrich
    Steffen Ullrich almost 10 years
    Looking at the code stripe comes with its own certificate store which should include everything necessary. You've said that everything worked before, so the question is what changed. Would you please 1. write in the question what has changed, 2. provide the error messages you get from the stripe API and 3. tell if the openssl tests where done on the the machine where the your stripe using programs runs.
  • ssaeed
    ssaeed almost 10 years
    thanks for sticking with me @steffen, I updated the question with that info
  • Steffen Ullrich
    Steffen Ullrich almost 10 years
    Network error: Timeout: HTTPSConnectionPool(host='api.stripe.com', port=443): Read timed out.) - this is not a certificate problem, but simply a problem of network connectivity. It might be a problem on your end, on their end or some firewall inferring with the connection, but it has nothing to do with certificate verification.
  • ssaeed
    ssaeed almost 10 years
    Thanks! So I should not be worried about the certificate error, it is a misleading error.