1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
//! # Rustls - a modern TLS library //! Rustls is a TLS library that aims to provide a good level of cryptographic security, //! requires no configuration to achieve that security, and provides no unsafe features or //! obsolete cryptography. //! //! ## Current features //! //! * TLS1.2 and TLS1.3 (draft 22) only. //! * ECDSA or RSA server authentication by clients. //! * RSA server authentication by servers. //! * Forward secrecy using ECDHE; with curve25519, nistp256 or nistp384 curves. //! * AES128-GCM and AES256-GCM bulk encryption, with safe nonces. //! * Chacha20Poly1305 bulk encryption. //! * ALPN support. //! * SNI support. //! * Tunable MTU to make TLS messages match size of underlying transport. //! * TLS1.2 session resumption. //! * TLS1.2 resumption via tickets (RFC5077). //! * TLS1.3 resumption via tickets. //! * Client authentication by clients. //! * Client authentication by servers. //! * Extended master secret support (RFC7627). //! * Exporters (RFC5705). //! * OCSP stapling by servers. //! * SCT stapling by servers. //! * SCT verification by clients. //! //! ## Possible future features //! //! * ECDSA server authentication by servers. //! * PSK support. //! * OCSP verification by clients. //! * Certificate pinning. //! //! ## Non-features //! //! The following things are broken, obsolete, badly designed, underspecified, //! dangerous and/or insane. Rustls does not support: //! //! * SSL1, SSL2, SSL3, TLS1 or TLS1.1. //! * RC4. //! * DES or triple DES. //! * EXPORT ciphersuites. //! * MAC-then-encrypt ciphersuites. //! * Ciphersuites without forward secrecy. //! * Renegotiation. //! * Kerberos. //! * Compression. //! * Discrete-log Diffie-Hellman. //! * Automatic protocol version downgrade. //! * AES-GCM with unsafe nonces. //! //! There are plenty of other libraries that provide these features should you //! need them. //! //! ## Design Overview //! ### Rustls does not take care of network IO //! It doesn't make or accept TCP connections, or do DNS, or read or write files. //! //! There's example client and server code which uses mio to do all needed network //! IO. //! //! ### Rustls provides encrypted pipes //! These are the `ServerSession` and `ClientSession` types. You supply raw TLS traffic //! on the left (via the `read_tls()` and `write_tls()` methods) and then read/write the //! plaintext on the right: //! //! ```text //! TLS Plaintext //! === ========= //! read_tls() +-----------------------+ io::Read //! | | //! +---------> ClientSession +---------> //! | or | //! <---------+ ServerSession <---------+ //! | | //! write_tls() +-----------------------+ io::Write //! ``` //! //! These objects are `Send` but not `Sync`, so are usable in only one thread unless //! you make your own arrangements. //! //! ### Rustls takes care of server certificate verification //! You do not need to provide anything other than a set of root certificates to trust. //! Certificate verification cannot be turned off or disabled in the main API. //! //! ## Getting started //! This is the minimum you need to do to make a TLS client connection. //! //! First, we make a `ClientConfig`. You're likely to make one of these per process, //! and use it for all connections made by that process. //! //! ``` //! let mut config = rustls::ClientConfig::new(); //! ``` //! //! Next we load some root certificates. These are used to authenticate the server. //! The recommended way is to depend on the `webpki_roots` crate which contains //! the Mozilla set of root certificates. //! //! ```rust,ignore //! config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); //! ``` //! //! Now we can make a session. You need to provide the server's hostname so we //! know what to expect to find in the server's certificate. //! //! ```no_run //! # extern crate rustls; //! # extern crate webpki; //! # use std::sync::Arc; //! # let mut config = rustls::ClientConfig::new(); //! let rc_config = Arc::new(config); //! let example_com = webpki::DNSNameRef::try_from_ascii_str("example.com").unwrap(); //! let mut client = rustls::ClientSession::new(&rc_config, example_com); //! ``` //! //! Now you should do appropriate IO for the `client` object. If `client.wants_read()` yields //! true, you should call `client.read_tls()` when the underlying connection has data. //! Likewise, if `client.wants_write()` yields true, you should call `client.write_tls()` //! when the underlying connection is able to send data. You should continue doing this //! as long as the connection is valid. //! //! The return types of `read_tls()` and `write_tls()` only tell you if the IO worked. No //! parsing or processing of the TLS messages is done. After each `read_tls()` you should //! therefore call `client.process_new_packets()` which parses and processes the messages. //! Any error returned from `process_new_packets` is fatal to the session, and will tell you //! why. For example, if the server's certificate is expired `process_new_packets` will //! return `Err(WebPKIError(CertExpired))`. From this point on, `process_new_packets` will //! not do any new work and will return that error continually. //! //! You can extract newly received data by calling `client.read()` (via the `io::Read` //! trait). You can send data to the peer by calling `client.write()` (via the `io::Write` //! trait). Note that `client.write()` buffers data you send if the TLS session is not //! yet established: this is useful for writing (say) a HTTP request, but don't write huge //! amounts of data. //! //! The following code uses a fictional socket IO API for illustration, and does not handle //! errors. //! //! ```text //! use std::io; //! //! client.write(b"GET / HTTP/1.0\r\n\r\n").unwrap(); //! let mut socket = connect("example.com", 443); //! loop { //! if client.wants_read() && socket.ready_for_read() { //! client.read_tls(&mut socket).unwrap(); //! client.process_new_packets().unwrap(); //! //! let mut plaintext = Vec::new(); //! client.read_to_end(&mut plaintext).unwrap(); //! io::stdout().write(&plaintext).unwrap(); //! } //! //! if client.wants_write() && socket.ready_for_write() { //! client.write_tls(&mut socket).unwrap(); //! } //! //! socket.wait_for_something_to_happen(); //! } //! ``` //! //! # Examples //! `tlsserver` and `tlsclient` are full worked examples. These both use mio. //! //! # Crate features //! Here's a list of what features are exposed by the rustls crate and what //! they mean. //! //! - `logging`: this makes the rustls crate depend on the `log` crate. //! rustls outputs interesting protocol-level messages at `trace!` and `debug!` //! level, and protocol-level errors at `warn!` and `error!` level. The log //! messages do not contain secret key data, and so are safe to archive without //! affecting session security. This feature is in the default set. //! //! - `dangerous_configuration`: this feature enables a `dangerous()` method on //! `ClientConfig` and `ServerConfig` that allows setting inadvisable options, //! such as replacing the certificate verification process. Applications //! requesting this feature should be reviewed carefully. //! // Require docs for public APIs, deny unsafe code, etc. #![forbid(unsafe_code, unstable_features)] #![deny(trivial_casts, trivial_numeric_casts, missing_docs, unused_import_braces, unused_extern_crates, unused_qualifications)] // Our dependencies: // webpki for certificate verification. extern crate webpki; // *ring* for cryptography. extern crate ring; // untrusted for feeding ring and webpki. extern crate untrusted; // sct for validation of stapled certificate transparency SCTs. extern crate sct; // rust-base64 for pemfile module. extern crate base64; // log for logging (optional). #[cfg(feature = "logging")] #[macro_use] extern crate log; #[cfg(not(feature = "logging"))] #[macro_use] mod compile_out_log { macro_rules! trace ( ($($tt:tt)*) => {{}} ); macro_rules! debug ( ($($tt:tt)*) => {{}} ); macro_rules! info ( ($($tt:tt)*) => {{}} ); macro_rules! warn ( ($($tt:tt)*) => {{}} ); macro_rules! error ( ($($tt:tt)*) => {{}} ); } mod util; #[allow(missing_docs)] #[macro_use] mod msgs; mod error; mod rand; mod hash_hs; mod vecbuf; mod prf; mod cipher; mod key_schedule; mod session; mod stream; mod pemfile; mod x509; mod anchors; mod verify; #[cfg(test)] mod verifybench; mod handshake; mod suites; mod ticketer; mod server; mod client; mod key; /// Internal classes which may be useful outside the library. /// The contents of this section DO NOT form part of the stable interface. pub mod internal { /// Functions for parsing PEM files containing certificates/keys. pub mod pemfile { pub use pemfile::{certs, rsa_private_keys, pkcs8_private_keys}; } /// Low-level TLS message parsing and encoding functions. pub mod msgs { pub use msgs::*; } } // The public interface is: pub use msgs::enums::ProtocolVersion; pub use msgs::enums::SignatureScheme; pub use msgs::enums::CipherSuite; pub use error::TLSError; pub use session::Session; pub use stream::Stream; pub use anchors::{DistinguishedNames, RootCertStore}; pub use client::StoresClientSessions; pub use client::handy::ClientSessionMemoryCache; pub use client::{ClientConfig, ClientSession}; pub use client::ResolvesClientCert; pub use server::StoresServerSessions; pub use server::handy::ServerSessionMemoryCache; pub use server::{ServerConfig, ServerSession}; pub use server::handy::ResolvesServerCertUsingSNI; pub use server::ResolvesServerCert; pub use server::ProducesTickets; pub use ticketer::Ticketer; pub use verify::{NoClientAuth, AllowAnyAuthenticatedClient, AllowAnyAnonymousOrAuthenticatedClient}; pub use suites::{ALL_CIPHERSUITES, SupportedCipherSuite}; pub use key::{Certificate, PrivateKey}; /// Message signing interfaces and implementations. pub mod sign; #[cfg(feature = "dangerous_configuration")] pub use verify::{ServerCertVerifier, ServerCertVerified, ClientCertVerifier, ClientCertVerified}; #[cfg(feature = "dangerous_configuration")] pub use client::danger::DangerousClientConfig;