Most developers understand SSL/TLS — namely, a protocol that enables a client and a server to securely exchange data. However, once you bring up Certificate Authorities, Intermediate CAs, Certificate Chains, Self-Signed Certificate errors and CSR, among others, that understanding often fades away.
If you work for a startup or a small project, chances are you will be doing tasks that are meant for your role and tasks that aren’t. It is very common for companies not to have dedicated DevOps engineers, at which point they might turn to Tech Leads or Solution Architects to set up their infrastructure. If you are the person that they can continually turn to in order to fix these issues, you have a much better chance of climbing the ladder and improving your position.
Below we will attempt to give you a fuller understanding of TLS and Certificates with the least amount of effort possible.
What Needs to Be Solved
In order to communicate securely with another host, you need to solve two major problems:
- Encryption: You need to be sure that when you send information, even if everybody can see it, only the right eyes can understand it.
- Authentication: You need to be sure you’re talking to the right person. After all, what is the point of encrypting communication between you and an attacker?
For encryption, you will want to start your communication using Asymmetric Encryption. There’s an abundance of material pertaining to this topic so I won’t delve into it. Suffice it to say, in very rough terms, that you have two keys. What one encrypts, the other one decrypts, and vice versa. So that the goal is to keep one of them private and distribute the other. That way, anybody who wants to communicate with you can encrypt data using your public key and only you can decrypt it using its associated private key.
We could go deeper into this explanation, since depending on the protocol, those keys do not necessarily need to have the same length. Therefore, which key is public and which one is private actually matters. But this is tangential to this blog post.
A few months ago I decided to move to a bigger place. The landlord is a very close family friend and he agreed to give me a good price for rent. He’s actually a friend of my father and merely an acquaintance of mine.
As he was moving out to a new house, the housekeeper they had hired had to be let go. So he mentioned that if I were interested in hiring her, she was very trustworthy and responsible. I agreed to hire her and she now works for our family.
Think about what happened here for a moment. A woman I don’t know now enters my house three times a week. Why? Because I trust her. But why do I trust her? Because I trust the landlord (well, not really the landlord — but I trust my dad and he told me the landlord is trustworthy). So you can begin to see a chain of trust forming here. I trust my father, my father trusts the landlord, the landlord trusts the housekeeper. Therefore, I trust the housekeeper.
This is precisely what happens with TLS. Let’s map the people in my story to the proper terminology. My dad is a Root Certificate Authority (Root CA). He doesn’t need to appeal to somebody else for my trust. I trust him a priori. This happens in your server too. Often your web browsers or Operating Systems will come preinstalled with a set of Root CAs, and will trust whatever those CAs (Certificate Authority) trust. For instance, if you have an apple device, here’s the list of trusted certificates pre-installed on your device.
The landlord is an Intermediate CA. I trust him because I trust the Root CA (my dad). Now the landlord can vouch for somebody that I will trust as well.
The Housekeeper is the entity whose identity I’m trying to establish. She will refer me to the landlord and my dad in order to ask for my trust.
A Certificate is the marriage between a Public Key and an Identity. If you take a public key and add information about the person who owns that pair of keys, you get a Certificate.
When your browser visits a website, the website may provide the full chain of certificates effectively saying: I am Facebook, you can know I’m Facebook because DigiCert SHA2 High Assurance Server CA (an intermediate CA) has issued my cert, you can trust DigiCert SHA2 High Assurance Server CA because their Certificate was issued by: DigiCert High Assurance EV Root CA (a Root CA that your browser trusts from factory).
Certificate Chain Errors
Imagine in the example above the landlord is out of the picture. We wouldn’t be able to establish the identity of the housekeeper. This is why it’s important that you present the full chain of certificates when you need to validate a host. In other words, if a link is missing, the rest of the chain is pointless.
A certificate looks like this:
This is what a certificate looks like. This format makes it easy to concatenate the certificates.
Note that a PEM file may contain a complete certificate chain, where the chain starts with the leaf / end certificate of the service, followed by the certificate that signed it, usually up to but not including the trusted root certificate.
Now that you understand the certificate chain’s purpose, you now need to understand how new certificates are formed.
Everything begins with the Root CA’s certificate. In this certificate, the Issuer and the Common Name match (Common Name: the name of the entity for whose the Certificate applies to). In other words, the Root Certificate Authority issues its own Certificate without relying on somebody else.
We now turn to Intermediate CAs. Let’s say the name of your company is MakingSense and you want to become an Intermediate CA. You first need to create a Public/Private Key Pair. Now you’re ready for encryption. The next step is to get the Root CA to say: This Key Pair belongs to Making Sense. In order to do this, you create a Certificate Signing Request.
In a nutshell, you tell a Certificate Authority: here’s my public key and my identity information. Your private key always remains private. Now the CA has to decide whether to issue a Certificate for you. To do that, they could validate your identity in some way. For instance, if you use Let’s Encrypt, they will ask you to place a file in your server with a secret that they will attempt to retrieve (if they can retrieve it, it means you have access to that server, which means you own it). Once the CA verifies your identity, they will create a Certificate for you and sign it using their private key. Great! You’re now an Intermediate CA. You can now issue Certificates for other people.
Note: When you issue a Certificate, you can deny the recipient from issuing more certificates by creating what’s known as a Leaf Certificate.
The process for issuing Leaf Certificates is similar. The Common Name entity will create a CSR with their identity information and a public key. You, as the Intermediate CA, will decide whether to issue them a certificate signed by you or not.
You will encounter the term X.509. This is the name for a standard defining the format of public key certificates — the way the header, fields, etc are structured.
Imagine an undercover cop pulls you over and asks for your license and registration. Imagine you demanded to see their badge to prove that they are in fact cops. As you ask, he turns around and writes in a little piece of paper: “I’m an NYPD cop” and hands that over to you. I hope you wouldn’t trust that. When somebody self asserts their identity, without appealing to a mutually trusted source (in this case whoever issues badges for cops), it makes little sense in terms of verifying they are who they say they are. After all, anybody can just turn around and do that.
This is why your browser complains when you’re using a self-signed certificate. It can still use the public key to encrypt that, but anybody could issue a self-signed certificate, saying “Hey I’m Facebook” or “I’m Google”. So avoid these certificates unless you issued them for local development.
Mutual TLS (mTLS)
Let’s say you want the server to also validate a client. For instance, you have a STAGING or UAT environment and you want only a limited set of users to be able to access it. You have many ways of accomplishing this. One such way is to create your own Root CA and issue certificates to the developers/testers/stakeholders that need access. Then you could configure the Server to require the Client to provide their Certificate and check that it was issued by your private Root CA. For the sake of brevity, I won’t include code showing how to accomplish this.
Understanding a Real Call to Action from Amazon
Just to test that you understand everything we’ve talked about here, let’s review a real email sent from Amazon to AWS customers:
Take a brief moment to make sure you understand what you’re being asked to do. Remember that a Root CA is someone you need to trust a priori. You need to trust a Root Certificate Authority before you can begin accepting TLS handshakes. The way to trust a Root CA is by taking their Certificate and adding it to the list of trusted Certificates. Amazon is asking you to do precisely that. In this case, you need to either add it to your Operating System pool of trusted Certificates or you need to update your application to include that Certificate in its list of trusted authorities.
TLS is a protocol that enables secure communications. I won’t cover its handshake here because this post will become too long, but I will link to resources at the end of this post. Something important to keep in mind is that the TLS link happens before any http traffic, meaning that it is independent of http. You can use TLS for your own custom proprietary protocol. For instance, I’m using TLS with a Go Binary protocol on top for one of my hobby projects.
The TLS handshake changed quite a bit in the 1.3 version so I will be referring you to a resource regarding that at the end of the post.
Beyond this post
There’s a lot we haven’t covered here — the fields in a Certificate, the fact that they can expire, blacklisting Certificates, OpenSSL, cfSSL, how the TLS Handshake works, creating your own intranet CA, etc. We will most likely need a followup post to dive a little further, but this should be enough for you to understand how Certificates Work. If you enjoyed this post and want to learn more about TLS and Certificates, keep an eye out for our followup post for the deep dive!
For a guide to creating your own Root CA using openSSL, you can go here.
For an introduction to the 1.2 TLS handshake, you can go here.
For an introduction to the 1.3 TLS handshake, you can go here and here.