TT Lab
Get started
Learn Learning paths Courses

The certificate was renewed, but the browser still showed the old one

Read one certificate in four pieces

Continue in TT Lab

Goal

Issue a server certificate from your own CA, and verify the chain, validity period, SAN, and key match each with openssl. Set up an intermediate CA, assemble a fullchain, and record the hostname check results in a table.

Why it matters

A certificate incident is one of four things — the chain is broken, it has expired, the name is different, or the key is not the matching one. The fixes are all different, so you have to read which one it is first. In this lab you create those four situations on purpose and see what the verifier says. In particular, the fact that x509 -req in OpenSSL 3.0 discards the CSR's extensions by default is a trap in which issuance looks successful, so it is better to run into it yourself.

Steps

  1. Create /root/pki/ca.key and the self-signed certificate /root/pki/ca.crt. The subject is CN=Lab Root CA and the validity is 30 days.
  2. Create the server key /root/pki/server.key and the CSR /root/pki/server.csr. The subject is CN=www.lab.internal, and the SANs are two entries, DNS:www.lab.internal and DNS:api.lab.internal.
  3. Sign with the CA to create /root/pki/server.crt. The validity is 3 days, and the SAN must remain in the certificate.
  4. Save the serial number, expiry date, SHA-256 fingerprint, and SAN of server.crt to /root/pki/04-fields.txt.
  5. Create one more key for comparison, /root/pki/other.key, and in /root/pki/05-keymatch.txt write three lines, cert=, key=, and other= (each the 64-digit sha256 of the public key PEM), plus verdict=match.
  6. In /root/pki/06-expiry.txt, write the output line of openssl x509 -enddate and renew_within_7d=yes|no. Decide the verdict by the exit code of -checkend 604800.
  7. Create an intermediate CA (/root/pki/inter.key, /root/pki/inter.crt, CN=Lab Intermediate CA, CA:TRUE) signed by the root, and with that intermediate CA issue the leaf /root/pki/api.crt (key /root/pki/api.key, SAN DNS:api.lab.internal). Concatenate the leaf and the intermediate CA in that order to make /root/pki/fullchain.pem.
  8. For server.crt, write the verification results for the three names www.lab.internal, api.lab.internal, and other.lab.internal to /root/pki/08-hostname.txt in the form 이름=OK|FAIL (name, then OK or FAIL; use the actual hostname on the left).

Notes

Create the root CA

Create /root/pki/ca.key and the self-signed /root/pki/ca.crt (CN=Lab Root CA, 30 days).

If you pass -x509 to req, you get a self-signed certificate instead of a CSR. Check with openssl x509 -text that the issuer and subject are the same and that basicConstraints is CA:TRUE.

A CSR with a SAN

Create /root/pki/server.key and /root/pki/server.csr (CN=www.lab.internal, two SANs).

You can create the key and the CSR in one go with -newkey rsa:2048 -nodes -keyout. Add the SAN with -addext, and check the Subject Alternative Name in openssl req -in server.csr -noout -text.

Issue a 3-day server certificate

Sign with the CA to create /root/pki/server.crt (3 days, SAN preserved).

The skeleton is x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3. If openssl x509 -in server.crt -noout -ext subjectAltName is empty after issuance, the CSR's extensions were discarded — there is an option that carries them over.

Read the identifying values

Save the serial number, expiry date, SHA-256 fingerprint, and SAN of server.crt to /root/pki/04-fields.txt.

You can pass -serial -enddate -fingerprint -sha256 -ext subjectAltName to x509 all at once. The grader recomputes the values from the same certificate and compares them.

Decide whether the keys match

Create /root/pki/other.key, and in /root/pki/05-keymatch.txt write cert=, key=, and other= (the sha256 of the public key PEM) plus verdict=match.

The certificate's public key comes from x509 -pubkey, and the public key of the private key from pkey -pubout, both in the same PEM format. Keep only the 64 digits with | sha256sum | cut -d' ' -f1. The cert and key values must be the same and only other must differ.

Judge expiry with a 7-day window

In /root/pki/06-expiry.txt, write the -enddate output line and renew_within_7d=yes|no.

-checkend 604800 exits with a nonzero code if the certificate expires within 7 days (604800 seconds). Catch it with an if statement and decide yes or no. For a 3-day certificate, the answer is already settled.

Intermediate CA and fullchain

Create an intermediate CA signed by the root (inter.key/inter.crt, CN=Lab Intermediate CA, CA:TRUE), issue the leaf api.crt (SAN api.lab.internal) with it, and then create /root/pki/fullchain.pem in the order leaf + intermediate.

When you sign the intermediate CA's CSR with the root, pass basicConstraints=critical,CA:TRUE,pathlen:0 and keyUsage=critical,keyCertSign,cRLSign in -extfile. Sign the leaf with -CA inter.crt -CAkey inter.key. It is a real chain only if openssl verify -CAfile ca.crt api.crt fails and passes when you add -untrusted inter.crt.

Hostname check table

For server.crt, write the -verify_hostname results for the three names www, api, and other to /root/pki/08-hostname.txt in the form 이름=OK|FAIL (name, then OK or FAIL).

The name check compares against the SAN's dNSName entries. A name that is in the CN but not in the SAN fails. Loop over the three names with for and decide OK or FAIL by the exit code.