Skip to main content

Connection

Struct Connection 

Source
pub struct Connection { /* private fields */ }
Expand description

A unified TLS or DTLS connection (client or server, any supported version).

Construct via Connection::client or Connection::server, passing a shared super::Config. The internal engine is picked from config.max_version.

Implementations§

Source§

impl Connection

Source

pub fn client(config: &Config) -> Result<Self, Error>

Build a client connection. Picks the engine from config.max_version.

Examples found in repository?
examples/tls_loopback.rs (line 39)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
More examples
Hide additional examples
examples/tls_get.rs (line 33)
19fn main() {
20    let insecure = std::env::args().any(|a| a == "--insecure");
21
22    let roots = if insecure {
23        RootCertStore::new()
24    } else {
25        load_system_roots()
26    };
27    let cfg = Config::builder()
28        .tls_only()
29        .roots(roots)
30        .server_name(HOST)
31        .verify_certificates(!insecure)
32        .build();
33    let mut conn = Connection::client(&cfg).expect("client config");
34
35    let mut sock = TcpStream::connect((HOST, 443)).expect("TCP connect");
36    sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
37
38    // Drive the handshake to completion.
39    let mut read_buf = [0u8; 8192];
40    loop {
41        let out = conn.pop().unwrap_or_default();
42        if !out.is_empty() {
43            sock.write_all(&out).unwrap();
44        }
45        match conn.handshake().unwrap() {
46            HandshakeStatus::Complete => break,
47            HandshakeStatus::WantWrite => continue,
48            HandshakeStatus::WantRead => {
49                let n = sock.read(&mut read_buf).expect("read");
50                assert!(n > 0, "peer closed during handshake");
51                conn.feed(&read_buf[..n]).expect("feed");
52            }
53        }
54    }
55    eprintln!(
56        "TLS 1.3 handshake with {HOST} complete (certificate {}verified)",
57        if insecure { "NOT " } else { "" }
58    );
59
60    let request = "GET / HTTP/1.1\r\nHost: example.org\r\n\r\n";
61    conn.send(request.as_bytes()).unwrap();
62    let out = conn.pop().unwrap_or_default();
63    sock.write_all(&out).unwrap();
64    sock.flush().unwrap();
65
66    let mut response = Vec::new();
67    loop {
68        match sock.read(&mut read_buf) {
69            Ok(0) => break,
70            Ok(n) => {
71                if conn.feed(&read_buf[..n]).is_err() {
72                    break;
73                }
74                let plain = conn.recv().unwrap_or_default();
75                response.extend_from_slice(&plain);
76                if response.len() > 16 * 1024 {
77                    break;
78                }
79            }
80            Err(e)
81                if e.kind() == std::io::ErrorKind::WouldBlock
82                    || e.kind() == std::io::ErrorKind::TimedOut =>
83            {
84                break;
85            }
86            Err(e) => {
87                eprintln!("read error: {e}");
88                break;
89            }
90        }
91    }
92
93    let text = String::from_utf8_lossy(&response);
94    println!("--- {} bytes received ---", response.len());
95    for line in text.lines().take(15) {
96        println!("{line}");
97    }
98}
Source

pub fn server(config: &Config) -> Result<Self, Error>

Build a server connection. Picks the engine from config.max_version. Requires config.identity.is_some().

Examples found in repository?
examples/tls_loopback.rs (line 29)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
Source

pub fn handshake(&mut self) -> Result<HandshakeStatus, Error>

Drive the handshake forward. Returns the next HandshakeStatus.

Examples found in repository?
examples/tls_get.rs (line 45)
19fn main() {
20    let insecure = std::env::args().any(|a| a == "--insecure");
21
22    let roots = if insecure {
23        RootCertStore::new()
24    } else {
25        load_system_roots()
26    };
27    let cfg = Config::builder()
28        .tls_only()
29        .roots(roots)
30        .server_name(HOST)
31        .verify_certificates(!insecure)
32        .build();
33    let mut conn = Connection::client(&cfg).expect("client config");
34
35    let mut sock = TcpStream::connect((HOST, 443)).expect("TCP connect");
36    sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
37
38    // Drive the handshake to completion.
39    let mut read_buf = [0u8; 8192];
40    loop {
41        let out = conn.pop().unwrap_or_default();
42        if !out.is_empty() {
43            sock.write_all(&out).unwrap();
44        }
45        match conn.handshake().unwrap() {
46            HandshakeStatus::Complete => break,
47            HandshakeStatus::WantWrite => continue,
48            HandshakeStatus::WantRead => {
49                let n = sock.read(&mut read_buf).expect("read");
50                assert!(n > 0, "peer closed during handshake");
51                conn.feed(&read_buf[..n]).expect("feed");
52            }
53        }
54    }
55    eprintln!(
56        "TLS 1.3 handshake with {HOST} complete (certificate {}verified)",
57        if insecure { "NOT " } else { "" }
58    );
59
60    let request = "GET / HTTP/1.1\r\nHost: example.org\r\n\r\n";
61    conn.send(request.as_bytes()).unwrap();
62    let out = conn.pop().unwrap_or_default();
63    sock.write_all(&out).unwrap();
64    sock.flush().unwrap();
65
66    let mut response = Vec::new();
67    loop {
68        match sock.read(&mut read_buf) {
69            Ok(0) => break,
70            Ok(n) => {
71                if conn.feed(&read_buf[..n]).is_err() {
72                    break;
73                }
74                let plain = conn.recv().unwrap_or_default();
75                response.extend_from_slice(&plain);
76                if response.len() > 16 * 1024 {
77                    break;
78                }
79            }
80            Err(e)
81                if e.kind() == std::io::ErrorKind::WouldBlock
82                    || e.kind() == std::io::ErrorKind::TimedOut =>
83            {
84                break;
85            }
86            Err(e) => {
87                eprintln!("read error: {e}");
88                break;
89            }
90        }
91    }
92
93    let text = String::from_utf8_lossy(&response);
94    println!("--- {} bytes received ---", response.len());
95    for line in text.lines().take(15) {
96        println!("{line}");
97    }
98}
Source

pub fn feed(&mut self, wire_in: &[u8]) -> Result<usize, Error>

Wire bytes from the peer into the engine. Returns the number of bytes consumed.

Examples found in repository?
examples/tls_loopback.rs (line 45)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
More examples
Hide additional examples
examples/tls_get.rs (line 51)
19fn main() {
20    let insecure = std::env::args().any(|a| a == "--insecure");
21
22    let roots = if insecure {
23        RootCertStore::new()
24    } else {
25        load_system_roots()
26    };
27    let cfg = Config::builder()
28        .tls_only()
29        .roots(roots)
30        .server_name(HOST)
31        .verify_certificates(!insecure)
32        .build();
33    let mut conn = Connection::client(&cfg).expect("client config");
34
35    let mut sock = TcpStream::connect((HOST, 443)).expect("TCP connect");
36    sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
37
38    // Drive the handshake to completion.
39    let mut read_buf = [0u8; 8192];
40    loop {
41        let out = conn.pop().unwrap_or_default();
42        if !out.is_empty() {
43            sock.write_all(&out).unwrap();
44        }
45        match conn.handshake().unwrap() {
46            HandshakeStatus::Complete => break,
47            HandshakeStatus::WantWrite => continue,
48            HandshakeStatus::WantRead => {
49                let n = sock.read(&mut read_buf).expect("read");
50                assert!(n > 0, "peer closed during handshake");
51                conn.feed(&read_buf[..n]).expect("feed");
52            }
53        }
54    }
55    eprintln!(
56        "TLS 1.3 handshake with {HOST} complete (certificate {}verified)",
57        if insecure { "NOT " } else { "" }
58    );
59
60    let request = "GET / HTTP/1.1\r\nHost: example.org\r\n\r\n";
61    conn.send(request.as_bytes()).unwrap();
62    let out = conn.pop().unwrap_or_default();
63    sock.write_all(&out).unwrap();
64    sock.flush().unwrap();
65
66    let mut response = Vec::new();
67    loop {
68        match sock.read(&mut read_buf) {
69            Ok(0) => break,
70            Ok(n) => {
71                if conn.feed(&read_buf[..n]).is_err() {
72                    break;
73                }
74                let plain = conn.recv().unwrap_or_default();
75                response.extend_from_slice(&plain);
76                if response.len() > 16 * 1024 {
77                    break;
78                }
79            }
80            Err(e)
81                if e.kind() == std::io::ErrorKind::WouldBlock
82                    || e.kind() == std::io::ErrorKind::TimedOut =>
83            {
84                break;
85            }
86            Err(e) => {
87                eprintln!("read error: {e}");
88                break;
89            }
90        }
91    }
92
93    let text = String::from_utf8_lossy(&response);
94    println!("--- {} bytes received ---", response.len());
95    for line in text.lines().take(15) {
96        println!("{line}");
97    }
98}
Source

pub fn pop(&mut self) -> Result<Vec<u8>, Error>

Wire bytes the engine wants to send to the peer. For TLS, this is a contiguous stream slice; for DTLS, this is one datagram per call.

Examples found in repository?
examples/tls_loopback.rs (line 43)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
More examples
Hide additional examples
examples/tls_get.rs (line 41)
19fn main() {
20    let insecure = std::env::args().any(|a| a == "--insecure");
21
22    let roots = if insecure {
23        RootCertStore::new()
24    } else {
25        load_system_roots()
26    };
27    let cfg = Config::builder()
28        .tls_only()
29        .roots(roots)
30        .server_name(HOST)
31        .verify_certificates(!insecure)
32        .build();
33    let mut conn = Connection::client(&cfg).expect("client config");
34
35    let mut sock = TcpStream::connect((HOST, 443)).expect("TCP connect");
36    sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
37
38    // Drive the handshake to completion.
39    let mut read_buf = [0u8; 8192];
40    loop {
41        let out = conn.pop().unwrap_or_default();
42        if !out.is_empty() {
43            sock.write_all(&out).unwrap();
44        }
45        match conn.handshake().unwrap() {
46            HandshakeStatus::Complete => break,
47            HandshakeStatus::WantWrite => continue,
48            HandshakeStatus::WantRead => {
49                let n = sock.read(&mut read_buf).expect("read");
50                assert!(n > 0, "peer closed during handshake");
51                conn.feed(&read_buf[..n]).expect("feed");
52            }
53        }
54    }
55    eprintln!(
56        "TLS 1.3 handshake with {HOST} complete (certificate {}verified)",
57        if insecure { "NOT " } else { "" }
58    );
59
60    let request = "GET / HTTP/1.1\r\nHost: example.org\r\n\r\n";
61    conn.send(request.as_bytes()).unwrap();
62    let out = conn.pop().unwrap_or_default();
63    sock.write_all(&out).unwrap();
64    sock.flush().unwrap();
65
66    let mut response = Vec::new();
67    loop {
68        match sock.read(&mut read_buf) {
69            Ok(0) => break,
70            Ok(n) => {
71                if conn.feed(&read_buf[..n]).is_err() {
72                    break;
73                }
74                let plain = conn.recv().unwrap_or_default();
75                response.extend_from_slice(&plain);
76                if response.len() > 16 * 1024 {
77                    break;
78                }
79            }
80            Err(e)
81                if e.kind() == std::io::ErrorKind::WouldBlock
82                    || e.kind() == std::io::ErrorKind::TimedOut =>
83            {
84                break;
85            }
86            Err(e) => {
87                eprintln!("read error: {e}");
88                break;
89            }
90        }
91    }
92
93    let text = String::from_utf8_lossy(&response);
94    println!("--- {} bytes received ---", response.len());
95    for line in text.lines().take(15) {
96        println!("{line}");
97    }
98}
Source

pub fn send(&mut self, app: &[u8]) -> Result<(), Error>

App bytes into the engine (post-handshake).

Examples found in repository?
examples/tls_loopback.rs (line 59)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
More examples
Hide additional examples
examples/tls_get.rs (line 61)
19fn main() {
20    let insecure = std::env::args().any(|a| a == "--insecure");
21
22    let roots = if insecure {
23        RootCertStore::new()
24    } else {
25        load_system_roots()
26    };
27    let cfg = Config::builder()
28        .tls_only()
29        .roots(roots)
30        .server_name(HOST)
31        .verify_certificates(!insecure)
32        .build();
33    let mut conn = Connection::client(&cfg).expect("client config");
34
35    let mut sock = TcpStream::connect((HOST, 443)).expect("TCP connect");
36    sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
37
38    // Drive the handshake to completion.
39    let mut read_buf = [0u8; 8192];
40    loop {
41        let out = conn.pop().unwrap_or_default();
42        if !out.is_empty() {
43            sock.write_all(&out).unwrap();
44        }
45        match conn.handshake().unwrap() {
46            HandshakeStatus::Complete => break,
47            HandshakeStatus::WantWrite => continue,
48            HandshakeStatus::WantRead => {
49                let n = sock.read(&mut read_buf).expect("read");
50                assert!(n > 0, "peer closed during handshake");
51                conn.feed(&read_buf[..n]).expect("feed");
52            }
53        }
54    }
55    eprintln!(
56        "TLS 1.3 handshake with {HOST} complete (certificate {}verified)",
57        if insecure { "NOT " } else { "" }
58    );
59
60    let request = "GET / HTTP/1.1\r\nHost: example.org\r\n\r\n";
61    conn.send(request.as_bytes()).unwrap();
62    let out = conn.pop().unwrap_or_default();
63    sock.write_all(&out).unwrap();
64    sock.flush().unwrap();
65
66    let mut response = Vec::new();
67    loop {
68        match sock.read(&mut read_buf) {
69            Ok(0) => break,
70            Ok(n) => {
71                if conn.feed(&read_buf[..n]).is_err() {
72                    break;
73                }
74                let plain = conn.recv().unwrap_or_default();
75                response.extend_from_slice(&plain);
76                if response.len() > 16 * 1024 {
77                    break;
78                }
79            }
80            Err(e)
81                if e.kind() == std::io::ErrorKind::WouldBlock
82                    || e.kind() == std::io::ErrorKind::TimedOut =>
83            {
84                break;
85            }
86            Err(e) => {
87                eprintln!("read error: {e}");
88                break;
89            }
90        }
91    }
92
93    let text = String::from_utf8_lossy(&response);
94    println!("--- {} bytes received ---", response.len());
95    for line in text.lines().take(15) {
96        println!("{line}");
97    }
98}
Source

pub fn recv(&mut self) -> Result<Vec<u8>, Error>

App bytes out (post-handshake).

Examples found in repository?
examples/tls_loopback.rs (line 64)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
More examples
Hide additional examples
examples/tls_get.rs (line 74)
19fn main() {
20    let insecure = std::env::args().any(|a| a == "--insecure");
21
22    let roots = if insecure {
23        RootCertStore::new()
24    } else {
25        load_system_roots()
26    };
27    let cfg = Config::builder()
28        .tls_only()
29        .roots(roots)
30        .server_name(HOST)
31        .verify_certificates(!insecure)
32        .build();
33    let mut conn = Connection::client(&cfg).expect("client config");
34
35    let mut sock = TcpStream::connect((HOST, 443)).expect("TCP connect");
36    sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
37
38    // Drive the handshake to completion.
39    let mut read_buf = [0u8; 8192];
40    loop {
41        let out = conn.pop().unwrap_or_default();
42        if !out.is_empty() {
43            sock.write_all(&out).unwrap();
44        }
45        match conn.handshake().unwrap() {
46            HandshakeStatus::Complete => break,
47            HandshakeStatus::WantWrite => continue,
48            HandshakeStatus::WantRead => {
49                let n = sock.read(&mut read_buf).expect("read");
50                assert!(n > 0, "peer closed during handshake");
51                conn.feed(&read_buf[..n]).expect("feed");
52            }
53        }
54    }
55    eprintln!(
56        "TLS 1.3 handshake with {HOST} complete (certificate {}verified)",
57        if insecure { "NOT " } else { "" }
58    );
59
60    let request = "GET / HTTP/1.1\r\nHost: example.org\r\n\r\n";
61    conn.send(request.as_bytes()).unwrap();
62    let out = conn.pop().unwrap_or_default();
63    sock.write_all(&out).unwrap();
64    sock.flush().unwrap();
65
66    let mut response = Vec::new();
67    loop {
68        match sock.read(&mut read_buf) {
69            Ok(0) => break,
70            Ok(n) => {
71                if conn.feed(&read_buf[..n]).is_err() {
72                    break;
73                }
74                let plain = conn.recv().unwrap_or_default();
75                response.extend_from_slice(&plain);
76                if response.len() > 16 * 1024 {
77                    break;
78                }
79            }
80            Err(e)
81                if e.kind() == std::io::ErrorKind::WouldBlock
82                    || e.kind() == std::io::ErrorKind::TimedOut =>
83            {
84                break;
85            }
86            Err(e) => {
87                eprintln!("read error: {e}");
88                break;
89            }
90        }
91    }
92
93    let text = String::from_utf8_lossy(&response);
94    println!("--- {} bytes received ---", response.len());
95    for line in text.lines().take(15) {
96        println!("{line}");
97    }
98}
Source

pub fn close(&mut self) -> Result<(), Error>

Close the connection, emitting a close_notify alert if the engine supports it.

Source

pub fn is_handshake_complete(&self) -> bool

True once the handshake has completed.

Examples found in repository?
examples/tls_loopback.rs (line 55)
13fn main() {
14    // --- Server setup: a self-signed certificate for "example.test". ---
15    let signing_key = RsaPrivateKey::<32>::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
16    let name = DistinguishedName::common_name("example.test");
17    let validity = Validity::new(
18        Time::utc(2024, 1, 1, 0, 0, 0),
19        Time::utc(2034, 1, 1, 0, 0, 0),
20    );
21    let cert = Certificate::self_signed(&signing_key, &name, &validity, 1, false).unwrap();
22    let cert_der = cert.to_der().to_vec();
23
24    let server_key = BoxedRsaPrivateKey::from_pkcs1_pem(SERVER_KEY_PEM).unwrap();
25    let server_cfg = Config::builder()
26        .tls_only()
27        .identity(vec![cert_der.clone()], SigningKey::Rsa(server_key))
28        .build();
29    let mut server = Connection::server(&server_cfg).expect("server config");
30
31    // --- Client setup: trust the server's certificate. ---
32    let mut roots = RootCertStore::new();
33    roots.add_der(cert_der).unwrap();
34    let client_cfg = Config::builder()
35        .tls_only()
36        .roots(roots)
37        .server_name("example.test")
38        .build();
39    let mut client = Connection::client(&client_cfg).expect("client config");
40
41    // --- Drive the handshake by shuttling records between the two ends. ---
42    for _ in 0..16 {
43        let to_server = client.pop().unwrap_or_default();
44        if !to_server.is_empty() {
45            server.feed(&to_server).unwrap();
46        }
47        let to_client = server.pop().unwrap_or_default();
48        if !to_client.is_empty() {
49            client.feed(&to_client).unwrap();
50        }
51        if to_server.is_empty() && to_client.is_empty() {
52            break;
53        }
54    }
55    assert!(client.is_handshake_complete() && server.is_handshake_complete());
56    println!("handshake complete");
57
58    // --- Application data: client -> server -> client. ---
59    client.send(b"GET / HTTP/1.0").unwrap();
60    let req = client.pop().unwrap_or_default();
61    server.feed(&req).unwrap();
62    println!(
63        "server received: {:?}",
64        String::from_utf8_lossy(&server.recv().unwrap_or_default())
65    );
66
67    server.send(b"HTTP/1.0 200 OK").unwrap();
68    let resp = server.pop().unwrap_or_default();
69    client.feed(&resp).unwrap();
70    println!(
71        "client received: {:?}",
72        String::from_utf8_lossy(&client.recv().unwrap_or_default())
73    );
74}
Source

pub fn negotiated_version(&self) -> Option<ProtocolVersion>

The negotiated wire version, if the handshake has progressed enough to determine it.

Source

pub fn negotiated_cipher_suite(&self) -> Option<u16>

IANA cipher-suite identifier of the negotiated suite. None until the handshake has advanced far enough to fix the suite (ServerHello processed on the client, ClientHello processed on the server).

Source

pub fn negotiated_cipher_suite_name(&self) -> Option<&'static str>

The IANA name of the negotiated cipher suite, or None until the suite is fixed. Returns the well-known strings for the suites purecrypto negotiates (TLS 1.3 trio + the TLS 1.2 ECDHE-AEAD set); unknown codes resolve to "UNKNOWN".

Source

pub fn alpn_selected(&self) -> Option<&[u8]>

The negotiated ALPN protocol, if any.

Source

pub fn peer_server_name(&self) -> Option<&str>

Server-side: the SNI host_name the client offered in the ClientHello server_name extension (RFC 6066 §3). None for client engines, for DTLS engines (no SNI plumbing yet), or when the peer omitted the extension. Available once the ClientHello has been processed.

Source

pub fn peer_certificates(&self) -> &[Vec<u8>]

The peer’s certificate chain (leaf first, DER).

Source

pub fn next_timeout(&self) -> Option<Duration>

DTLS: next retransmit timeout. None on TLS variants.

Source

pub fn on_timeout(&mut self, now: Duration)

DTLS: notify the engine that the retransmit deadline has elapsed. No-op on TLS variants.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.