<aside> 🧭
Module 03 · Inside an X.509 Certificate
In Module 01 you pulled a real certificate off the internet and read four lines of it. This module reads all of it — every field, every extension, including the ones you have been skipping past because they looked like noise. By the end you will be able to look at any certificate and say what it is for, what it is allowed to do, and whether it is the right one.
🧠 concept → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (answers hidden)
Prerequisite: Modules 01 and 02. You need the digital signature idea from Module 01 (Part B5), the passport analogy from Module 01 (C2), and DER/ASN.1 plus openssl asn1parse from Module 02 (Part B1).
</aside>
<aside> 🛂
The picture to hold in your head for this whole module — the passport, opened.
In Module 01 you learned what a passport is: a document holding your photo and name, stamped by a government the border officer already trusts.
This module opens the passport and reads every page.
The photo page. The passport number. The expiry date. The issuing office. And then the pages at the back — the visas, the endorsements, the stamps that say where this document is valid and what it entitles you to do.
Those back pages are the extensions, and they are where almost all of the real behaviour lives. Most people never read them. That is exactly why reading them is worth something in an interview.
</aside>
<aside> 🖥️
Set up a working directory for this module before you start.
mkdir -p ~/tls-lab/m03 && cd ~/tls-lab/m03
umask 077
# A live certificate from the internet (you saved one in Module 01, but grab a fresh one)
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -out live.pem
# A root CA certificate from your own trust store - stable, offline, never changes
cp /etc/ssl/certs/ISRG_Root_X1.pem root.pem 2>/dev/null \
|| cp /etc/ssl/certs/DigiCert_Global_Root_CA.pem root.pem 2>/dev/null \
|| ls /etc/ssl/certs/*.pem | head -5
ls -l live.pem root.pem
The live certificate shows you what a real server certificate looks like. The root certificate never changes, works offline, and is the best thing to compare against — because a root and a leaf differ in almost every interesting field.
On macOS or a distro without /etc/ssl/certs/*.pem, pick any file from ls /etc/ssl/certs/ — any root will do.
</aside>
<aside> 📖
Official docs: RFC 5280 §4.1 — Basic Certificate Fields · openssl x509 manual · openssl asn1parse manual
</aside>
<aside> ✍️
The analogy — a signed contract.
Pick up a signed contract and you are holding three separate things, even though it looks like one document:
The signature covers part 1 only. It has to — a signature cannot cover itself.
An X.509 certificate has exactly this shape, and knowing it explains something that otherwise looks strange: the certificate names its signature algorithm twice, once inside the signed part and once outside it.
</aside>
The three parts have proper names, and you will see them in error messages:
| Part | What it holds | Contract analogy |
|---|---|---|
| tbsCertificate | Everything meaningful — version, serial, issuer, subject, validity, public key, all extensions. "tbs" means to be signed | The text of the agreement |
| signatureAlgorithm | Which algorithm the issuer used to sign, e.g. sha256WithRSAEncryption |
"Signed in black ink" |
| signatureValue | The signature itself — a blob of bytes produced by the issuer's private key | The signature at the bottom |
flowchart TD
C["📜 Certificate<br>one file, three parts"]
C --> T["1️⃣ tbsCertificate<br>version, serial, issuer, subject,<br>validity, public key, extensions"]
C --> A["2️⃣ signatureAlgorithm<br>which algorithm was used"]
C --> S["3️⃣ signatureValue<br>the signature bytes"]
T -->|"hashed, then signed with<br>the ISSUER private key"| S
style T fill:#d5e8d4,stroke:#82b366,stroke-width:2px
style S fill:#ffe6cc,stroke:#d79b00,stroke-width:2px
<aside> 🔑
The single most important sentence in this module: the signature is made with the issuer's private key, not the subject's.
Your certificate is signed by the CA. Your own private key is never used to sign your own certificate — that would prove nothing, exactly like signing your own passport. This is why you can hand your certificate to anyone: it contains no secret of yours, and you could not have forged it yourself.
</aside>
🧪 Exercise A1.1 — See the three parts with your own eyes
cd ~/tls-lab/m03
# The top-level structure only
openssl asn1parse -in live.pem | head -6
echo "--- and the very end of the file ---"
openssl asn1parse -in live.pem | tail -3
🧪 Exercise A1.2 — Find the algorithm named twice, and understand why
cd ~/tls-lab/m03
openssl x509 -in live.pem -noout -text | grep -n -i 'signature algorithm'