Trusting your own Certificate Authority

Updated at by

Tips on getting your own CA work with various programs and utilities. The CA certificate resides in /opt/my-first-ca/my-first-ca.crt (PEM format) in the following examples.

Operating system CA installation on CentOS 7 and Debian/Ubuntu

I'll refer this as the OS level installation in later steps. This usually covers getting the your to CA work with most tools and software available from official repositories.

For example curl burps out an error message when the CA cannot be recognized.

curl: (60) Peer's Certificate issuer is not recognized.

And wget output

ERROR: cannot verify hurr-durr.my-tld's certificate, issued by ‘/C=XX/ST=Muh State/L=Muh City/O=Muh Org/CN=My First CA’:
  Unable to locally verify the issuer's authority.

On CentOS 7

cp /opt/my-first-ca/my-first-ca.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust extract

On Debian/Ubuntu flavors

cp /opt/my-first-ca/my-first-ca.crt /usr/local/share/ca-certificates/
update-ca-certificates

Java

When java bounces into unknown CA you might see something like this:

<surrounding square meter of stack trace>
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
</stack trace>

For recent Debian/Ubuntu and CentOS distributions the OS level installation above also updates the java keystore.

But as some applications are shipped "standalone" bundled with it's very own JVM means it usually ignores CAs installed on OS level. Combined with inability to add CAs in the software might require you to find the keystore and add your CA to it manually by using keytool.

cd /opt/some-standalone-java-app/
# Find the cacerts file
find . -name 'cacerts'
> ./jre64/lib/security/cacerts

# import your CA into the cacerts, default password is 'changeit'
keytool -import -trustcacerts -keystore ./jre64/lib/security/cacerts -alias "My First CA" -file /opt/my-first-ca/my-first-ca.crt

# Or if you don't have JVM installed, use the keytool provided by the software
./jre64/bin/keytool -import -trustcacerts -keystore ./jre64/lib/security/cacerts -alias "My First CA" -file /opt/my-first-ca/my-first-ca.crt

NodeJS from nodesource repositories on CentOS 7

Nodejs smashing itself against unknown CA.

{ Error: unable to verify the first certificate
at TLSSocket.<anonymous> (_tls_wrap.js:1103:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket._finishInit (_tls_wrap.js:637:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:467:38) code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' }

Version 8.9.4 (at the time of writing) of nodejs ships with it's very own CAs but you can specify NODE_EXTRA_CA_CERTS environment variable to pass a file containing additional certificates. Using the ca bundle file created by the OS level installation causes a duplicate entry warning as node's own and OS ca-bundles are partially same so I'll specify the single extra CA for the env variable.

NODE_EXTRA_CA_CERTS=/opt/my-first-ca/my-first-ca.crt node my-application.js
or
NODE_EXTRA_CA_CERTS=/opt/my-first-ca/my-first-ca.crt npm install smallest

Firefox

Another application which ships with it's own CAs. Firefox has settings for CAs but you can also manipulate the nss database with certutil which is supplied by nss-tools on CentOS and libnss3-tools on Debian.

# Find the NSS database from the depths of .mozilla directory
find ~/.mozilla -name 'cert8.db'
> .mozilla/firefox/7rbrb6cb.default/cert8.db

# Add your certificate as CA with trust args "C,," meaning the CA is used for validating SSL/TLS but not for email or object signing (software).
certutil -A -n "My First CA" -d ~/.mozilla/firefox/7rbrb6cb.default -t C,, -a -i /opt/my-first-ca/my-first-ca.crt

Chromium / Chrome on Ubuntu

Chrome doesn't use the OS installed CAs but rather ships with it's own CAs and adds certificates found in ~/.pki/nssdb on top of them. Use GUI or certutil in your home directory.

certutil -A -n "My First CA" -d .pki/nssdb -t C,, -a -i /opt/my-first-ca/my-first-ca.crt
> certutil: function failed: SEC_ERROR_LEGACY_DATABASE: The certificate/key database is in an old, unsupported format.

# Error above indicates the NSS database is in SQLite format so the -d switch has to be prefixed with "sql:"
certutil -A -n "My First CA" -d sql:.pki/nssdb -t C,, -a -i /opt/my-first-ca/my-first-ca.crt

Docker alpine

A simple Dockerfile with CA installation. curl is installed for testing purposes.

FROM alpine:latest
RUN apk add --update --no-cache ca-certificates curl
COPY my-first-ca.crt /usr/local/share/ca-certificates/my-first-ca.crt
RUN update-ca-certificates
RUN curl https://site-signed-with-my-own-ca.herpderp.my-own-tld

Share on FacebookShare on Facebook Share on TwitterShare on Twitter

Leave a comment