← Week 3: mTLS and TLS Extensions

Day 18: TLS Extensions — SNI, ALPN, supported_groups

Phase 1 · May 31, 2026

← Week 3: mTLS and TLS Extensions

Agenda (2–3 hours)

  • Read (60 min): RFC 8446 §4.2 (Extensions); RFC 6066 §3 (SNI); RFC 7301 (ALPN)
  • Study (45 min): Extension wire format, negotiation mechanics, privacy implications
  • Practice (45 min): Observe and control extensions with Rust
  • Challenge (30 min): Custom SNI + ALPN client
← Week 3: mTLS and TLS Extensions

TLS Extension Wire Format

struct {
    ExtensionType extension_type;   // 2 bytes: type code
    opaque extension_data<0..2^16-1>;
} Extension;

Extensions appear in: ClientHello, ServerHello, EncryptedExtensions, Certificate,
CertificateRequest, HelloRetryRequest, NewSessionTicket.

Some extensions (key_share, supported_versions) are mandatory in TLS 1.3 ClientHellos.

← Week 3: mTLS and TLS Extensions

SNI: Server Name Indication (RFC 6066 §3)

Problem: Multiple virtual hosts on one IP. How does the server know which cert to serve before the TLS handshake is authenticated?

Solution: Client sends the hostname in the ClientHello (in plaintext).

HostName: server name (e.g., "api.amazon.com")

Privacy implication: SNI is visible to network observers even in TLS 1.3.
ECH (Encrypted ClientHello) is the in-progress IETF solution (RFC 9258 + drafts).

If the server doesn't recognize the SNI, it may send unrecognized_name (alert 112).

← Week 3: mTLS and TLS Extensions

ALPN: Application-Layer Protocol Negotiation (RFC 7301)

Client offers a list of protocols it supports:

ProtocolNameList: ["h2", "http/1.1"]

Server responds with the selected protocol in EncryptedExtensions:

ProtocolName: "h2"

Relevant to your work: provisioning APIs over gRPC use ALPN "h2".
If ALPN is misconfigured, clients may fall back to HTTP/1.1 silently.

← Week 3: mTLS and TLS Extensions

supported_groups Extension

Client lists acceptable named groups for ECDHE:

NamedGroupList: [x25519, secp256r1, secp384r1, ...]

Server picks one and sends its key_share for that group.

Current recommended order: x25519 first (fastest, no timing side-channels),
then secp256r1 for broader compatibility.

Post-quantum note: IETF TLS WG is defining hybrid groups:
X25519Kyber768Draft00 = x25519 + ML-KEM-768 (Phase 3 preview).

← Week 3: mTLS and TLS Extensions

Practice Exercise

# Observe SNI in a capture (plaintext in ClientHello)
tshark -r /tmp/phase1_day14.pcapng -Y "tls.handshake.type==1" \
  -T fields -e tls.handshake.extensions_server_name

# Observe ALPN
tshark -r /tmp/phase1_day14.pcapng -Y "tls.handshake.type==2" \
  -T fields -e tls.handshake.extensions_alpn_str
← Week 3: mTLS and TLS Extensions

Challenge Assignment

Write a Rust TLS client using tokio-rustls and rustls that:

  1. Accepts --host, --port, --sni, and --alpn CLI arguments
  2. Connects using the specified SNI (which may differ from the actual hostname)
  3. Offers the specified ALPN protocol(s)
  4. Prints the negotiated ALPN protocol from the server's response
  5. Prints whether the server certificate's SANs match the SNI value provided

Test with SNI matching and mismatching the actual host. Document what happens.

← Week 3: mTLS and TLS Extensions

Resources

  • RFC 8446 §4.2: Extension definitions
  • RFC 6066 §3: Server Name Indication
  • RFC 7301: ALPN
  • rustls ClientConfig docs — how to set ALPN protocols
  • ECH draft: draft-ietf-tls-esni (for privacy context, optional reading)