tl;dr If the cert contains some variation of
CA:TRUE, it makes sense to distribute it, if it does not, then there is no benefit to distributing it.
The chain of trust itself can be explained in terms of the certificate structure.
If we start from your server's cert (i.e. the cert you would typically use for apache):
- you server cert is generated by a certificate authority, based on a CSR you provide. That CSR contains your public key, and some other information the CA may or may not be interested in using.
- the CA receives your CSR, and (generally), will create a signed certificate using an intermediate CA. Your certificate will have two public keys: one for the subject (which is the public key extracted from your CSR), and one for the issuing party, which is the CA's intermediate certificate.
- the CA's intermediate certificate is itself a signed certificate (with some special options), where the subject key will be the intermediate CA's public key (which is the same public key as is found in the Issuer Public Key of your server certificate). The signing (or issuing) key will be the CA's root certificate (alternatively, it will be another intermediate).
- the CA's root certificate is (generally) a self-signed certificate. In practice, this means that the Issuer and Subject keys are the same public key.
You can see this by checking certificates in the wild, e.g.:
$ openssl s_client -connect google.com:443 < /dev/null
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = *.google.com
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
The chain of trust this builds can be summarised as (I am starting from the 'bottom' - the Equifax cert):
- the root CA (Equifax) delegates day-to-day activities to an intermediate CA (GeoTrust) and signs a certificate representing this fact (i.e setting CA:TRUE, KeyUsage: keyCertSign). In other words, the root CA 'trusts' the intermediate to issue certificates on its behalf (hopefully after completing a series of mandatory validation steps).
- in this chain, the intermediate (Geotrust) has further delegated to a Google CA (CN=Google Internet Authority G2).
- the delegate (a.k.a the Google intermediate CA) then signs a CSR, which effectively is a document stating that for a given set of names (the CN, and possibly Subject Alternative Names), a private/public key pair is valid/trusted (the trust here coming from the fact they have validated the claim to speak for a given name - in this case, the Google CA has issued a certificate for *.google.com).
Note that (root) CAs are generally self-signed - a CA is trusted generally because it abides by a set of processes and procedures that are felt to ensure it does not issue certificates to people who should not have them. Which is why I can't go out and get myself a certificate saying I am google.
This is therefore a convention of sorts (albeit one backed by formal mechanisms), and if you start your own CA, distributing its root (and intermediate) certificates achieves exactly the same thing as distributing the certs of other CAs does: it makes certificates issued by that CA be accepted as valid (i.e. trustworthy) by the system.
In more practical terms, the trust store (for openSSL) is pretty much a bunch of files with a specific naming convention. See https://www.openssl.org/docs/faq.html#USER5:
When a certificate is verified its root CA must be "trusted" by OpenSSL this typically means that the CA certificate must be placed in a directory or file and the relevant program configured to read it
That directory is /etc/ssl/certs (there are others, such as /etc/pki on RH-likes).
https://superuser.com/questions/437330/how-do-you-add-a-certificate-authority-ca-to-ubuntu#719047 provides some further overview of how one adds a certificate to the store, as does https://askubuntu.com/questions/73287/how-do-i-install-a-root-certificate,
The short version is that update-ca-certificates automates the process, and is the commonly used tool.
The slightly longer version is that certificates need to be stored by hash (e.g. in files named based on the output of
openssl x509 -hash -in cert.pem), so that openSSL can efficiently validate chains.
See https://www.openssl.org/docs/man1.0.2/apps/c_rehash.html for some additional background.
updated to respond to the questions in comments:
The server certificate, in this discussion, is defined as trusted or not based on its chain of trust.
If you think about how (e.g.)
curl https://google.com works, it is a bit easier to understand:
- curl opens a TLS connection to google, which returns a certificate.
- curl looks at that 'end-user' certificate - i.e. the server's certificate, and looks specifically for the issuer.
- if the issuer is 'known' in the trust store, the remainder of the trust chain is validated (i.e. the server certificate issuer's certificate is checked, and if it has an issuer other than itself, that issuer is checked, etc). Only if the full trust chain can be validated is the certificate considered valid.
However, it would absolutely impractical to distribute trust chains if end-user certificates needed to be included.
I don't have any numbers on how many websites are out there, but based on the fact Alexa provide a top 1M, you would assume it is more than 1 million.
Which is sort of the point of a chain of trust: you generally need to have the issuer certificates around, but you do not need the end certificates to be distributed, because they tell you who the issuer is.
And you can verify they aren't lying, because you can check the issuers public key (and the chain of trust that establishes it is the proper key), and validate whether the end-user (i.e. server) certificate was really signed by the private counterpart of the issuer's public key.
So no, you should not distribute the end-user certs, but only the chain of trust - or, in simpler terms: distribute all the certs you generate where the BasicConstraints (legitimately) say something at least CA:TRUE.
Do not distribute anything that does not meet that condition, because it is a waste of your time and disk space - everything that does not say CA:TRUE can be validated against something that does.