| @@ -78,6 +78,12 @@ version = "1.0.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" | |||
| [[package]] | |||
| name = "base64" | |||
| version = "0.12.1" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42" | |||
| [[package]] | |||
| name = "bitflags" | |||
| version = "1.2.1" | |||
| @@ -483,6 +489,7 @@ dependencies = [ | |||
| "futures-util", | |||
| "ilmp", | |||
| "lazy_static", | |||
| "orion", | |||
| "ring", | |||
| "serde", | |||
| "serde_json", | |||
| @@ -538,6 +545,18 @@ version = "1.4.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" | |||
| [[package]] | |||
| name = "orion" | |||
| version = "0.15.1" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "6e2dd0d645e94ec75aacc27460cb68438263342f4e4e1aeaf7af67847687e7a8" | |||
| dependencies = [ | |||
| "base64", | |||
| "getrandom", | |||
| "subtle", | |||
| "zeroize", | |||
| ] | |||
| [[package]] | |||
| name = "pin-project" | |||
| version = "0.4.16" | |||
| @@ -773,6 +792,12 @@ dependencies = [ | |||
| "syn", | |||
| ] | |||
| [[package]] | |||
| name = "subtle" | |||
| version = "2.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" | |||
| [[package]] | |||
| name = "syn" | |||
| version = "1.0.21" | |||
| @@ -1001,3 +1026,9 @@ dependencies = [ | |||
| "winapi 0.2.8", | |||
| "winapi-build", | |||
| ] | |||
| [[package]] | |||
| name = "zeroize" | |||
| version = "1.1.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" | |||
| @@ -19,3 +19,4 @@ toml = "0.5.6" | |||
| ilmp = { path = "../ilmp"} | |||
| ring = "0.16.13" | |||
| thiserror = "1.0.18" | |||
| orion = "0.15.1" | |||
| @@ -2,25 +2,25 @@ | |||
| use crate::config::ClientConfig as Config; | |||
| use crate::Result; | |||
| use async_std::net::TcpStream; | |||
| /*use futures::io::ReadHalf;*/ | |||
| use futures_util::io::AsyncReadExt; | |||
| /// wraps the client | |||
| pub async fn client(port: u16) -> Result<()> { | |||
| let _config = Config::load()?; | |||
| let mut stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; | |||
| let stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; | |||
| println!("connection established to: {}:{}", stream.peer_addr()?.ip(), port); | |||
| let (mut read, mut write) = stream.split(); | |||
| let message = ilmp::Message::new( | |||
| let key = crate::initialize_connection(&mut read, &mut write).await?; | |||
| println!("{:?}", key); | |||
| /*let message = ilmp::Message::new( | |||
| "Isabelle".to_owned(), | |||
| "oh god oh fuck this shit actually works".to_owned(), | |||
| ); | |||
| ilmp::write(&mut stream, message, ilmp::NoEncrypt::new()).await; | |||
| ilmp::write(&mut stream, message, encrypt::NoEncrypt::new()).await?;*/ | |||
| loop {} | |||
| /*let (read, mut write) = stream.split();*/ | |||
| Ok(()) | |||
| } | |||
| @@ -3,7 +3,12 @@ mod client; | |||
| mod config; | |||
| mod server; | |||
| use ring::{agreement, rand}; | |||
| use async_std::net::TcpStream; | |||
| use futures::io::{ReadHalf, WriteHalf}; | |||
| use ilmp::encrypt; | |||
| use ilmp::Sendable; | |||
| use orion::aead; | |||
| use ring::{agreement, digest, rand}; | |||
| use thiserror::Error; | |||
| // re-exports | |||
| @@ -20,21 +25,35 @@ pub enum MsgError { | |||
| StdIo(#[from] std::io::Error), | |||
| #[error("toml error")] | |||
| Toml(#[from] toml::de::Error), | |||
| #[error("ring fucking broke")] | |||
| Ring, | |||
| #[error("orion error")] | |||
| Orion(#[from] orion::errors::UnknownCryptoError), | |||
| } | |||
| pub struct AsymmetricKeys { | |||
| pub private: agreement::EphemeralPrivateKey, | |||
| pub public: agreement::PublicKey, | |||
| } | |||
| /// uses ring's agreement to generate key material and key | |||
| pub async fn initialize_connection( | |||
| read: &mut ReadHalf<TcpStream>, | |||
| write: &mut WriteHalf<TcpStream>, | |||
| ) -> Result<aead::SecretKey> { | |||
| // create / send agreement key | |||
| let rng = rand::SystemRandom::new(); | |||
| let my_priv_key = | |||
| agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng).expect("ring broke"); | |||
| let my_pub_key = my_priv_key.compute_public_key().expect("ring broke"); | |||
| let agreement_packet = ilmp::Agreement::new(my_pub_key.as_ref().into()); | |||
| ilmp::write(write, agreement_packet, encrypt::NoEncrypt::new()).await?; | |||
| // receive peer's pub key | |||
| let packet = ilmp::read(read).await?.unwrap(); | |||
| let agreement_packet = ilmp::Agreement::from_packet(packet)?; | |||
| let peer_pub_key = | |||
| agreement::UnparsedPublicKey::new(&agreement::X25519, agreement_packet.public_key); | |||
| impl AsymmetricKeys { | |||
| pub fn generate() -> AsymmetricKeys { | |||
| let rng = rand::SystemRandom::new(); | |||
| let private = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng) | |||
| .expect("failed to create private key"); | |||
| let public = private | |||
| .compute_public_key() | |||
| .expect("failed to create public key"); | |||
| AsymmetricKeys { private, public } | |||
| } | |||
| // generate aead key | |||
| agreement::agree_ephemeral(my_priv_key, &peer_pub_key, MsgError::Ring, |key_material| { | |||
| let key_material = | |||
| digest::digest(&digest::SHA256, key_material.as_ref().into()).as_ref().to_vec(); | |||
| Ok(aead::SecretKey::from_slice(&key_material)?) | |||
| }) | |||
| } | |||
| @@ -18,7 +18,6 @@ lazy_static! { | |||
| /// wraps the server | |||
| pub async fn server(port: u16) -> Result<()> { | |||
| let asym_keys = crate::AsymmetricKeys::generate(); | |||
| let listener = TcpListener::bind(format!("127.0.0.1:{}", &port)).await?; | |||
| println!("online as server at: {}:{}", listener.local_addr()?.ip(), port); | |||
| @@ -31,11 +30,12 @@ pub async fn server(port: u16) -> Result<()> { | |||
| println!("new stream from: {}", &stream_addr); | |||
| let (read, write) = stream.split(); | |||
| let (mut read, mut write) = stream.split(); | |||
| let stream_id = Uuid::new_v4(); | |||
| let key = crate::initialize_connection(&mut read, &mut write).await?; | |||
| println!("{:?}", key); | |||
| WRITE_STREAMS.lock().expect("could not aqcuire lock").insert(stream_id.clone(), write); | |||
| task::spawn(handle_stream(read, stream_id)); | |||
| } | |||