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
//! TLS client connections: `rustls` with real certificate-chain
//! verification, over an `embassy-net` TCP socket.
//!
//! A cut-down embedded TLS stack would encrypt the connection without
//! meaningfully authenticating the peer, which for a board that sends
//! alerts or fetches data means anybody on the path can impersonate the
//! other end. This is `rustls` in `no_std` + `alloc` mode instead, checking
//! the server's chain against trust anchors and its validity against the
//! clock.
//!
//! ```ignore
//! let config = tls::client_config(); // once, and share the Arc
//! let mut socket = TcpSocket::new(stack, &mut rx, &mut tx);
//! socket.connect((address, 443)).await?;
//! let mut stream = TlsStream::connect(socket, config.clone(), "example.com").await?;
//! stream.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n").await?;
//! ```
//!
//! # What a Pi has to supply
//!
//! Three things a hosted platform provides for free, each a place this
//! could silently go wrong:
//!
//! * **A crypto provider.** `ring` and `aws-lc-rs` both need a C toolchain,
//! so `rustls-rustcrypto` is the one that builds for a bare-metal target.
//! **It is pre-release and unaudited.** The protocol handling and the
//! chain verification are real `rustls`; the primitives underneath are not
//! audited ones. Weigh that against what the connection protects.
//! * **A clock.** Certificate validity is checked against
//! [`crate::clock`], through [`clock::rustls_time_provider`]. Until
//! something has set the clock — `sntp`, on a board with no RTC — every
//! handshake fails closed rather than validating against 1970.
//! * **Entropy.** The primitives reach randomness through `getrandom`, and
//! a bare-metal target has no backend for it. The `entropy` feature
//! registers the SoC's hardware generator as one; without it, or another,
//! the image fails to link on `__getrandom_custom`.
//!
//! [`clock::rustls_time_provider`]: crate::clock::rustls_time_provider
//!
//! # Trust anchors
//!
//! [`client_config_with`] takes a `RootCertStore`, so a board talking to
//! one private server carries that server's anchor and nothing else. With
//! the `webpki-roots` feature, [`client_config`] builds one from Mozilla's
//! set, compiled in. There is no system trust store on a board and nothing
//! to update one, so a root rotation is a firmware update — the same trade
//! every other constant in the image makes, and better than anchors read
//! off a card anybody can write.
//!
//! [`client_config_with`]: crate::tls::client_config_with
//! [`client_config`]: crate::tls::client_config
use Arc;
use ;
pub use ;
/// Builds a client configuration trusting `roots`.
///
/// **TLS 1.3 only.** Dropping 1.2 removes a meaningful amount of protocol
/// surface from an unaudited crypto provider, and every service these
/// boards talk to speaks 1.3. A board that must reach a 1.2-only server
/// builds its own `ClientConfig` from the same pieces: the provider from
/// `rustls_rustcrypto::provider()` and the clock from
/// [`clock::rustls_time_provider`](crate::clock::rustls_time_provider).
///
/// Allocates, and the trust anchor set is the largest single allocation a
/// board is likely to make outside the filesystem: build it once and share
/// the `Arc`, rather than once per connection.
/// Builds a client configuration trusting Mozilla's root set, compiled in.
/// See [`client_config_with`].
/// How many trust anchors [`client_config`] compiles in, for a bring-up
/// line.