Skip to main content

Ssl

Struct Ssl 

Source
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

Source

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?
examples/ssl.rs (line 63)
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}
Source

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.

Source

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?
examples/ssl.rs (line 56)
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}
Source

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?
examples/ssl.rs (line 55)
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}
Source

pub fn set_accept_state(&mut self)

Set this SSL object to operate in server (accept) mode.

Examples found in repository?
examples/ssl.rs (line 57)
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}
Source

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?
examples/ssl.rs (line 74)
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}
Source

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?
examples/ssl.rs (line 84)
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}
Source

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
Source

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?
examples/ssl.rs (line 116)
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}
Source

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?
examples/ssl.rs (line 112)
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}
Source

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.

Source

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?
examples/ssl.rs (line 101)
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}
Source

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.

Source

pub fn set_session(&mut self, session: &SslSession) -> Result<(), ErrorStack>

Set a previously obtained session for resumption (SSL_set_session).

Call before the handshake.

§Errors

Trait Implementations§

Source§

impl Drop for Ssl

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for Ssl

Auto Trait Implementations§

§

impl Freeze for Ssl

§

impl RefUnwindSafe for Ssl

§

impl !Sync for Ssl

§

impl Unpin for Ssl

§

impl UnsafeUnpin for Ssl

§

impl UnwindSafe for Ssl

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.