From 471f5943457ac4811ed7b88d12d9131b7a25742c Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Mon, 17 Jan 2022 19:48:53 +0000 Subject: [PATCH] Support loading certificates in the server --- olivefsd/Cargo.toml | 2 +- olivefsd/src/main.rs | 57 ++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/olivefsd/Cargo.toml b/olivefsd/Cargo.toml index 8930825..3a5318a 100644 --- a/olivefsd/Cargo.toml +++ b/olivefsd/Cargo.toml @@ -31,4 +31,4 @@ quinn = { version = "0.8.0", features = [] } # Compression and Encryption zstd = "0.9.2+zstd.1.5.1" rustls = "0.20.2" -rcgen = { version = "0.8.14", features = ["pem", "x509-parser"] } +rcgen = { version = "0.8.14", features = ["x509-parser"] } diff --git a/olivefsd/src/main.rs b/olivefsd/src/main.rs index a62584c..f7055ba 100644 --- a/olivefsd/src/main.rs +++ b/olivefsd/src/main.rs @@ -4,7 +4,8 @@ use futures_util::StreamExt; use quinn::Endpoint; use rcgen::{BasicConstraints, Certificate, CertificateParams, IsCa, KeyPair}; use rustls::internal::msgs::codec::Codec; -use std::io::Read; +use rustls::{PrivateKey, RootCertStore}; +use std::io::{BufReader, Cursor, Read}; use std::net::SocketAddr; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -27,17 +28,17 @@ pub enum Command { }, } -pub async fn write_file(path: &Path, content: &str) -> anyhow::Result<()> { +pub async fn write_file(path: &Path, content: &[u8]) -> anyhow::Result<()> { let mut file = File::create(path).await?; - file.write_all(content.as_bytes()).await?; + file.write_all(content).await?; Ok(()) } -pub async fn read_file(path: &Path) -> anyhow::Result { +pub async fn read_file(path: &Path) -> anyhow::Result> { let mut file = File::open(path).await?; - let mut string = String::new(); - file.read_to_string(&mut string).await?; - Ok(string) + let mut bytes = Vec::new(); + file.read_to_end(&mut bytes).await?; + Ok(bytes) } #[tokio::main] @@ -56,19 +57,19 @@ async fn main() -> anyhow::Result<()> { // TODO don't hard code a date :-). ca_params.not_after = rcgen::date_time_ymd(2042, 1, 1); let ca_cert = Certificate::from_params(ca_params)?; - let cert_pem = ca_cert.serialize_pem()?; - let key_pem = ca_cert.serialize_private_key_pem(); + let cert_der = ca_cert.serialize_der()?; + let key_der = ca_cert.serialize_private_key_der(); - write_file(&ca_key_path, &key_pem).await?; - write_file(&ca_cert_path, &cert_pem).await?; + write_file(&ca_key_path, &key_der).await?; + write_file(&ca_cert_path, &cert_der).await?; } - let ca_key_pem = read_file(&ca_key_path).await?; - let ca_cert_pem = read_file(&ca_cert_path).await?; + let ca_key_der = read_file(&ca_key_path).await?; + let ca_cert_der = read_file(&ca_cert_path).await?; - let ca_keypair = KeyPair::from_pem(&ca_key_pem)?; - let ca_cert = Certificate::from_params(CertificateParams::from_ca_cert_pem( - &ca_cert_pem, + let ca_keypair = KeyPair::from_der(&ca_key_der)?; + let ca_cert = Certificate::from_params(CertificateParams::from_ca_cert_der( + &ca_cert_der, ca_keypair, )?)?; @@ -79,12 +80,12 @@ async fn main() -> anyhow::Result<()> { let leaf_cert = Certificate::from_params(cert_params)?; write_file( &ca_dir.join(format!("{}.key", &name)), - &leaf_cert.serialize_private_key_pem(), + &leaf_cert.serialize_private_key_der(), ) .await?; write_file( &ca_dir.join(format!("{}.pem", &name)), - &leaf_cert.serialize_pem_with_signer(&ca_cert)?, + &leaf_cert.serialize_der_with_signer(&ca_cert)?, ) .await?; } @@ -92,11 +93,27 @@ async fn main() -> anyhow::Result<()> { println!("Hello, world!"); + let mut root_cert_store = RootCertStore::empty(); + // TODO take ca path from config + let ca_cert_der = read_file(Path::new("ca/ca.pem")).await?; + let ca_cert = rustls::Certificate::read_bytes(&ca_cert_der).ok_or_else(|| anyhow!(""))?; + root_cert_store.add(&ca_cert)?; + + // TODO we want to check the names of the clients. Figure out how. + let verifier = rustls::server::AllowAnyAuthenticatedClient::new(root_cert_store); + + // TODO take cert path from config + let server_cert_der = read_file(Path::new("ca/server.pem")).await?; + let server_cert = + rustls::Certificate::read_bytes(&server_cert_der).ok_or_else(|| anyhow!(""))?; + let server_key_der = read_file(Path::new("ca/server.key")).await?; + let server_key = PrivateKey(server_key_der); + //let x = quinn::ServerConfig::with_native_roots(); let crypto = rustls::ServerConfig::builder() .with_safe_defaults() - .with_client_cert_verifier(todo!()) - .with_single_cert(todo!(), todo!())?; + .with_client_cert_verifier(verifier) + .with_single_cert(vec![server_cert], server_key)?; let crypto = Arc::new(crypto); let x = quinn::ServerConfig::with_crypto(crypto); let (ep, mut incoming) =