← Week 3: mTLS and TLS Extensions

Day 15: mTLS — Client Certificate Authentication

Phase 1 · May 28, 2026

← Week 3: mTLS and TLS Extensions

Agenda (2–3 hours)

  • Read (60 min): RFC 8446 §4.3.2 (CertificateRequest), §4.4.2 (Certificate in client auth context)
  • Study (45 min): Full mTLS flow, server-side validation, use cases
  • Practice (60 min): Set up a working mTLS connection with openssl
← Week 3: mTLS and TLS Extensions

Why mTLS?

Standard TLS authenticates the server to the client.
mTLS adds client authentication — the server verifies the client's identity too.

Use cases directly relevant to your work:

  • Service-to-service communication (Lambda → provisioning API)
  • Device provisioning bootstrap (device proves identity to get its first cert)
  • Admin/operator interfaces (human clients with certs instead of passwords)

mTLS eliminates the need for API keys or tokens when both sides have certs.

← Week 3: mTLS and TLS Extensions

mTLS Handshake Flow

Client                              Server
  │── ClientHello ─────────────────────►│
  │◄── ServerHello ────────────────────│
  │◄── EncryptedExtensions ────────────│
  │◄── CertificateRequest ─────────────│  ← server requests client cert
  │◄── Certificate (server) ───────────│
  │◄── CertificateVerify (server) ─────│
  │◄── Finished (server) ──────────────│
  │── Certificate (client) ────────────►│  ← client sends its cert
  │── CertificateVerify (client) ───────►│  ← client proves key ownership
  │── Finished (client) ───────────────►│

CertificateRequest is what differentiates mTLS from standard TLS.

← Week 3: mTLS and TLS Extensions

CertificateRequest Message

struct {
    opaque certificate_request_context<0..2^8-1>;
    Extension extensions<2..2^16-1>;
} CertificateRequest;

Key extensions:

  • signature_algorithms: what the server will accept for client CertificateVerify
  • certificate_authorities: list of acceptable CA DNs (client filters its certs)
  • oid_filters: filter by certificate extension OIDs

If the client has no acceptable cert, it sends an empty Certificate message (not an error in TLS 1.3 — the server decides whether to abort).

← Week 3: mTLS and TLS Extensions

Practice Exercise

# Step 1: Create a local CA
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
  -keyout ca.key -out ca.crt -days 365 -nodes -subj "/CN=Test CA"

# Step 2: Create server cert signed by CA
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
  -keyout server.key -out server.csr -nodes -subj "/CN=localhost"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 365

# Step 3: Create client cert signed by CA
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
  -keyout client.key -out client.csr -nodes -subj "/CN=test-client"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out client.crt -days 365

# Step 4: Test mTLS
openssl s_server -cert server.crt -key server.key -CAfile ca.crt \
  -Verify 1 -port 4433 &
openssl s_client -connect localhost:4433 -cert client.crt -key client.key \
  -CAfile ca.crt
← Week 3: mTLS and TLS Extensions

Challenge Assignment

Save the openssl commands from the practice exercise as a shell script setup_mtls.sh.
Then extend it to deliberately cause and capture these two failures:

  1. Client presents a cert signed by a different CA — what alert does the server send?
  2. Client sends an empty Certificate message (use -cert /dev/null trick or similar)
    — what does the server do? Does it abort or continue?

Document the exact TLS alert (type + description) for each failure.

← Week 3: mTLS and TLS Extensions

Resources

  • RFC 8446 §4.3.2: CertificateRequest
  • RFC 8446 §4.4.2: Certificate (covers both client and server cert messages)
  • openssl s_server / s_client man pages