Hacker DirectoryHacker Directory

WEB / WEB-05.03

TLS handshake, SNI and ALPN

Track offers, selections, validation and peer-local completion in TLS1.3 flights.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

TLS1.3 full flow

  1. TCP is ready before TLS

    A new TLS context uses existing TCP, selecting no PSK, early data or client certificate.

    Client · TLS
    CH offers ready; TLS peer unverified; application gate=false
    Server · TLS
    TCP ready; no ClientHello; application gate=false
  2. ClientHello at the server

    Offers and SNI arrived; no service/user-authentication result exists.

    Client · TLS
    CH offers ready; TLS peer unverified; application gate=false
    Server · TLS
    CH received; SNI=api.example.org; ALPN offers=h2,http/1.1; peer unverified
  3. Local selection and flight preparation

    The server selects cryptographic options and EE ALPN=h2; emitting its own Finished does not verify the peer.

    Client · TLS
    CH offers ready; TLS peer unverified; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  4. ServerHello at the client

    Selected key share/version/cipher supply local derivation context; identity remains pending.

    Client · TLS
    SH received; handshake key context; service identity pending; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  5. Protected flight at the client

    The encrypted server-handshake summary arrived; receipt is not validation success.

    Client · TLS
    EE/Certificate/CertificateVerify/Finished received; checks pending; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  6. Local client authentication gate

    Client checks pass and its own Finished is handed off; the server has not received it.

    Client · TLS
    path/name/key proof/peer Finished=true; own Finished emitted; application gate=true
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  7. Client Finished at the server

    The handshake-protected Finished arrived; local verification is the next step.

    Client · TLS
    path/name/key proof/peer Finished=true; own Finished emitted; application gate=true
    Server · TLS
    client Finished received; local verification pending; application gate=false
  8. Local server verification

    The selected MAC check passes; both directions are application-ready, with no HTTP business result.

    Client · TLS
    path/name/key proof/peer Finished=true; own Finished emitted; application gate=true
    Server · TLS
    client Finished verified; own Finished emitted; application gate=true; user identity unmodeled

Finished failure

  1. TCP is ready before TLS

    A new TLS context uses existing TCP, selecting no PSK, early data or client certificate.

    Client · TLS
    CH offers ready; TLS peer unverified; application gate=false
    Server · TLS
    TCP ready; no ClientHello; application gate=false
  2. ClientHello at the server

    Offers and SNI arrived; no service/user-authentication result exists.

    Client · TLS
    CH offers ready; TLS peer unverified; application gate=false
    Server · TLS
    CH received; SNI=api.example.org; ALPN offers=h2,http/1.1; peer unverified
  3. Local selection and flight preparation

    The server selects cryptographic options and EE ALPN=h2; emitting its own Finished does not verify the peer.

    Client · TLS
    CH offers ready; TLS peer unverified; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  4. ServerHello at the client

    Selected key share/version/cipher supply local derivation context; identity remains pending.

    Client · TLS
    SH received; handshake key context; service identity pending; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  5. Protected flight at the client

    The encrypted server-handshake summary arrived; receipt is not validation success.

    Client · TLS
    EE/Certificate/CertificateVerify/Finished received; checks pending; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified
  6. Local client authentication gate

    Finished is selected to fail; neither own Finished nor application transmission is selected.

    Client · TLS
    path/name/key proof=true; server Finished=false; own Finished unsent; application gate=false
    Server · TLS
    selected TLS1.3/X25519; SH + protected flight ready; own Finished emitted; client Finished unverified

ALPN no overlap

  1. Expect a shared protocol

    The selected ALPN offer and server support differ.

    Client · TLS
    CH ALPN=h2 ready; peer unverified
    Server · TLS
    server ALPN support=http/1.1; no CH
  2. ALPN offer at the server

    The offer contains only h2, absent from server support.

    Client · TLS
    CH ALPN=h2 ready; peer unverified
    Server · TLS
    CH received; ALPN=h2; server supports http/1.1
  3. Local no-overlap decision

    Selected negotiation stops with no_application_protocol; no new TCP is opened.

    Client · TLS
    CH ALPN=h2 ready; peer unverified
    Server · TLS
    no common ALPN; fatal alert prepared; no SH/protected channel
  4. Alert at the client

    The semantic failure alert arrived; no actual encoding or encryption is claimed.

    Client · TLS
    fatal no_application_protocol received; application gate=false
    Server · TLS
    no common ALPN; fatal alert prepared; no SH/protected channel

ECH accepted

  1. Selected ECH configuration

    A preconfigured public-key alias separates Outer public_name from the Inner service.

    Client · TLS
    usable ECH config; Outer/Inner prepared; acceptance pending
    Server · TLS
    shared-mode ECH support; no Outer
  2. ClientHelloOuter at the server

    Outer arrival does not expose the Inner service to every observer; HPKE outcome remains pending.

    Client · TLS
    usable ECH config; Outer/Inner prepared; acceptance pending
    Server · TLS
    Outer received; public_name=front.example.org; encrypted Inner pending
  3. Local Inner selection

    The shared-mode terminator uses the selected Inner; this is not hostname verification.

    Client · TLS
    usable ECH config; Outer/Inner prepared; acceptance pending
    Server · TLS
    selected HPKE success; Inner SNI=api.example.org; ALPN=h2 offer; identity unverified
  4. Accepted response context

    ECH acceptance is selected; actual response TLS encoding is not modeled.

    Client · TLS
    usable ECH config; Outer/Inner prepared; acceptance pending
    Server · TLS
    ECH accepted selected; Inner-context response flight ready; client acceptance pending
  5. Response at the client

    Response arrival does not replace acceptance determination and identity verification.

    Client · TLS
    Inner-context response received; ECH acceptance/identity checks pending
    Server · TLS
    ECH accepted selected; Inner-context response flight ready; client acceptance pending
  6. Local acceptance and identity

    Both checks are selected to pass; config discovery/retry and actual HPKE do not execute, and no request is sent.

    Client · TLS
    ECH acceptance + intended identity verified selected; Outer/IP metadata remain; no HTTP request
    Server · TLS
    ECH accepted selected; Inner-context response flight ready; client acceptance pending

ACTORS · STATE · DATA FLOW

The selected path for a new TLS connection

The TLS-over-TCP scene starts with an already-established TCP connection. It selects a new TLS1.3 connection with an ephemeral X25519 share, server-certificate authentication, ALPN and ordinary 1-RTT. Client certificates, PSK resumption, 0-RTT, HelloRetryRequest and post-handshake authentication are not executed. A TLS handshake is not a new TCP handshake.

The current RFC9846 replaces and obsoletes RFC8446 while retaining TLS 1.3; section numbering also changed. Certificate/CertificateVerify/Finished are now 4.5.1/4.5.2/4.5.3. Rather than invent capture bytes, this lesson shows semantic message flights and each peer’s learning and validation points.

ClientHello offers; ServerHello selects

ClientHello carries offers such as supported_versions, cipher suites, supported groups/key_share and signature_algorithms. The normal example offers TLS1.3, TLS_AES_128_GCM_SHA256, X25519 and ed25519 capabilities, using key-share aliases instead of bytes. A TLS1.3 cipher suite selects an AEAD/hash pair, not the entire certificate-signature and key-exchange algorithm combination.

ServerHello completes the context for the client key schedule using negotiated version/cipher and selected key_share. Deriving shared secrets and handshake keys is local; those keys are not carried in another network message. The legacy_version field is not the negotiated TLS version; modern version negotiation uses supported_versions. The branch requiring HelloRetryRequest is outside this example.

Protected handshake follows ServerHello

EncryptedExtensions is followed, in the certificate-authenticated branch, by Certificate, CertificateVerify and server Finished; handshake messages after ServerHello use handshake traffic keys. Ordinary TLS1.3 ClientHello and ServerHello are outside that protection. EncryptedExtensions carries parameters such as ALPN selection; do not copy the TLS1.2 ALPN diagram’s ServerHello placement into TLS1.3.

A flight does not mean that every message occupies one TCP segment or TLS record. The scene separates ServerHello arrival from protected server-flight arrival, then aggregates protected messages in one semantic summary. Key aliases, deprotection and path/name outcomes are selected conditions; no real serializer, transcript hash or certificate parser executes.

Transcript, key proof and Finished are distinct checks

CertificateVerify binds possession of the selected certificate private key to the handshake through a signature input containing a context string and transcript hash. Finished MACs the transcript using a key derived from the relevant handshake traffic secret. Neither is the CA certificate signature; the peer’s list, negotiated-parameter history and key confirmation provide distinct evidence.

In the selected normal branch, the client accepts path/hostname, CertificateVerify and server Finished, then sends its own Finished before opening its local application-data gate. The server may have sent its own Finished while not yet receiving and validating the client’s. Sending server application data after its first flight is a separately permitted case; this scene does not select it and proves no client user identity.

SNI helps select a service

The host_name field in SNI’s server_name extension indicates the client’s intended DNS hostname; the server can use it to choose a certificate or configuration. api.example.org is a routing hint, not an authenticated user or proof of a matching certificate. Even after server configuration selection, the client independently verifies its reference identity.

RFC6066 host_name uses an ASCII DNS name, with A-labels for IDNs and no trailing dot or literal IPv4/IPv6 address. SNI and HTTP authority/Host belong to different layers: the normal case expresses the same service intent, but the former is not authorization proof for the latter. The TLS1.3 SNI response belongs in EncryptedExtensions; legacy extended-ServerHello placement must not be generalized to this profile.

ALPN selects one protocol for a connection

The client offers h2 and http/1.1; the selected server preference finds h2 as a common option and reports it in EncryptedExtensions. This negotiation does not open another TCP connection; it determines which application parser and semantics use the existing TLS connection. Offering h2 or connecting to port443 does not prove that h2 was selected.

In the selected no-overlap branch, the client supports only h2 and the server only http/1.1: ALPN negotiation stops with a fatal no_application_protocol result. No ServerHello or protected-channel setup is selected before failure; the scene shows semantic alert arrival without claiming encryption or actual wire bytes. h3 belongs to HTTP3 over QUIC and does not automatically result from ordinary TLS-over-TCP h2 selection.

ECH requires additional conditions beyond ordinary TLS1.3

RFC9849 defines public ClientHelloOuter and encrypted ClientHelloInner for ECH. With a usable configuration/public key and client/server support, accepted ECH can protect the real service’s SNI and sensitive offers inside Inner; Outer public_name and external connection information remain. TLS1.3 does not mean every ClientHello is hidden.

The ECH branch selects a usable preconfigured configuration and shared mode: the client-facing and TLS-terminating server are one actor. Local Inner decryption and acceptance determination do not replace handshake-identity verification. A connection established through rejected ECH cannot carry application data; retry/configuration policy is a separate process not executed here. ECH does not hide all IP/time/size observations or the endpoint’s service knowledge; presence and acceptance are different facts.

2. Red · Trust & Impact

Read every scenario without motion

Finished gate

  1. Negotiation is not authentication yet

    ServerHello selects TLS 1.3/cipher/group; ALPN is selected in EncryptedExtensions. SH arrival does not change clientPeerVerified=false; a key share is not an identity verdict.

    Negotiation evidence
    SH selection / identity pending
    Verification gate
    No verification
    Application boundary
    Application gate closed
  2. Receipt and verification were separated

    finishedFailure has path/name/CertificateVerify=true but serverFinished=false. Receiving Finished does not mean the local MAC check passed.

    Negotiation evidence
    SH selection / identity pending
    Verification gate
    Finished received ≠ verified
    Application boundary
    Application gate closed
  3. The application gate retained its predicate

    clientFinishedSent=false and applicationGateOpen=false are failure outcomes. A provisional protected flight is not promoted to application success.

    Negotiation evidence
    SH selection / identity pending
    Verification gate
    Finished received ≠ verified
    Application boundary
    Own Finished withheld / gate closed
  4. SNI selection carries no entitlement

    sniDnsName=api.example.org informs server-configuration selection. serverNameResponseCarriesHostname=false; user/resource permission requires separate application predicates.

    Negotiation evidence
    SNI hint / not user authority
    Verification gate
    Finished received ≠ verified
    Application boundary
    Own Finished withheld / gate closed
  5. The server’s next step was skipped

    Because the client withheld its own Finished, the server cannot receive and verify it. Failed server-Finished verification keeps the application gate closed; SNI selection does not alter that result.

    Negotiation evidence
    SNI hint / not user authority
    Verification gate
    Server Finished failed; no client Finished
    Application boundary
    Application gate closed
  6. Verification failed; application closed

    Successful path, hostname and CertificateVerify predicates do not compensate for serverFinished=false. This example skips client Finished and application-data transmission; diagnosing a real connection requires separate endpoint evidence.

    Negotiation evidence
    SNI hint / not user authority
    Verification gate
    Server Finished failed; no client Finished
    Application boundary
    Finished rejected; application closed

ECH scope

  1. Outer and Inner carry different names

    In the ECH example, public Outer carries front.example.org while Inner requests api.example.org. A usable configuration and shared-mode terminator are supplied. Seeing Outer proves neither acceptance of Inner nor verification of the service identity.

    Negotiation evidence
    Outer front.example.org / Inner api.example.org
    Verification gate
    Acceptance and identity not yet reviewed
    Application boundary
    No application outcome
  2. Receipt and verification were separated

    ECH acceptedSelected and echAcceptanceVerifiedSelected are supplied together. Extension visibility alone establishes neither acceptance nor intendedServiceIdentityVerifiedSelected.

    Negotiation evidence
    Outer front.example.org / Inner api.example.org
    Verification gate
    ECH acceptance requires check
    Application boundary
    Application gate closed
  3. The boundary of accepted ECH

    This branch supplies true acceptedSelected, echAcceptanceVerifiedSelected and intendedServiceIdentityVerifiedSelected. An unusable rejected connection is a separate rule, not an event in this accepted branch. No HTTP-operation or retry outcome is supplied.

    Negotiation evidence
    Outer front.example.org / Inner api.example.org
    Verification gate
    Acceptance and intended identity predicates true
    Application boundary
    Accepted ECH; no HTTP outcome
  4. The terminator knows the service; user permission is separate

    In shared mode, the TLS terminator opening Inner learns api.example.org. That service knowledge is neither user identity nor resource authorization. Accepted ECH does not hide the service name from the endpoint that processes it.

    Negotiation evidence
    Terminator knows the Inner service name
    Verification gate
    Acceptance and intended identity predicates true
    Application boundary
    Accepted ECH; no HTTP outcome
  5. Privacy scope was not expanded

    Ordinary CH/SH are not protected by handshake keys; postServerHelloHandshakeProtected=true. ECH Outer stays public and ip/time/size fully hidden=false; encryption does not hide all metadata.

    Negotiation evidence
    Terminator knows the Inner service name
    Verification gate
    Outer/public metadata separate
    Application boundary
    Accepted ECH; no HTTP outcome
  6. The failure control finished within scope

    ECH is bounded by a shared-mode terminator, preconfigured configuration and selected acceptance predicates. Without executing HPKE/DNS or live client support, no deployment acceptance is added.

    Negotiation evidence
    Terminator knows the Inner service name
    Verification gate
    Outer/public metadata separate
    Application boundary
    ECH acceptance predicates supplied; runtime unmeasured

ASSUMPTION · BOUNDARY · CONTROL

Broken assumption: Hello selection is authentication

Treating a key-share and cipher selection as verified service identity skips path/name/CertificateVerify/Finished gates. SNI configuration selection does not repair that omission.

Keep negotiated context and validated identity in distinct state. The SH arrival supplies key context while identity remains pending.

Broken assumption: Finished presence establishes validity

Finished arrival without MAC verification does not complete key confirmation. The required mistake is treating received transcript data as a validation result.

Keep the own-Finished/application gate closed when local checks fail. This branch shows a selected fixture outcome, without actual transcript alteration or network interference.

Broken assumption: a privacy extension hides everything

Seeing an ECH extension does not establish acceptance or a validated intended service. Outer context, IP and traffic patterns retain separate information boundaries.

Explain configuration, selected topology, acceptance and identity results separately. Recording an ALPN offer as the selected protocol makes the same premature-state error.

3. Blue · Secure development & defense

Read every scenario without motion

Peer gates

  1. An offer is not the selected protocol

    Normal CH offers alpn=[h2, http/1.1]. Server preference is the same list; the first common h2 is selected and reported in EncryptedExtensions.

    Offer evidence
    Offer h2,http/1.1 / selected h2
    Selection evidence
    No selection review
    Peer-gate review
    No gate review
  2. The selection message is at the right stage

    alpnSelectedInServerHello=false. A TLS cipher suite does not identify certificate key type; version/cipher/group agreement is read separately from ALPN and certificate-signature predicates.

    Offer evidence
    Offer h2,http/1.1 / selected h2
    Selection evidence
    ALPN in EE / cipher≠cert key type
    Peer-gate review
    No gate review
  3. Client peer-gate scope was examined

    Protected server-flight receipt still has clientPeerVerified=false/clientApplicationReady=false. Receipt is not verification success before local path/name/CertificateVerify/Finished checks complete.

    Offer evidence
    Offer h2,http/1.1 / selected h2
    Selection evidence
    ALPN in EE / cipher≠cert key type
    Peer-gate review
    Receipt / client verification pending
  4. The server gate updates independently

    Client local checks+own Finished emission make the client ready while serverPeerFinishedVerified stays false. Even after client Finished receipt, server-local verification is separate.

    Offer evidence
    Offer h2,http/1.1 / selected h2
    Selection evidence
    Emission ≠ server Finished verification
    Peer-gate review
    Client ready; server Finished verification pending
  5. The server completed local verification

    peerGates[3] records message receipt; peerGates[4] records server-local verification of client Finished. Only the latter sets serverPeerFinishedVerified and serverApplicationReadySelected true. Normal ALPN selection remains h2.

    Offer evidence
    Offer h2,http/1.1 / selected h2
    Selection evidence
    Server verified client Finished
    Peer-gate review
    Both endpoints ready; no HTTP outcome
  6. Endpoint evidence is matched to the connection

    In an actual review, client and server TLS implementations produce their own verification results. Correlate those outcomes to the connection, separately from selected ALPN and message receipt. An open TLS gate proves no HTTP request, user authorization or application commit.

    Offer evidence
    Offer h2,http/1.1 / selected h2
    Selection evidence
    Client and server verification need separate producers
    Peer-gate review
    Peer gates open; HTTP unknown

No ALPN overlap

  1. An offer is not the selected protocol

    The client offers only h2 while the server offers only http/1.1. With no common protocol, selectedProtocol remains null. Recording a client offer as negotiated selection would conceal that negative control.

    Offer evidence
    Offer h2 / no overlap
    Selection evidence
    No selection review
    Peer-gate review
    No gate review
  2. No common protocol was found

    The intersection of client [h2] and server [http/1.1] is empty. selectedProtocol remains null; this branch produces no ALPN selection in EncryptedExtensions. The positive branch’s h2 outcome cannot be copied into this connection.

    Offer evidence
    Offer h2 / server http/1.1
    Selection evidence
    No overlap; no ALPN selection
    Peer-gate review
    Gate outcome not yet reviewed
  3. The protected flight was skipped

    The selected server outcome is a fatal no_application_protocol alert. This scene prepares no ServerHello, EncryptedExtensions, Certificate or Finished flight. It cannot supply receipt or verification evidence for those skipped messages.

    Offer evidence
    Offer h2 / server http/1.1
    Selection evidence
    Fatal no_application_protocol
    Peer-gate review
    Protected flight skipped
  4. A fatal alert is not a verification failure

    In the Core scene, the client receives the alert and its application gate stays closed. Path, hostname, CertificateVerify and Finished checks were not reached, so they are not classified as failed checks. Client Finished transmission is skipped too.

    Offer evidence
    Offer h2 / server http/1.1
    Selection evidence
    Client received fatal alert; checks skipped
    Peer-gate review
    Application closed; no client Finished
  5. Same TCP context; negotiation stopped

    newTcpConnectionCreated=false records that ALPN opened no new TCP connection. Stopped TLS negotiation alone does not determine the existing socket’s later operating-system state or a network-failure cause. This branch contains no HTTP exchange.

    Offer evidence
    no_application_protocol / no new TCP
    Selection evidence
    Client received fatal alert; checks skipped
    Peer-gate review
    Application closed; no client Finished
  6. Evidence and coverage of the negative branch

    Review client-offer evidence, server protocol configuration and the endpoint alert for the same connection together. Normal h2 selection is a separate comparison. If alert evidence is missing, do not guess the cause; this semantic example produces no actual TLS log or HTTP outcome.

    Offer evidence
    no_application_protocol / no new TCP
    Selection evidence
    Offer + server policy + endpoint alert required
    Peer-gate review
    ALPN rejected; HTTP outcome not supplied

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Connect the flight ledger to local state

Follow CH offer, local server selection, SH arrival at the client, protected flight receipt, client validation/Finished, then server receipt/validation. Protected flight arrival does not yet complete identity verification.

Server and client gates do not change in one shared step. Explain the difference between sender Finished emission and receiver verification; the scene completes no HTTP application exchange.

Calculate the offer/selection matrix

Evaluate version/cipher/group overlap separately from ALPN overlap. The first shared ALPN in server preference is h2 in the normal case; selectedProtocol remains null when no overlap exists.

A TLS cipher-suite name does not specify the certificate key type. SNI api.example.org is a DNS routing hint; neither a literal IP nor a suffix comparison supplies user permissions.

Advertise only application protocols the implementation can handle, and dispatch the connection according to its negotiated protocol. Writing HTTP/1.1 messages after h2 was selected does not honor that selection. Do not turn a null no-overlap result into an invented successful fallback. Verify both normal h2 selection and the no_application_protocol branch where application exchange never starts; correct SNI routing does not replace this protocol boundary.

Preserve conditions in the visibility table

Mark ordinary clear CH/SH context, later encrypted handshake and accepted-ECH Inner protection separately. The Outer visibility field does not claim that every deployment protects all Inner fields.

The ECH branch uses a preselected configuration, without DNS discovery, HPKE or rejection retry. A current RFC definition is not a measurement of deployment prevalence or client support.

NOW APPLY IT TO THE CASE

How do negotiation, receipt and peer acceptance differ?

The client offers api.example.org through SNI and h2 through ALPN. These are not verified-peer outcomes. Failed Finished verification keeps the application gate closed; ECH Outer and traffic metadata remain separate considerations.

Who is the peer of the case’s secure connection? Explain TLS peer trust, browser origin and user object permission as separate decisions.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Atlas · tls-hello-flight-ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "profile": {
    "transport": "already-established TCP",
    "tlsVersion": "TLS 1.3",
    "currentSpecification": "RFC9846",
    "serverAuthentication": "certificate",
    "clientCertificateRequested": false,
    "pskEarlyDataHrrSelected": false,
    "actualTlsImplementationRun": false
  },
  "clientHello": {
    "supportedVersions": [
      "TLS 1.3"
    ],
    "cipherSuites": [
      "TLS_AES_128_GCM_SHA256"
    ],
    "supportedGroups": [
      "x25519"
    ],
    "keyShareAlias": "client-x25519-public",
    "signatureAlgorithms": [
      "ed25519"
    ],
    "sniDnsName": "api.example.org",
    "alpn": [
      "h2",
      "http/1.1"
    ]
  },
  "serverHello": {
    "supportedVersion": "TLS 1.3",
    "cipherSuite": "TLS_AES_128_GCM_SHA256",
    "selectedGroup": "x25519",
    "keyShareAlias": "server-x25519-public",
    "alpnSelectedInServerHello": false
  },
  "encryptedExtensions": {
    "alpn": "h2",
    "sniAcknowledgementSelected": true,
    "serverNameResponseCarriesHostname": false
  },
  "serverProtectedFlight": [
    "EncryptedExtensions",
    "Certificate",
    "CertificateVerify",
    "server Finished"
  ],
  "certificateChecksSelected": {
    "path": true,
    "referenceHostname": true,
    "certificateVerify": true,
    "serverFinished": true
  },
  "finishedFailure": {
    "path": true,
    "referenceHostname": true,
    "certificateVerify": true,
    "serverFinished": false,
    "clientFinishedSent": false,
    "applicationGateOpen": false
  },
  "peerGates": [
    {
      "after": "SH arrival at client",
      "clientPeerVerified": false,
      "clientApplicationReady": false,
      "serverPeerFinishedVerified": false,
      "serverApplicationReadySelected": false
    },
    {
      "after": "protected server flight receipt",
      "clientPeerVerified": false,
      "clientApplicationReady": false,
      "serverPeerFinishedVerified": false,
      "serverApplicationReadySelected": false
    },
    {
      "after": "client local checks + own Finished emission",
      "clientPeerVerified": true,
      "clientApplicationReady": true,
      "serverPeerFinishedVerified": false,
      "serverApplicationReadySelected": false
    },
    {
      "after": "client Finished receipt at server",
      "clientPeerVerified": true,
      "clientApplicationReady": true,
      "serverPeerFinishedVerified": false,
      "serverApplicationReadySelected": false
    },
    {
      "after": "server local client Finished verification",
      "clientPeerVerified": true,
      "clientApplicationReady": true,
      "serverPeerFinishedVerified": true,
      "serverApplicationReadySelected": true
    }
  ],
  "alpnCases": [
    {
      "case": "normal",
      "client": [
        "h2",
        "http/1.1"
      ],
      "serverPreference": [
        "h2",
        "http/1.1"
      ],
      "selectedProtocol": "h2",
      "serverResponseMessage": "EncryptedExtensions",
      "newTcpConnectionCreated": false
    },
    {
      "case": "alpn-no-overlap",
      "client": [
        "h2"
      ],
      "serverPreference": [
        "http/1.1"
      ],
      "selectedProtocol": null,
      "selectedFatalAlert": "no_application_protocol",
      "newTcpConnectionCreated": false
    }
  ],
  "visibility": {
    "ordinaryClientHelloProtectedByHandshakeKeys": false,
    "ordinaryServerHelloProtectedByHandshakeKeys": false,
    "postServerHelloHandshakeProtected": true,
    "ipTimeSizeFullyHidden": false
  },
  "ech": {
    "specification": "RFC9849",
    "topology": "shared mode: client-facing server is TLS terminator",
    "config": "preconfigured usable teaching alias",
    "publicName": "front.example.org",
    "innerServerName": "api.example.org",
    "clientServerSupportSelected": true,
    "hpkeDecryptionSelected": true,
    "acceptedSelected": true,
    "echAcceptanceVerifiedSelected": true,
    "intendedServiceIdentityVerifiedSelected": true,
    "outerStillPublic": true,
    "actualHpkeOrDnsRun": false,
    "rejectedEchConnectionApplicationUsable": false,
    "retryPolicySimulated": false
  },
  "limits": "Semantic flights only; no key bytes, transcript hash, HPKE, TLS record/message encoding, certificate parser, real network or HTTP exchange."
}
clientHello
Client capabilities and routing/protocol offers.
serverHello
Selected cryptographic context; ALPN is not here.
serverProtectedFlight
Handshake-message order without a record/segment count.
peerGates
Receipt versus local validation/completion.
ech
Explicit selected configuration/topology limits for accepted ECH.

A TLS1.3 semantic flight fixture without actual TLS, HPKE, path validation, transcript/record encoding or networking.

Two reality checks

ServerHello arrival verifies the server identity.

It supplies key context; certificate path/name, CertificateVerify and Finished checks remain necessary.

TLS1.3 always encrypts every ClientHello field.

Ordinary CH is clear context. With suitable config/support and acceptance, ECH protects Inner fields while Outer and metadata remain.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

The ALPN client offers only h2 and the server only http/1.1. What is the selected outcome?

  1. no_application_protocol; selectedProtocol null.
  2. ALPN combines both protocols and opens a new TCP connection.
Read the explained answer

no_application_protocol; selectedProtocol null. — Negotiation fails in the selected fatal no-overlap branch; no new TCP connection is created.

Why is serverApplicationReady not immediately true when client Finished reaches the server?

Selected lesson artifact fields; teaching example

peerGates[3]
{"after":"client Finished receipt at server","clientPeerVerified":true,"clientApplicationReady":true,"serverPeerFinishedVerified":false,"serverApplicationReadySelected":false}
peerGates[4]
{"after":"server local client Finished verification","clientPeerVerified":true,"clientApplicationReady":true,"serverPeerFinishedVerified":true,"serverApplicationReadySelected":true}
  1. The server must separately complete local Finished verification.
  2. Arrival automatically proves completion of every cryptographic check.
Read the explained answer

The server must separately complete local Finished verification. — At the receipt snapshot, serverPeerFinishedVerified=false; the next local check opens the gate.

Order the selected certificate-handshake stages through opening the server application gate.

  1. ServerHello reaches the client.
  2. The protected server flight reaches the client.
  3. Client checks pass and it sends its own Finished.
  4. Client Finished reaches the server.
  5. Server local Finished verification passes.
Read the explained answer

ServerHello reaches the client. → The protected server flight reaches the client. → Client checks pass and it sends its own Finished. → Client Finished reaches the server. → Server local Finished verification passes. — Protected-flight receipt is not yet peer proof; client checks and later the server’s own verification are required. This is semantic stage ordering, not wire encoding.

Why do SNI api.example.org and ALPN h2 not replace certificate hostname proof? Also explain ordinary Hello visibility.

Read the explained answer

SNI is a hint for server-context selection; ALPN selects the application protocol. Trusted-path, reference-hostname, CertificateVerify and Finished checks are separate authentication conditions. Ordinary TLS 1.3 ClientHello/ServerHello are not hidden by handshake keys; selected ECH is another negotiated context, not assumed for every TLS connection.

□ I did not count SNI/ALPN as authentication evidence.

□ I distinguished ordinary Hello from selected ECH.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope