1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
use std::io::Write;
use std::sync::Arc;
use rustls::ServerConfig;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use rustls::server::Acceptor;
fn main() {
env_logger::init();
let pki = TestPki::new();
let server_config = pki.server_config();
let listener = std::net::TcpListener::bind(format!("[::]:{}", 4443)).unwrap();
for stream in listener.incoming() {
let mut stream = stream.unwrap();
let mut acceptor = Acceptor::default();
let accepted = loop {
acceptor.read_tls(&mut stream).unwrap();
if let Some(accepted) = acceptor.accept().unwrap() {
break accepted;
}
};
match accepted.into_connection(server_config.clone()) {
Ok(mut conn) => {
let msg = concat!(
"HTTP/1.1 200 OK\r\n",
"Connection: Closed\r\n",
"Content-Type: text/html\r\n",
"\r\n",
"<h1>Hello World!</h1>\r\n"
)
.as_bytes();
// Note: do not use `unwrap()` on IO in real programs!
conn.writer().write_all(msg).unwrap();
conn.write_tls(&mut stream).unwrap();
conn.complete_io(&mut stream).unwrap();
conn.send_close_notify();
conn.write_tls(&mut stream).unwrap();
conn.complete_io(&mut stream).unwrap();
}
Err((err, _)) => {
eprintln!("{err}");
}
}
}
}
struct TestPki {
server_cert_der: CertificateDer<'static>,
server_key_der: PrivateKeyDer<'static>,
}
impl TestPki {
fn new() -> Self {
let alg = &rcgen::PKCS_ECDSA_P256_SHA256;
let mut ca_params = rcgen::CertificateParams::new(Vec::new()).unwrap();
ca_params
.distinguished_name
.push(rcgen::DnType::OrganizationName, "Provider Server Example");
ca_params
.distinguished_name
.push(rcgen::DnType::CommonName, "Example CA");
ca_params.is_ca = rcgen::IsCa::Ca(rcgen::BasicConstraints::Unconstrained);
ca_params.key_usages = vec![
rcgen::KeyUsagePurpose::KeyCertSign,
rcgen::KeyUsagePurpose::DigitalSignature,
];
let ca_key = rcgen::KeyPair::generate_for(alg).unwrap();
let ca_cert = ca_params.self_signed(&ca_key).unwrap();
// Create a server end entity cert issued by the CA.
let mut server_ee_params =
rcgen::CertificateParams::new(vec!["localhost".to_string()]).unwrap();
server_ee_params.is_ca = rcgen::IsCa::NoCa;
server_ee_params.extended_key_usages = vec![rcgen::ExtendedKeyUsagePurpose::ServerAuth];
let server_key = rcgen::KeyPair::generate_for(alg).unwrap();
let server_cert = server_ee_params
.signed_by(&server_key, &ca_cert, &ca_key)
.unwrap();
Self {
server_cert_der: server_cert.into(),
// TODO(XXX): update below once https://github.com/rustls/rcgen/issues/260 is resolved.
server_key_der: PrivatePkcs8KeyDer::from(server_key.serialize_der()).into(),
}
}
fn server_config(self) -> Arc<ServerConfig> {
let mut server_config =
ServerConfig::builder_with_provider(rustls_provider_example::provider().into())
.with_safe_default_protocol_versions()
.unwrap()
.with_no_client_auth()
.with_single_cert(vec![self.server_cert_der], self.server_key_der)
.unwrap();
server_config.key_log = Arc::new(rustls::KeyLogFile::new());
Arc::new(server_config)
}
}
|