Search code examples
ubuntusslcurlapple-push-notificationspushkit

Sending Pushkit Notifications via cURL - curl: (60) SSL certificate problem: unable to get local issuer certificate


I use cURL to send pushkit notifications to Apple. My Rails code looks like this:

curl --http2 -v -d '#{payload.to_json}' --cert #{pem} #{pushkit_base_uri}/#{registration_id}

Since 19th Jan, 20201, running this command on Ubuntu has been returning the following:

...
...
...

* SSL certificate problem: unable to get local issuer certificate
* stopped the pause stream!
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

I have tried the following solutions so far:

  1. update-ca-certificates (Docs here)
  2. Solutions listed here

I haven't been able to get this to work yet. Any help is appreciated, and I will update this post if I find a solution.


Solution

  • Scroll to end for TLDR;

    By running awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | less we are able to view a list of all authorities trusted by our OS.

    ...
    ...
    ...
    subject=C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
    subject=C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA 2
    subject=C = EU, L = Madrid (see current address at www.camerfirma.com/address), serialNumber = A82743287, O = AC Camerfirma S.A., CN = Chambers of Commerce Root - 2008
    subject=C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
    subject=O = "Cybertrust, Inc", CN = Cybertrust Global Root
    subject=C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
    subject=C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 EV 2009
    subject=O = Digital Signature Trust Co., CN = DST Root CA X3
    ...
    ...
    ...
    

    And by opening api.push.apple.com in Firefox, we are able to inspect their certificate.

    Apple Certificate Details on Firefox

    Depending on when your browser last updated it's CA Store, the site might or might not show up as secure. We see that the Apple IST CA 2 - G1 certificate was issued by GeoTrust Global CA. Both of these terms return no results when searching the list of trusted CAs in our OS.

    To solve the problem, we can download api-push-apple-com-chain.pem maid available by Firefox, and then use it when making our cURL request as:

    curl --cacert '#{ca_cert}' --http2 -v -d ...

    While this solves our problem and our request succeeds, we can go ahead and try and understand why this issue started appearing. Looking at /etc/ca-certificates.conf we find that several GeoTrust CAs have been marked as not trustworthy. ( Note the bang at the start of line )

    ...
    ...
     !mozilla/GeoTrust_Global_CA.crt
     !mozilla/GeoTrust_Primary_Certification_Authority.crt
     mozilla/GeoTrust_Primary_Certification_Authority_-_G2.crt
     !mozilla/GeoTrust_Primary_Certification_Authority_-_G3.crt
     !mozilla/GeoTrust_Universal_CA.crt
     !mozilla/GeoTrust_Universal_CA_2.crt
    ...
    ...
    

    On some googling, we find this ticket and this wiki.

    In accordance with the consensus proposal that was adopted in 2017, Mozilla began to distrust Symantec (including GeoTrust, RapidSSL, and Thawte) certificates issued before 1-June 2016 starting in Firefox 60, and plans to distrust Symantec certificates regardless of the date of issuance starting in Firefox 64, unless they are issued by whitelisted subordinate CAs that have the following SHA-256 Subject Public Key hashes (subjectPublicKeyInfo):

    It also includes a list of Apple certificates whitelisted:

    c0554bde87a075ec13a61f275983ae023957294b454caf0a9724e3b21b7935bc
    56e98deac006a729afa2ed79f9e419df69f451242596d2aaf284c74a855e352e
    7289c06dedd16b71a7dcca66578572e2e109b11d70ad04c2601b6743bc66d07b
    fae46000d8f7042558541e98acf351279589f83b6d3001c18442e4403d111849
    b5cf82d47ef9823f9aa78f123186c52e8879ea84b0f822c91d83e04279b78fd5
    e24f8e8c2185da2f5e88d4579e817c47bf6eafbc8505f0f960fd5a0df4473ad3
    3174d9092f9531c06026ba489891016b436d5ec02623f9aafe2009ecc3e4d557
    

    which makes it possible for us to open the URLs securely on firefox. ( Not on Firefox Developer Version for some reason )

    TLDR: Use the attached file as --cacert with your cURL command.