1use native_ossl::bio::Bio;
10use native_ossl::pkey::KeygenCtx;
11use native_ossl::ssl::{SslCtx, SslIoError, SslVerifyMode, TlsVersion};
12use native_ossl::x509::{X509Builder, X509NameOwned};
13
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 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 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 let client_ctx = SslCtx::new_client()?;
46 client_ctx.set_min_proto_version(TlsVersion::Tls13)?;
47 client_ctx.set_verify(SslVerifyMode::NONE);
49
50 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 let (client_bio, server_bio) = Bio::new_pair()?;
63 client.set_bio_duplex(client_bio);
64 server.set_bio_duplex(server_bio);
65
66 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 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 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}