Skip to content

Commit

Permalink
feat: basic TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
0xAlcibiades committed Sep 10, 2024
1 parent 25d98a3 commit 5113505
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 50 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ tokio-rustls = "0.26.0"
tokio-stream = { version = "0.1.16", features = ["net"] }
tower = { version = "0.5.1", features = ["util"] }
tracing = "0.1.40"
futures = "0.3.30"

[dev-dependencies]
hyper = { version = "1.4.1", features = ["client"] }
Expand Down
70 changes: 20 additions & 50 deletions src/tls.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,22 @@
use std::sync::Arc;
use std::{fs, io};
use tokio::net::TcpStream;
use crate::Error;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_rustls::TlsAcceptor;
use rustls::ServerConfig;
use rustls::pki_types::{CertificateDer, PrivateKeyDer};

fn error(err: String) -> io::Error {
io::Error::new(io::ErrorKind::Other, err)
}

pub fn create_tls_acceptor(cert_path: &str, key_path: &str) -> io::Result<TlsAcceptor> {
// Load public certificate.
let certs = load_certs(cert_path)?;
// Load private key.
let key = load_private_key(key_path)?;

// Build TLS configuration.
let mut server_config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)
.map_err(|e| error(e.to_string()))?;
server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()];

Ok(TlsAcceptor::from(Arc::new(server_config)))
}

// Load public certificate from file.
fn load_certs(filename: &str) -> io::Result<Vec<CertificateDer<'static>>> {
// Open certificate file.
let certfile = fs::File::open(filename)
.map_err(|e| error(format!("failed to open {}: {}", filename, e)))?;
let mut reader = io::BufReader::new(certfile);

// Load and return certificate.
rustls_pemfile::certs(&mut reader).collect()
}

// Load private key from file.
fn load_private_key(filename: &str) -> io::Result<PrivateKeyDer<'static>> {
// Open keyfile.
let keyfile = fs::File::open(filename)
.map_err(|e| error(format!("failed to open {}: {}", filename, e)))?;
let mut reader = io::BufReader::new(keyfile);

// Load and return a single private key.
rustls_pemfile::private_key(&mut reader).map(|key| key.unwrap())
use tokio_stream::{Stream, StreamExt};

pub(crate) fn tls_incoming<IO>(
tcp_stream: impl Stream<Item = Result<IO, Error>>,
tls: TlsAcceptor,
) -> impl Stream<Item = Result<tokio_rustls::server::TlsStream<IO>, Error>>
where
IO: AsyncRead + AsyncWrite + Unpin + Send + 'static,
{
tcp_stream.then(move |result| {
let tls = tls.clone();
async move {
match result {
Ok(io) => tls.accept(io).await.map_err(Error::from),
Err(e) => Err(e),

Check warning on line 18 in src/tls.rs

View check run for this annotation

Codecov / codecov/patch

src/tls.rs#L6-L18

Added lines #L6 - L18 were not covered by tests
}
}
})
}

Check warning on line 22 in src/tls.rs

View check run for this annotation

Codecov / codecov/patch

src/tls.rs#L20-L22

Added lines #L20 - L22 were not covered by tests

pub async fn tls_accept(acceptor: TlsAcceptor, tcp_stream: TcpStream) -> Result<tokio_rustls::server::TlsStream<TcpStream>, std::io::Error> {
acceptor.accept(tcp_stream).await.map_err(|e| error(format!("failed to perform tls handshake: {}", e)))
}

0 comments on commit 5113505

Please sign in to comment.