// The TLS 1.3 client handshake state machine (RFC 8446 Appendix A.1). After sending its
// ClientHello a client walks WAIT_SH -> WAIT_EE -> WAIT_CERT_CR -> WAIT_CERT ->
// WAIT_CV -> WAIT_FINISHED -> CONNECTED as it receives the server's flight, branching
// past the certificate messages on a PSK/resumption handshake. This is the pure
// transition the handshake driver runs on each received message; an out-of-order
// message raises. (The full-handshake, certificate-authenticated path is modelled; the
// certificate-request branch is included.)
///|
/// A client's handshake state (RFC 8446 A.1), after the ClientHello has been sent.
pub(all) enum TlsClientState {
WaitServerHello
WaitEncryptedExtensions
WaitCertCertReq
WaitCert
WaitCertVerify
WaitFinished
Connected
} derive(Eq, Debug)
///|
/// The initial state, having just sent the ClientHello (START -> WAIT_SH; sending the
/// ClientHello is the client's output action, not a received message).
pub fn TlsClientState::new() -> TlsClientState {
WaitServerHello
}
///|
/// TLS 1.3 handshake message types (RFC 8446 ยง4).
let tls_hs_server_hello : Int = 2
///|
let tls_hs_encrypted_extensions : Int = 8
///|
let tls_hs_certificate : Int = 11
///|
let tls_hs_certificate_request : Int = 13
///|
let tls_hs_certificate_verify : Int = 15
///|
let tls_hs_finished : Int = 20
///|
/// The next client state on receiving a handshake message of `msg_type` (RFC 8446 A.1).
/// A message that does not belong in the current state is an unexpected-message error.
pub fn tls_client_next(
state : TlsClientState,
msg_type : Int,
) -> TlsClientState raise StreamStateError {
match (state, msg_type) {
(WaitServerHello, t) if t == tls_hs_server_hello => WaitEncryptedExtensions
(WaitEncryptedExtensions, t) if t == tls_hs_encrypted_extensions =>
WaitCertCertReq
// After EncryptedExtensions the server may request a client certificate, or send
// its own Certificate directly.
(WaitCertCertReq, t) if t == tls_hs_certificate_request => WaitCert
(WaitCertCertReq, t) if t == tls_hs_certificate => WaitCertVerify
(WaitCert, t) if t == tls_hs_certificate => WaitCertVerify
(WaitCertVerify, t) if t == tls_hs_certificate_verify => WaitFinished
(WaitFinished, t) if t == tls_hs_finished => Connected
_ => raise StreamStateError("unexpected TLS 1.3 handshake message")
}
}