1/*! # Customising private key usage
2
3By default rustls supports PKCS#8-format[^1] RSA or ECDSA keys, plus PKCS#1-format RSA keys.
4
5However, if your private key resides in a HSM, or in another process, or perhaps
6another machine, rustls has some extension points to support this:
7
8The main trait you must implement is [`sign::SigningKey`][signing_key]. The primary method here
9is [`choose_scheme`][choose_scheme] where you are given a set of [`SignatureScheme`s][sig_scheme] the client says
10it supports: you must choose one (or return `None` -- this aborts the handshake). Having
11done that, you return an implementation of the [`sign::Signer`][signer] trait.
12The [`sign()`][sign_method] performs the signature and returns it.
13
14(Unfortunately this is currently designed for keys with low latency access, like in a
15PKCS#11 provider, Microsoft CryptoAPI, etc. so is blocking rather than asynchronous.
16It's a TODO to make these and other extension points async.)
17
18Once you have these two pieces, configuring a server to use them involves, briefly:
19
20- packaging your `sign::SigningKey` with the matching certificate chain into a [`sign::CertifiedKey`][certified_key]
21- making a [`ResolvesServerCertUsingSni`][cert_using_sni] and feeding in your `sign::CertifiedKey` for all SNI hostnames you want to use it for,
22- setting that as your `ServerConfig`'s [`cert_resolver`][cert_resolver]
23
24[signing_key]: ../../sign/trait.SigningKey.html
25[choose_scheme]: ../../sign/trait.SigningKey.html#tymethod.choose_scheme
26[sig_scheme]: ../../enum.SignatureScheme.html
27[signer]: ../../sign/trait.Signer.html
28[sign_method]: ../../sign/trait.Signer.html#tymethod.sign
29[certified_key]: ../../sign/struct.CertifiedKey.html
30[cert_using_sni]: ../../struct.ResolvesServerCertUsingSni.html
31[cert_resolver]: ../../struct.ServerConfig.html#structfield.cert_resolver
32
33[^1]: For PKCS#8 it does not support password encryption -- there's not a meaningful threat
34 model addressed by this, and the encryption supported is typically extremely poor.
35
36# Unexpected EOF
37
38TLS has a `close_notify` mechanism to prevent truncation attacks[^2].
39According to the TLS RFCs, each party is required to send a `close_notify` message before
40closing the write side of the connection. However, some implementations don't send it.
41So long as the application layer protocol (for instance HTTP/2) has message length framing
42and can reject truncated messages, this is not a security problem.
43
44Rustls treats an EOF without `close_notify` as an error of type `std::io::Error` with
45`ErrorKind::UnexpectedEof`. In some situations it's appropriate for the application to handle
46this error the same way it would handle a normal EOF (a read returning `Ok(0)`). In particular
47if `UnexpectedEof` occurs on an idle connection it is appropriate to treat it the same way as a
48clean shutdown. And if an application always uses messages with length framing (in other words,
49messages are never delimited by the close of the TCP connection), it can unconditionally
50ignore `UnexpectedEof` errors from rustls.
51
52[^2]: <https://datatracker.ietf.org/doc/html/rfc8446#section-6.1>
53*/
54