embedded_tls/
lib.rs

1#![cfg_attr(not(any(test, feature = "std")), no_std)]
2#![doc = include_str!("../README.md")]
3#![allow(dead_code)]
4
5/*!
6# Example
7
8```
9use embedded_tls::*;
10use embedded_io_adapters::tokio_1::FromTokio;
11use rand::rngs::OsRng;
12use tokio::net::TcpStream;
13
14#[tokio::main]
15async fn main() {
16    let stream = TcpStream::connect("http.sandbox.drogue.cloud:443").await.expect("error creating TCP connection");
17
18    println!("TCP connection opened");
19    let mut read_record_buffer = [0; 16384];
20    let mut write_record_buffer = [0; 16384];
21    let config = TlsConfig::new()
22        .with_server_name("http.sandbox.drogue.cloud");
23    let mut tls: TlsConnection<FromTokio<TcpStream>, Aes128GcmSha256> =
24        TlsConnection::new(FromTokio::new(stream), &mut read_record_buffer, &mut write_record_buffer);
25
26    // Allows disabling cert verification, in case you are using PSK and don't need it, or are just testing.
27    // otherwise, use embedded_tls::webpki::CertVerifier, which only works on std for now.
28    tls.open::<OsRng, NoVerify>(TlsContext::new(&config, &mut OsRng)).await.expect("error establishing TLS connection");
29
30    println!("TLS session opened");
31}
32```
33*/
34
35// This mod MUST go first, so that the others see its macros.
36pub(crate) mod fmt;
37
38use parse_buffer::ParseError;
39pub mod alert;
40mod application_data;
41pub mod blocking;
42mod buffer;
43mod change_cipher_spec;
44mod cipher_suites;
45mod common;
46mod config;
47mod connection;
48mod content_types;
49mod crypto_engine;
50mod extensions;
51mod handshake;
52mod key_schedule;
53mod parse_buffer;
54pub mod read_buffer;
55mod record;
56mod record_reader;
57mod split;
58mod write_buffer;
59
60#[cfg(feature = "webpki")]
61pub mod webpki;
62
63mod asynch;
64pub use asynch::*;
65
66#[derive(Debug, Copy, Clone)]
67#[cfg_attr(feature = "defmt", derive(defmt::Format))]
68pub enum TlsError {
69    ConnectionClosed,
70    Unimplemented,
71    MissingHandshake,
72    HandshakeAborted(alert::AlertLevel, alert::AlertDescription),
73    AbortHandshake(alert::AlertLevel, alert::AlertDescription),
74    IoError,
75    InternalError,
76    InvalidRecord,
77    UnknownContentType,
78    InvalidNonceLength,
79    InvalidTicketLength,
80    UnknownExtensionType,
81    InsufficientSpace,
82    InvalidHandshake,
83    InvalidCipherSuite,
84    InvalidSignatureScheme,
85    InvalidSignature,
86    InvalidExtensionsLength,
87    InvalidSessionIdLength,
88    InvalidSupportedVersions,
89    InvalidApplicationData,
90    InvalidKeyShare,
91    InvalidCertificate,
92    InvalidCertificateEntry,
93    InvalidCertificateRequest,
94    UnableToInitializeCryptoEngine,
95    ParseError(ParseError),
96    OutOfMemory,
97    CryptoError,
98    EncodeError,
99    DecodeError,
100    Io(embedded_io::ErrorKind),
101}
102
103impl embedded_io::Error for TlsError {
104    fn kind(&self) -> embedded_io::ErrorKind {
105        match self {
106            Self::Io(k) => *k,
107            _ => {
108                error!("TLS error: {:?}", self);
109                embedded_io::ErrorKind::Other
110            }
111        }
112    }
113}
114
115#[cfg(feature = "std")]
116mod stdlib {
117    use crate::config::TlsClock;
118
119    use std::time::SystemTime;
120    impl TlsClock for SystemTime {
121        fn now() -> Option<u64> {
122            Some(
123                SystemTime::now()
124                    .duration_since(SystemTime::UNIX_EPOCH)
125                    .unwrap()
126                    .as_secs(),
127            )
128        }
129    }
130}