moonbitstack/moontls/msg does not have a README file

    Hello

    pub(all) struct Hello {
    version : Int
    random : Bytes
    session_id : Bytes
    cookie : Bytes
    suites : Array[Int]
    compression : Bytes
    extensions : Array[
    Ext
    ]
    } derive(Eq,
    Debug
    )

    A ClientHello (RFC 8446 §4.1.2; RFC 5246 §7.4.1.2 for TLS 1.2).

    version is the legacy_version: 0x0303 from a TLS 1.3 client, whose real offer is in supported_versions, and the highest version a TLS 1.2 client speaks. compression is the list of compression methods, which TLS 1.3 fixes at the null method alone.

    Hello::equal

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

    Hello::not_equal

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

    Hello::to_repr

    Kind

    pub(all) enum Kind {
    ClientHello
    ServerHello
    NewSessionTicket
    EndOfEarlyData
    CompressedCertificate
    EncryptedExtensions
    Certificate
    CertificateRequest
    CertificateVerify
    Finished
    KeyUpdate
    HelloVerifyRequest
    ServerKeyExchange
    ServerHelloDone
    ClientKeyExchange
    Other(Int)
    } derive(Eq,
    Debug
    )

    Which handshake message this is (RFC 8446 §4, and IANA's TLS HandshakeType registry).

    Other keeps a type this package has no codec for. A handshake message is framed by a type and a 24-bit length, so one it does not understand can still be measured, skipped and fed to the transcript — which is what a receiver has to do, since the transcript hash covers every message whether or not it was understood.

    Kind::code

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

    The octet this message 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 message type an octet names. Never fails: one without a codec here becomes Other.

    Kind::to_repr

    Server

    pub(all) struct Server {
    version : Int
    random : Bytes
    session_id : Bytes
    suite : Int
    compression : Int
    extensions : Array[
    Ext
    ]
    } derive(Eq,
    Debug
    )

    A ServerHello (RFC 8446 §4.1.3): one chosen cipher suite and one compression method, both of which TLS 1.3 fixes, the version at 0x0303 and the method at null.

    Server::equal

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

    Server::not_equal

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

    Server::to_repr

    Ticket

    pub(all) struct Ticket {
    lifetime : Int
    age_add : Int
    nonce : Bytes
    ticket : Bytes
    extensions : Array[
    Ext
    ]
    } derive(Eq,
    Debug
    )

    A TLS 1.3 NewSessionTicket (RFC 8446 §4.6.1): how long the ticket lasts, the number that hides a client's own clock from the server, the nonce that makes this ticket's PSK its own, the opaque ticket, and the extensions — of which early_data is the one that matters.

    Ticket::equal

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

    Ticket::not_equal

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

    Ticket::to_repr

    certificate

    fn certificate(certs : ArrayView[Bytes], context? : BytesView) -> Bytes

    Encode a Certificate body (RFC 8446 §4.4.2): the certificate_request_context, then the certificate_list — each entry a three-octet-length DER certificate and a two-octet-length extensions block.

    context is empty when a server sends its certificate unprompted, which is every case until client certificates land. The DER is carried opaque: what is in a certificate is mooncred's question, not the handshake's.

    certificate12

    fn certificate12(certs : ArrayView[Bytes]) -> Bytes

    A TLS 1.2 Certificate body (RFC 5246 §7.4.2): the chain with no context and no extensions.

    certificate_request

    fn certificate_request(context : BytesView, exts : ArrayView[
    Ext
    ]) -> Bytes

    A CertificateRequest body (RFC 8446 §4.4.2): the context the client's Certificate must echo, and the extensions that say what it may answer with.

    signature_algorithms is mandatory in one of these (§4.4.2.2), and a certificate_authorities list is a hint about which anchors the server takes. A post-handshake request carries a fresh context of its own.

    certificate_request12

    fn certificate_request12(types : ArrayView[Int], names? : ArrayView[Bytes], schemes? : ArrayView[Int]) -> Bytes

    A TLS 1.2 CertificateRequest body (RFC 5246 §7.4.4): the certificate types accepted, optionally the signature and hash algorithms, then the anchors.

    schemes is absent for TLS 1.0 and 1.1, which have no supported_signature_algorithms: there the pair is fixed by the certificate type, and a sender that wrote a list anyway would be writing a field the peer reads as its first anchor.

    certificate_status

    fn certificate_status(certs : ArrayView[Bytes], status : BytesView) -> Bytes

    A Certificate body whose leaf entry carries extensions — which is how TLS 1.3 staples an OCSP response to it (RFC 8446 §4.4.2.1).

    certificate_status12

    fn certificate_status12(response : BytesView) -> Bytes

    A TLS 1.2 CertificateStatus message body (RFC 6066 §8).

    certificate_verify

    fn certificate_verify(signature : BytesView, scheme : Int) -> Bytes

    Encode a CertificateVerify body: the SignatureScheme and the two-octet- length-prefixed signature (RFC 8446 §4.4.3).

    scheme is the code the signature was made under, which the verifier reads back to decide what to check it with; it is a parameter because the certificate's key decides it, not this package.

    certificate_verify_legacy

    fn certificate_verify_legacy(signature : BytesView) -> Bytes

    A TLS 1.0 or 1.1 CertificateVerify body (RFC 2246 §7.4.8): the signature with no scheme in front of it, because there is no signature_algorithms to name one — the certificate type fixes it.

    client_context

    let client_context : String

    The client's CertificateVerify context string (RFC 8446 §4.4.3).

    client_key_exchange

    fn client_key_exchange(public : BytesView, wide? : Bool) -> Bytes

    A ClientKeyExchange body. wide is the two-octet length DHE and RSA use; ECDHE's is one octet (RFC 5246 §7.4.7, RFC 8422 §5.7).

    compressed_certificate

    fn compressed_certificate(algorithm : Int, uncompressed : Int, compressed : BytesView) -> Bytes

    A CompressedCertificate body (RFC 8879 §4): the algorithm, the length the Certificate will have once decompressed, and the compressed octets.

    The uncompressed length is what lets a receiver refuse a decompression bomb before it happens, so it is a promise the sender is held to rather than a hint.

    dh_params

    fn dh_params(prime : BytesView, generator : BytesView, public : BytesView) -> Bytes

    What a DHE ServerKeyExchange's signature covers besides the two randoms (RFC 5246 §7.4.3): the prime, the generator and the server's public value.

    ecdsa_sign

    let ecdsa_sign : Int

    ecdsa_sign, the client certificate type of an ECDSA key (RFC 8422 §5.8).

    encrypted_extensions

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

    An EncryptedExtensions body (RFC 8446 §4.3.1): an extension list, and the first message the server sends under handshake encryption.

    It carries every negotiated extension not needed to establish the cryptographic context — the selected ALPN protocol, and for a QUIC server the quic_transport_parameters RFC 9001 §8.2 requires.

    end_of_early_data

    fn end_of_early_data() -> Bytes

    An EndOfEarlyData body: nothing at all (RFC 8446 §4.5). The message exists so the server knows where a client's 0-RTT data stops, and so the transcript has a point to fold it in.

    finished

    fn finished(verify_data : BytesView) -> Bytes

    A Finished body (RFC 8446 §4.4.4): the verify_data and nothing else.

    Computing it is keys' job — @keys.finished — because it is the key schedule that says what is MACed under what.

    frame

    fn frame(kind : Kind, body : BytesView) -> Bytes

    Frame a handshake body: the message type, then a 24-bit big-endian length (RFC 8446 §4).

    hello

    fn hello(ch : Hello, cookie? : Bool) -> Bytes

    Encode a ClientHello as a whole handshake message.

    cookie writes DTLS 1.2's cookie field (RFC 6347 §4.2.1), which no other version has: a DTLS 1.2 server reads the field whatever it holds, so a hello without it is a hello whose cipher suite list starts where the cookie length should be, and one it cannot parse.

    hello_verify_request

    fn hello_verify_request(version : Int, cookie : BytesView) -> Bytes

    A HelloVerifyRequest (RFC 6347 §4.2.1): the server's version and the cookie the client has to echo in its next ClientHello.

    It is not in the transcript and does not advance the handshake — it is the answer to a hello the server decided not to keep any state for.

    key_params

    fn key_params(group : Int, public : BytesView) -> Bytes

    What a ServerKeyExchange's signature covers besides the two randoms (RFC 8422 §5.4): the curve type, the named curve, and the server's public value.

    new_session_ticket

    fn new_session_ticket(t : Ticket) -> Bytes

    Encode a NewSessionTicket as a whole handshake message.

    new_session_ticket12

    fn new_session_ticket12(lifetime : Int, ticket : BytesView) -> Bytes

    A TLS 1.2 NewSessionTicket (RFC 5077 §3.3): the lifetime in seconds, and the ticket.

    read_certificate

    fn read_certificate(body : BytesView) -> (Bytes, Array[Bytes])?

    Decode a Certificate body into its certificate_request_context and the DER certificates, skipping each entry's extensions, or None when it does not fit its lengths: an empty certificate is not one (cert_data<1..2^24-1>).

    read_certificate12

    fn read_certificate12(body : BytesView) -> Array[Bytes]?

    A TLS 1.2 Certificate body as DER certificates, or None when it does not fit its lengths.

    read_certificate_entries

    fn read_certificate_entries(body : BytesView) -> (Bytes, Array[Bytes], Array[Array[
    Ext
    ]])?

    A Certificate body's context, its chain, and the extensions of each entry — which is what a client needs to find the OCSP response stapled to the leaf.

    read_certificate_request

    fn read_certificate_request(body : BytesView) -> (Bytes, Array[
    Ext
    ])?

    Decode a CertificateRequest body into its context and extensions, or None when it does not fit its lengths.

    read_certificate_request12

    fn read_certificate_request12(body : BytesView, schemes? : Bool) -> (Array[Int], Array[Int], Array[Bytes])?

    Decode a TLS 1.2 CertificateRequest body into its types, schemes and anchors, or None when it does not fit its lengths.

    schemes is false for a request written by TLS 1.0 or 1.1, which has no field there; the scheme such a peer will sign under follows from the type.

    read_certificate_status12

    fn read_certificate_status12(body : BytesView) -> Bytes?

    The response a TLS 1.2 CertificateStatus carries.

    read_certificate_verify

    fn read_certificate_verify(body : BytesView) -> (Int, Bytes)?

    Decode a CertificateVerify body into its scheme and signature, or None when it does not fit its lengths.

    read_certificate_verify_legacy

    fn read_certificate_verify_legacy(body : BytesView) -> Bytes?

    The signature such a body carries, or None when it does not fit its own length.

    read_client_key_exchange

    fn read_client_key_exchange(body : BytesView, wide? : Bool) -> Bytes?

    The value in a ClientKeyExchange body, wide as in client_key_exchange.

    read_compressed_certificate

    fn read_compressed_certificate(body : BytesView) -> (Int, Int, Bytes)?

    The algorithm, uncompressed length and compressed octets such a body carries, or None when it does not fit its lengths.

    read_dh_key_exchange

    fn read_dh_key_exchange(body : BytesView) -> (Bytes, Bytes, Bytes, Int, Bytes)?

    A DHE ServerKeyExchange's prime, generator, public value, signature scheme and signature, as they were written, since the signature covers them that way.

    read_encrypted_extensions

    fn read_encrypted_extensions(body : BytesView) -> Array[
    Ext
    ]?

    Decode an EncryptedExtensions body, or None if it is truncated.

    read_hello

    fn read_hello(body : BytesView, cookie? : Bool) -> Hello?

    Decode a ClientHello from a handshake body, or None when it does not fit its lengths: a suite list empty or of odd length, no compression method, a session_id past 32 octets.

    read_hello_verify_request

    fn read_hello_verify_request(body : BytesView) -> Bytes?

    The cookie a HelloVerifyRequest carries, or None when the body does not fit its lengths.

    read_new_session_ticket

    fn read_new_session_ticket(body : BytesView) -> Ticket?

    Decode a NewSessionTicket body, or None when it does not fit its lengths: a ticket of no octets is not one (ticket<1..2^16-1>).

    read_new_session_ticket12

    fn read_new_session_ticket12(body : BytesView) -> (Int, Bytes)?

    The lifetime and ticket a TLS 1.2 NewSessionTicket carries, or None when it does not fit its lengths.

    read_server_hello

    fn read_server_hello(body : BytesView) -> Server?

    Decode a ServerHello from a handshake body, or None when it does not fit its lengths.

    read_server_key_exchange

    fn read_server_key_exchange(body : BytesView) -> (Int, Bytes, Int, Bytes)?

    An ECDHE ServerKeyExchange's group, public value, signature scheme and signature, or None for anything else: a named curve is the only curve_type TLS still has.

    rsa_sign

    let rsa_sign : Int

    rsa_sign, the client certificate type of an RSA key (RFC 5246 §7.4.4).

    server_context

    let server_context : String

    The server's CertificateVerify context string (RFC 8446 §4.4.3).

    server_hello

    fn server_hello(sh : Server) -> Bytes

    Encode a ServerHello as a whole handshake message.

    server_key_exchange

    fn server_key_exchange(params : BytesView, scheme : Int, signature : BytesView) -> Bytes

    A ServerKeyExchange body: the parameters, the signature scheme and the signature.

    signed

    fn signed(context : String, transcript : BytesView) -> Bytes

    What a CertificateVerify signs (RFC 8446 §4.4.3): 64 octets of 0x20, the context string, a single 0x00 separator, then the transcript hash through the Certificate message.

    The 64 spaces and the context string are what stop a signature made for one role, or for an earlier version of the protocol, from counting as one made for another.

    unframe

    fn unframe(view : BytesView) -> (Kind, Bytes)?

    One handshake message's type and body, or None while the view is short of a whole message.

    The framing is all this reads. What a body means is the codec for that type, below — which is why a message this package has no codec for still comes back rather than failing.

    Source Files