commit 21d2b16ee82caec6d9d65aae231f913130867726 Author: Federico Pasqua (eisterman) Date: Mon Jan 15 20:21:10 2024 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d61b266 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +# Experiments with certificates +/*.pem \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b6cd942 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,571 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bonknet_client" +version = "0.1.0" +dependencies = [ + "rustls-pemfile", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "bonknet_server" +version = "0.1.0" +dependencies = [ + "rcgen", + "rustls-pemfile", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "libbonknet" +version = "0.1.0" + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pem" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rcgen" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d918c80c5a4c7560db726763020bd16db179e4d5b828078842274a443addb5d" +dependencies = [ + "pem", + "ring", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" +dependencies = [ + "base64", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a" + +[[package]] +name = "rustls-webpki" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e20cc00 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +resolver = "2" +members = [ + "bonknet_client", + "bonknet_server", + "libbonknet", +] diff --git a/bonknet_client/Cargo.toml b/bonknet_client/Cargo.toml new file mode 100644 index 0000000..46e35a4 --- /dev/null +++ b/bonknet_client/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "bonknet_client" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tokio = { version = "1", features = ["full"] } +tokio-rustls = "0.25.0" +rustls-pemfile = "2.0.0" diff --git a/bonknet_client/src/main.rs b/bonknet_client/src/main.rs new file mode 100644 index 0000000..e194a61 --- /dev/null +++ b/bonknet_client/src/main.rs @@ -0,0 +1,67 @@ +use std::io::{BufReader, Error, ErrorKind}; +use std::sync::Arc; +use rustls_pemfile::{Item, read_one}; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, split}; +use tokio::net::TcpStream; +use tokio_rustls::rustls::{ClientConfig, RootCertStore}; +use tokio_rustls::rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer, ServerName}; +use tokio_rustls::TlsConnector; + +fn load_cert(filename: &str) -> std::io::Result { + let cert_file = std::fs::File::open(filename).unwrap(); + let mut buf = std::io::BufReader::new(cert_file); + if let Item::X509Certificate(cert) = read_one(&mut buf).unwrap().unwrap() { + Ok(cert) + } else { + eprintln!("File {} doesn't contain a X509 Certificate", filename); + Err(Error::new(ErrorKind::InvalidInput, "no x509 cert")) + } +} + +fn load_prkey(filename: &str) -> std::io::Result { + let prkey_file = std::fs::File::open(filename).unwrap(); + let mut buf = BufReader::new(prkey_file); + if let Item::Pkcs8Key(pkey) = read_one(&mut buf).unwrap().unwrap() { + Ok(pkey) + } else { + eprintln!("File {} doesn't contain a Pkcs8 Private Key", filename); + Err(Error::new(ErrorKind::InvalidInput, "no pkcs8key")) + } +} + +#[tokio::main] +async fn main() -> std::io::Result<()> { + // Root certs to verify the server is the right one + let mut server_root_cert_store = RootCertStore::empty(); + let server_root_cert_der = load_cert("server_root_cert.pem").unwrap(); + server_root_cert_store.add(server_root_cert_der).unwrap(); + // Auth Cert to send the server who am I + let root_client_cert = load_cert("client_root_cert.pem").unwrap(); + let client_cert = load_cert("client_cert.pem").unwrap(); + let client_prkey = load_prkey("client_key.pem").unwrap(); + // Load TLS Config + let tlsconfig = ClientConfig::builder() + .with_root_certificates(server_root_cert_store) + // .with_no_client_auth(); + .with_client_auth_cert(vec![client_cert, root_client_cert], client_prkey.into()) + .unwrap(); + let connector = TlsConnector::from(Arc::new(tlsconfig)); + let dnsname = ServerName::try_from("localhost").unwrap(); + + let stream = TcpStream::connect("localhost:6379").await?; + let stream = connector.connect(dnsname, stream).await?; + let (mut rd,mut tx) = split(stream); + + tokio::spawn(async move { + let mut stdout = tokio::io::stdout(); + tokio::io::copy(&mut rd, &mut stdout).await.unwrap(); + }); + + let mut reader = tokio::io::BufReader::new(tokio::io::stdin()).lines(); + + while let Some(line) = reader.next_line().await.unwrap() { + tx.write_all(line.as_bytes()).await.unwrap(); + } + + Ok(()) +} \ No newline at end of file diff --git a/bonknet_server/Cargo.toml b/bonknet_server/Cargo.toml new file mode 100644 index 0000000..3702966 --- /dev/null +++ b/bonknet_server/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "bonknet_server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tokio = { version = "1", features = ["full"] } +rcgen = "0.12.0" +tokio-rustls = "0.25.0" +rustls-pemfile = "2.0.0" \ No newline at end of file diff --git a/bonknet_server/src/bin/init_certs.rs b/bonknet_server/src/bin/init_certs.rs new file mode 100644 index 0000000..7ec6887 --- /dev/null +++ b/bonknet_server/src/bin/init_certs.rs @@ -0,0 +1,86 @@ +use std::fs::File; +use std::io::Write; +use rcgen::{self, BasicConstraints, Certificate, CertificateParams, DnType}; + +fn server_root_cert() -> Certificate { + let subject_alt_names = vec!["hello.world.example".into()]; + let mut certparams = CertificateParams::new(subject_alt_names); + certparams.is_ca = rcgen::IsCa::Ca(BasicConstraints::Unconstrained); + let mut distname = rcgen::DistinguishedName::new(); + distname.push(DnType::OrganizationName, "Eister Corporation"); + distname.push(DnType::CommonName, "Bonknet Server Root Cert CA"); + certparams.distinguished_name = distname; + Certificate::from_params(certparams).unwrap() +} + +fn server_cert() -> Certificate { + let mut params = CertificateParams::new(vec!["entity.other.host".into(), "localhost".into()]); + params.distinguished_name.push(DnType::CommonName, "localhost"); + params.use_authority_key_identifier_extension = true; + params.key_usages.push(rcgen::KeyUsagePurpose::DigitalSignature); + params + .extended_key_usages + .push(rcgen::ExtendedKeyUsagePurpose::ServerAuth); + Certificate::from_params(params).unwrap() +} + +fn client_root_cert() -> Certificate { + let subject_alt_names = vec!["hello.world.example".into()]; + let mut certparams = CertificateParams::new(subject_alt_names); + certparams.is_ca = rcgen::IsCa::Ca(BasicConstraints::Unconstrained); + let mut distname = rcgen::DistinguishedName::new(); + distname.push(DnType::OrganizationName, "Eister Corporation"); + distname.push(DnType::CommonName, "Bonknet Client Root Cert CA"); + certparams.distinguished_name = distname; + Certificate::from_params(certparams).unwrap() +} + +fn client_cert() -> Certificate { + let mut params = CertificateParams::new(vec!["entity.other.host".into(), "bonk.client.1".into()]); + params.distinguished_name.push(DnType::CommonName, "Client 1"); + params.use_authority_key_identifier_extension = true; + params.key_usages.push(rcgen::KeyUsagePurpose::DigitalSignature); + params + .extended_key_usages + .push(rcgen::ExtendedKeyUsagePurpose::ClientAuth); + Certificate::from_params(params).unwrap() +} + +fn main() -> std::io::Result<()> { + // SERVER + let server_root_cert = server_root_cert(); + // The certificate is now valid for localhost and the domain "hello.world.example" + { + let mut certfile = File::create("server_root_cert.pem")?; + certfile.write_all(server_root_cert.serialize_pem().unwrap().as_bytes())?; + let mut privkfile = File::create("server_root_key.pem")?; + privkfile.write_all(server_root_cert.serialize_private_key_pem().as_bytes())?; + } + // Now create the leaf + let server_leaf_cert = server_cert(); + { + let mut certfile = File::create("server_cert.pem")?; + certfile.write_all(server_leaf_cert.serialize_pem_with_signer(&server_root_cert).unwrap().as_bytes())?; + let mut privkfile = File::create("server_key.pem")?; + privkfile.write_all(server_leaf_cert.serialize_private_key_pem().as_bytes())?; + } + // CLIENT + let client_root_cert = client_root_cert(); + // The certificate is now valid for localhost and the domain "hello.world.example" + { + let mut certfile = File::create("client_root_cert.pem")?; + certfile.write_all(client_root_cert.serialize_pem().unwrap().as_bytes())?; + let mut privkfile = File::create("client_root_key.pem")?; + privkfile.write_all(client_root_cert.serialize_private_key_pem().as_bytes())?; + } + // Now create the leaf + let client_leaf_cert = client_cert(); + { + let mut certfile = File::create("client_cert.pem")?; + certfile.write_all(client_leaf_cert.serialize_pem_with_signer(&client_root_cert).unwrap().as_bytes())?; + let mut privkfile = File::create("client_key.pem")?; + privkfile.write_all(client_leaf_cert.serialize_private_key_pem().as_bytes())?; + } + println!("Certificates created"); + Ok(()) +} \ No newline at end of file diff --git a/bonknet_server/src/bin/server.rs b/bonknet_server/src/bin/server.rs new file mode 100644 index 0000000..396ab69 --- /dev/null +++ b/bonknet_server/src/bin/server.rs @@ -0,0 +1,75 @@ +use tokio::net::{TcpListener}; +use std::io::{BufReader, Error, ErrorKind}; +use std::sync::{Arc}; +use tokio_rustls::{TlsAcceptor}; +use tokio_rustls::rustls::{RootCertStore, ServerConfig}; +use tokio_rustls::rustls::server::WebPkiClientVerifier; +use rustls_pemfile::{read_one, Item}; +use tokio::io::{AsyncWriteExt, copy, split}; +use tokio_rustls::rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer}; + +fn load_cert(filename: &str) -> std::io::Result { + let cert_file = std::fs::File::open(filename).unwrap(); + let mut buf = std::io::BufReader::new(cert_file); + if let Item::X509Certificate(cert) = read_one(&mut buf).unwrap().unwrap() { + Ok(cert) + } else { + eprintln!("File {} doesn't contain a X509 Certificate", filename); + Err(Error::new(ErrorKind::InvalidInput, "no x509 cert")) + } +} + +fn load_prkey(filename: &str) -> std::io::Result { + let prkey_file = std::fs::File::open(filename).unwrap(); + let mut buf = BufReader::new(prkey_file); + if let Item::Pkcs8Key(pkey) = read_one(&mut buf).unwrap().unwrap() { + Ok(pkey) + } else { + eprintln!("File {} doesn't contain a Pkcs8 Private Key", filename); + Err(Error::new(ErrorKind::InvalidInput, "no pkcs8key")) + } +} + + +#[tokio::main] +async fn main() { + let server_root_cert_der = load_cert("server_root_cert.pem").unwrap(); + let server_cert_der = load_cert("server_cert.pem").unwrap(); + let server_prkey_der = load_prkey("server_key.pem").unwrap(); + // CLIENT ROOT + let client_root_cert_der = load_cert("client_root_cert.pem").unwrap(); + // Client Verifier + let mut clientrootstore = RootCertStore::empty(); + clientrootstore.add(client_root_cert_der).unwrap(); + let client_verifier = WebPkiClientVerifier::builder(Arc::new(clientrootstore)).build().unwrap(); + // Configure TLS + let tlsconfig = ServerConfig::builder() + // .with_no_client_auth() + .with_client_cert_verifier(client_verifier) + .with_single_cert(vec![server_cert_der.clone(), server_root_cert_der.clone()], server_prkey_der.into()) + .unwrap(); + let acceptor = TlsAcceptor::from(Arc::new(tlsconfig)); + + let listener = TcpListener::bind("localhost:6379").await.unwrap(); + + loop { + let (stream, peer_addr) = listener.accept().await.unwrap(); + let acceptor = acceptor.clone(); + + let fut = async move { + let stream = acceptor.accept(stream).await?; + let (mut reader, mut writer) = split(stream); + let n = copy(&mut reader, &mut writer).await?; + writer.flush().await?; + println!("Echo: {} - {}", peer_addr, n); + + Ok(()) as std::io::Result<()> + }; + + tokio::spawn(async move { + if let Err(err) = fut.await { + eprintln!("{:?}", err); + } + }); + } +} diff --git a/libbonknet/Cargo.toml b/libbonknet/Cargo.toml new file mode 100644 index 0000000..4f7d560 --- /dev/null +++ b/libbonknet/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "libbonknet" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/libbonknet/src/lib.rs b/libbonknet/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/libbonknet/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +}