seleniumbase_rs_codec::tls_spec holds the TLS specification a client should
reproduce. A TlsSpec is a whole TLS profile as plain data: the ids a
ClientHello carries and the content of the extensions that have any.
TlsSpec::from_client_hello records it from a parsed hello. A caller can layer a
custom JA3, JA4 (as JA4_r or JA4_ro) or peetprint over a base spec; each
overlay replaces what its fingerprint carries, takes the rest from the base, runs
check_reproducible, and recomputes its own fingerprint to compare with the
input, so an accepted input reproduces its own fingerprint and a spec BoringSSL
cannot emit is refused before any client exists.
The lists never hold GREASE: the grease flag says BoringSSL adds its GREASE
values. The per-extension flags of the design plan (ocsp_stapling, sct,
session_ticket, renegotiation, ech_grease) are methods that read the
extension list, so they cannot disagree with it. The table of what is refused is
in Wire formats.
The measured spec carries the trust_anchors extension and the ML-DSA signature
schemes, which BoringSSL cannot send, so its own check_reproducible fails; the
spec without its known gaps passes.
TlsSpec#
struct
A whole TLS profile: what a ClientHello must carry for a client to look like
this one.
The handshake client_version (771).
Cipher suites in wire order, without GREASE.
Extension ids in wire order, without GREASE; SNI and ALPN are listed when sent.
Whether the client shuffles the extension order on every connection, as Chrome
does (the measured Chrome 155 spec has true).
Default: "false"
Whether GREASE values are added: a cipher, a group, a version and two extensions.
Default: "false"
Supported groups in preference order.
EC point formats: [0] when the extension is sent.
Signature algorithms in preference order.
ALPN protocol names in preference order.
The application_settings extension, when sent.
delegated_credential signature schemes.
supported_versions, highest first, without GREASE.
psk_key_exchange_modes.
compress_certificate algorithms.
record_size_limit.
TlsSpec::from_client_hello, with_observed_order#
method
from_client_hello records the profile a parsed hello shows; GREASE becomes the
grease flag, and the extension order is taken as observed
(permute_extensions is false). with_observed_order compares a second hello
of the same client: a changed extension order sets permute_extensions. It
returns SpecError::HellosDiffer when the cipher suites or the set of extensions
differ.
Extension flags#
methodWhether the spec sends the extension with this id, status_request (OCSP
stapling), signed_certificate_timestamp, session_ticket,
renegotiation_info, encrypted_client_hello (as GREASE ECH) or
extended_master_secret.
Fingerprints of a spec#
methodThe JA3 this spec produces (extensions in the listed order); what JA4 reads from
it; its JA4; the unhashed JA4 in the given order; and its peetprint, which with
grease carries the GREASE tokens BoringSSL adds (one each in versions, groups
and ciphers, two in the extensions). See JA3 and
JA4.
TlsSpec::without_known_gaps#
method
Removes the listed known gaps: TrustAnchorsExtension drops extension 0xCA34;
MlDsaSignatureAlgorithms drops 0x0904 to 0x0906 from the signature
algorithms and the delegated credentials.
TlsSpec::check_reproducible#
method
Checks the spec against what BoringSSL can emit (plan section 3.8) and returns
the first SpecError found, checking in this order: the version, the cipher
suites, the extensions, the groups, the point formats, the signature algorithms,
then extension content.
Overlays#
methodReplaces the version, ciphers, extensions, groups and point formats with a custom
JA3. Everything JA3 does not carry (signature algorithms, ALPN, key shares,
versions and the other extension bodies) comes from self; content of extensions
the JA3 omits is dropped. Extension permutation is turned off, so the JA3 on the
wire is exact.
Replaces the signature algorithms. UnsupportedSigalg for a scheme BoringSSL
cannot send, ExtensionContent when the list is empty or the extension is not
sent.
Replaces the ciphers, extensions and signature algorithms with a JA4_r
(Ja4Order::Sorted) or JA4_ro (Ja4Order::Original). The sorted form carries
no order: the ids keep the order they have in self, new ones follow in
ascending order, and permute_extensions is kept. The original-order form pins
ciphers and extensions and turns permutation off. The TLS version and the first
ALPN name come from the a section; groups and the other bodies come from
self. Ja4Mismatch when the result would not reproduce raw.
Replaces the ciphers, extensions, groups, versions, ALPN, signature algorithms,
PSK modes and certificate compression with a custom peetprint. The extension field
is sorted, so extension order comes from self. GREASE tokens set the grease
flag, and a layout BoringSSL would not produce is refused. PeetprintMismatch
when the result would not reproduce peet.
Alps#
struct
The application_settings extension: the protocols it announces (such as h2)
and whether it uses the new codepoint (0x44CD) rather than the old one
(0x4469).
KnownGap#
enum
A known difference between a measured browser hello and what BoringSSL can send.
The measured file records them in provenance.known_gaps.
SpecError#
enum
Why a spec cannot be reproduced, or an overlay cannot be applied.