I'm trying to use a service that uses a self-signed cert.

  1. Download the cert:

    # printf QUIT | openssl s_client -connect my-server.net:443 -showcerts 2>/dev/null >  my-server.net.crt
  2. Check that it's self signed (issuer and subject are the same):

    # openssl x509 -subject -issuer -noout -in my-server.net.crt
    subject=O = Acme Co, CN = Controller Fake Certificate
    issuer=O = Acme Co, CN = Controller Fake Certificate
  3. Try to use it with curl's --cacert option:

    # curl https://my-server.net  --cacert my-server.net.crt
    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 don't understand why curl cannot verify the cert.

  • 1
    For diagnostics, connecting to your server with your browser will probably give more detailed info about the certificate error than curl does. Aug 16 '18 at 20:03
  • 4
    Is this really a CA certificate, i.e. has it basic constrains CA true? Otherwise it will be ignored by --cacert. Aug 16 '18 at 20:04
  • @SteffenUllrich you're right it has: CA:FALSE Aug 16 '18 at 20:43
  • @SteffenUllrich if you add this as an answer, I'll mark it as the accepted answer. Aug 16 '18 at 21:08
  • 1
    In general s_client -showcerts >file gets the entire chain sent by the server, but x509 -in file displays only the first one while curl --cacert file or s_client -CAfile file would use all of them. However when the leaf cert is selfsigned as here, the server shouldn't be sending any (additional) chain certs. Aug 17 '18 at 3:13

From the comments:

Is this really a CA certificate, i.e. has it basic constrains CA true? ... – Steffen Ullrich
@SteffenUllrich you're right it has: CA:FALSE – little-dude

Signing a certificate requires that the issuer certificate must have the correct flags so that signing is actually allowed. To correctly sign a certificate the issuer certificate need to have the basic constraints CA set to true. This is true both when signing another certificate as for signing the same certificate (i.e. self-signed). It looks like the certificate had not the correct CA:true flag in the case here.

Moreover, the --cacert option is like its name says only for CA certificates and not for arbitrary certificates. For example if you have the leaf-certificates of a site you cannot just add is as trusted with --cacert since it is (usually) not a CA certificate. It will simply be ignored when reading the certificates from the given file.


Two guesses:

1. Is it allowed to do Server authentication?

Check the Extended / Enhanced Key Usage field of your self-signed cert.

Enhanced Key Usage field of a certificate showing Server Authentication

2. Does the server's hostname appear in the CN or SAN fields?

Curl is going to check that the certificate returned by the server matches the hostname you requested (my-server.net).

  • So for the certificate key usages, Firefox lists Not Critical, Signing, Encipherment, and extended key usages: Not Critical, TLS Web Server Authentication. The Alt Names are listed correctly. So I guess that is all good. The reason it's not working with curl is probably because it has CA:FALSE as noted by @SteffenUllrich, then? Aug 16 '18 at 20:47
  • 1
    @little-dude Cool. Out of curiosity, how on earth did you manage to generate a self-signed certificate that's not a CA? That is, by definition, an invalid certificate. Does OpenSSL even let you do that? Aug 16 '18 at 20:57
  • I did not generate it myself, I don't manage that server. I'm going to ask the question and report back :) Aug 16 '18 at 20:59
  • Actually, from the CN (Kubernetes Ingress Controller Fake Certificate which I shortened a bit in my OP), it looks like the cert if generated by some kubernetes component: github.com/kubernetes/ingress-nginx/issues/1984 Aug 16 '18 at 21:03
  • 1
    I still don't know why ingress-nginx controller generates these weird certificates, but I know why it served it to me. The server implements SNI and if I don't specify -servername with openssl, it served me this default cert instead of the "real" one. Aug 17 '18 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.