pki 0.2.2

Public key infrastructure tools for Rust
Documentation
use std::net::Shutdown;
use std::{
    io::{Read, Write},
    net::{TcpListener, TcpStream},
};

use native_tls::{Certificate, Identity, TlsAcceptor, TlsConnector};

const HOSTNAME: &str = "localhost";
const PORT: u16 = 8000;

fn accept(server: TcpListener, acceptor: TlsAcceptor) -> Result<(), Box<dyn std::error::Error>> {
    for stream in server.incoming() {
        let mut tls_stream = acceptor.accept(stream?)?;
        let mut buf = Vec::new();
        tls_stream.read_to_end(&mut buf)?;
        println!("{}", String::from_utf8_lossy(&buf));
        tls_stream.get_ref().shutdown(Shutdown::Read)?;
        tls_stream.write_all(b"pong")?;
    }
    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key_store = pki::util::create_easy_server_chain(HOSTNAME)?;
    let pkcs8 = key_store.to_pkcs8()?;

    let identity = Identity::from_pkcs8(&pkcs8, &pkcs8)?;
    let acceptor = TlsAcceptor::builder(identity).build()?;
    let server = TcpListener::bind(format!("{}:{}", HOSTNAME, PORT))?;

    std::thread::spawn(move || {
        let _ = accept(server, acceptor);
    });

    let client = TcpStream::connect(format!("{}:{}", HOSTNAME, PORT))?;
    let connector = TlsConnector::builder()
        .add_root_certificate(Certificate::from_der(
            &key_store.certs().last().unwrap().to_der()?,
        )?)
        .build()?;
    let mut tls_stream = connector.connect(HOSTNAME, client)?;
    tls_stream.write_all(b"ping")?;
    tls_stream.get_ref().shutdown(Shutdown::Write)?;

    let mut reply = Vec::new();
    tls_stream.read_to_end(&mut reply)?;
    println!("{}", String::from_utf8_lossy(&reply));

    Ok(())
}