Module 14 — Full Interview Simulation
Updated 28 August 2026
This module teaches nothing new. Everything in it comes from Modules 01–13.
It exists because knowing this material and being able to say it are different skills, and only one of them gets you the job. You can read an answer and feel it land; then somebody asks you the question, out loud, and thirty seconds of silence goes by. This module is where you find that out — while it is still cheap.
🧠 concept → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (answers hidden)
Prerequisite: Modules 01–13, and ideally the twelve self-assessment questions at the end of each one, attempted out loud.
A cast can know every line perfectly and still fall apart on opening night. That is why the dress rehearsal exists: same stage, same costumes, same running order, nobody watching. It is not about learning the lines. It is about finding out which lines you only think you know, in a room where forgetting one costs nothing.
That is this module. The questions are ones you have already met. The difference is that this time you say the answer before you read it — and the gap between those two experiences is the entire point.
mkdir -p ~/tls-lab/m14/logs && cd ~/tls-lab/m14You will need nginx and, for one optional comparison, Go. Skip the Go part if you do not have it — the output is shown.
To stop everything and clean up:
nginx -s stop -c ~/tls-lab/m14/nginx.conf 2>/dev/null
rm -rf ~/tls-lab/m14All output in this module was produced on OpenSSL 3.0.13, nginx 1.24.0, curl 8.5.0, Python 3.12 and Go 1.22.
Part A · How the interview actually runs
A1 · The four rounds, and what each is really testing
The examiner is not checking whether you can operate a clutch. They are checking whether you check your mirrors when nobody is looking, whether you slow down before you can see round the bend, and what you do when something unexpected happens.
A TLS interview is the same. The questions are about certificates. What is being measured is how you think when you do not know the answer, and whether your instincts are safe ones.
Almost every technical interview on this subject runs in the same four phases, in the same order, and each is measuring something different:
| Round | What it looks like | What is actually being measured |
|---|---|---|
| 1 · Rapid-fire | Ten to twenty short questions, thirty seconds each | Do you have the vocabulary? Nobody hires on this round — but a wrong answer here colours everything after it |
| 2 · Live troubleshooting | "Here is an error message. Talk me through it." | How do you think under pressure? They want your order of operations, not the answer |
| 3 · Design and judgement | "How would you handle certificates for 500 services?" | Do you know the trade-offs? There is no right answer. There are wrong ones, and there is no-answer |
| 4 · The deep follow-up | "You said X. Why?" — three or four levels down | Where is the edge of what you know? And crucially: what do you do when you reach it? |
The follow-ups are not an attack. Every candidate gets pushed until they run out of knowledge — that is the point of them. The interviewer is finding the boundary, and then watching what happens at it.
There are two things you can do when you hit that edge. One is to keep talking, generating plausible-sounding sentences. The other is to say "I don't know — here's how I'd find out" and then actually describe how.
The second one scores far higher, and it is not close. A senior engineer who bluffs is dangerous; a junior one who says "I'd check the RFC and test it" is trainable. If you take one thing from this module, take that.
A2 · The shape of a strong answer
A detective novel saves the answer for the last page. A news story puts it in the first sentence and adds detail underneath, so that a reader who stops after one line still knows what happened.
Answer like a news story. Give the conclusion first, then the mechanism, then the detail. An interviewer who has heard enough can move on — and one who wants more will ask.
Every model answer in Modules 01–13 was written in the same three-part shape, deliberately. It is worth naming it, because you can reproduce it under pressure:
| Part | What goes in it |
|---|---|
| 1. The answer | One or two sentences. Directly responsive. No preamble — not "that's a great question", not "so basically" |
| 2. The mechanism | Why it is that way. This is where you show you understand rather than remember |
| 3. The detail that separates | One operational fact, gotcha or trade-off that only someone who has done it would know |
Here is the same question answered three ways. The difference is not knowledge — it is structure.
Everything here is true. It is a list of facts in the order they occurred to him, and it answers a question nobody asked. There is no claim, so there is nothing to follow up on — which means the interviewer has to do the work of finding the next question.
Correct, well-ordered, and complete. This is a perfectly good answer and it is also every other candidate's answer. Nothing in it distinguishes reading from doing.
The detail that matters operationally is that trust is the union of every CA in that store, not the intersection. Around 150 roots, about 70 organisations — and any one of them can issue for your domain and every browser will accept it. That's the whole reason CT and CAA exist, and it's why 'is this certificate valid' and 'should this certificate exist' are completely different questions."
Same facts. It ends on a claim the interviewer will want to pull on, which means you have chosen the next question rather than waiting for it.
Filler openings. "That's a great question", "so, basically", "essentially". They buy two seconds and cost credibility. Silence is better — a pause reads as thinking.
Answering a bigger question than the one asked. Asked about SNI, do not deliver the whole handshake. It reads as evasion even when it is enthusiasm.
Certainty about things that change. Say "as of the last time I checked" about lifetimes, ballots and browser policy. Anyone who states 2019 facts flatly in 2026 has stopped reading.
Never saying "I don't know". Covered above, and worth repeating: it is the highest-value sentence available to you, provided it is followed by how you would find out.
A3 · Find out what you actually know
Re-reading a chapter feels productive and barely works. The brain recognises the material and reports "I know this", which is a completely different sensation from being able to produce it.
Retrieval — pulling the answer out of an empty head — is what actually builds recall, and it feels much worse. That discomfort is the work happening.
So this exercise is deliberately uncomfortable: the answer is hidden until you have said yours out loud. Saying it in your head does not count and you will be tempted to let it.
🧪 Exercise A3.1 — Twenty questions, out loud, timed
Save as ~/tls-lab/m14/drill.py and run it before you read Part B:
#!/usr/bin/env python3
"""drill.py - rapid-fire self-test. Say the answer OUT LOUD, then press Enter."""
import random, sys, time
Q = [
("What does a certificate actually bind together?",
"A public key to an identity, signed by a CA. Nothing else."),
("Why can't RSA be used to encrypt a whole HTTP response?",
"It can only encrypt less than the key size, and it is thousands of times slower than AES. It moves a small secret; AES moves the data."),
("PEM vs DER?",
"DER is the binary encoding. PEM is DER base64-encoded with -----BEGIN----- headers. Same bytes, different clothing."),
("What is in a CSR, and what is not?",
"Public key, subject, requested extensions, self-signed to prove key possession. NOT the private key, and NOT the validity dates."),
("Why must a certificate have a SAN, when it has a CN?",
"RFC 9525: the CN must not be used to identify a service. Browsers and Go reject CN-only certs; OpenSSL, curl and Python still accept them via legacy fallback."),
("What does basicConstraints CA:TRUE do?",
"Marks the certificate as allowed to sign other certificates. Without it, a leaf cannot be a CA - which is what stopped the 2008-era attacks."),
("Which order do certificates go in fullchain.pem?",
"Leaf first, then each intermediate upward. Never the root."),
("What does the client do with the root certificate the server sent?",
"Ignores it. It must already have the root locally or the chain is worthless. Sending it wastes bytes."),
("TLS 1.3 handshake in one sentence?",
"One round trip: the client guesses the key-share, the server picks it and everything after ServerHello is encrypted."),
("What is forward secrecy and what provides it?",
"Ephemeral key exchange - ECDHE. The session key is never derivable from the server's long-term key, so recorded traffic stays safe if the key later leaks."),
("Verify code 20 vs 21?",
"20: YOUR trust store lacks the issuer. 21: THEY did not send the intermediate. Same symptom, opposite fix."),
("Verify code 18 vs 19?",
"18: the leaf is self-signed. 19: a self-signed cert appears IN the chain - usually the server wrongly sending the root, on a machine that lacks that root."),
("Why is public revocation broken?",
"Soft-fail. Browsers cannot reach the responder reliably, so they ignore failures - which means an attacker who blocks the check wins."),
("What replaced OCSP in practice?",
"Short lifetimes. Plus CRLite and CRLSets, which push the checking out of the connection path."),
("What is an ACME challenge proving?",
"Control of the domain - nothing about who you are. That is why DV is domain-validated and says nothing about the organisation."),
("What does an SCT prove?",
"That a log SIGNED A PROMISE to publish the certificate. Not that it is published. The browser checks only the signature."),
("What does a CAA record do?",
"Tells CAs which of them may issue for your domain. Enforced by CA policy, not by clients. Costs one DNS record."),
("In mTLS, which message is the actual proof of identity?",
"CertificateVerify - a signature over the handshake made with the client's private key. The certificate alone is public and proves nothing."),
("Does mTLS give you authorisation?",
"No. Every certificate your trusted CA ever issued gets in. Authorisation is a separate thing you must write."),
("First command when someone says the site's SSL is broken?",
"One curl, and read the sentence. Not -k, which disables the failing check and always succeeds."),
]
def run(n=20):
qs = random.sample(Q, min(n, len(Q)))
start = time.time(); wrong = []
for i, (q, a) in enumerate(qs, 1):
print(f"\n[{i}/{len(qs)}] {q}")
input(" ...say it out loud, then press Enter ")
print(f" -> {a}")
if input(" did you get it? [y/N] ").strip().lower() != "y":
wrong.append(q)
mins = (time.time() - start) / 60
print(f"\n{'='*60}")
print(f"score {len(qs)-len(wrong)}/{len(qs)} time {mins:.1f} min "
f"({mins*60/len(qs):.0f}s per question)")
if wrong:
print("\nrevise these:")
for w in wrong: print(" -", w)
else:
print("\nnothing to revise. Move on to Part C.")
if __name__ == "__main__":
run(int(sys.argv[1]) if len(sys.argv) > 1 else 20)python3 ~/tls-lab/m14/drill.py✅ Expected result — click to reveal
[1/20] What does an SCT prove?
...say it out loud, then press Enter
-> That a log SIGNED A PROMISE to publish the certificate. Not that it
is published. The browser checks only the signature.
did you get it? [y/N] y
[2/20] Which order do certificates go in fullchain.pem?
...say it out loud, then press Enter
-> Leaf first, then each intermediate upward. Never the root.
did you get it? [y/N] n
...
============================================================
score 16/20 time 8.4 min (25s per question)
revise these:
- Which order do certificates go in fullchain.pem?
- Verify code 18 vs 19?
- What replaced OCSP in practice?
- What is an ACME challenge proving?What to read out of this — the score matters less than the two numbers beside it.
- Under 25 seconds per question is the target. Round 1 questions are answered in a sentence or two. If you are taking a minute, you know the material but have not rehearsed it, and that reads in a room as uncertainty rather than depth.
- Anything below about 16/20 means go back before continuing. Not because the score matters, but because Part C assumes this vocabulary is automatic — you cannot troubleshoot while also trying to remember what an intermediate is.
- The revise list is the actual output. Each of those maps to a specific module. Go and re-read that one section, then run the drill again tomorrow rather than immediately.
🔑 Run it again in two days, not in ten minutes. Immediately re-testing gives you a flattering score and teaches you almost nothing, because the answers are still in short-term memory. Spacing is what makes retrieval stick, and two or three passes across a week beats an afternoon of cramming by a wide margin.
💡 The "say it out loud" instruction is not padding. Saying an answer in your head skips the hardest part — turning a mental shape into an ordered sentence — which is precisely the part that fails in an interview. Speaking, even quietly, to an empty room, is the whole exercise. It feels ridiculous. Do it anyway.
🎯 Interview questions — About the interview itself
Q. What do you say when you genuinely do not know the answer?
Say so, immediately and without apology, and then say how you would find out. "I don't know that off the top of my head. I'd check RFC 5280 for the extension semantics, and honestly I'd test it — build the certificate and see what OpenSSL and a browser each do with it, because they don't always agree."
That is a complete answer. It ends the topic cleanly and it demonstrates something the question itself could not.
The detail worth adding: understand what is being tested. Every candidate gets pushed until they run out of knowledge — that is the purpose of the follow-ups, not a sign the interview is going badly. What varies is what happens at the edge. Bluffing is the single most damaging thing you can do, because an engineer who generates confident-sounding wrong answers is a liability in an incident, and interviewers are specifically watching for it. Saying "I don't know" costs one question. Being caught bluffing costs the interview.
Q. How do you keep up with a subject that changes this fast?
Name your actual sources. The CA/Browser Forum ballots for what is coming, the Chrome Root Program and Mozilla root store policies for what browsers will enforce, the Let's Encrypt blog for what the largest CA is doing in practice, and the ct-policy and dev-security-policy mailing lists for the arguments before they become rules.
And say what changed recently, concretely: certificate lifetimes falling towards 47 days, OCSP being retired, multi-perspective validation becoming mandatory, the move to static CT logs.
The detail worth adding: the framing that lands is that in this field the facts have a shelf life, so the skill is knowing where the current answer lives rather than memorising it. Then demonstrate the habit in the interview itself — say "as of the last time I checked" about anything policy-related. Someone who states a 2019 fact flatly in 2026 has told you exactly when they stopped reading, and interviewers notice it immediately.
Part B · Round 1 — Rapid-fire fundamentals
B1 · Thirty seconds each, no notes
Nobody wins a tennis match during the knock-up. But a player who sprays balls into the net for five minutes has told their opponent something, and it will affect how the match is played.
Round 1 is the knock-up. You cannot win the interview here, and you can absolutely lose it. Fumbling "what is a CSR" means every later answer is heard slightly more sceptically — and the questions are so predictable that fumbling one is entirely avoidable.
These are the questions that come up again and again, grouped by where they come from in the track. Say each answer out loud before opening it. The answers here are deliberately short — Round 1 wants a sentence or two, not a lecture.
Keys, encoding and certificates
Q. What is a certificate, in one sentence?
A signed statement binding a public key to an identity, issued by a CA that the client already trusts.
Everything else — dates, extensions, SANs — is qualification on that one binding.
Q. Why does TLS use both asymmetric and symmetric cryptography?
Asymmetric solves the problem of agreeing a secret with someone you have never met. Symmetric solves the problem of moving data quickly. Asymmetric is far too slow for bulk data and can only encrypt less than the key size anyway.
So the handshake uses asymmetric cryptography to agree a session key, and everything after that is AES.
Q. PEM or DER — what is the difference?
DER is the binary encoding of the certificate. PEM is that same DER, base64-encoded, wrapped in -----BEGIN CERTIFICATE----- headers so it survives being pasted into text.
Identical content, different container. openssl x509 -inform der -in c.der -out c.pem converts one to the other.
Q. What is in a CSR?
The public key, the subject, any requested extensions, and a self-signature made with the private key to prove you hold it.
Not the private key, and not the validity dates — the CA decides those.
Q. Why is a SAN required when the certificate already has a Common Name?
Because RFC 9525 says the CN must not be used to identify a service — the CN is a display field with no structure, and a certificate can legitimately serve many names.
Practically: browsers and Go reject CN-only certificates outright. OpenSSL, curl and Python still accept them through a legacy fallback, which is exactly why this bug reaches production.
Q. What does basicConstraints CA:TRUE mean, and why does it matter?
It marks a certificate as permitted to sign other certificates. Without it, a leaf cannot act as a CA no matter what else it contains.
It matters because before it was enforced, anyone with a valid leaf certificate could sign certificates for any domain they liked, and clients would accept them.
Chains and validation
Q. What order do certificates go in fullchain.pem?
Leaf first, then each intermediate above it, working upward. The root is never included — the client must already have it, and sending it wastes bytes on every handshake.
In nginx the file goes in ssl_certificate; getting the order wrong produces key values mismatch, not a chain error, because nginx pairs the key with whichever certificate is first.
Q. What does a client actually check?
That the chain reaches a trusted root; that every signature is valid; that nothing has expired; that the hostname matches a SAN; that the extensions permit this use; and, if it is checking, that nothing is revoked.
Any one of those failing ends the connection.
Q. Error 20 versus error 21?
20 is unable to get local issuer certificate — your trust store lacks the issuer. 21 is unable to verify the first certificate — they did not send the intermediate.
Same symptom, opposite fix. Count the certificates in the s_client chain listing to tell them apart.
Q. What is an intermediate CA for?
So the root's private key can stay offline. The root signs one intermediate and then goes in a safe; the intermediate does the daily issuing.
If the intermediate is compromised you replace it and reissue. If the root is compromised you replace every trust store on earth.
The handshake
Q. Walk me through the TLS 1.3 handshake.
The client sends ClientHello with its supported versions, ciphers, and a guessed key share. The server replies with ServerHello containing its own key share — and from that point everything, including its certificate, is encrypted. It sends its certificate and a signature proving it holds the private key, then Finished. The client verifies and sends Finished.
One round trip, and the certificate is no longer sent in the clear.
Q. How is 1.3 different from 1.2?
One round trip instead of two. Everything after ServerHello is encrypted. Static RSA key exchange is gone, so forward secrecy is mandatory rather than optional. The cipher suite list is cut from hundreds to five. And there is 0-RTT resumption, which is fast and replayable.
Q. What is forward secrecy?
The session key is generated ephemerally — ECDHE — and never derivable from the server's long-term private key. So an attacker who records traffic today and steals the server key next year still cannot decrypt it.
Static RSA key exchange has no forward secrecy, which is why TLS 1.3 removed it.
Q. What are SNI and ALPN?
SNI is the client telling the server which hostname it wants before the certificate is chosen, so one IP and port can serve many sites. ALPN is the client and server agreeing the application protocol — HTTP/1.1, h2 — inside the same handshake, avoiding an extra round trip.
SNI is sent in the clear in TLS 1.3, which is the privacy gap Encrypted Client Hello is meant to close.
Operations
Q. Why is certificate revocation broken?
Soft-fail. A browser that cannot reach the revocation responder carries on rather than blocking the user — so an attacker who can block the check has defeated it. Hard-fail was tried and made revocation-responder outages into internet outages.
The industry's answer was not better revocation, it was shorter lifetimes.
Q. What is ACME actually proving?
Control of the domain, and nothing else. HTTP-01 proves you can write to the web root; DNS-01 proves you can edit the zone; TLS-ALPN-01 proves you control port 443.
None of them says anything about who you are, which is exactly why DV certificates carry no verified organisation name.
Q. What does an SCT prove?
That a Certificate Transparency log signed a promise to publish the certificate within its merge delay. Not that it has been published — the browser only verifies the signature, because contacting the log would leak browsing history.
Enforcement happens out of band, via monitors, not in the connection.
Q. What is a CAA record and does it stop anyone?
A DNS record naming which CAs may issue for your domain. Every publicly-trusted CA has been required to check it since September 2017.
It stops nobody technically — it is enforced by CA policy, not by clients. It works because ignoring it is an auditable violation that root programs act on.
Q. What is mTLS?
Both ends present certificates. The server sends a CertificateRequest, the client replies with its certificate plus a CertificateVerify signature proving it holds the matching key.
Identity is established during the handshake, so an unknown client never reaches the application at all.
Q. How would you decide between a public CA and running your own?
Public CA via ACME for anything on the internet — always, without exception. Your own CA only for internal traffic, and preferably not by hand: cert-manager in Kubernetes, Vault, or a cloud private CA.
The cost of running your own is not issuance, it is keeping the key safe for a decade through staff turnover.
🧪 Exercise B1.1 — Build a working CA from memory, with nothing open
This is the honest test of Round 1 knowledge. Close every other tab. Then, without looking anything up, write and run the commands to create a CA, issue a certificate for test.local with a proper SAN, and verify it.
mkdir -p ~/tls-lab/m14/frommemory && cd ~/tls-lab/m14/frommemory
# ... your commands here, from memory ...When you are done — or stuck — check yourself against this:
openssl verify -CAfile myca.crt server.crt # must print: server.crt: OK
openssl x509 -in server.crt -noout -ext subjectAltName # must show DNS:test.local✅ Model answer — attempt it first, then click
# 1. the CA
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out myca.key
openssl req -x509 -new -key myca.key -sha256 -days 3650 -out myca.crt \
-subj "/CN=My Test CA" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
# 2. the server's key and request
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key
openssl req -new -key server.key -out server.csr -subj "/CN=test.local"
# 3. the extensions the CA will apply (a CSR's extensions are NOT copied)
cat > server.cnf <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:test.local
EOF
# 4. sign it
openssl x509 -req -in server.csr -CA myca.crt -CAkey myca.key -CAcreateserial \
-days 90 -sha256 -extfile server.cnf -out server.crt
# 5. check
openssl verify -CAfile myca.crt server.crt
openssl x509 -in server.crt -noout -ext subjectAltNameserver.crt: OK
X509v3 Subject Alternative Name:
DNS:test.localWhat to read out of this — score yourself on the four things people forget, not on whether it ran.
- Did you write an extensions file at all? The most common omission. Without -extfile, openssl x509 -req produces a certificate with no SAN, no EKU and no basicConstraints — and it will still say OK, because openssl verify does not check hostnames. It will fail in every browser.
- Did you set CA:TRUE on the CA? Leaving it off produces a CA certificate that cannot sign anything, and the error appears later and confusingly.
- Did you remember that CSR extensions are ignored? This is the one that catches people who have only ever used a hosted CA. Whatever you put in the CSR, the issuer decides the final extensions — copy_extensions defaults to none for good reason.
- Did you use -sha256? Old OpenSSL defaulted to SHA-1. Being explicit costs nothing.
🔑 If you could not do this from memory, that is worth knowing now rather than at a whiteboard. Interviewers ask candidates to write these commands surprisingly often, and it is a fair test — anyone who has actually run a CA has typed them enough times. Practise it twice more this week; it takes four minutes.
💡 A neater variant worth knowing, because it does it in one command with no separate CSR: openssl req -x509 -newkey rsa:2048 -nodes -keyout k.pem -out c.pem -days 90 -subj "/CN=test.local" -addext "subjectAltName=DNS:test.local". That produces a self-signed certificate, which is a different thing from a CA-issued one — do not offer it as an answer to this question, but knowing both is a good sign.
Part C · Round 2 — Live troubleshooting
C1 · Thinking out loud, and the lab to practise on
The examiner is standing over your shoulder. They already know what the dish should taste like. What they are watching is whether you wash your hands, whether you taste as you go, and what you do when the sauce splits.
Round 2 works the same way. The interviewer usually knows the answer before they ask. They are watching your order of operations — and a candidate who narrates a clean, cheap-first process and gets the wrong answer scores better than one who silently guesses right.
Three rules for this round, and they are worth rehearsing until they are automatic.
Narrate before you type. "First I'd rule out whether this is TLS at all — one curl, and I'd read the error text." The interviewer cannot score silence.
Cheapest first, and say why. curl before s_client, s_client before a scanner, and the server's log before any of your own theories. If you jump straight to reading nginx configs, you have skipped the free evidence.
State what you have ruled out. "So it is not expiry and not the hostname — that leaves the chain." This is the single strongest signal available to you, because it shows you are narrowing a space rather than pattern-matching a symptom.
1. Is it TLS at all? A 500 from the application is not a certificate problem, and a surprising number of "SSL issues" are DNS.
2. Which of the five is it? Expired · wrong name · broken chain · wrong certificate served · not TLS. One curl usually decides.
3. Whose side is it on? Error 20 is yours, error 21 is theirs. Getting this backwards wastes the most time.
4. Is what I am testing what the user is hitting? Same node? Same SNI? Same trust store? Most "I can't reproduce it" lives here.
🧪 Exercise C1.1 — Build four faults you have not seen before
Every fault in Module 13 was one you had already met. These four are not — work through them cold.
mkdir -p ~/tls-lab/m14/logs && cd ~/tls-lab/m14
# --- root, and TWO intermediates: one healthy, one already expired ---
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 3650 -out root.crt \
-subj "/CN=Exam Root CA" \
-addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"
mkdir -p ca/newcerts && touch ca/index.txt && echo 2000 > ca/serial && echo 2000 > ca/crlnumber
mkca() { cat > $1-ca.cnf <<EOF
[ ca ]
default_ca = D
[ D ]
dir=$PWD/ca
database=\$dir/index.txt
new_certs_dir=\$dir/newcerts
serial=\$dir/serial
crlnumber=\$dir/crlnumber
certificate=$PWD/$2
private_key=$PWD/$3
default_md=sha256
policy=pol
copy_extensions=none
unique_subject=no
[ pol ]
commonName=supplied
EOF
}
mkca root root.crt root.key
printf 'basicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign\n' > int.cnf
NOW=$(date -u +%Y%m%d%H%M%SZ)
for pair in "int:+1825 days" "oldint:-5 days"; do
n=${pair%%:*}; end=${pair##*:}
start=$NOW; [ "$n" = "oldint" ] && start=$(date -u -d '-800 days' +%Y%m%d%H%M%SZ)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out $n.key
openssl req -new -key $n.key -out $n.csr -subj "/CN=Exam ${n} CA"
openssl ca -batch -config root-ca.cnf -extfile int.cnf -in $n.csr -out $n.crt \
-startdate $start -enddate $(date -u -d "$end" +%Y%m%d%H%M%SZ)
done
mkca int int.crt int.key
mkca oldint oldint.crt oldint.key
# --- leaves ---
END=$(date -u -d '+60 days' +%Y%m%d%H%M%SZ)
leaf() { # name cn sanline-or-empty which-ca
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out $1.key
openssl req -new -key $1.key -out $1.csr -subj "/CN=$2"
{ printf 'basicConstraints=critical,CA:FALSE\nkeyUsage=critical,digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth\n'
[ -n "$3" ] && printf 'subjectAltName=%s\n' "$3"; } > $1.cnf
openssl ca -batch -config $4-ca.cnf -extfile $1.cnf -in $1.csr -out $1.crt -startdate $NOW -enddate $END
}
leaf ok app.exam.test "DNS:app.exam.test,DNS:localhost,IP:127.0.0.1" int
leaf nosan app.exam.test "" int
leaf legacy app.exam.test "DNS:app.exam.test,DNS:localhost,IP:127.0.0.1" oldint
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out selfsigned.key
openssl req -x509 -new -key selfsigned.key -sha256 -days 60 -out selfsigned.crt \
-subj "/CN=app.exam.test" -addext "subjectAltName=DNS:app.exam.test,DNS:localhost,IP:127.0.0.1"
cat ok.crt int.crt > c-ok.pem
cat nosan.crt int.crt > c-nosan.pem
cat legacy.crt oldint.crt > c-legacy.pem
cat ok.crt int.crt root.crt > c-withroot.pem
cat int.crt ok.crt > c-wrongorder.pem
# --- serve them ---
cat > nginx.conf <<EOF
worker_processes 1;
error_log $PWD/logs/error.log warn;
pid $PWD/logs/nginx.pid;
events { worker_connections 64; }
http {
access_log off;
default_type text/plain;
server { listen 9101 ssl; server_name app.exam.test;
ssl_certificate $PWD/selfsigned.crt; ssl_certificate_key $PWD/selfsigned.key;
location / { return 200 "ok\n"; } }
server { listen 9102 ssl; server_name app.exam.test;
ssl_certificate $PWD/c-nosan.pem; ssl_certificate_key $PWD/nosan.key;
location / { return 200 "ok\n"; } }
server { listen 9103 ssl; server_name app.exam.test;
ssl_certificate $PWD/c-legacy.pem; ssl_certificate_key $PWD/legacy.key;
location / { return 200 "ok\n"; } }
server { listen 9104 ssl; server_name app.exam.test;
ssl_certificate $PWD/c-withroot.pem; ssl_certificate_key $PWD/ok.key;
location / { return 200 "ok\n"; } }
}
EOF
nginx -t -c $PWD/nginx.conf && nginx -c $PWD/nginx.conf && sleep 1
# --- now diagnose. Do NOT read the next section first. ---
for p in 9101 9102 9103 9104; do
out=$(echo | openssl s_client -connect 127.0.0.1:$p -servername app.exam.test \
-verify_hostname app.exam.test -CAfile root.crt 2>/dev/null)
printf "%-5s %s certs %s\n" "$p" "$(echo "$out" | grep -c '^ *[0-9] s:')" \
"$(echo "$out" | grep -m1 'Verify return code')"
done✅ Expected result — click to reveal
9101 1 certs Verify return code: 18 (self-signed certificate)
9102 2 certs Verify return code: 0 (ok)
9103 2 certs Verify return code: 10 (certificate has expired)
9104 3 certs Verify return code: 0 (ok)What to read out of this — two of the four say ok and two of the four are lying to you.
- 9101 is honest. Error 18, self-signed. One certificate, no chain, nothing to argue about.
- 9103 says "expired" and the leaf is not expired. Go and look — the leaf has 60 days left. Something else in that chain has expired, and neither curl nor OpenSSL will tell you which. This is C2's second scenario.
- 9102 says 0 (ok) even with -verify_hostname — and it will fail in a browser. The reason is in Module 03, and it catches almost everyone.
- 9104 says 0 (ok) on your machine and will not on a colleague's. Three certificates for a two-certificate chain. The extra one is the tell.
🔑 This is the honest lesson of Round 2: 0 (ok) is not the same as "working". OpenSSL validates a chain against your trust store with your flags. Browsers, Go, and machines that lack your internal root all apply stricter or simply different rules. Half the incidents in this field are somebody having verified the wrong thing and believed it.
C2 · Four scenarios, cold
Everyone in the waiting room says the same thing: "the website won't load and it says something about a certificate." Four identical presenting symptoms, four completely different underlying conditions, and the treatment for one would do nothing for another.
Work through each of these before opening the answer. Say out loud: what you would run, in what order, and what you would conclude.
Scenario 1 — "It works on my laptop and not on the server"
The interviewer says: "A developer deployed a service. It loads fine in their browser after they clicked through a warning. From our CI runner, curl fails. Port 9101. Go."
🩺 Diagnose it — then open this
curl -sS -o /dev/null https://app.exam.test:9101/ --resolve app.exam.test:9101:127.0.0.1 2>&1 | head -1
echo | openssl s_client -connect 127.0.0.1:9101 -servername app.exam.test 2>/dev/null \
| sed -n '/Certificate chain/,/^---/p'curl: (60) SSL certificate problem: self-signed certificate
Certificate chain
0 s:CN = app.exam.test
i:CN = app.exam.testThe diagnosis: a self-signed certificate reached a real environment. Verify code 18. The tell is in the chain listing — s: and i: are the same name, and there is only one entry.
What a strong answer says. "Subject equals issuer and there's one certificate in the chain — that's self-signed, error 18. The developer's browser only 'works' because they clicked through the interstitial, which suppresses it for them and nobody else. CI has no such button, which is why it's failing there and not for them.
The fix isn't to add the certificate to CI's trust store — that would make the pipeline pass while every real client still fails. It needs a certificate from a CA the clients already trust: a public CA via ACME if it's internet-facing, or the internal CA if it isn't."
🔑 The thing being tested is whether you resist the tempting wrong fix. "Add it to the trust store" makes the error go away and leaves the service broken for everyone else. Interviewers ask this precisely because the wrong answer is so much easier to reach.
⚠️ And name the second-order risk: whoever clicked through the warning has trained themselves to click through warnings. That habit is worth more attacker effort than the certificate.
Scenario 2 — "The certificate has months left and it says expired"
The interviewer says: "Monitoring says this certificate is valid until October. Users are getting expiry errors right now. Port 9103."
🩺 Diagnose it — then open this
echo "--- the leaf:"
echo | openssl s_client -connect 127.0.0.1:9103 -servername app.exam.test 2>/dev/null \
| openssl x509 -noout -subject -dates
echo "--- the whole chain:"
echo | openssl s_client -connect 127.0.0.1:9103 -servername app.exam.test -CAfile root.crt 2>/dev/null \
| sed -n '/Certificate chain/,/^---/p'--- the leaf:
subject=CN = app.exam.test
notBefore=Aug 27 07:58:35 2026 GMT
notAfter=Oct 26 07:58:35 2026 GMT
--- the whole chain:
Certificate chain
0 s:CN = app.exam.test
i:CN = Exam Legacy Issuing CA
v:NotBefore: Aug 27 07:58:35 2026 GMT; NotAfter: Oct 26 07:58:35 2026 GMT
1 s:CN = Exam Legacy Issuing CA
i:CN = Exam Root CA
v:NotBefore: Jun 18 07:58:22 2024 GMT; NotAfter: Aug 22 07:58:22 2026 GMTThe diagnosis: the intermediate expired, five days ago. The leaf is fine. A chain is only valid if every certificate in it is valid, and curl reports only certificate has expired without saying which one.
What a strong answer says. "The leaf has two months left, so I'd look at the rest of the chain — and entry 1, the intermediate, expired on the 22nd. Path validation checks every certificate, so one expired link invalidates the whole thing.
The fix is to get a certificate from the CA's current intermediate and redeploy the full chain — reissuing the leaf alone from the same expired intermediate changes nothing. And the reason nobody saw it coming is that our monitoring reads the leaf's notAfter and stops there."
🔑 This is the highest-value scenario in Part C, because the fix is a monitoring change, not a certificate change. Alert on the earliest expiry in the whole chain, not the leaf's. Almost nobody does, and it produces exactly this outage — one that arrives with no warning on a certificate everybody believed was healthy.
💡 It happens for real, at scale. When a public CA rotates intermediates, anyone still pinning or shipping the old one hits this on the day it expires. Let's Encrypt's DST Root CA X3 cross-sign expiry in September 2021 broke a very large number of older clients for precisely this reason.
Scenario 3 — "Every tool says it's fine and the browser says it isn't"
The interviewer says: "curl gets a 200. openssl s_client says Verify return code: 0. Our Python service connects happily. Chrome refuses and our Go service refuses. Port 9102."
🩺 Diagnose it — then open this
echo -n "openssl : "; echo | openssl s_client -connect 127.0.0.1:9102 -servername app.exam.test \
-verify_hostname app.exam.test -CAfile root.crt 2>/dev/null | grep -m1 "Verify return code"
echo -n "curl : "; curl -sS -o /dev/null -w "HTTP %{http_code}\n" --cacert root.crt \
--resolve app.exam.test:9102:127.0.0.1 https://app.exam.test:9102/
echo "--- and what is actually in the certificate:"
echo | openssl s_client -connect 127.0.0.1:9102 -servername app.exam.test 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltNameopenssl : Verify return code: 0 (ok)
curl : HTTP 200
--- and what is actually in the certificate:
subject=CN = app.exam.test(-ext subjectAltName printed nothing — there is no SAN at all.)
If you have Go available, the confirmation is unambiguous:
9102 REJECTED: tls: failed to verify certificate: x509: certificate relies on
legacy Common Name field, use SANs insteadThe diagnosis: the certificate has no SAN, only a Common Name. RFC 9525 says the CN must not be used to identify a service — but OpenSSL, curl and Python still fall back to it, while browsers and Go do not.
What a strong answer says. "The -ext subjectAltName output is empty, so there's no SAN — the name is only in the CN. Modern clients reject that under RFC 9525; OpenSSL and curl keep a legacy fallback, which is exactly why our CLI tools disagree with our users.
The fix is to reissue with a proper SAN. And the thing I'd change afterwards is the check — a smoke test built on curl will keep passing on a certificate no browser will accept, so it needs to assert the SAN is present, not just that the connection worked."
🔑 The generalisable lesson is the one worth voicing: your CLI tools are more permissive than your users' clients. A green curl is weak evidence. Anywhere it matters, assert on the certificate's contents rather than on the connection succeeding.
💡 How it happens: somebody generated a CSR with -subj "/CN=app.example.com" and no extensions file, and the CA issued exactly what was asked for. Module 04's warning — a CSR's extensions are not copied unless the CA chooses to — is the same fact from the other direction.
Scenario 4 — "It works for us and not for the new starter"
The interviewer says: "Nobody on the team can reproduce it. One person's machine, and one customer, get a certificate error. Everyone else is fine. Port 9104."
🩺 Diagnose it — then open this
echo -n "with our root trusted : "
echo | openssl s_client -connect 127.0.0.1:9104 -servername app.exam.test -CAfile root.crt 2>/dev/null \
| grep -m1 "Verify return code"
echo -n "without it : "
echo | openssl s_client -connect 127.0.0.1:9104 -servername app.exam.test 2>/dev/null \
| grep -m1 "Verify return code"
echo "--- how many certificates is the server sending?"
echo | openssl s_client -connect 127.0.0.1:9104 -servername app.exam.test 2>/dev/null \
| grep -c "^ *[0-9] s:"with our root trusted : Verify return code: 0 (ok)
without it : Verify return code: 19 (self-signed certificate in certificate chain)
--- how many certificates is the server sending?
3The diagnosis: the server is sending the root as well as the leaf and intermediate. Three certificates for a two-certificate chain. On any machine that already trusts the root it validates fine; on one that does not, the root is just a self-signed certificate sitting in the chain — error 19.
What a strong answer says. "Three certificates for what should be a two-certificate chain, and the verdict changes depending on whose trust store you use — so I'd look at what the extra one is. It's the root, and the server shouldn't be sending it.
Error 19 is 'self-signed certificate in certificate chain', which is what a root looks like to a client that doesn't have it. The fix is to rebuild fullchain.pem as leaf plus intermediates only. It also shaves a certificate off every handshake, which is a small real win."
🔑 Distinguish 18 from 19 out loud, because they get confused constantly. 18 — the leaf itself is self-signed. 19 — a self-signed certificate appears inside an otherwise real chain, which in practice always means the server is sending the root.
⚠️ "It works for everyone except one person" is a trust-store question every time. A new starter on a fresh machine, a container without ca-certificates, a customer on a corporate laptop with a stripped-down store. The certificate is identical for all of them; what differs is what they already trust.
🎯 Interview questions — The troubleshooting round
Q. curl says the certificate has expired, but the certificate has two months left. Explain.
Something else in the chain has expired — almost always the intermediate. Path validation requires every certificate in the chain to be valid, and both curl and OpenSSL report certificate has expired without saying which one, so it reads as if the leaf is the problem.
Confirm it by reading the whole chain: openssl s_client -connect host:443 -servername host and look at the v:NotAfter line on every entry, not just entry 0.
The detail worth adding: the fix is a monitoring change, not a certificate change. Most expiry monitoring reads the leaf's notAfter and stops, which means an expiring intermediate produces an outage with no warning at all — on a certificate every dashboard says is healthy. Alert on the earliest expiry across the whole chain. It happens at scale whenever a public CA rotates intermediates; the Let's Encrypt DST Root CA X3 expiry in 2021 broke a large number of clients exactly this way.
Q. Everything on the command line says the certificate is fine, and browsers reject it. What would you check?
First whether it has a SAN at all — openssl x509 -noout -ext subjectAltName. A certificate with only a Common Name is rejected by browsers and by Go under RFC 9525, while OpenSSL, curl and Python still accept it through a legacy fallback. That single difference explains a large share of these reports.
If the SAN is present, I'd look at what else browsers enforce and OpenSSL does not: Certificate Transparency policy, the browser's own root store distrusting a CA the OS still trusts, or a chain the browser can't build because an intermediate is missing and it has nothing cached.
The detail worth adding: the principle underneath is that your CLI tools are more permissive than your users' clients, so a green curl is weak evidence. The practical consequence is that smoke tests should assert on the certificate's contents — SAN present, expiry, issuer — rather than on the connection succeeding, because the connection succeeding is exactly what fails to catch this.
Q. One person out of thirty gets a certificate error. Where do you look?
At their trust store, not at the certificate. The certificate is identical for everyone, so anything that affects one machine and not the others is local: a fresh install missing an internal root, a container without ca-certificates, a corporate laptop with a modified store, or a browser using its own root store rather than the OS one.
The quick confirmation is to run the same openssl s_client twice — once with -CAfile pointing at the expected root and once without — and see whether the verdict changes.
The detail worth adding: there is a server-side version of this worth naming, because it looks identical from the outside. If the server sends the root along with the chain, machines that already trust it validate fine and machines that don't get error 19, self-signed certificate in certificate chain. So "works for everyone but one person" can still be a server misconfiguration — the fix being to send leaf plus intermediates only.
Part D · Rounds 3 and 4 — Design, and the deep follow-up
D1 · Design questions have no right answer, and several wrong ones
Ask two architects for a house and the weaker one starts describing windows. The better one asks how many people live there, which way the sun comes, what the budget is, and whether you plan to stay for thirty years.
Round 3 is testing whether you ask before you answer. A candidate who immediately says "use cert-manager" has designed for a problem nobody described. The questions you ask are worth more than the solution you land on.
Every design answer in this subject has the same four moves, and doing them in order is most of the score:
| Move | What it sounds like |
|---|---|
| 1. Scope it | "Before I answer — is any of this internet-facing, or all internal? Kubernetes or VMs? And what's the current pain: outages, audit, or effort?" |
| 2. State the principle | "Whatever we choose, the rule is: public CA and ACME for anything public, short lifetimes, and no human in the renewal path." |
| 3. Pick, and say why | "Given Kubernetes, cert-manager. Not because it's the only option — because it's a control loop, and a cron job isn't." |
| 4. Name what it costs | "The trade-off is a cluster-wide controller with broad permissions, and the failure mode is workloads not picking up renewed certificates without a restart." |
Every design answer that presents a choice as free reads as inexperience. There is no configuration of this that has no downside — wildcards trade fewer logged names for a bigger blast radius, short lifetimes trade security for a hard dependency on automation, mTLS trades a strong front door for a certificate-distribution problem.
Say the cost out loud, unprompted. It is the fastest way to signal that you have run the thing rather than read about it.
Question 1 — "How would you manage certificates for 500 services?"
🏗️ Design it — then open this
Scope first, out loud. "How many are public versus internal? Kubernetes, VMs, or both? Is the pain expiry outages, audit findings, or engineer time? And is there an existing CA I have to live with?"
Then the principle. "Public-facing goes to a public CA over ACME — free, browser-trusted, and it forces automation. Internal goes to an internal CA. Both get short lifetimes, and nothing renews by hand at 500 services. The 47-day schedule means that stops being a choice anyway."
Then the shape. In Kubernetes: cert-manager, with a ClusterIssuer per environment, duration and renewBefore set well beyond the deployment window, and privateKey.rotationPolicy: Always. On VMs: certbot with deploy hooks for public, Vault PKI for internal. Behind a load balancer or CDN, terminate there and keep origin certificates internal.
Then monitoring, because this is where the marks are. "Expiry monitoring read from the live connection, not from files — and alerting on the earliest expiry in the whole chain, not the leaf's. Plus CT monitoring for certificates issued for our domains by CAs we don't use, and CAA records so that's unlikely in the first place."
Then the cost. "cert-manager is a cluster-wide controller with broad permissions. The common failure is a service not picking up a renewed certificate because it read the file once at start-up. And short lifetimes make the renewal path a hard availability dependency — if issuance breaks for a fortnight, that's an outage, not a ticket."
🔑 What the interviewer is listening for is whether you mention monitoring at all. Most candidates answer the issuance half and stop. Issuance is the easy part; knowing when it silently stopped working is the hard part, and it is what actually causes the outages.
Question 2 — "Should we use mTLS everywhere internally?"
🏗️ Design it — then open this
This is a trap question, and the trap is answering yes.
"Probably yes eventually, but not as a first move, and it depends what we're protecting against. mTLS gives us a verified identity on every connection, which is a genuinely strong control — but it gives us authentication, not authorisation. If every service shares one client CA, every service can reach every other service, which is roughly where we started."
Then the real cost. "The hard part isn't turning it on, it's distributing and rotating thousands of client certificates without a human. If we can't do that, mTLS becomes long-lived keys sitting in files, which is not obviously better than the tokens we have now. So the order is: get automated issuance working first — SPIFFE/SPIRE or cert-manager — then turn on mTLS, then add authorisation on the identities."
Then the alternative. "If the goal is 'stop services talking to things they shouldn't', network policy may get us most of the way faster and cheaper. mTLS is the better long-term answer because it survives a flat network, but it's worth naming the cheaper option rather than pretending it doesn't exist."
🔑 The distinguishing move is sequencing. Anyone can say "mTLS is good". Saying "automation first, then mTLS, then authorisation — in that order, because doing it the other way round produces long-lived keys on disk" is the answer of someone who has watched a rollout stall.
⚠️ And name the operational tax: when mTLS is on, an expired client certificate is a hard connection failure with no application log line, because the request never arrives. Debuggability gets worse before it gets better, and teams are always surprised by it.
Question 3 — "Certificate lifetimes are dropping to 47 days. What does that mean for us?"
🏗️ Design it — then open this
"It means manual renewal stops being viable — which is the point of the change, not a side effect. The industry concluded that revocation doesn't work, so the answer became making certificates expire before revocation would have mattered."
What breaks: anything with a human in the loop; certificates baked into container images or golden images; appliances and vendor products with no ACME support; anything pinning a certificate; and anything reading its certificate once at start-up without a reload path.
What to do about it: "Inventory first — I'd want to know every place a certificate lives before changing anything, and CT logs plus an estate sweep get most of that. Then automate the easy majority. Then deal with the awkward remainder deliberately: for appliances that can't do ACME, either a proxy in front that can, or an accepted manual process with a calendar and an owner. And shorten lifetimes before we're forced to, so the failures happen while we're watching."
The cost: "Renewal becomes a production dependency. It needs monitoring, alerting and a runbook of its own — and the alert threshold has to be longer than our worst-case deployment window, which for anything needing a change freeze might be three weeks, not seven days."
🔑 The framing that lands: this is the same conclusion internal PKI reached independently. Vault, SPIRE and cert-manager all default to short lifetimes and continuous rotation. Short lifetimes plus automation beat long lifetimes plus revocation — the public web and the service mesh got there separately, which is decent evidence it is the right answer.
💡 Voluntarily shortening early is the strongest thing you can say here. If renewal breaks on a 90-day certificate you find out in three months, alone, at the worst moment. On a 30-day one you find out in a fortnight, while the change is fresh and the person who made it is still around.
🧪 Exercise D1.1 — Write the one-page strategy, then mark it yourself
Take Question 1. Before reading the answer above again, write your own version — no more than one page — as though handing it to a team. Then score it against this checklist. A complete answer covers all ten; most first attempts cover four or five.
[ ] 1. Asked scoping questions before answering
[ ] 2. Split public-facing from internal, with different answers for each
[ ] 3. Named a specific tool, and said why that one
[ ] 4. Short lifetimes, and said automation is the precondition not the reward
[ ] 5. Key rotation, not just certificate renewal
[ ] 6. Expiry monitoring read from the LIVE CONNECTION, not from files
[ ] 7. Alerting on the whole chain's earliest expiry, not the leaf's
[ ] 8. CT monitoring and CAA records
[ ] 9. A named failure mode - reload, node drift, or renewal breaking silently
[ ] 10. An explicit cost or trade-off, stated without being asked✅ How to read your score — click to reveal
Items 1, 9 and 10 are worth more than the rest combined, and they are the three most often missing.
- 1 — scoping. Answering immediately is the single most common Round 3 mistake. It is not eagerness; it reads as not knowing that the answer depends.
- 9 — a named failure mode. "The usual failure is the service reading its certificate once at start-up and never picking up the renewal" proves you have operated this. No amount of tool knowledge substitutes.
- 10 — an unprompted cost. If your page presents your design as free, rewrite it. Every choice here trades something.
Items 6 and 7 are the technical tell. Almost everyone says "monitor expiry". Saying from the live connection and the earliest expiry in the chain are the two details that distinguish someone who has been burned from someone who has read a blog post — and both come straight from Scenario 2 in Part C.
🔑 Four out of ten is a normal first attempt. The point of the checklist is not the score, it is that the missing items are specific and fixable. Rewrite the page covering all ten, read it aloud once, and it will be there when you need it.
💡 Keep it to one page deliberately. In a real interview you get ninety seconds for this, not ten minutes. If your written version is three pages, the spoken version will ramble — and rambling on a design question reads as not having a clear view.
D2 · Round 4 — how far down does it go?
Every parent knows the sequence. Why is the sky blue? — Because of the air. — Why does air do that? — It scatters light. — Why does it scatter blue more? — and at some point, four or five levels down, every adult reaches the honest end of what they know.
Round 4 is that, on purpose. The interviewer is not trying to catch you out; they are finding the depth. Everybody has a bottom. What is being scored is whether you notice you have reached yours.
Here is a real follow-up chain on one question. Try to answer each level before reading the next.
Level 1 — "Why is TLS 1.3 faster than 1.2?"
One round trip instead of two. In 1.2 the client and server exchange hellos, then exchange key material, then finish — two full round trips before any data. In 1.3 the client guesses which key exchange group the server will pick and sends its key share in the very first message, so the server can reply with everything it needs.
On a 100ms link that is 100ms saved on every new connection.
Level 2 — "What happens if the client guesses wrong?"
The server responds with a HelloRetryRequest naming the group it does want, and the client sends a new ClientHello with the right key share. That costs the extra round trip back — so a wrong guess is exactly as slow as TLS 1.2, never slower.
In practice clients guess X25519 and are almost always right, so the retry is rare.
Level 3 — "Why X25519 rather than one of the NIST curves?"
It is fast, it has no known weak parameters, and its design avoids several implementation pitfalls — every 32-byte string is a valid public key, so there is no point-validation step to get wrong, and it is naturally constant-time, which makes timing side channels much harder to introduce.
There is also long-standing unease about the provenance of the NIST curve parameters. X25519's are generated from a published rationale anyone can check.
Level 4 — "Constant-time — why does that matter?"
If the time an operation takes depends on the secret, an attacker who can measure timing across many operations can recover the secret. It is a real attack class, not a theoretical one, and it has broken deployed implementations.
X25519's arithmetic is designed so the same instructions execute regardless of the key bits, which removes the signal.
Level 5 — "How would you verify a given implementation is actually constant-time?"
This is where most people should stop, and saying so is the correct answer.
"Honestly, that's past where I'd trust myself. I know it's done with statistical timing analysis — tools like dudect, and constant-time verification passes in some compilers — and that the usual advice is not to write this code yourself but to use a reviewed library. If I actually needed to assess it I'd be reading the library's own audit reports rather than trying to measure it myself."
That is a strong answer. It is honest, it demonstrates you know the shape of the field beyond your own depth, and it names what you would do instead.
Levels 1–2 — did you learn the protocol, or a summary of it? Most prepared candidates reach here.
Level 3 — do you know why the choices were made, not just what they are? This is where "read a book" separates from "read the RFC".
Level 4 — do you have any real depth outside your specialism?
Level 5 — what do you do at your limit? This is the actual question, and every level before it was setup.
The mistake is treating levels 4 and 5 as failures. They are not — the interviewer will keep going until you stop, by design. Reaching level 4 and saying "I don't know" cleanly is a better result than reaching level 2 and bluffing level 3.
🧪 Exercise D2.1 — Find your own floor, on three topics
Pick three topics you feel confident about and drill each one downward, out loud, asking yourself "but why?" until you cannot answer. Write down where you stopped.
Suggested starting points:
"Why do we need certificates at all?" ... down towards MITM, key distribution
"Why does a CSR need to be self-signed?" ... down towards proof of possession
"Why is revocation broken?" ... down towards soft-fail, privacy, CRL size
"Why must the SAN be checked, not the CN?" ... down towards RFC 9525, parsing ambiguity
"Why is 0-RTT replayable?" ... down towards no server randomness in the first flight
"Why can't RSA encrypt bulk data?" ... down towards padding, key size, performance✅ What to do with the answer — click to reveal
Three levels deep on a topic you claim is a strength is the working minimum. If you stop at level 2 on something you would put on a CV, that is the gap to close first — and it is a much better use of an evening than learning a new topic.
- Write the stopping point down verbatim. "I can explain why 0-RTT is replayable but not what a server can actually do about it." Specific gaps get closed. Vague ones ("I should learn more about TLS") do not.
- Then close two and leave the rest. You cannot bottom out every topic, and trying to is how people arrive at interviews exhausted and shallow everywhere. Two topics you can go five levels down on are worth more than ten you can go two.
- Rehearse the sentence you will use at the bottom. Really — out loud, once. "I don't know that one. Here's how I'd find out." Under pressure people bluff not because they intend to but because they have no prepared alternative to silence. Give yourself one.
🔑 The counter-intuitive part worth sitting with. Deliberately finding your limits before the interview makes you sound more confident in it, not less. You already know where the floor is, so hitting it is a fact rather than a shock — and the calm in your voice when you say "I don't know" is what the interviewer is actually reading.
🎯 Interview questions — Design and depth
Q. What is the biggest mistake teams make with TLS?
Treating it as a setup task rather than an operational one. A certificate gets installed, the padlock appears, and nobody looks again until it expires — so the failure modes that matter are all in the parts nobody watches: renewal that silently stopped, an intermediate expiring, a node missed by a rollout, a certificate deployed but never reloaded.
The cryptography is not where the risk is. The maths has been fine for twenty years; the outages are all operational.
The detail worth adding: give the second-order version, because it is the more interesting answer. The other big mistake is monitoring only expiry, which catches one of the five common failure modes and reports everything else as healthy — a broken chain, a wrong name, an obsolete protocol and a stale certificate all show ok forever. And it is worth noting that the industry's own answer to this was not better tooling but shorter lifetimes, which forces the automation that fixes the whole class.
Q. If you joined a company tomorrow and owned TLS, what would you do first?
Build an inventory. I cannot improve what I cannot see, and almost nobody has a complete list — so I would sweep every endpoint we know about for issuer, expiry, chain and protocol, and cross-check against Certificate Transparency for certificates issued for our domains that are not on that list. CT usually finds things nobody remembers.
Then triage: anything expiring soon, anything with a broken chain, anything not automated.
The detail worth adding: say what you would do second, because it shows you are thinking past the audit. Publish CAA records on every domain including the parked ones — it is one DNS record, it costs nothing, and it takes issuance from about seventy organisations down to one or two. Then fix the monitoring so the inventory stays true on its own. An audit that is a one-off document is worthless within a quarter; the goal is a check that runs, not a spreadsheet.
Part E · Putting it together
E1 · How this all fits — the whole track, mapped to the interview
Diagram source
flowchart TD
R1["🎾 Round 1 · Rapid-fire<br>30 seconds each<br>tests: vocabulary"]
R2["🩺 Round 2 · Live troubleshooting<br>tests: order of operations"]
R3["🏗️ Round 3 · Design<br>tests: trade-offs"]
R4["🪆 Round 4 · Deep follow-up<br>tests: what you do at your limit"]
subgraph F["🟢 Foundation · Modules 01-04"]
M14["keys · encoding · CSRs<br>X.509 · SAN · extensions"]
end
subgraph I["🟡 Intermediate · Modules 05-10"]
M510["chains · handshake · validation<br>deployment · revocation · ACME"]
end
subgraph A["🔴 Advanced · Modules 11-13"]
M1113["CT · CAA · mTLS · internal PKI<br>troubleshooting at scale"]
end
M14 --> R1
M510 --> R1
M510 --> R2
M1113 --> R2
M510 --> R3
M1113 --> R3
M1113 --> R4
M14 --> R4
R1 --> R2 --> R3 --> R4
R4 --> OUT{"At your limit,<br>what happens?"}
OUT -->|"bluff"| BAD["❌ The worst outcome<br>an engineer who invents<br>answers under pressure"]
OUT -->|"say so, then say<br>how you'd find out"| GOOD["✅ The best available answer<br>honest, and shows the<br>shape of the field"]
style R1 fill:#e1d5e7,stroke:#9673a6,stroke-width:2px
style R2 fill:#e1d5e7,stroke:#9673a6,stroke-width:2px
style R3 fill:#e1d5e7,stroke:#9673a6,stroke-width:2px
style R4 fill:#e1d5e7,stroke:#9673a6,stroke-width:3px
style OUT fill:#fff2cc,stroke:#d6b656,stroke-width:3px
style BAD fill:#ffcccc,stroke:#cc0000,stroke-width:2px
style GOOD fill:#d5e8d4,stroke:#82b366,stroke-width:3pxRead the arrows into each round as where the material comes from. Rounds 1 and 2 are almost entirely Modules 01–10 — the mechanism and the failure modes. Round 3 is Modules 10–13, because design questions are really operations questions. Round 4 can start anywhere, which is why the follow-ups on a Module 02 topic can go just as deep as on a Module 13 one.
The yellow diamond is the whole module in one shape. Everything above it is knowledge, and knowledge runs out for everyone — the interviewer will make sure of it. What is actually being decided happens in those two arrows, and only one of them is a skill you can practise.
E2 · Production practice — the week before
| Habit | Why |
|---|---|
| Say every answer out loud, to an empty room | Turning a mental shape into an ordered sentence is the part that fails under pressure, and it is the only part silent revision never practises |
| Run the drill three times across a week, not three times in an evening | Spaced retrieval is what makes recall stick. Cramming produces a flattering score and nothing on the day |
| Answer in three parts: the answer, the mechanism, the detail | It is reproducible under pressure, and it ends on a claim the interviewer wants to pull on — so you choose the next question |
| Lead with the conclusion. No preamble | "That's a great question" and "so basically" buy two seconds and cost credibility. A pause reads as thinking; filler does not |
| Rehearse the sentence you will use at your limit | People bluff because they have no prepared alternative to silence. Give yourself one, out loud, in advance |
| Deliberately find your floor on three topics beforehand | Hitting a known limit is a fact. Hitting an unknown one is a shock, and the shock is what the interviewer hears |
| Say "as of the last time I checked" about anything policy-related | Lifetimes, ballots and browser policy all move. Stating a 2019 fact flatly in 2026 says exactly when you stopped reading |
| Narrate before you type in the troubleshooting round | The interviewer is scoring your order of operations. They cannot score silence |
| Say what you have ruled out, not just what you suspect | "So it's not expiry and not the hostname" shows you are narrowing a space rather than pattern-matching a symptom |
| Ask scoping questions before answering any design question | Answering immediately reads as not knowing that the answer depends. The questions are worth more than the solution |
| Name one cost, unprompted, in every design answer | Presenting a choice as free is the fastest way to sound like you have only read about it |
| Have two topics you can go five levels deep on | Worth more than ten you can go two levels deep on, and far less exhausting to prepare |
| Keep the broken lab and re-run it the day before | Four faults, four verify codes, fifteen minutes. It is the highest-value revision available and it is muscle memory, not recall |
| Prepare two questions to ask them | "How do you handle certificate renewal today?" tells you more about the job than anything on the advert, and it is a question you can now assess the answer to |
E3 · Capstone exercise
Record yourself if you can bear it. Almost nobody does, and it is the single most useful thing in this module: you will hear the filler words, the trailing sentences and the two questions you thought you answered well and did not.
Brief. Run all four rounds in one sitting, in order, timed. Then score yourself against the rubric.
| Round | Timer | What to do |
|---|---|---|
| 1 · Rapid-fire | 10 min | python3 drill.py 20. Out loud. Do not pause the timer to think |
| 2 · Troubleshooting | 15 min | Start the Part C lab. Have someone name a port at random, or shuffle them. Narrate everything |
| 3 · Design | 10 min | Answer all three Part D questions out loud, 3 minutes each. Not written |
| 4 · Depth | 10 min | Pick one topic and drill down until you stop. Then say your limit sentence out loud |
✅ The scoring rubric — attempt the whole thing first, then click
Score each line 0, 1 or 2. 0 = did not do it · 1 = did it partly or late · 2 = did it well and unprompted.
ROUND 1 - RAPID-FIRE /10
[ ] 16 or more of 20 correct
[ ] under 25 seconds per question
[ ] answers were one or two sentences, not paragraphs
[ ] no filler openings ("great question", "so basically", "essentially")
[ ] said "I don't know" cleanly on the ones you did not know
ROUND 2 - TROUBLESHOOTING /12
[ ] narrated the plan BEFORE typing
[ ] went cheapest-first (curl -> s_client -> scanner)
[ ] read the SERVER's log, not only client output
[ ] said what you had ruled out, not just what you suspected
[ ] identified the fault correctly
[ ] named the fix AND what you would change so it cannot recur
ROUND 3 - DESIGN /10
[ ] asked scoping questions before answering
[ ] separated public-facing from internal
[ ] named a specific tool and said why that one
[ ] mentioned monitoring unprompted
[ ] named at least one cost or trade-off without being asked
ROUND 4 - DEPTH /8
[ ] reached level 3 or deeper
[ ] explained WHY, not just WHAT, at least once
[ ] noticed when you reached your limit
[ ] said the limit sentence without bluffing first
TOTAL /40How to read the total.
- 32+ — you are ready. Re-run the drill twice more before the day and leave it alone.
- 24–31 — the knowledge is there and the delivery is not. Do not revise more material. Re-run this capstone twice; almost every lost mark will be a habit, not a fact.
- Under 24 — go back to the modules behind whichever round scored lowest. Round 1 low means Modules 01–06. Round 2 low means Modules 07, 08 and 13. Round 3 low means Modules 10–12.
1. Round 2 is worth the most marks, deliberately. It is the round that most resembles the job, and it is the one candidates prepare for least — because you cannot revise it by reading. The only way to practise it is to break something and fix it while talking.
2. Notice that four of Round 2's six lines are not about TLS at all. Narrating, ordering, reading the right log, stating what is excluded — those are the transferable half, and they are what an interviewer remembers a week later.
3. The last line of Round 4 is the single most important line on the sheet. Everything else can be recovered by another month of study. That one cannot, and it is worth more in the job than in the interview.
🔑 If you score 24–31, the instinct will be to go and read more. Resist it. The gap at that score is between knowing and saying, and more input does not close it — more output does. Run the capstone again tomorrow, out loud, and watch the score move without learning a single new fact.
💡 Do the whole thing in one sitting, even the parts you are confident about. Interviews are tiring in a specific way — sustained talking under mild pressure — and forty-five minutes of it is a different experience from four separate ten-minute sessions. Practising the fatigue is part of practising the interview.
E4 · Official documentation — what to bookmark and how to read it
Almost everyone carries two or three TLS beliefs that are out of date or were never quite true. They are not caught by reading — reading confirms them. They are caught by testing them, which takes about a minute each and is the exercise below.
Core reference pages
| Link | What it is for |
|---|---|
| RFC 8446 — TLS 1.3 | §2 is the handshake overview and is genuinely readable. Read it once end to end |
| RFC 5280 — X.509 and CRL profile | §4.2 for every extension, §6 for path validation. The reference you return to most |
| RFC 9525 — service identity | Why the CN must not identify a service. Obsoletes RFC 6125 |
| openssl verify — verification errors | Every numbered code. The page to check before theorising in Round 2 |
| openssl s_client | -servername, -verify_hostname, -showcerts. Your instrument in the live round |
| RFC 8555 — ACME | The challenge types and what each actually proves |
| RFC 6962 — Certificate Transparency | Merkle trees, precertificates, SCTs |
| RFC 8659 — DNS CAA | The tags and the tree-climbing rule |
| CA/Browser Forum — Baseline Requirements | What CAs must do. §6.3.2 for lifetimes, §3.2.2 for validation |
| Chrome Root Program Policy | What browsers will enforce, and when |
| Let's Encrypt blog | What the largest CA is doing in practice, usually before it is a rule |
| TLS configuration generator | Do not hand-write a cipher list. Take the Intermediate profile |
| SSL Labs Server Rating Guide | The weights and the capping rules |
Where to look when the answer might have changed
The facts in this subject expire faster than the certificates do. When something is policy rather than protocol, check here before stating it:
lifetimes, validation rules, serial entropy -> CA/Browser Forum ballots
what browsers will actually reject -> Chrome Root Program + Mozilla root store policy
what a large CA does in practice -> Let's Encrypt blog and community forum
CT log states, SCT requirements -> Chrome CT policy pages
arguments before they become rules -> ct-policy and dev-security-policy mailing lists🧪 Exercise E4.1 — Test three things you believe
Everything below is something people state confidently in interviews. Two of them are false. Predict each answer before you run it.
cd ~/tls-lab/m14
echo "CLAIM 1: OpenSSL rejects a certificate that has a CN but no SAN"
echo | openssl s_client -connect 127.0.0.1:9102 -servername app.exam.test \
-verify_hostname app.exam.test -CAfile root.crt 2>/dev/null | grep -m1 "Verify return code"
echo "CLAIM 2: s_client checks the hostname by default"
echo -n " without -verify_hostname, asking for a name the cert does not have: "
echo | openssl s_client -connect 127.0.0.1:9104 -servername wrong.example \
-CAfile root.crt 2>/dev/null | grep -m1 "Verify return code"
echo -n " with -verify_hostname wrong.example : "
echo | openssl s_client -connect 127.0.0.1:9104 -servername wrong.example \
-verify_hostname wrong.example -CAfile root.crt 2>/dev/null | grep -m1 "Verify return code"
echo "CLAIM 3: the extensions you put in a CSR end up in the certificate"
openssl req -new -key ok.key -out t.csr -subj "/CN=claim3.test" -addext "subjectAltName=DNS:claim3.test"
openssl req -in t.csr -noout -text | grep -A1 "Alternative"
openssl x509 -req -in t.csr -CA root.crt -CAkey root.key -CAcreateserial -days 30 -sha256 -out t.crt
openssl x509 -in t.crt -noout -ext subjectAltName✅ Expected result — click to reveal
CLAIM 1: OpenSSL rejects a certificate that has a CN but no SAN
Verify return code: 0 (ok)
CLAIM 2: s_client checks the hostname by default
without -verify_hostname, asking for a name the cert does not have: Verify return code: 0 (ok)
with -verify_hostname wrong.example : Verify return code: 62 (hostname mismatch)
CLAIM 3: the extensions you put in a CSR end up in the certificate
X509v3 Subject Alternative Name:
DNS:claim3.test
No extensions in certificateWhat to read out of this — claims 1 and 2 are false, and claim 3 is false in the most expensive way.
- Claim 1 is false. OpenSSL accepts a CN-only certificate through its legacy fallback, and so do curl and Python. Browsers and Go reject it. Anyone who says "the tools would have caught that" is wrong, and Scenario 3 in Part C is the outage that follows.
- Claim 2 is false, and it is the more dangerous one. Plain s_client returned 0 (ok) for a certificate that does not cover the name we asked for. It only checks when told to. Every "I verified it and it was fine" that later turned out not to be fine lives here.
- Claim 3 is false and it surprises people who have only used hosted CAs. The CSR clearly requested DNS:claim3.test; the issued certificate contains no extensions at all. The issuer decides, not the requester — copy_extensions defaults to none, deliberately, because otherwise anyone could request CA:TRUE.
🔑 Do this with your own beliefs, not just these three. Write down three things you would say confidently in an interview, then find a way to test each one in under five minutes. The ones that survive you can say with real conviction; the ones that do not were going to be caught by someone in a room, which is a considerably worse place to find out.
💡 The pattern behind all three is the same: the permissive thing succeeds silently. OpenSSL accepts the legacy CN, skips the hostname check, and drops the extensions you asked for — and in every case it returns success rather than a warning. Tools default to letting you continue. That is a reasonable design choice and it means a green result is much weaker evidence than it feels.
E5 · Self-assessment
Answer each out loud before opening it. If your answer is materially thinner than the one behind the toggle, that topic is worth a second pass.
1. What are the four rounds of a TLS interview testing?
Rapid-fire tests vocabulary — you cannot win on it and you can lose on it. Live troubleshooting tests your order of operations under pressure. Design tests whether you know the trade-offs and whether you scope before answering.
The deep follow-up tests what you do when you reach the edge of what you know — and since everybody reaches it, that round is really about one behaviour, not about knowledge.
2. What is the shape of a strong answer?
Three parts: the answer in one or two sentences with no preamble, then the mechanism — why it is that way — then one operational detail, gotcha or trade-off that only someone who has done it would know.
Ending on a claim is deliberate: it gives the interviewer something to pull on, which means you have chosen the next question rather than waiting for it.
3. What do you say when you do not know?
Say so immediately, without apology, and then say how you would find out — which document, and what you would test. That is a complete answer and it closes the topic cleanly.
Bluffing is the most damaging thing available to you, because an engineer who produces confident wrong answers is a liability in an incident, and interviewers are specifically watching for it.
4. Error 18 versus error 19?
18 — the leaf itself is self-signed: subject equals issuer, one certificate in the chain. Usually a test certificate that reached a real environment.
19 — a self-signed certificate appears inside an otherwise real chain, which in practice always means the server is sending the root as well as the leaf and intermediate. It only errors on machines that do not already trust that root, which is why it presents as "works for everyone except one person".
5. curl says "expired" and the leaf has two months left. What happened?
Something else in the chain expired — almost always the intermediate. Path validation requires every certificate to be valid, and neither curl nor OpenSSL says which one failed.
The fix is a monitoring change more than a certificate change: alert on the earliest expiry across the whole chain, not the leaf's, because leaf-only monitoring gives no warning at all for this.
6. Every CLI tool says fine, browsers refuse. First check?
Whether the certificate has a SAN at all — openssl x509 -noout -ext subjectAltName. A CN-only certificate is rejected by browsers and Go under RFC 9525 while OpenSSL, curl and Python accept it through a legacy fallback.
The general principle is that your CLI tools are more permissive than your users' clients, so smoke tests should assert on the certificate's contents rather than on the connection succeeding.
7. Does openssl s_client check the hostname?
Not unless you pass -verify_hostname. Without it, a certificate that does not cover the name you asked for still reports Verify return code: 0 (ok).
This is the single most common way people verify the wrong thing and believe it. -servername sets SNI; it does not enable the check.
8. Are a CSR's requested extensions used?
No, not by default. The issuer decides the final extensions; copy_extensions defaults to none. A CSR asking for a SAN can produce a certificate with no extensions at all.
It is deliberate: with copying enabled, a requester could ask for basicConstraints=CA:TRUE and be issued a CA certificate.
9. What are the four moves of a design answer?
Scope it — ask what is public versus internal, what platform, what the actual pain is. State the principle. Pick something and say why that one. Then name what it costs, unprompted.
The fourth is the one people skip, and presenting a choice as free is the fastest way to sound like you have only read about it.
10. What is the most common gap in a "500 services" answer?
Monitoring. Most candidates answer the issuance half — cert-manager, ACME, Vault — and stop. Issuance is the easy part; knowing when it silently stopped working is what actually prevents outages.
The two details that distinguish a real answer are reading expiry from the live connection rather than from files, and alerting on the whole chain's earliest expiry.
11. Why should you deliberately find your limits before an interview?
Because hitting a known limit is a fact and hitting an unknown one is a shock — and the shock is audible. People bluff not because they intend to but because they have no prepared alternative to silence.
Three levels deep is the working minimum on anything you would claim as a strength. Two topics you can go five levels down on are worth more than ten you can go two.
12. You scored 27/40 on the mock. What do you do?
Not more reading. A score in the mid-twenties means the knowledge is there and the delivery is not, and more input does not close that gap — more output does.
Re-run the capstone out loud, twice, and most of the lost marks will move without learning a single new fact. Save the module revision for whichever round scored lowest.
E6 · Command reference — the ones worth having in your hands
Look at anything
openssl x509 -in cert.pem -noout -text # ⭐ everything
openssl x509 -in cert.pem -noout -subject -issuer -dates # ⭐ the four facts
openssl x509 -in cert.pem -noout -ext subjectAltName # ⭐ which names is it for?
openssl req -in req.csr -noout -text # read a CSR
openssl crl -in ca.crl -noout -text # read a CRLLook at a live server
echo | openssl s_client -connect host:443 -servername host -verify_hostname host # ⭐
echo | openssl s_client -connect host:443 -servername host 2>/dev/null \
| sed -n '/Certificate chain/,/^---/p' # ⭐ what did they send?
echo | openssl s_client -connect host:443 -servername host 2>/dev/null \
| openssl x509 -noout -subject -dates -fingerprint -sha256 # ⭐ the cert you got
curl -sS https://host/ 2>&1 | head -1 # ⭐ the ten-second triageMake things
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out k.pem # ⭐ a key
openssl req -new -key k.pem -out c.csr -subj "/CN=example.com" # ⭐ a CSR
openssl x509 -req -in c.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 90 -sha256 -extfile ext.cnf -out c.crt # ⭐ sign it
openssl req -x509 -new -key ca.key -sha256 -days 3650 -out ca.crt \
-subj "/CN=My CA" -addext "basicConstraints=critical,CA:TRUE" # ⭐ a CACheck things match
openssl x509 -in c.crt -noout -pubkey | openssl sha256 # ⭐ does the key match the cert?
openssl pkey -in k.pem -pubout | openssl sha256 # ⭐ compare these two
openssl verify -CAfile ca.crt c.crt # ⭐ does the chain verify?
openssl verify -CAfile ca.crt -purpose sslclient c.crt # valid for client auth?
openssl x509 -in c.crt -noout -purpose # what is it allowed to do?openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out ca.key
openssl req -x509 -new -key ca.key -sha256 -days 3650 -out ca.crt -subj "/CN=My CA" \
-addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out srv.key
openssl req -new -key srv.key -out srv.csr -subj "/CN=example.com"
printf 'basicConstraints=critical,CA:FALSE\nkeyUsage=critical,digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth\nsubjectAltName=DNS:example.com\n' > ext.cnf
openssl x509 -req -in srv.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 90 -sha256 -extfile ext.cnf -out srv.crt
openssl verify -CAfile ca.crt srv.crtThe extensions file is the part people forget, and without it the certificate has no SAN, no EKU and no basicConstraints — and openssl verify will still say OK.
Look back at where this started. Module 01 built four cryptographic primitives and a lab directory. Fourteen modules later you can read a certificate byte by byte, run a two-tier CA, deploy and debug TLS on real servers, explain why revocation failed and what replaced it, monitor an estate, and audit any endpoint with a tool you wrote yourself.
The thing worth keeping is not the facts. Those change — lifetimes are still falling, OCSP is still being retired, post-quantum key exchange is arriving as you read this. What does not change is the shape underneath: trust is a union, not an intersection; short lifetimes beat revocation; automation is a precondition rather than a reward; and the tools default to letting you continue, so a green result is weaker evidence than it feels.
Three things worth doing next, in order. Re-run the drill and the Part C lab once a month — fifteen minutes, and it stays sharp. Publish CAA records on every domain you own, today, because it is the highest value-per-minute action in the entire track. And go and break something on purpose in a lab, because the fastest way to keep this knowledge alive is to keep meeting the failures while they are still cheap.
Good luck in the interview. You are considerably more prepared than most people in that room.
📚 Sources for the interview questions
This module is a rehearsal rather than new material — every technical claim in it was established and verified in Modules 01–13, and the sources for each are recorded there. The question selection and the round structure were cross-referenced against publicly published 2026 SSL/TLS and PKI interview question sets, then rewritten and deepened:
- InterviewPrep — Top 25 SSL interview questions
- A published SSL/TLS/mTLS system-design mock interview
- ClimbTheLadder — PKI interview questions
- Medium — SSL certificates: a common interview question and how to answer it
Every command and expected output in Parts A, C and E was executed on OpenSSL 3.0.13, nginx 1.24.0, curl 8.5.0, Python 3.12 and Go 1.22 — including all four Part C scenarios and their verify codes (18, 0, 10, 0 with the root trusted; 19 without it), the Go rejections quoted in Scenario 3, and all three claims in Exercise E4.1.
Two results are worth recording because they are the module's own evidence for its central point. Scenario 3's certificate, which has a Common Name and no SAN, is accepted by OpenSSL, curl and Python and rejected by Go with x509: certificate relies on legacy Common Name field, use SANs instead — confirming the finding first established and corrected in Module 03. And in Exercise E4.1, two of the three "confident" claims are false when tested: openssl s_client returns Verify return code: 0 (ok) for a hostname the certificate does not cover unless -verify_hostname is passed, and a CSR requesting subjectAltName produced a certificate reported as having no extensions at all.
The four rounds, the three-part answer shape, and the scoring rubric are a synthesis of how technical interviews in this field are commonly structured rather than a claim about any particular employer's process. Treat them as a rehearsal framework, not a specification.
Answers were rewritten and deepened rather than reproduced — published versions are usually correct but shallow, and the added operational detail is what actually differentiates a candidate in the room.