pub struct Ssl { /* private fields */ }Expand description
Per-connection TLS object (SSL*).
Has exclusive ownership over its state; no Clone. BIOs passed to
Ssl::set_bio_duplex or Ssl::set_bio are owned by the Ssl thereafter.
Implementations§
Source§impl Ssl
impl Ssl
Sourcepub fn set_bio_duplex(&mut self, bio: Bio)
pub fn set_bio_duplex(&mut self, bio: Bio)
Set a single duplex BIO for both reading and writing.
Transfers ownership of bio to the SSL object; do not use bio
afterwards. Suitable for BIO_new_bio_pair endpoints.
When rbio == wbio (same pointer), OpenSSL only increments the
reference count once, so the single reference in bio is correct.
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn set_bio(&mut self, rbio: Bio, wbio: Bio)
pub fn set_bio(&mut self, rbio: Bio, wbio: Bio)
Set separate read and write BIOs.
Transfers ownership of both rbio and wbio to the SSL object.
Sourcepub fn set_hostname(&mut self, hostname: &CStr) -> Result<(), ErrorStack>
pub fn set_hostname(&mut self, hostname: &CStr) -> Result<(), ErrorStack>
Set the SNI hostname extension sent during the TLS handshake.
Call before Self::connect on client connections to enable SNI.
hostname must be a NUL-terminated ASCII/UTF-8 hostname.
SSL_set_tlsext_host_name is a C macro expanding to
SSL_ctrl(s, 55 /*SSL_CTRL_SET_TLSEXT_HOSTNAME*/, 0 /*TLSEXT_NAMETYPE_host_name*/, name).
§Errors
Returns Err if the control call fails.
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn set_connect_state(&mut self)
pub fn set_connect_state(&mut self)
Set this SSL object to operate in client (connect) mode.
Required before calling Self::do_handshake if neither Self::connect nor
Self::accept will be used.
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn set_accept_state(&mut self)
pub fn set_accept_state(&mut self)
Set this SSL object to operate in server (accept) mode.
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn connect(&mut self) -> Result<(), SslIoError>
pub fn connect(&mut self) -> Result<(), SslIoError>
Initiate a client-side TLS handshake (SSL_connect).
Returns Ok(()) on success, SslIoError::WantRead / SslIoError::WantWrite
when the operation must be retried after more data is available.
§Errors
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn accept(&mut self) -> Result<(), SslIoError>
pub fn accept(&mut self) -> Result<(), SslIoError>
Accept an incoming TLS connection (SSL_accept).
Returns Ok(()) on success, SslIoError::WantRead / SslIoError::WantWrite
on non-blocking retry.
§Errors
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn do_handshake(&mut self) -> Result<(), SslIoError>
pub fn do_handshake(&mut self) -> Result<(), SslIoError>
Drive the TLS handshake in either role (SSL_do_handshake).
The role must have been set via Self::set_connect_state or Self::set_accept_state
(or implicitly by Self::connect / Self::accept).
§Errors
Sourcepub fn read(&mut self, buf: &mut [u8]) -> Result<usize, SslIoError>
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, SslIoError>
Read decrypted application data (SSL_read_ex).
Returns the number of bytes written into buf on success.
§Errors
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn write(&mut self, buf: &[u8]) -> Result<usize, SslIoError>
pub fn write(&mut self, buf: &[u8]) -> Result<usize, SslIoError>
Write application data (SSL_write_ex).
Returns the number of bytes consumed from buf on success.
§Errors
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn shutdown(&mut self) -> Result<ShutdownResult, ErrorStack>
pub fn shutdown(&mut self) -> Result<ShutdownResult, ErrorStack>
Send a TLS close-notify alert (SSL_shutdown).
Returns ShutdownResult::Sent after the first shutdown stage and
ShutdownResult::Complete after a bidirectional shutdown. Call
twice on a non-blocking connection to complete the exchange.
§Errors
Returns Err on a fatal error during shutdown.
Sourcepub fn peer_certificate(&self) -> Option<X509>
pub fn peer_certificate(&self) -> Option<X509>
Return the peer’s certificate, or None if unavailable.
The returned certificate has its reference count incremented, so it
outlives self.
Examples found in repository?
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 // ── Key pair and self-signed certificate ───────────────────────────────────
16
17 let mut kgen = KeygenCtx::new(c"ED25519")?;
18 let priv_key = kgen.generate()?;
19 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
20
21 let mut name = X509NameOwned::new()?;
22 name.add_entry_by_txt(c"CN", b"localhost")?;
23
24 let cert = X509Builder::new()?
25 .set_version(2)?
26 .set_serial_number(1)?
27 .set_not_before_offset(0)?
28 .set_not_after_offset(86400)?
29 .set_subject_name(&name)?
30 .set_issuer_name(&name)?
31 .set_public_key(&pub_key)?
32 .sign(&priv_key, None)?
33 .build();
34
35 // ── Server context ─────────────────────────────────────────────────────────
36
37 let server_ctx = SslCtx::new_server()?;
38 server_ctx.set_min_proto_version(TlsVersion::Tls13)?;
39 server_ctx.use_certificate(&cert)?;
40 server_ctx.use_private_key(&priv_key)?;
41 server_ctx.check_private_key()?;
42
43 // ── Client context ─────────────────────────────────────────────────────────
44
45 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 // Skip certificate verification for this self-signed example.
48 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 // ── SSL objects ────────────────────────────────────────────────────────────
51
52 let mut client = client_ctx.new_ssl()?;
53 let mut server = server_ctx.new_ssl()?;
54
55 client.set_connect_state();
56 client.set_hostname(c"localhost")?;
57 server.set_accept_state();
58
59 // ── In-process BIO pair ────────────────────────────────────────────────────
60 // Data written to client_bio is readable from server_bio and vice-versa.
61
62 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 // ── Drive the handshake ────────────────────────────────────────────────────
67 // Alternate between client and server until both report success.
68
69 let mut client_done = false;
70 let mut server_done = false;
71
72 for step in 0..20 {
73 if !client_done {
74 match client.connect() {
75 Ok(()) => {
76 client_done = true;
77 println!("Client handshake done at step {step}");
78 }
79 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
80 Err(e) => return Err(format!("client error: {e}").into()),
81 }
82 }
83 if !server_done {
84 match server.accept() {
85 Ok(()) => {
86 server_done = true;
87 println!("Server handshake done at step {step}");
88 }
89 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
90 Err(e) => return Err(format!("server error: {e}").into()),
91 }
92 }
93 if client_done && server_done {
94 break;
95 }
96 }
97 assert!(client_done && server_done, "handshake did not complete");
98
99 // ── Inspect the peer certificate on the client ─────────────────────────────
100
101 if let Some(peer_cert) = client.peer_certificate() {
102 if let Some(subject) = peer_cert.subject_name().to_string() {
103 println!("Server cert subject: {subject}");
104 }
105 }
106
107 // ── Application data exchange ──────────────────────────────────────────────
108
109 let request = b"GET / HTTP/1.0\r\n\r\n";
110 let response = b"HTTP/1.0 200 OK\r\n\r\nHello, TLS!";
111
112 let written = client.write(request)?;
113 assert_eq!(written, request.len());
114
115 let mut rbuf = [0u8; 64];
116 let n = server.read(&mut rbuf)?;
117 assert_eq!(&rbuf[..n], request);
118 println!("Server received: {:?}", std::str::from_utf8(&rbuf[..n])?);
119
120 let written = server.write(response)?;
121 assert_eq!(written, response.len());
122
123 let n = client.read(&mut rbuf)?;
124 assert_eq!(&rbuf[..n], response);
125 println!("Client received: {:?}", std::str::from_utf8(&rbuf[..n])?);
126
127 println!("In-process TLS 1.3 round-trip: OK");
128
129 Ok(())
130}Sourcepub fn get1_session(&self) -> Option<SslSession>
pub fn get1_session(&self) -> Option<SslSession>
Get an owned reference to the current session (SSL_get1_session).
Returns None if no session is established. The session can be passed
to Self::set_session on a new Ssl for resumption.
Sourcepub fn set_session(&mut self, session: &SslSession) -> Result<(), ErrorStack>
pub fn set_session(&mut self, session: &SslSession) -> Result<(), ErrorStack>
Set a previously obtained session for resumption (SSL_set_session).
Call before the handshake.