I have created my own CA:

openssl genrsa -out private/rootCA.key 2048
openssl req -batch -new -x509 -nodes -key private/rootCA.key -sha256 -days 1024 -config ./openssl.conf -out certs/rootCA.pem

I have created a certificate for my site:

openssl genrsa -out private/$domain.key 2048
openssl req -batch -new -key private/$domain.key -config ./openssl.conf -subj "/commonName=$domain" -out csr/$domain.csr
openssl x509 -req -in csr/$domain.csr -CA certs/rootCA.pem -CAkey private/rootCA.key -CAcreateserial -out certs/$domain.crt -days 500 -sha256

I join the site cert and the root cert into a bundle:

cat certs/$domain.crt certs/rootCA.pem > bundles/$domain.bundle.crt

I copy the cert / key to the nginx config dir:

cp bundles/$domain.bundle.crt private/$domain.key /etc/nginx/conf/certs

I make sure that nginx uses those certs for my site:

    ssl_certificate /etc/nginx/certs/mysite.bundle.crt;
    ssl_certificate_key /etc/nginx/certs/mysite.key;

I restart nginx.

I install the root cert in my system:

sudo cp certs/rootCA.pem /usr/local/share/ca-certificates/myrootCA.crt
sudo update-ca-certificates

I verify with httpie:

» http https://mysite

http: error: SSLError: HTTPSConnectionPool(host='mysite', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),))

I verify with openssl (telling it to use the ca-certificates dir, which is not used by default it seems):

openssl s_client -host mysite -port 443 -prexit -showcerts -CApath /usr/local/share/ca-certificates

Which gives:

Verify return code: 19 (self signed certificate in certificate chain)

And verification does not complete.

Opening the site in Chrome gives me the standard error:

This server could not prove that it is mysite; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.

I have two questions:

  1. Why is the site not trusted, system-wide, after installing the root cert? Chrome is using system-wide cerficates, right?
  2. Why is open_ssl s_client not able to complete the cert validation?


Curl is working, with the system-wide installed cert:

curl https://mysite

Why is curl working and chrome/httpie not?

  • Well does your cert actually contain the hostname registry.dgvmetro? Did you verify that your root cert contains the v3_ca extension or similar? – Seth Mar 19 '18 at 10:20
  • Stop self signed certificate, use let's encrypt – Gilles Quenot Mar 19 '18 at 11:31
  • @GillesQuenot There is absolutely nothing wrong with self-signed certificates. Bottom line, Let’s Encrypt certificates, are basically self-signed certificates anyways but the root authority is trusted by all browsers. – Ramhound Mar 20 '18 at 0:46

For OpenSSL Ubuntu update-ca-certificates as described on its man page reads from /usr/share/ca-certificates AND /usr/local/share/ca-certificates but writes symlinks with the subjhash.num names needed by OpenSSL to /etc/ssl/certs and a combined file in /etc/ssl/certs/ca-certificates.crt so the latter two should be used with -CApath and/or -CAfile respectively.

curl apparently uses the OpenSSL default, which in this build is /etc/ssl/certs/, but depending on which Ubuntu, OpenSSL may be old enough to have the bug that commandline s_client does NOT use the default automatically.

For Chrome I can't help; I don't use Chrome on Ubuntu. Left CW in case someone else can.

Although I do know once you get the CA trusted, recent Chrome also requires your server cert (in PKI terms, End Entity = EE = not CA) have a SAN extension (SubjectAlternateNames) with the correct name(s), which neither of the others do (for now), and you don't indicate if/how you did that. (expanded:) rfc 2818 for HTTPS and the CABforum standards have for over a decade required server certs to contain valid SAN, and by now all or nearly all clients use SAN when present, but to my knowledge so far Chrome is the only client that requires SAN be present.


It seems my self-generated root CA was wrong. It was missing:

basicConstraints               = CA:TRUE

After solving this, httpie is behaving properly. It is strange that curl was not complaining about this.

This is not yet solving the problem in Chrome though ... I assume that Chrome does not use system-wide CAs.

  • Chrome generally should use the platform's truststore -- but not necessarily the PEM-format one. (I use it on Windows and there it definitely does use the Windows store. That's why I left that part of my answer open.) – dave_thompson_085 Mar 20 '18 at 0:40
  • “I assume that Chrome does not use system-wide CAs.” - You would be mistaken. Chrome trusts the OS and/or user’s certificate store. Since you solved your original problem, might consider removing your additional question, and submitting a different question to get the answer to it. Be sure to isolate the information, we don’t need everything, we needed for the original problem – Ramhound Mar 20 '18 at 0:47
  • @Ramhound yessir! – blueFast Mar 20 '18 at 14:57

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.