L0070 Certification Chain
A certificate chain is a sequence of digital certificates where each certificate is signed by the previous certificate in the chain. That allows a client to verify that a server's certificate is trustworthy, by tracing it back to a root CA. | ![]() |
This structure doesn't have to be linear, it can have a shape of a tree.
Creation of a Certification Chain
We will make our own certificate chain. We will create three certificates, just like on the image above.
Root Certificate
| I will create root private key. This is RSA private key. | cd /home/fff/Desktop |
| We will use the CA private key to generate CSR file. We will add one extension. Extensions are those special elements in a certificate. The name of extension is "basicConstraints". Here we say whether the private key can be used to sign other keys. For root and intermediate certificates, we must set this setting to true ( CA:TRUE ). For leaf certificates it will be FALSE. critical – this is severity of our setting. Possible values are critical and non-critical. Default is non-critical. If the setting is critical then a client must obey that setting. If a client doesn't understand the critical setting, then it must reject connection. For "basicConstraints" extension we must always use critical. |
openssl req -new -subj "/CN=Root CA" -addext "basicConstraints=critical,CA:TRUE" -key RootCA.key -out RootCSR.csr |
Inside of the CSR file, we can see our extension. openssl req -in RootCSR.csr -noout -text | ![]() |
CA will sign its own key. "RootCSR.csr" will be signed by "RootCA.key". The result is certificate "RootCert.crt". openssl x509 -req -in RootCSR.csr -copy_extensions copyall -key RootCA.key -days 365 -out RootCert.crt |
![]() | openssl x509 -in RootCert.crt -noout -text Issuer and Subject of the self signed certificate are the same. Validity of this certificate is 365 days. |
![]() | By default, extensions will not be copied from the CSR file to the certificate. We need to use the option "-copy_extensions copyall" to make that happen. |
Intermediate Certificate
| We will create elliptic private key for intermediate certificate. | openssl genpkey -algorithm ED448 -out Intermediate.key |
| After that, we will create intermediate certificate signing request, based on that key. |
openssl req -new -subj "/CN=Intermediate CA" -addext "basicConstraints=critical,CA:TRUE" -key Intermediate.key -out Intermediate.csr |
| The next step is to sign CSR file. For signing process we must provide both root private key and root certificate. Private key is used for encryption, but certificate is used for information. Data about root CA will be copied from root CA certificate into intermediate certificate. |
openssl x509 -req -in Intermediate.csr -copy_extensions copyall -CAkey RootCA.key -CA RootCert.crt -days 365 -out Intermediate.crt |
Intermediate certificate is issued by "Root CA" to "Intermediate CA". openssl x509 -in Intermediate.crt -noout -text | ![]() |
Leaf Certificate
The last piece of the puzzle is leaf certificate. No matter the certificate, we always follow the same steps.
| We will generate elliptic leaf key. | openssl genpkey -algorithm ED448 -out LeafKey.key |
Based on the private key, we will create CSR file. "basicConstraint" is set to FALSE for the leaf CSR. |
openssl req -new -subj "/CN=Leaf" -addext "basicConstraints=critical,CA:FALSE" -key LeafKey.key -out LeafCSR.csr |
| We will use intermediate key to sign leaf CSR file. We will transfer Issuer data from intermediate certificate to leaf certificate. |
openssl x509 -req -in LeafCSR.csr -copy_extensions copyall -CAkey Intermediate.key -CA Intermediate.crt -days 365 -out LeafCert.crt |
The leaf certificate is issued by "Intermediate CA". "basicConstraint" is set to FALSE. openssl x509 -in LeafCert.crt -noout -text | ![]() |
| As a result, we ended up with 9 files. The CSR files can be deleted, but we will still have 6 other files. Key proliferation is something we need to take seriously. In large organizations, the number of keys can grow dramatically, and this requires meticulous key management. |
![]() |
Certificate Verification
This is how we can verify certificate chain. We have trust in the root certificate, but not into intermediate certificate. Because, this is a chain of certificates, we only need one certificate we trust. openssl verify -verbose -show_chain -trusted RootCert.crt -untrusted Intermediate.crt LeafCert.crt | ![]() |
We can also use option "-CAfile" to designate the root certificate. openssl verify -show_chain -CAfile RootCert.crt -untrusted Intermediate.crt LeafCert.crt | We would get the same result. |
Certification Chain with Long Commands
Root CA
| We can run this long command to get self signed root certificate. |
openssl req -new -newkey rsa:2048 -noenc -keyout RootCA.key -x509 -subj "/CN=Root CA" -addext "basicConstraints=critical,CA:TRUE" -days 365 -out RootCert.crt |
Intermediate Level
| This command will create private key and CSR for intermediate level. |
openssl req -new -newkey ED448 -noenc -keyout Intermediate.key -subj "/CN=Intermediate CA" -addext "basicConstraints=critical,CA:TRUE" -out Intermediate.csr |
| We will sign the CSR, to get intermediate certificate. |
openssl x509 -req -in Intermediate.csr -copy_extensions copyall -CAkey RootCA.key -CA RootCert.crt -days 365 -out Intermediate.crt |
Leaf Level
| We will repeat the same steps as from intermediate level, to create a key and CSR for leaf level. First, we will get private key and CSR file. |
openssl req -newkey ED448 -noenc -keyout LeafKey.key -subj "/CN=Leaf" -addext "basicConstraints=critical,CA:FALSE" -out LeafCSR.csr |
| The last step is to sign leaf CSR file, and to get leaf certificate. |
openssl x509 -req -in LeafCSR.csr -copy_extensions copyall -CA Intermediate.crt -CAkey Intermediate.key -days 365 -out LeafCert.crt |
Usage of a Chain
| We will test chain of certificates with an OpenSSL server. We will start the server, and we will provide private key and certificate of the leaf. We must also provide an intermediate certificate. |
openssl s_server -port 4433 -key LeafKey.key -cert LeafCert.crt -cert_chain Intermediate.crt |
| On the side of the client, we will provide certificate of the root. | openssl s_client -connect localhost:4433 -CAfile RootCert.crt |
| The client is waiting to communicate with the server using the root certificate. The client only needs that certificate to authenticate the server. The server needs to prove its identity, and to do that, it needs the entire chain. That's why the server has both a leaf and an intermediate certificate. The server will send both certificates to the client. The client will then have all three chained certificates. The client trusts the root CA certificate, and because of that, it will trust the intermediate and leaf certificates. That's how a certificate chain works. |
![]() |
![]() | Client and server can now have their protected conversation. |
Why do We Need Certificate Chains?
![]() | If we look at the certificate chain for the Facebook website, we see at the top the DigiCert certificate. Below that is the intermediate certificate, also from DigiCert. At the bottom is Facebook. The purpose of certificate chains is to reduce the risk of a CA's private key being compromised. The CA will use its private key to sign a number of intermediate keys. These intermediate keys will be used to sign user certificates. The root key will be hidden, where no one can find or access it. No one will be able to steal the root private key, but the CA will still be able to sign user certificates normally. If the intermediate private key is compromised, it will only affect some users and will not destroy the CA's business. Certificate chains are a solution for CAs to protect themselves and their users. |
Where Does Root Certificates Come From?
When we browse the Internet, we use TLS. When we download some programs to our computer, the program installation files are signed using asymmetric keys. The question is how we can trust web sites and downloaded files if we have never downloaded a certificate from a certification authority.
The answer is that these CA certificates are already on our computer. Trusted root certificates are already determined by the platform creator. A platform can be an operating system, a web browser, a web server, a VPN server. When we install Ubuntu, we will get all the root certificates that Ubuntu trusts. When we install a web browser, that web browser will have many certificates in it. When we trust some servers or some websites, it is because Ubuntu and Chrome already have pre-installed certificates that provide trust to those servers/sites.
Ubuntu has its certificate store on this location: /etc/ssl/certs Inside of this folder we can see many certificates in PEM file format. | ![]() | ![]() Content of one PEM file. |
I have Brave browser installed. Its certificates are at the location "~/.local/share/pki/nssdb". |
| When we connect to some server, the server will send us certificate chain ( without the root certificate ). We will then search our local certificate store to find CA certificate that is valid for that certificate chain. Because we trust CA certificates from the local repository, then we will able to trust other certificates in the certificate chain. | ![]() |































































We will get 4 "BEGIN/END CERTIFICATE" elements =>










