From 796eb374f415e403c912e8640c06364280050bc7 Mon Sep 17 00:00:00 2001 From: ennucore Date: Thu, 18 Nov 2021 22:27:58 +0300 Subject: [PATCH] Cryptography is ready --- Cargo.lock | 256 ++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 + src/crypto.rs | 56 +++++++---- src/interface.rs | 1 + src/ironforce.rs | 3 + src/lib.rs | 5 + src/message.rs | 0 src/transport.rs | 1 + 8 files changed, 304 insertions(+), 22 deletions(-) create mode 100644 src/interface.rs create mode 100644 src/ironforce.rs create mode 100644 src/message.rs create mode 100644 src/transport.rs diff --git a/Cargo.lock b/Cargo.lock index 6184e55..4dd57f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64ct" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" + [[package]] name = "block-buffer" version = "0.7.3" @@ -11,7 +29,7 @@ dependencies = [ "block-padding", "byte-tools", "byteorder", - "generic-array", + "generic-array 0.12.4", ] [[package]] @@ -41,13 +59,49 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array 0.14.4", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "der" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" +dependencies = [ + "const-oid", + "crypto-bigint", +] + [[package]] name = "digest" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "generic-array", + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", ] [[package]] @@ -65,6 +119,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -93,22 +157,121 @@ version = "0.1.0" dependencies = [ "rand", "rand_os", + "rsa", "serde", "sha2", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] + [[package]] name = "libc" version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +[[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + +[[package]] +name = "num-bigint-dig" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4547ee5541c18742396ae2c895d0717d0f886d8823b8399cdaf7b07d63ad0480" +dependencies = [ + "autocfg 0.1.7", + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg 1.0.1", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg 1.0.1", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg 1.0.1", + "libm", +] + [[package]] name = "opaque-debug" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "pem-rfc7468" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs1" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "116bee8279d783c0cf370efa1a94632f2108e5ef0bb32df31f051647810a4e2c" +dependencies = [ + "der", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der", + "pem-rfc7468", + "pkcs1", + "spki", + "zeroize", +] + [[package]] name = "ppv-lite86" version = "0.2.15" @@ -192,6 +355,27 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rsa" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c2603e2823634ab331437001b411b9ed11660fbc4066f3908c84a9439260d" +dependencies = [ + "byteorder", + "digest 0.9.0", + "lazy_static", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand", + "serde", + "subtle", + "zeroize", +] + [[package]] name = "serde" version = "1.0.130" @@ -219,11 +403,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" dependencies = [ "block-buffer", - "digest", + "digest 0.8.1", "fake-simd", "opaque-debug", ] +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.81" @@ -235,6 +446,18 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "typenum" version = "1.14.0" @@ -247,6 +470,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -258,3 +487,24 @@ name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "zeroize" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/Cargo.toml b/Cargo.toml index 9b8cb9d..960c91b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,8 @@ rand_os = "*" # ed25519-dalek = { version = "1.0", features = ["serde"] } sha2 = "0.8.1" rand = "*" +rsa = { version = "0.5", features = ["serde"] } serde = { version = "1.0", features = ["derive", "alloc"], default-features = false } + +[profile.dev.package.num-bigint-dig] +opt-level = 3 diff --git a/src/crypto.rs b/src/crypto.rs index cff1a90..030f880 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,49 +1,67 @@ +/// This module has wrappers for cryptography with RSA algorithms. +/// Its main structs - `PublicKey` and `Keys` implement all functions for key generation, signatures and asymmetric encryption use alloc::vec::Vec; +use alloc::vec; use serde::{Deserialize, Serialize}; +use rsa::{RsaPublicKey, RsaPrivateKey, PaddingScheme, PublicKey as RPK}; +use rsa::errors::Result as RsaRes; +use rand::rngs::OsRng; + +static KEY_LENGTH: usize = 2048; + /// Public key of a node #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct PublicKey { - pub key: [u8; 32], + pub key: RsaPublicKey, } impl PublicKey { - /// Check if the sign is valid for gived data and key - pub fn verify_sign(&self, _data: &[u8], _sign: &[u8]) -> bool { - todo!() + /// Check if the sign is valid for given data and key + pub fn verify_sign(&self, data: &[u8], sign: &[u8]) -> bool { + self.key.verify(PaddingScheme::PKCS1v15Sign { hash: None }, data, sign).is_ok() } /// Encrypt some data for a user with this public key - pub fn encrypt_data(&self, _data: &[u8]) -> Vec { - todo!() + pub fn encrypt_data(&self, data: &[u8]) -> RsaRes> { + self.key.encrypt(&mut OsRng {}, PaddingScheme::PKCS1v15Encrypt, data) } } /// Key pair (public and secret) for a node, should be stored locally #[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Keys {} +pub struct Keys { + public_key: RsaPublicKey, + private_key: RsaPrivateKey, +} impl Keys { /// Generate new random key - pub fn generate() -> Keys { - todo!() + pub fn generate() -> Self { + let mut rng = OsRng; + let private_key = RsaPrivateKey::new(&mut rng, KEY_LENGTH).expect("failed to generate a key"); + let public_key = RsaPublicKey::from(&private_key); + Self { + private_key, + public_key, + } } } impl Keys { /// Sign content using these keys - pub fn sign(&self, _content: &[u8]) -> Vec { - todo!() + pub fn sign(&self, content: &[u8]) -> RsaRes> { + self.private_key.sign(PaddingScheme::PKCS1v15Sign { hash: None }, content) } /// Decrypt data - pub fn decrypt_data(&self, _data_encrypted: &[u8]) -> Option> { - todo!() + pub fn decrypt_data(&self, data_encrypted: &[u8]) -> RsaRes> { + self.private_key.decrypt(PaddingScheme::PKCS1v15Encrypt, data_encrypted) } /// Get public key pub fn get_public(&self) -> PublicKey { - todo!() + PublicKey { key: self.public_key.clone() } } } @@ -52,8 +70,8 @@ fn test_encrypt() { let data = vec![0, 5, 8, 135, 67]; let keys = Keys::generate(); assert_eq!( - keys.decrypt_data(keys.get_public().encrypt_data(data)), - Some(data) + keys.decrypt_data(&keys.get_public().encrypt_data(&data).unwrap()).unwrap(), + data ); } @@ -62,14 +80,14 @@ fn test_invalid_encrypt() { let data = vec![0, 5, 8, 135, 67]; let keys_1 = Keys::generate(); let keys_2 = Keys::generate(); - assert!(keys_2.decrypt_data(keys_1.get_public().encrypt_data(data)) != Some(data)); + assert!(keys_2.decrypt_data(&keys_1.get_public().encrypt_data(&data).unwrap()).is_err()); } #[test] fn test_signing() { let data = vec![0, 5, 8, 135, 67]; let keys = Keys::generate(); - assert!(keys.get_public().verify_sign(data, keys.sign(data))); + assert!(keys.get_public().verify_sign(&data, &keys.sign(&data).unwrap())); } #[test] @@ -77,5 +95,5 @@ fn test_invalid_signing() { let data = vec![0, 5, 8, 135, 67]; let keys_1 = Keys::generate(); let keys_2 = Keys::generate(); - assert!(keys_2.get_public().verify_sign(data, keys_1.sign(data))); + assert!(!keys_2.get_public().verify_sign(&data, &keys_1.sign(&data).unwrap())); } diff --git a/src/interface.rs b/src/interface.rs new file mode 100644 index 0000000..e1bee76 --- /dev/null +++ b/src/interface.rs @@ -0,0 +1 @@ +pub trait Interface {} diff --git a/src/ironforce.rs b/src/ironforce.rs new file mode 100644 index 0000000..2f7ed9c --- /dev/null +++ b/src/ironforce.rs @@ -0,0 +1,3 @@ +pub struct IronForce { + +} diff --git a/src/lib.rs b/src/lib.rs index e332a88..ff8301e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,13 @@ extern crate alloc; extern crate rand; +extern crate rsa; mod crypto; +mod ironforce; +mod message; +mod transport; +mod interface; #[cfg(test)] mod tests { diff --git a/src/message.rs b/src/message.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/transport.rs b/src/transport.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/transport.rs @@ -0,0 +1 @@ +