From 6f2a0ca82859cffcf2bae8d3dce766f94d81797c Mon Sep 17 00:00:00 2001 From: c0repwn3r Date: Wed, 3 May 2023 20:38:05 -0400 Subject: [PATCH] code cleanup - pt1 --- libepf/src/ca_pool.rs | 14 +- libepf/src/error.rs | 16 +- libepf/src/handshake_stream.rs | 312 +++++++++++++++++++++++---------- libepf/src/lib.rs | 10 +- libepf/src/log.rs | 2 +- libepf/src/pki.rs | 100 ++++++++--- libepf/src/protocol.rs | 31 ++-- libepf/src/util.rs | 4 +- 8 files changed, 333 insertions(+), 156 deletions(-) diff --git a/libepf/src/ca_pool.rs b/libepf/src/ca_pool.rs index b81ddb5..0553d07 100644 --- a/libepf/src/ca_pool.rs +++ b/libepf/src/ca_pool.rs @@ -1,11 +1,11 @@ use crate::pki::{EPFCertificate, EpfPkiSerializable, EpfPublicKey}; +use crate::util::verifying_key; +use log::trace; use std::collections::HashMap; use std::error::Error; -use std::ffi::{OsStr}; +use std::ffi::OsStr; use std::fmt::{Display, Formatter}; use std::fs; -use log::trace; -use crate::util::verifying_key; pub struct EpfCaPool { pub ca_lookup_table: HashMap, @@ -36,12 +36,14 @@ impl EpfCaPoolOps for EpfCaPool { #[derive(Debug)] pub enum EpfCaPoolLoaderError { - CertDirDoesNotExist(String) + CertDirDoesNotExist(String), } impl Display for EpfCaPoolLoaderError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - EpfCaPoolLoaderError::CertDirDoesNotExist(d) => write!(f, "Certificate dir does not exist: {}", d) + EpfCaPoolLoaderError::CertDirDoesNotExist(d) => { + write!(f, "Certificate dir does not exist: {}", d) + } } } } @@ -65,4 +67,4 @@ pub fn load_ca_pool() -> Result> { } Ok(ca_pool) -} \ No newline at end of file +} diff --git a/libepf/src/error.rs b/libepf/src/error.rs index 92b2849..c2f829e 100644 --- a/libepf/src/error.rs +++ b/libepf/src/error.rs @@ -1,6 +1,6 @@ +use crate::pki::EpfPkiCertificateValidationError; use std::error::Error; use std::fmt::{Display, Formatter}; -use crate::pki::EpfPkiCertificateValidationError; #[derive(Debug)] pub enum EpfHandshakeError { @@ -9,18 +9,22 @@ pub enum EpfHandshakeError { InvalidCertificate(EpfPkiCertificateValidationError), UntrustedCertificate, EncryptionError, - MissingKeyProof + MissingKeyProof, } impl Display for EpfHandshakeError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { EpfHandshakeError::AlreadyTunnelled => write!(f, "Already tunneled"), - EpfHandshakeError::UnsupportedProtocolVersion(v) => write!(f, "Unsupported protocol version {}", v), + EpfHandshakeError::UnsupportedProtocolVersion(v) => { + write!(f, "Unsupported protocol version {}", v) + } EpfHandshakeError::InvalidCertificate(e) => write!(f, "Invalid certificate: {}", e), - EpfHandshakeError::UntrustedCertificate => write!(f, "Certificate valid but not trusted"), + EpfHandshakeError::UntrustedCertificate => { + write!(f, "Certificate valid but not trusted") + } EpfHandshakeError::EncryptionError => write!(f, "Encryption error"), - EpfHandshakeError::MissingKeyProof => write!(f, "Missing key proof") + EpfHandshakeError::MissingKeyProof => write!(f, "Missing key proof"), } } } -impl Error for EpfHandshakeError {} \ No newline at end of file +impl Error for EpfHandshakeError {} diff --git a/libepf/src/handshake_stream.rs b/libepf/src/handshake_stream.rs index 99e132b..f1a443a 100644 --- a/libepf/src/handshake_stream.rs +++ b/libepf/src/handshake_stream.rs @@ -1,19 +1,25 @@ -use std::error::Error; -use std::io; -use async_trait::async_trait; -use chacha20poly1305::{AeadCore, Key, KeyInit, XChaCha20Poly1305, XNonce}; -use chacha20poly1305::aead::{Aead, Payload}; -use ed25519_dalek::{SecretKey, SigningKey}; -use log::{debug, trace}; -use rand::Rng; -use rand::rngs::OsRng; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use x25519_dalek::{PublicKey, StaticSecret, x25519}; -use crate::ca_pool::{EpfCaPool, load_ca_pool}; +use crate::ca_pool::{load_ca_pool, EpfCaPool}; use crate::danger_trace; use crate::error::EpfHandshakeError; -use crate::pki::{EPFCertificate, EPFPKI_PUBLIC_KEY_LENGTH, EpfPkiCertificateOps, EpfPrivateKey, EpfPublicKey}; -use crate::protocol::{encode_packet, EpfApplicationData, EpfClientHello, EpfClientState, EpfFinished, EpfMessage, EpfServerHello, EpfServerState, PACKET_APPLICATION_DATA, PACKET_CLIENT_HELLO, PACKET_FINISHED, PACKET_SERVER_HELLO, PROTOCOL_VERSION, recv_packet}; +use crate::pki::{ + EPFCertificate, EpfPkiCertificateOps, EpfPrivateKey, EpfPublicKey, EPFPKI_PUBLIC_KEY_LENGTH, +}; +use crate::protocol::{ + encode_packet, recv_packet, EpfApplicationData, EpfClientHello, EpfClientState, EpfFinished, + EpfMessage, EpfServerHello, EpfServerState, PACKET_APPLICATION_DATA, PACKET_CLIENT_HELLO, + PACKET_FINISHED, PACKET_SERVER_HELLO, PROTOCOL_VERSION, +}; +use async_trait::async_trait; +use chacha20poly1305::aead::{Aead, Payload}; +use chacha20poly1305::{AeadCore, Key, KeyInit, XChaCha20Poly1305, XNonce}; +use ed25519_dalek::{SecretKey, SigningKey}; +use log::{debug, trace}; +use rand::rngs::OsRng; +use rand::Rng; +use std::error::Error; +use std::io; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use x25519_dalek::{x25519, PublicKey, StaticSecret}; ///// CLIENT ///// @@ -27,23 +33,31 @@ pub struct EpfClientUpgraded { server_cert: Option, cipher: Option, private_key: EpfPrivateKey, - public_key: PublicKey + public_key: PublicKey, } #[derive(Debug)] pub enum ClientAuthentication { Cert(Box, EpfPrivateKey), - Ephemeral + Ephemeral, } #[async_trait] pub trait EpfClientUpgradable { - async fn upgrade(self, auth: ClientAuthentication) -> EpfClientUpgraded where Self: Sized + AsyncWriteExt + AsyncReadExt + Send; + async fn upgrade(self, auth: ClientAuthentication) -> EpfClientUpgraded + where + Self: Sized + AsyncWriteExt + AsyncReadExt + Send; } #[async_trait] -impl EpfClientUpgradable for T where T: AsyncWriteExt + AsyncReadExt + Send { - async fn upgrade(self, auth: ClientAuthentication) -> EpfClientUpgraded where Self: Sized + AsyncWriteExt + AsyncReadExt + Send { +impl EpfClientUpgradable for T +where + T: AsyncWriteExt + AsyncReadExt + Send, +{ + async fn upgrade(self, auth: ClientAuthentication) -> EpfClientUpgraded + where + Self: Sized + AsyncWriteExt + AsyncReadExt + Send, + { danger_trace!(target: "EpfClientUpgradable", "upgrade(auth: {:?})", auth); let private_key; @@ -56,7 +70,7 @@ impl EpfClientUpgradable for T where T: AsyncWriteExt + AsyncReadExt + Send { cert = Some(cert_d); private_key = key.clone(); public_key = PublicKey::from(&StaticSecret::from(private_key.to_bytes())); - }, + } ClientAuthentication::Ephemeral => { cert = None; let private_key_l: [u8; 32] = OsRng.gen(); @@ -84,24 +98,33 @@ impl EpfClientUpgradable for T where T: AsyncWriteExt + AsyncReadExt + Send { #[async_trait] pub trait EpfClientHandshaker { async fn handshake(&mut self, cert_pool: EpfCaPool) -> Result<(), Box>; - async fn upgrade(self) -> EpfClientStream where Self: Sized; + async fn upgrade(self) -> EpfClientStream + where + Self: Sized; } #[async_trait] -impl EpfClientHandshaker for EpfClientUpgraded { +impl EpfClientHandshaker + for EpfClientUpgraded +{ async fn handshake(&mut self, cert_pool: EpfCaPool) -> Result<(), Box> { match self.state { EpfClientState::NotStarted => (), - _ => return Err(EpfHandshakeError::AlreadyTunnelled.into()) + _ => return Err(EpfHandshakeError::AlreadyTunnelled.into()), } // Step 1: Send Client Hello - self.inner.write_all(&encode_packet(PACKET_CLIENT_HELLO, &EpfClientHello { - protocol_version: PROTOCOL_VERSION, - client_random: self.client_random, - client_certificate: self.client_cert.clone(), - client_x25519_public_key: self.public_key.to_bytes(), - })?).await?; + self.inner + .write_all(&encode_packet( + PACKET_CLIENT_HELLO, + &EpfClientHello { + protocol_version: PROTOCOL_VERSION, + client_random: self.client_random, + client_certificate: self.client_cert.clone(), + client_x25519_public_key: self.public_key.to_bytes(), + }, + )?) + .await?; self.inner.flush().await?; trace!("---- !!!!! SENT CLIENT HELLO"); @@ -126,7 +149,10 @@ impl EpfClientHandshaker for self.server_random = server_hello.server_random; if server_hello.protocol_version != PROTOCOL_VERSION { - return Err(EpfHandshakeError::UnsupportedProtocolVersion(server_hello.protocol_version as usize).into()); + return Err(EpfHandshakeError::UnsupportedProtocolVersion( + server_hello.protocol_version as usize, + ) + .into()); } self.server_cert = Some(server_hello.server_certificate); @@ -139,10 +165,10 @@ impl EpfClientHandshaker for // Step 3: Validate Server Certificate let cert_valid = self.server_cert.as_ref().unwrap().verify(&cert_pool); if let Err(e) = cert_valid { - return Err(EpfHandshakeError::InvalidCertificate(e).into()) + return Err(EpfHandshakeError::InvalidCertificate(e).into()); } if let Ok(false) = cert_valid { - return Err(EpfHandshakeError::UntrustedCertificate.into()) + return Err(EpfHandshakeError::UntrustedCertificate.into()); } // Server Cert OK @@ -151,13 +177,24 @@ impl EpfClientHandshaker for let private_key = StaticSecret::from(self.private_key.to_bytes()); let their_public_key = PublicKey::from(server_x25519_key); - assert_ne!(their_public_key.to_bytes(), PublicKey::from(&private_key).to_bytes()); + assert_ne!( + their_public_key.to_bytes(), + PublicKey::from(&private_key).to_bytes() + ); - danger_trace!("pr: {}, their pub: {}, my pub: {}", hex::encode(self.private_key.to_bytes()), hex::encode(self.server_cert.as_ref().unwrap().details.public_key), hex::encode(self.private_key.verifying_key().to_bytes())); + danger_trace!( + "pr: {}, their pub: {}, my pub: {}", + hex::encode(self.private_key.to_bytes()), + hex::encode(self.server_cert.as_ref().unwrap().details.public_key), + hex::encode(self.private_key.verifying_key().to_bytes()) + ); let shared_key = private_key.diffie_hellman(&their_public_key).to_bytes(); - trace!("server public key: {:x?}", self.server_cert.as_ref().unwrap().details.public_key); + trace!( + "server public key: {:x?}", + self.server_cert.as_ref().unwrap().details.public_key + ); danger_trace!("shared key: {}", hex::encode(shared_key)); let cc20p1305_key = Key::from(shared_key); @@ -177,15 +214,18 @@ impl EpfClientHandshaker for let encrypted_0x42 = match self.cipher.as_ref().unwrap().encrypt(nonce, payload) { Ok(d) => d, - Err(_) => { - return Err(EpfHandshakeError::EncryptionError.into()) - } + Err(_) => return Err(EpfHandshakeError::EncryptionError.into()), }; - self.inner.write_all(&encode_packet(PACKET_FINISHED, &EpfFinished { - protocol_version: PROTOCOL_VERSION, - encrypted_0x42 - })?).await?; + self.inner + .write_all(&encode_packet( + PACKET_FINISHED, + &EpfFinished { + protocol_version: PROTOCOL_VERSION, + encrypted_0x42, + }, + )?) + .await?; self.inner.flush().await?; self.state = EpfClientState::WaitingForFinished; @@ -207,7 +247,12 @@ impl EpfClientHandshaker for aad: &self.server_random, }; - danger_trace!("ciphertext: {:?}, aad: {:?}, nonce: {:?}", packet_finished.encrypted_0x42, payload.aad, nonce); + danger_trace!( + "ciphertext: {:?}, aad: {:?}, nonce: {:?}", + packet_finished.encrypted_0x42, + payload.aad, + nonce + ); let hopefully_0x42 = match self.cipher.as_ref().unwrap().decrypt(nonce, payload) { Ok(d) => d, @@ -217,7 +262,7 @@ impl EpfClientHandshaker for }; if hopefully_0x42 != vec![0x42] { - return Err(EpfHandshakeError::MissingKeyProof.into()) + return Err(EpfHandshakeError::MissingKeyProof.into()); } break; @@ -228,7 +273,10 @@ impl EpfClientHandshaker for Ok(()) } - async fn upgrade(self) -> EpfClientStream where Self: Sized { + async fn upgrade(self) -> EpfClientStream + where + Self: Sized, + { let aad = self.server_random.clone(); let client_cert = self.client_cert.clone(); let packet_queue = self.packet_queue.clone(); @@ -258,7 +306,7 @@ pub struct EpfClientStream { server_cert: EPFCertificate, cipher: XChaCha20Poly1305, private_key: EpfPrivateKey, - public_key: PublicKey + public_key: PublicKey, } #[async_trait] @@ -279,9 +327,7 @@ impl EpfStreamOps for EpfClientS let ciphertext = match self.cipher.encrypt(&nonce, payload) { Ok(c) => c, - Err(_) => { - return Err(io::Error::new(io::ErrorKind::Other, "Encryption error").into()) - } + Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "Encryption error").into()), }; let application_data = EpfApplicationData { protocol_version: PROTOCOL_VERSION, @@ -339,17 +385,33 @@ pub struct EpfServerUpgraded { cipher: Option, cert: EPFCertificate, private_key: EpfPrivateKey, - public_key: EpfPublicKey + public_key: EpfPublicKey, } #[async_trait] pub trait EpfServerUpgradable { - async fn upgrade(self, cert: EPFCertificate, private_key: EpfPrivateKey) -> EpfServerUpgraded where Self: Sized + AsyncWriteExt + AsyncReadExt + Send; + async fn upgrade( + self, + cert: EPFCertificate, + private_key: EpfPrivateKey, + ) -> EpfServerUpgraded + where + Self: Sized + AsyncWriteExt + AsyncReadExt + Send; } #[async_trait] -impl EpfServerUpgradable for T where T: AsyncWriteExt + AsyncReadExt + Send { - async fn upgrade(self, cert: EPFCertificate, private_key: EpfPrivateKey) -> EpfServerUpgraded where Self: Sized + AsyncWriteExt + AsyncReadExt + Send { +impl EpfServerUpgradable for T +where + T: AsyncWriteExt + AsyncReadExt + Send, +{ + async fn upgrade( + self, + cert: EPFCertificate, + private_key: EpfPrivateKey, + ) -> EpfServerUpgraded + where + Self: Sized + AsyncWriteExt + AsyncReadExt + Send, + { EpfServerUpgraded { inner: self, state: EpfServerState::WaitingForClientHello, @@ -368,15 +430,19 @@ impl EpfServerUpgradable for T where T: AsyncWriteExt + AsyncReadExt #[async_trait] pub trait EpfServerHandshaker { async fn handshake(&mut self, cert_pool: EpfCaPool) -> Result<(), Box>; - async fn upgrade(self) -> EpfServerStream where Self: Sized; + async fn upgrade(self) -> EpfServerStream + where + Self: Sized; } #[async_trait] -impl EpfServerHandshaker for EpfServerUpgraded { +impl EpfServerHandshaker + for EpfServerUpgraded +{ async fn handshake(&mut self, cert_pool: EpfCaPool) -> Result<(), Box> { match self.state { EpfServerState::WaitingForClientHello => (), - _ => return Err(EpfHandshakeError::AlreadyTunnelled.into()) + _ => return Err(EpfHandshakeError::AlreadyTunnelled.into()), } let client_public_key; @@ -397,7 +463,10 @@ impl EpfServerHandshaker for self.client_random = client_hello.client_random; if client_hello.protocol_version != PROTOCOL_VERSION { - return Err(EpfHandshakeError::UnsupportedProtocolVersion(client_hello.protocol_version as usize).into()); + return Err(EpfHandshakeError::UnsupportedProtocolVersion( + client_hello.protocol_version as usize, + ) + .into()); } self.client_cert = client_hello.client_certificate; @@ -413,10 +482,10 @@ impl EpfServerHandshaker for if let Some(client_cert) = &self.client_cert { let cert_valid = client_cert.verify(&cert_pool); if let Err(e) = cert_valid { - return Err(EpfHandshakeError::InvalidCertificate(e).into()) + return Err(EpfHandshakeError::InvalidCertificate(e).into()); } if let Ok(false) = cert_valid { - return Err(EpfHandshakeError::UntrustedCertificate.into()) + return Err(EpfHandshakeError::UntrustedCertificate.into()); } } // Client Cert OK (if present) @@ -424,12 +493,20 @@ impl EpfServerHandshaker for trace!("client cert okay"); // Step 3: Send Server Hello - self.inner.write_all(&encode_packet(PACKET_SERVER_HELLO, &EpfServerHello { - protocol_version: PROTOCOL_VERSION, - server_certificate: self.cert.clone(), - server_random: self.server_random, - server_x25519_public_key: PublicKey::from(&StaticSecret::from(self.private_key.to_bytes())).to_bytes() - })?).await?; + self.inner + .write_all(&encode_packet( + PACKET_SERVER_HELLO, + &EpfServerHello { + protocol_version: PROTOCOL_VERSION, + server_certificate: self.cert.clone(), + server_random: self.server_random, + server_x25519_public_key: PublicKey::from(&StaticSecret::from( + self.private_key.to_bytes(), + )) + .to_bytes(), + }, + )?) + .await?; self.inner.flush().await?; trace!("sent server hello"); @@ -440,9 +517,17 @@ impl EpfServerHandshaker for let private_key = StaticSecret::from(self.private_key.to_bytes()); let their_public_key = PublicKey::from(client_public_key); - assert_ne!(their_public_key.to_bytes(), PublicKey::from(&private_key).to_bytes()); + assert_ne!( + their_public_key.to_bytes(), + PublicKey::from(&private_key).to_bytes() + ); - danger_trace!("pr: {}, their pub: {}, my pub: {}", hex::encode(self.private_key.to_bytes()), hex::encode(client_public_key), hex::encode(self.private_key.verifying_key().to_bytes())); + danger_trace!( + "pr: {}, their pub: {}, my pub: {}", + hex::encode(self.private_key.to_bytes()), + hex::encode(client_public_key), + hex::encode(self.private_key.verifying_key().to_bytes()) + ); let shared_key = private_key.diffie_hellman(&their_public_key).to_bytes(); @@ -476,7 +561,12 @@ impl EpfServerHandshaker for }; trace!("trying to decrypt 0x42"); - danger_trace!("ciphertext: {:?}, nonce: {:?}, aad: {:?}", payload.msg, nonce, payload.aad); + danger_trace!( + "ciphertext: {:?}, nonce: {:?}, aad: {:?}", + payload.msg, + nonce, + payload.aad + ); let hopefully_0x42 = match self.cipher.as_ref().unwrap().decrypt(nonce, payload) { Ok(d) => d, @@ -486,7 +576,7 @@ impl EpfServerHandshaker for }; if hopefully_0x42 != vec![0x42] { - return Err(EpfHandshakeError::MissingKeyProof.into()) + return Err(EpfHandshakeError::MissingKeyProof.into()); } break; @@ -494,15 +584,18 @@ impl EpfServerHandshaker for let encrypted_0x42 = match self.cipher.as_ref().unwrap().encrypt(nonce, payload) { Ok(d) => d, - Err(_) => { - return Err(EpfHandshakeError::EncryptionError.into()) - } + Err(_) => return Err(EpfHandshakeError::EncryptionError.into()), }; - self.inner.write_all(&encode_packet(PACKET_FINISHED, &EpfFinished { - protocol_version: PROTOCOL_VERSION, - encrypted_0x42 - })?).await?; + self.inner + .write_all(&encode_packet( + PACKET_FINISHED, + &EpfFinished { + protocol_version: PROTOCOL_VERSION, + encrypted_0x42, + }, + )?) + .await?; self.inner.flush().await?; self.state = EpfServerState::WaitingForFinished; @@ -512,7 +605,10 @@ impl EpfServerHandshaker for Ok(()) } - async fn upgrade(self) -> EpfServerStream where Self: Sized { + async fn upgrade(self) -> EpfServerStream + where + Self: Sized, + { EpfServerStream { aad: self.server_random, server_cert: self.cert, @@ -521,7 +617,7 @@ impl EpfServerHandshaker for cipher: self.cipher.unwrap(), private_key: self.private_key, public_key: self.public_key, - raw_stream: self.inner + raw_stream: self.inner, } } } @@ -534,7 +630,7 @@ pub struct EpfServerStream { server_cert: EPFCertificate, cipher: XChaCha20Poly1305, private_key: EpfPrivateKey, - public_key: EpfPublicKey + public_key: EpfPublicKey, } #[async_trait] @@ -549,9 +645,7 @@ impl EpfStreamOps for EpfServerS let ciphertext = match self.cipher.encrypt(&nonce, payload) { Ok(c) => c, - Err(_) => { - return Err(io::Error::new(io::ErrorKind::Other, "Encryption error").into()) - } + Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "Encryption error").into()), }; let application_data = EpfApplicationData { protocol_version: PROTOCOL_VERSION, @@ -599,20 +693,23 @@ impl EpfStreamOps for EpfServerS #[cfg(test)] mod tests { - use std::net::SocketAddr; - use std::str::FromStr; - use std::time::{SystemTime, UNIX_EPOCH}; + use crate::ca_pool::{EpfCaPool, EpfCaPoolOps}; + use crate::handshake_stream::{ + ClientAuthentication, EpfClientHandshaker, EpfClientUpgradable, EpfClientUpgraded, + EpfServerHandshaker, EpfServerUpgradable, EpfServerUpgraded, EpfStreamOps, + }; + use crate::pki::{EPFCertificate, EPFCertificateDetails, EpfPkiCertificateOps}; use ed25519_dalek::{SecretKey, SigningKey}; use log::{debug, trace}; use rand::rngs::OsRng; + use std::net::SocketAddr; + use std::str::FromStr; + use std::time::{SystemTime, UNIX_EPOCH}; use tcp_test::channel; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::join; use tokio::net::{TcpListener, TcpSocket, TcpStream}; use x25519_dalek::{PublicKey, StaticSecret}; - use crate::ca_pool::{EpfCaPool, EpfCaPoolOps}; - use crate::handshake_stream::{ClientAuthentication, EpfClientHandshaker, EpfClientUpgradable, EpfClientUpgraded, EpfServerHandshaker, EpfServerUpgradable, EpfServerUpgraded, EpfStreamOps}; - use crate::pki::{EPFCertificate, EPFCertificateDetails, EpfPkiCertificateOps}; #[tokio::test] pub async fn stream_test() { @@ -620,7 +717,9 @@ mod tests { let tcp_listener = TcpListener::bind("0.0.0.0:36116").await.unwrap(); - let tcp_client_future = TcpSocket::new_v4().unwrap().connect(SocketAddr::from_str("127.0.0.1:36116").unwrap()); + let tcp_client_future = TcpSocket::new_v4() + .unwrap() + .connect(SocketAddr::from_str("127.0.0.1:36116").unwrap()); let (a, b) = join![tcp_listener.accept(), tcp_client_future]; @@ -634,7 +733,11 @@ mod tests { details: EPFCertificateDetails { name: "Testing Server Certificate".to_string(), not_before: 0, - not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 30, + not_after: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + + 30, public_key: server_private_key.verifying_key().to_bytes(), issuer_public_key: [0u8; 32], claims: Default::default(), @@ -644,13 +747,20 @@ mod tests { }; server_cert.sign(&server_private_key).unwrap(); - debug!("{}", hex::encode(server_private_key.verifying_key().to_bytes())); + debug!( + "{}", + hex::encode(server_private_key.verifying_key().to_bytes()) + ); let mut client_cert = EPFCertificate { details: EPFCertificateDetails { name: "Testing Client Certificate".to_string(), not_before: 0, - not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 30, + not_after: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + + 30, public_key: client_private_key.verifying_key().to_bytes(), issuer_public_key: [0u8; 32], claims: Default::default(), @@ -667,8 +777,13 @@ mod tests { cert_pool_2.insert(&client_cert); cert_pool_2.insert(&server_cert); - let mut c: EpfClientUpgraded = EpfClientUpgradable::upgrade(c, ClientAuthentication::Cert(Box::new(client_cert), client_private_key)).await; - let mut s: EpfServerUpgraded = EpfServerUpgradable::upgrade(s, server_cert, server_private_key).await; + let mut c: EpfClientUpgraded = EpfClientUpgradable::upgrade( + c, + ClientAuthentication::Cert(Box::new(client_cert), client_private_key), + ) + .await; + let mut s: EpfServerUpgraded = + EpfServerUpgradable::upgrade(s, server_cert, server_private_key).await; let server_handshake_accept_task = tokio::spawn(async move { trace!("starting server handshake listener"); @@ -702,6 +817,11 @@ mod tests { assert_eq!(ss_1.to_bytes(), ss_2.to_bytes()); - println!("SS: {}, B_p: {}, A_p: {}", hex::encode(ss_1.to_bytes()), hex::encode(bob_pub.to_bytes()), hex::encode(alice_pub.to_bytes())); + println!( + "SS: {}, B_p: {}, A_p: {}", + hex::encode(ss_1.to_bytes()), + hex::encode(bob_pub.to_bytes()), + hex::encode(alice_pub.to_bytes()) + ); } -} \ No newline at end of file +} diff --git a/libepf/src/lib.rs b/libepf/src/lib.rs index 63f46d8..3b61326 100644 --- a/libepf/src/lib.rs +++ b/libepf/src/lib.rs @@ -1,8 +1,8 @@ pub mod ca_pool; -pub mod pki; -pub mod util; -pub mod protocol; -pub mod handshake_stream; pub mod error; +pub mod handshake_stream; +pub mod pki; +pub mod protocol; +pub mod util; #[macro_use] -pub mod log; \ No newline at end of file +pub mod log; diff --git a/libepf/src/log.rs b/libepf/src/log.rs index 7d804cf..5f71684 100644 --- a/libepf/src/log.rs +++ b/libepf/src/log.rs @@ -14,4 +14,4 @@ macro_rules! danger_trace { log::trace!($($arg)+) } } -} \ No newline at end of file +} diff --git a/libepf/src/pki.rs b/libepf/src/pki.rs index f09e59b..0cfd479 100644 --- a/libepf/src/pki.rs +++ b/libepf/src/pki.rs @@ -202,7 +202,7 @@ impl EpfPkiCertificateOps for EPFCertificate { } else { return Ok(false); } - } else if let Some(cert) = ca_pool.get_ca(&verifying_key(&self.details.issuer_public_key) ){ + } else if let Some(cert) = ca_pool.get_ca(&verifying_key(&self.details.issuer_public_key)) { cert } else { return Ok(false); @@ -272,9 +272,11 @@ impl EpfPkiSerializable for EPFCertificate { } fn as_pem(&self) -> Result, Box> { - Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes_pki()?)) - .as_bytes() - .to_vec()) + Ok( + pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes_pki()?)) + .as_bytes() + .to_vec(), + ) } fn from_pem(bytes: &[u8]) -> Result> @@ -303,9 +305,11 @@ impl EpfPkiSerializable for EpfPublicKey { } fn as_pem(&self) -> Result, Box> { - Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes().to_vec())) - .as_bytes() - .to_vec()) + Ok( + pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes().to_vec())) + .as_bytes() + .to_vec(), + ) } fn from_pem(bytes: &[u8]) -> Result> @@ -316,7 +320,11 @@ impl EpfPkiSerializable for EpfPublicKey { if pem.tag() != Self::PEM_BANNER { return Err("Not a public key".into()); } - Ok(Self::from_bytes(pem.contents().try_into().map_err(|_| -> Box { "Wrong size".into() })?)?) + Ok(Self::from_bytes( + pem.contents() + .try_into() + .map_err(|_| -> Box { "Wrong size".into() })?, + )?) } } @@ -334,9 +342,11 @@ impl EpfPkiSerializable for EpfPrivateKey { } fn as_pem(&self) -> Result, Box> { - Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes_pki()?)) - .as_bytes() - .to_vec()) + Ok( + pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes_pki()?)) + .as_bytes() + .to_vec(), + ) } fn from_pem(bytes: &[u8]) -> Result> @@ -347,7 +357,11 @@ impl EpfPkiSerializable for EpfPrivateKey { if pem.tag() != Self::PEM_BANNER { return Err("Incorrect PEM tag".into()); } - Ok(Self::from_keypair_bytes(pem.contents().try_into().map_err(|_| -> Box { "Wrong size".into() })?)?) + Ok(Self::from_keypair_bytes( + pem.contents() + .try_into() + .map_err(|_| -> Box { "Wrong size".into() })?, + )?) } } @@ -359,12 +373,12 @@ mod tests { EpfPkiCertificateValidationError, EpfPkiSerializable, EpfPrivateKey, EpfPublicKey, EPFPKI_PUBLIC_KEY_LENGTH, EPFPKI_SIGNATURE_LENGTH, }; + use crate::util::{signing_key, verifying_key}; use ed25519_dalek::{SignatureError, SigningKey}; + use hex_literal::hex; use rand::rngs::OsRng; use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; - use hex_literal::hex; - use crate::util::{signing_key, verifying_key}; #[test] pub fn certificate_serialization() { @@ -373,7 +387,10 @@ mod tests { #[test] pub fn certificate_deserialization() { - assert_eq!(EPFCertificate::from_bytes_pki(&cert_bytes()).unwrap(), cert()) + assert_eq!( + EPFCertificate::from_bytes_pki(&cert_bytes()).unwrap(), + cert() + ) } #[test] @@ -394,17 +411,26 @@ mod tests { #[test] pub fn pubkey_serialization() { - assert_eq!((verifying_key(&[0u8; 32])).as_bytes_pki().unwrap(), [0u8; 32].to_vec()) + assert_eq!( + (verifying_key(&[0u8; 32])).as_bytes_pki().unwrap(), + [0u8; 32].to_vec() + ) } #[test] pub fn pubkey_deserialization() { - assert_eq!(EpfPublicKey::from_bytes(&[0u8; 32]).unwrap(), verifying_key(&[0u8; 32])) + assert_eq!( + EpfPublicKey::from_bytes(&[0u8; 32]).unwrap(), + verifying_key(&[0u8; 32]) + ) } #[test] pub fn pubkey_serialization_pem() { - assert_eq!((verifying_key(&[0u8; 32])).as_pem().unwrap(), null_public_key_pem()) + assert_eq!( + (verifying_key(&[0u8; 32])).as_pem().unwrap(), + null_public_key_pem() + ) } #[test] @@ -424,21 +450,30 @@ mod tests { #[test] pub fn privkey_serialization() { let priv_key_data = hex!("00000000000000000000000000000000000000000000000000000000000000003B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"); - assert_eq!((signing_key(&priv_key_data)).as_bytes_pki().unwrap(), priv_key_data.to_vec()) + assert_eq!( + (signing_key(&priv_key_data)).as_bytes_pki().unwrap(), + priv_key_data.to_vec() + ) } #[test] pub fn privkey_deserialization() { let priv_key = EpfPrivateKey::generate(&mut OsRng); - assert_eq!(priv_key.to_keypair_bytes(), signing_key(&priv_key.to_keypair_bytes()).to_keypair_bytes()) + assert_eq!( + priv_key.to_keypair_bytes(), + signing_key(&priv_key.to_keypair_bytes()).to_keypair_bytes() + ) } #[test] pub fn privkey_serialization_pem() { let priv_key_data = hex!("00000000000000000000000000000000000000000000000000000000000000003B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"); - assert_eq!((signing_key(&priv_key_data)).as_pem().unwrap(), null_private_key_pem()) + assert_eq!( + (signing_key(&priv_key_data)).as_pem().unwrap(), + null_private_key_pem() + ) } #[test] @@ -446,7 +481,9 @@ mod tests { let priv_key_data = hex!("00000000000000000000000000000000000000000000000000000000000000003B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"); assert_eq!( - EpfPrivateKey::from_pem(&null_private_key_pem()).unwrap().to_keypair_bytes(), + EpfPrivateKey::from_pem(&null_private_key_pem()) + .unwrap() + .to_keypair_bytes(), signing_key(&priv_key_data).to_keypair_bytes() ) } @@ -455,7 +492,9 @@ mod tests { #[should_panic] pub fn privkey_deserialization_pem_wrong_tag() { assert_eq!( - EpfPrivateKey::from_pem(&null_public_key_pem()).unwrap().to_keypair_bytes(), + EpfPrivateKey::from_pem(&null_public_key_pem()) + .unwrap() + .to_keypair_bytes(), signing_key(&[0u8; 64]).to_keypair_bytes() ) } @@ -632,9 +671,7 @@ mod tests { fingerprint: "".to_string(), signature: [0u8; EPFPKI_SIGNATURE_LENGTH], }; - not_trusted_cert - .sign(&private_key) - .unwrap(); + not_trusted_cert.sign(&private_key).unwrap(); let ca_pool = EpfCaPool::new(); @@ -866,6 +903,15 @@ mod tests { ] } fn null_private_key_pem() -> Vec { - vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55, 97, 105, 101, 56, 122, 114, 97, 107, 76, 87, 75, 106, 113, 78, 65, 113, 98, 119, 49, 122, 13, 10, 90, 84, 73, 86, 100, 120, 51, 105, 81, 54, 89, 54, 119, 69, 105, 104, 105, 49, 110, 97, 75, 81, 61, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10] + vec![ + 45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, + 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55, 97, 105, 101, 56, 122, 114, 97, 107, 76, + 87, 75, 106, 113, 78, 65, 113, 98, 119, 49, 122, 13, 10, 90, 84, 73, 86, 100, 120, 51, + 105, 81, 54, 89, 54, 119, 69, 105, 104, 105, 49, 110, 97, 75, 81, 61, 61, 13, 10, 45, + 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, 32, 75, 69, + 89, 45, 45, 45, 45, 45, 13, 10, + ] } } diff --git a/libepf/src/protocol.rs b/libepf/src/protocol.rs index 2b66570..e6b50ca 100644 --- a/libepf/src/protocol.rs +++ b/libepf/src/protocol.rs @@ -1,15 +1,15 @@ -use std::error::Error; +use crate::pki::{EPFCertificate, EPFPKI_PUBLIC_KEY_LENGTH}; use log::debug; use serde::{Deserialize, Serialize}; -use tokio::io::{AsyncReadExt}; -use crate::pki::{EPFCertificate, EPFPKI_PUBLIC_KEY_LENGTH}; +use std::error::Error; +use tokio::io::AsyncReadExt; pub const PROTOCOL_VERSION: u32 = 1; #[derive(Serialize, Deserialize, Clone)] pub struct EpfMessage { pub packet_id: u32, - pub packet_data: Vec + pub packet_data: Vec, } pub const PACKET_CLIENT_HELLO: u32 = 1; @@ -19,7 +19,7 @@ pub struct EpfClientHello { pub protocol_version: u32, pub client_random: [u8; 24], pub client_certificate: Option, - pub client_x25519_public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH] + pub client_x25519_public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH], } pub const PACKET_SERVER_HELLO: u32 = 2; @@ -29,7 +29,7 @@ pub struct EpfServerHello { pub protocol_version: u32, pub server_certificate: EPFCertificate, pub server_random: [u8; 16], - pub server_x25519_public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH] + pub server_x25519_public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH], } pub const PACKET_FINISHED: u32 = 3; @@ -37,7 +37,7 @@ pub const PACKET_FINISHED: u32 = 3; #[derive(Serialize, Deserialize)] pub struct EpfFinished { pub protocol_version: u32, - pub encrypted_0x42: Vec + pub encrypted_0x42: Vec, } pub const PACKET_APPLICATION_DATA: u32 = 4; @@ -46,7 +46,7 @@ pub const PACKET_APPLICATION_DATA: u32 = 4; pub struct EpfApplicationData { pub protocol_version: u32, pub encrypted_application_data: Vec, - pub nonce: [u8; 24] + pub nonce: [u8; 24], } #[derive(Clone)] @@ -55,7 +55,7 @@ pub enum EpfClientState { WaitingForServerHello, WaitingForFinished, Transport, - Closed + Closed, } #[derive(Clone)] @@ -63,10 +63,13 @@ pub enum EpfServerState { WaitingForClientHello, WaitingForFinished, Transport, - Closed + Closed, } -pub fn encode_packet(id: u32, packet: &T) -> Result, rmp_serde::encode::Error> { +pub fn encode_packet( + id: u32, + packet: &T, +) -> Result, rmp_serde::encode::Error> { let message_data = rmp_serde::to_vec(packet)?; let message_wrapper = EpfMessage { packet_id: id, @@ -80,11 +83,13 @@ pub fn encode_packet(id: u32, packet: &T) -> Result, rmp_s Ok(packet) } -pub async fn recv_packet(stream: &mut C) -> Result> { +pub async fn recv_packet( + stream: &mut C, +) -> Result> { let packet_length = stream.read_u64_le().await?; let mut packet_data_buf = vec![0u8; packet_length as usize]; stream.read_exact(&mut packet_data_buf).await?; let message: EpfMessage = rmp_serde::from_slice(&packet_data_buf)?; Ok(message) -} \ No newline at end of file +} diff --git a/libepf/src/util.rs b/libepf/src/util.rs index 8870b66..b8771a0 100644 --- a/libepf/src/util.rs +++ b/libepf/src/util.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, Utc}; +use ed25519_dalek::{SigningKey, VerifyingKey}; use std::ops::Add; use std::time::{Duration, SystemTime}; -use ed25519_dalek::{SigningKey, VerifyingKey}; pub fn pretty_print_date(date: &SystemTime) -> String { let datetime: DateTime = (*date).into(); @@ -17,4 +17,4 @@ pub fn verifying_key(key: &[u8; 32]) -> VerifyingKey { } pub fn signing_key(key: &[u8; 64]) -> SigningKey { SigningKey::from_keypair_bytes(key).unwrap() -} \ No newline at end of file +}