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
impl Connection
Sourcepub fn client(config: &Config) -> Result<Self, Error>
pub fn client(config: &Config) -> Result<Self, Error>
Build a client connection. Picks the engine from config.max_version.
Examples found in repository?
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
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}Sourcepub fn server(config: &Config) -> Result<Self, Error>
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?
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}Sourcepub fn handshake(&mut self) -> Result<HandshakeStatus, Error>
pub fn handshake(&mut self) -> Result<HandshakeStatus, Error>
Drive the handshake forward. Returns the next HandshakeStatus.
Examples found in repository?
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}Sourcepub fn feed(&mut self, wire_in: &[u8]) -> Result<usize, Error>
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?
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
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}Sourcepub fn pop(&mut self) -> Result<Vec<u8>, Error>
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?
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
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}Sourcepub fn send(&mut self, app: &[u8]) -> Result<(), Error>
pub fn send(&mut self, app: &[u8]) -> Result<(), Error>
App bytes into the engine (post-handshake).
Examples found in repository?
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
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}Sourcepub fn recv(&mut self) -> Result<Vec<u8>, Error>
pub fn recv(&mut self) -> Result<Vec<u8>, Error>
App bytes out (post-handshake).
Examples found in repository?
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
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}Sourcepub fn close(&mut self) -> Result<(), Error>
pub fn close(&mut self) -> Result<(), Error>
Close the connection, emitting a close_notify alert if the engine supports it.
Sourcepub fn is_handshake_complete(&self) -> bool
pub fn is_handshake_complete(&self) -> bool
True once the handshake has completed.
Examples found in repository?
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}Sourcepub fn negotiated_version(&self) -> Option<ProtocolVersion>
pub fn negotiated_version(&self) -> Option<ProtocolVersion>
The negotiated wire version, if the handshake has progressed enough to determine it.
Sourcepub fn negotiated_cipher_suite(&self) -> Option<u16>
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).
Sourcepub fn negotiated_cipher_suite_name(&self) -> Option<&'static str>
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".
Sourcepub fn alpn_selected(&self) -> Option<&[u8]>
pub fn alpn_selected(&self) -> Option<&[u8]>
The negotiated ALPN protocol, if any.
Sourcepub fn peer_server_name(&self) -> Option<&str>
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.
Sourcepub fn peer_certificates(&self) -> &[Vec<u8>]
pub fn peer_certificates(&self) -> &[Vec<u8>]
The peer’s certificate chain (leaf first, DER).
Sourcepub fn next_timeout(&self) -> Option<Duration>
pub fn next_timeout(&self) -> Option<Duration>
DTLS: next retransmit timeout. None on TLS variants.
Sourcepub fn on_timeout(&mut self, now: Duration)
pub fn on_timeout(&mut self, now: Duration)
DTLS: notify the engine that the retransmit deadline has elapsed. No-op on TLS variants.