Ubuntu – Getting SSL certificate error on valid certificate when accessing via Curl


I have a wildcard SSL certificate which powers *.mysite.com. The site is accessible from all browsers without any problem. There is also a service (on a different server)
with URL: service.mysite.com. Strangely, when I access service.mysite.com using curl I get this:

curl: (60) SSL certificate problem: certificate has expired

On digging further I found that I can indeed access service.mysite.com from a Ubuntu 18.04 server but not from Ubuntu 14.04. That tells me that perhaps my CA bundle is not in order.

So I did this:

curl -vv --cacert mysite.ca-bundle.crt https://service.mysite.com

mysite.ca-bundle.crt is the one I received from the SSL provider. But I still get exactly same error. What am I missing?

Best Answer

  • You didn't provide the actual address of the website, nor the SSL provider's name, nor any other information about the certificate, and basically want us to guess at various possible causes.

    My guess is that your certificate chain ends with "AddTrust External Root" as the topmost CA, and that root certificate just expired several hours ago.

    Sectigo, the certificate's owner, has a diagram of the chain – due to old CA certificates cross-signing new ones, "AddTrust External Root" was basically a higher tier above what would normally be the company's actual root CA. New operating systems would see Sectigo/Comodo's certificates as self-signed root CAs, while old ones would see them as intermediate CAs below AddTrust Root.

    So on old operating systems which only recognize Sectigo via cross-signing by the AddTrust Root CA certificate, as soon as the latter expires, the whole chain is invalid. To fix this, you have to switch to another CA which those systems recognize as a root (check /etc/ssl/certs).

    It could be that those systems do recognize Sectigo as a root CA in its own right. In theory, is completely legal for a certificate to validate through multiple chains, e.g. a CA can simultaneously be a root and be cross-signed by another CA.

    But in practice, many TLS client libraries are really bad at building alternate chains and assume there's always exactly one way to validate a certificate. (Windows is a bit better, and the big web browsers also include code to handle this extra complexity on top of what the TLS library would probide.)

    For example, older versions of OpenSSL were very strict about which certificates could act as trust roots. If the server sent a chain "OldCA–NewCA–Intermediate–MyServer", OpenSSL 1.0 would only accept if you had "OldCA" as a trusted certificate – but it wouldn't be smart enough to accept it if you had "NewCA" instead.

    So if Ubuntu 14.04 already recognizes Sectigo as a certificate authority, then you need to fix the certificate chain that is being sent by your webserver – I suspect removing the certificate which says "Issuer: AddTrust" should be enough.

    Let's say the old certificate chain looks like this:

    [AddTrust External Root]                               [included in OS]
    +-- USERTrust RSA Certification Authority (Sectigo)    sent by your server
        +-- Gandi Standard SSL CA 2                        sent by your server
            +-- git.kernel.org                             sent by your server

    You need to edit it so that your server stops sending the cross-signed USERTrust certificate:

    [USERTrust RSA Certification Authority (Sectigo)]      [included in OS]
    +-- Gandi Standard SSL CA 2                            sent by your server
        +-- git.kernel.org                                 sent by your server

    You can also fix this on the client side, by removing the AddTrust root CA.

  • Related Question