moonbitstack/moontls/ext does not have a README file

    Ext

    pub(all) struct Ext {
    kind : Kind
    data : Bytes
    } derive(Eq,
    Debug
    )

    One extension: its type and its still-unparsed payload (RFC 8446 §4.2).

    Ext::equal

    fn Ext::equal(Ext, Ext) -> Bool

    Ext::not_equal

    fn Ext::not_equal(x : Ext, y : Ext) -> Bool

    Ext::to_repr

    Identity

    pub(all) struct Identity {
    identity : Bytes
    age : Int
    } derive(Eq,
    Debug
    )

    One PskIdentity: an opaque identity and the age the client reports for it, obfuscated by adding the ticket's own ticket_age_add (RFC 8446 §4.2.11.1).

    Identity::equal

    fn Identity::equal(Identity, Identity) -> Bool

    Identity::not_equal

    fn Identity::not_equal(x : Identity, y : Identity) -> Bool

    Identity::to_repr

    Kind

    pub(all) enum Kind {
    ServerName
    SupportedGroups
    SignatureAlgorithms
    Alpn
    SupportedVersions
    KeyShare
    QuicTransportParameters
    UseSrtp
    Padding
    PreSharedKey
    EarlyData
    PskKeyExchangeModes
    EcPointFormats
    ExtendedMasterSecret
    RenegotiationInfo
    EncryptThenMac
    SessionTicket
    StatusRequest
    RecordSizeLimit
    Heartbeat
    CompressCertificate
    Cookie
    CertificateAuthorities
    PostHandshakeAuth
    Other(Int)
    } derive(Eq,
    Debug
    )

    Which extension this is (RFC 8446 §4.2, and IANA's TLS ExtensionType registry).

    Other keeps a type this package has no codec for. An extension is self-describing — a type and a length — so one it does not understand can be carried, forwarded and counted without being parsed, which is what RFC 8446 §4.2 asks a receiver to do with an extension it does not recognise.

    Kind::code

    fn Kind::code(self : Kind) -> Int

    The two octets this extension type goes on the wire as.

    Kind::equal

    fn Kind::equal(Kind, Kind) -> Bool

    Kind::not_equal

    fn Kind::not_equal(x : Kind, y : Kind) -> Bool

    Kind::of

    fn Kind::of(code : Int) -> Kind

    The extension type a code names. Never fails: one without a codec here becomes Other.

    Kind::to_repr

    authorities

    fn authorities(names : ArrayView[Bytes]) -> Bytes

    A certificate_authorities payload (RFC 8446 §4.2.4, RFC 5246 §7.4.4): the DER names of the anchors this endpoint takes a certificate from.

    The names are carried opaque. What a distinguished name says is the certificate library's question, and a client that cannot name one from the list is free to send a certificate anyway — the list is a hint.

    binder_offset

    fn binder_offset(hello : BytesView, hash : Int, n? : Int) -> Int?

    Where a ClientHello's binders start, given a whole ClientHello handshake message whose pre_shared_key extension is last, a binder of hash octets, and n binders offered (RFC 8446 §4.2.11.2).

    The binder covers the ClientHello up to this offset, which is where the binders list begins — its two-octet length field included in what follows, excluded from what is hashed. The message's own length fields are as if the binders were there, which is what makes the offset a subtraction from the end rather than a field to search for: a server has the whole message and knows how long a binder for its suite is.

    brainpool_p256

    let brainpool_p256 : Int

    brainpoolP256r1 (RFC 7027), a TLS 1.2 key-exchange group.

    brainpool_p384

    let brainpool_p384 : Int

    brainpoolP384r1 (RFC 7027).

    brainpool_p512

    let brainpool_p512 : Int

    brainpoolP512r1 (RFC 7027).

    certificate_status

    fn certificate_status(response : BytesView) -> Bytes

    The status_request extension a TLS 1.3 Certificate entry carries (RFC 8446 §4.4.2.1): the OCSP response, length-prefixed.

    certificate_status12

    fn certificate_status12(response : BytesView) -> Bytes

    A TLS 1.2 CertificateStatus body (RFC 6066 §8): the same shape without the extension framing.

    compression_algorithms

    fn compression_algorithms(ids : ArrayView[Int]) -> Bytes

    A compress_certificate payload (RFC 8879 §3): the algorithms a client will accept, best first.
    fn cookie(value : BytesView) -> Bytes

    A cookie payload (RFC 8446 §4.2.2): opaque octets, length-prefixed.

    The server puts whatever it needs into it and the client hands it back untouched. Over datagrams that round trip is the whole defence (RFC 9147 §5.1): a server that answers a ClientHello with a cookie has committed no memory, and an address that cannot receive never comes back.

    decode

    fn decode(view : BytesView) -> Array[Ext] raise
    Refused

    Decode an extension block, refusing one that does not fit its lengths or carries one type twice, which RFC 8446 §4.2 forbids: nothing says which of the two to believe.

    early_data

    fn early_data() -> Bytes

    early_data in a ClientHello or an EncryptedExtensions: no payload at all (RFC 8446 §4.2.10).

    ecdsa_brainpool_p256

    let ecdsa_brainpool_p256 : Int

    ecdsa_brainpoolP256r1tls13_sha256 (RFC 8734).

    ecdsa_brainpool_p384

    let ecdsa_brainpool_p384 : Int

    ecdsa_brainpoolP384r1tls13_sha384 (RFC 8734).

    ecdsa_brainpool_p512

    let ecdsa_brainpool_p512 : Int

    ecdsa_brainpoolP512r1tls13_sha512 (RFC 8734).

    ecdsa_secp256r1_sha256

    let ecdsa_secp256r1_sha256 : Int

    ecdsa_secp256r1_sha256, the other scheme §9.1 requires.

    ecdsa_secp384r1_sha384

    let ecdsa_secp384r1_sha384 : Int

    ecdsa_secp384r1_sha384 (RFC 8446 §4.2.3).

    ecdsa_secp521r1_sha512

    let ecdsa_secp521r1_sha512 : Int

    ecdsa_secp521r1_sha512.

    ecdsa_sha1

    let ecdsa_sha1 : Int

    ecdsa_sha1, rsa_pkcs1_sha1's counterpart.

    ecdsa_sha224

    let ecdsa_sha224 : Int

    ecdsa_sha224, which TLS 1.2 alone has.

    ed25519

    let ed25519 : Int

    ed25519.

    encode

    fn encode(exts : ArrayView[Ext]) -> Bytes

    Encode an extension block: a two-octet total length, then each extension as a two-octet type, a two-octet length, and its payload.

    ffdhe2048

    let ffdhe2048 : Int

    The five finite-field groups of RFC 7919, by size.

    ffdhe3072

    let ffdhe3072 : Int

    ffdhe4096

    let ffdhe4096 : Int

    ffdhe6144

    let ffdhe6144 : Int

    ffdhe8192

    let ffdhe8192 : Int

    find

    fn find(exts : ArrayView[Ext], kind : Kind) -> Ext?

    The first extension of a given type, or None.

    groups

    fn groups(offered : ArrayView[Int]) -> Bytes

    A supported_groups payload (RFC 8446 §4.2.7).
    let h2 : String

    HTTP/2 over TLS's ALPN identifier (RFC 7540 §3.3).
    let h3 : String

    HTTP/3's ALPN identifier (RFC 9114 §3.1).

    http11

    let http11 : String

    HTTP/1.1's ALPN identifier (RFC 7301 §6).

    max_early_data

    fn max_early_data(size : Int) -> Bytes

    early_data in a NewSessionTicket: the max_early_data_size a client may send under it (§4.6.1). The ticket's own name is what says the field is a number rather than nothing.

    mldsa44

    let mldsa44 : Int

    mldsa44 (draft-ietf-tls-mldsa).

    mldsa65

    let mldsa65 : Int

    mldsa65 (draft-ietf-tls-mldsa).

    mldsa87

    let mldsa87 : Int

    mldsa87 (draft-ietf-tls-mldsa).

    mlkem1024

    let mlkem1024 : Int

    mlkem512

    let mlkem512 : Int

    ML-KEM alone (draft-ietf-tls-mlkem), by parameter set.

    mlkem768

    let mlkem768 : Int

    no_renegotiation

    fn no_renegotiation() -> Bytes

    renegotiation_info for an initial handshake: the empty renegotiated_connection (RFC 5746 §3.4).

    point_formats

    fn point_formats() -> Bytes

    ec_point_formats naming the uncompressed form, the only one RFC 8422 §5.1.2 leaves.

    pre_shared_key

    fn pre_shared_key(identities : ArrayView[Identity], binders : ArrayView[Bytes]) -> Bytes

    An OfferedPsks payload (RFC 8446 §4.2.11): the identities, then one binder per identity, in the same order.

    The binders are the authentication, and they cover a truncated ClientHello — see [binder_offset] for where that truncation falls.

    protocols

    fn protocols(names : ArrayView[String]) -> Bytes

    An ALPN ProtocolNameList payload (RFC 7301 §3.1): a two-octet length of the name list, then each protocol as a one-octet length and its octets.

    psk_dhe_ke

    let psk_dhe_ke : Int

    psk_dhe_ke, the mode RFC 8446 §4.2.9 expects: the PSK authenticates the handshake and a key exchange gives it forward secrecy.

    psk_ke

    let psk_ke : Int

    psk_ke, the mode where a PSK alone keys the handshake, with no Diffie-Hellman (RFC 8446 §4.2.9). This library does not offer it: without a key exchange there is no forward secrecy at all, and a stolen ticket would open every connection made with it.

    psk_modes

    fn psk_modes(modes : ArrayView[Int]) -> Bytes

    A psk_key_exchange_modes payload: one length octet, then the modes (RFC 8446 §4.2.9).

    read_authorities

    fn read_authorities(view : BytesView) -> Array[Bytes]?

    The names such a payload carries: at least one, each at least one octet (DistinguishedName<1..2^16-1>), or None when it does not fit its lengths.

    read_block

    fn read_block(view : BytesView) -> Array[Ext]?

    Decode an extension block whose two-octet total length has already been read — what a structure that frames the block itself, like a TLS 1.3 Certificate entry, needs.

    read_certificate_status

    fn read_certificate_status(view : BytesView) -> Bytes?

    The OCSP response such an extension carries, or None when it does not fit its length.

    read_certificate_status12

    fn read_certificate_status12(view : BytesView) -> Bytes?

    The response a TLS 1.2 CertificateStatus carries.

    read_compression_algorithms

    fn read_compression_algorithms(view : BytesView) -> Array[Int]?

    The algorithms such a payload names: at least one, each two octets, or None when it does not fit its own length.
    fn read_cookie(view : BytesView) -> Bytes?

    The octets such a payload carries, or None when it does not fit its lengths.

    An empty cookie is refused rather than read as an empty one: §4.2.2 gives the field a minimum of one octet, and a cookie proving nothing is worse than no cookie, because it looks like proof.

    read_groups

    fn read_groups(view : BytesView) -> Array[Int]?

    The groups such a payload offers.

    read_max_early_data

    fn read_max_early_data(view : BytesView) -> Int?

    The max_early_data_size such a payload carries, or None when it is not four octets.

    read_point_formats

    fn read_point_formats(data : BytesView) -> Bytes?

    The formats in an ec_point_formats body, or None when it does not fit its length or names none.

    read_pre_shared_key

    fn read_pre_shared_key(view : BytesView) -> (Array[Identity], Array[Bytes])?

    The identities and binders such a payload carries: at least one of each, the same number of both, each identity at least one octet and each binder in 32..255 (§4.2.11), or None.

    read_protocols

    fn read_protocols(view : BytesView) -> Array[String]?

    The protocol names such a payload carries: at least one, none empty (RFC 7301 §3.1).

    read_psk_modes

    fn read_psk_modes(view : BytesView) -> Array[Int]?

    The modes such a payload offers, or None when it names none or does not fit its length.

    read_record_size_limit

    fn read_record_size_limit(view : BytesView) -> Int?

    The limit such a payload states, or None when it is not two octets in 64..2^14+1.

    read_renegotiation

    fn read_renegotiation(view : BytesView) -> (Bytes, Bytes)?

    The two verify_data a renegotiation_info payload carries, either of which may be empty, or None when it does not fit its length.

    read_schemes

    fn read_schemes(view : BytesView) -> Array[Int]?

    The schemes such a payload offers.

    read_selected_share

    fn read_selected_share(view : BytesView) -> (Int, Bytes)?

    The group and key such a payload selected: one entry and nothing after it.

    read_selected_version

    fn read_selected_version(view : BytesView) -> Int?

    The version such a payload selected, or None if it is not two octets.

    read_server_names

    fn read_server_names(data : BytesView) -> Array[String]?

    The host_name a server_name payload carries, or None when it is malformed. RFC 6066 §3 defines no other name type, and gives one no length a reader could skip it by, so an entry of another type is malformed too.

    read_session_ticket

    fn read_session_ticket(view : BytesView) -> Bytes?

    The ticket such a payload carries: empty is a legitimate value, and None means only that it does not fit its own length.

    read_shares

    fn read_shares(view : BytesView) -> Array[(Int, Bytes)]?

    The shares such a payload offers, in order; an empty list asks the server to pick a group and retry (RFC 8446 §4.2.8).

    read_status_request

    fn read_status_request(view : BytesView) -> Bool?

    Whether such a payload asks for OCSP at all, and None when it does not parse. The responder list and the request extensions are read and dropped: this server staples one response.

    read_use_srtp

    fn read_use_srtp(view : BytesView) -> (Array[Int], Bytes)?

    The profiles and MKI such a payload carries, or None when it does not fit its lengths.

    A profile list of odd length is a decode failure rather than a list with the last octet dropped: RFC 5764 §4.1.2 makes each profile two octets, so an odd length means the sender and the receiver disagree about the structure.

    read_versions

    fn read_versions(view : BytesView) -> Array[Int]?

    The versions such a payload offers, in order (versions<2..254>).

    record_size_limit

    fn record_size_limit(limit : Int) -> Bytes

    A record_size_limit payload (RFC 8449 §4): the largest record, header and tag included, this end will read.

    The extension is not a negotiation: each end states its own and applies the other's. A limit below 64 is refused by the receiver (§4), since a record that small cannot carry anything.

    renegotiation

    fn renegotiation(client : BytesView, server : BytesView) -> Bytes

    renegotiation_info for a renegotiation (RFC 5746 §3.4): the previous handshake's client and server Finished verify_data, one after the other.

    The two values are what makes a renegotiation safe: they tie the new handshake to the old one, so a ClientHello recorded from another connection cannot be spliced in.

    rsa_pkcs1_sha1

    let rsa_pkcs1_sha1 : Int

    rsa_pkcs1_sha1: what a TLS 1.2 client means by leaving signature_algorithms out. RFC 9155 forbids it in new work.

    rsa_pkcs1_sha224

    let rsa_pkcs1_sha224 : Int

    rsa_pkcs1_sha224, which TLS 1.2 alone has.

    rsa_pkcs1_sha256

    let rsa_pkcs1_sha256 : Int

    rsa_pkcs1_sha256: not for a TLS 1.3 handshake signature (RFC 8446 §4.2.3), but what most certificate chains are signed with, which the same list speaks for when no signature_algorithms_cert is sent.

    rsa_pkcs1_sha384

    let rsa_pkcs1_sha384 : Int

    rsa_pkcs1_sha384, for certificates only.

    rsa_pkcs1_sha512

    let rsa_pkcs1_sha512 : Int

    rsa_pkcs1_sha512, for certificates only.

    rsa_pss_rsae_sha256

    let rsa_pss_rsae_sha256 : Int

    rsa_pss_rsae_sha256, the signature scheme RFC 8446 §9.1 requires.

    rsa_pss_rsae_sha384

    let rsa_pss_rsae_sha384 : Int

    rsa_pss_rsae_sha384.

    rsa_pss_rsae_sha512

    let rsa_pss_rsae_sha512 : Int

    rsa_pss_rsae_sha512.

    schemes

    fn schemes(offered : ArrayView[Int]) -> Bytes

    A signature_algorithms payload (RFC 8446 §4.2.3).

    secp256r1

    let secp256r1 : Int

    secp256r1 (NIST P-256).

    secp256r1mlkem768

    let secp256r1mlkem768 : Int

    SecP256r1MLKEM768: P-256 and ML-KEM-768, the curve half first.

    secp384r1

    let secp384r1 : Int

    secp384r1 (NIST P-384).

    secp384r1mlkem1024

    let secp384r1mlkem1024 : Int

    SecP384r1MLKEM1024: P-384 and ML-KEM-1024, the curve half first.

    secp521r1

    let secp521r1 : Int

    secp521r1 (NIST P-521).

    selected_share

    fn selected_share(group : Int, key : BytesView) -> Bytes

    A ServerHello's key_share payload: one KeyShareEntry.

    selected_version

    fn selected_version(version : Int) -> Bytes

    A ServerHello's supported_versions payload: the selected version alone, with no list prefix (RFC 8446 §4.2.1).

    server_name

    fn server_name(host : String) -> Bytes

    A server_name payload (RFC 6066 §3): one host_name entry. TLS carries no IP literal here.

    session_ticket

    fn session_ticket(ticket : BytesView) -> Bytes

    A session_ticket payload (RFC 5077 §3.2): the ticket the client hands back, or nothing at all, which is a server saying it will send one.

    share

    fn share(group : Int, key : BytesView) -> Bytes

    One KeyShareEntry: the named group, the key's length, then the key (RFC 8446 §4.2.8).

    shares

    fn shares(entries : ArrayView[(Int, Bytes)]) -> Bytes

    A ClientHello's key_share payload: the client_shares length, then the KeyShareEntry list.

    status_request

    fn status_request() -> Bytes

    A ClientHello's status_request (RFC 6066 §8): the OCSP status of the leaf, please. The two empty vectors are the ones that extension gives a client that has no preferences to state.

    use_srtp

    fn use_srtp(profiles : ArrayView[Int], mki : BytesView) -> Bytes

    A use_srtp payload (RFC 5764 §4.1.2): the protection profiles offered, then the master key identifier.

    A client sends every profile it will accept; a server answers with exactly one, which is why the same codec serves both ends and the count is left to the caller. The MKI is empty in every profile this family implements — RFC 5764 §4.1.2 allows one, and nothing here needs it.

    version_13

    let version_13 : Int

    The TLS 1.3 version code supported_versions selects (RFC 8446 §4.2.1).

    version_13_datagram

    let version_13_datagram : Int

    The code DTLS 1.3 is named by in supported_versions (RFC 9147 §4.2.1). DTLS has its own numbers for the versions it shares with TLS, and 1.3 is no exception: a ClientHello over a datagram that lists 0x0304 is not offering DTLS 1.3 at all, and no other implementation accepts a datagram handshake that names it that way.

    versions

    fn versions(offered : ArrayView[Int]) -> Bytes

    A ClientHello's supported_versions payload (RFC 8446 §4.2.1): a one-octet length, then each version as two octets, most preferred first.

    x25519

    let x25519 : Int

    x25519, the group RFC 8446 §4.2.7 lists first and TLS 1.3 offers first.

    x25519mlkem768

    let x25519mlkem768 : Int

    X25519MLKEM768 (draft-ietf-tls-ecdhe-mlkem): ML-KEM-768 and X25519 in one share, the ML-KEM half first. What browsers offer first.

    x448

    let x448 : Int

    x448 (RFC 7748).

    zlib_compression

    let zlib_compression : Int

    zlib, the one certificate compression algorithm this library speaks (RFC 8879 §4.2). Brotli and zstd are the registry's other two, and neither is in this repository's dependencies.

    Source Files