From c8e6e834e9ac213152a26a5aa3e1280db4aa202a Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Fri, 1 Jul 2022 10:39:14 -0700 Subject: [PATCH] config bin to test seed encryption to device --- .gitignore | 3 +- Cargo.toml | 1 + crypter/src/ecdh.rs | 6 ++-- crypter/src/lib.rs | 14 +++----- tester/Cargo.toml | 12 +++++++ tester/src/config.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 tester/src/config.rs diff --git a/.gitignore b/.gitignore index ca2e8d2..fbad06e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ Cargo.lock .DS_Store sphinx-key/Cargo.lock notes.md -test-flash \ No newline at end of file +test-flash +.env \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 4213dcc..6108ea6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,4 @@ exclude = [ # updates the "rand" create to use esp RNG getrandom = { version = "0.2", git = "https://github.com/esp-rs-compat/getrandom.git" } secp256k1 = { git = "https://github.com/Evanfeenstra/rust-secp256k1", branch = "v0.22.0-new-rand" } +lightning = { git = "https://github.com/Evanfeenstra/rust-lightning", branch = "v0.0.108-branch" } diff --git a/crypter/src/ecdh.rs b/crypter/src/ecdh.rs index 8d998c1..cc55641 100644 --- a/crypter/src/ecdh.rs +++ b/crypter/src/ecdh.rs @@ -2,9 +2,9 @@ use secp256k1::ecdh::SharedSecret; use secp256k1::{SecretKey, PublicKey}; use anyhow::Result; -const PUBLIC_KEY_LEN: usize = 33; -const PRIVATE_KEY_LEN: usize = 32; -const SECRET_LEN: usize = 32; +pub const PUBLIC_KEY_LEN: usize = 33; +pub const PRIVATE_KEY_LEN: usize = 32; +pub const SECRET_LEN: usize = 32; pub fn derive_shared_secret_from_slice(their_public_key: [u8; PUBLIC_KEY_LEN], my_private_key: [u8; PRIVATE_KEY_LEN]) -> Result<[u8; SECRET_LEN]> { let public_key = PublicKey::from_slice(&their_public_key[..])?; diff --git a/crypter/src/lib.rs b/crypter/src/lib.rs index 5e2ca49..222b5ad 100644 --- a/crypter/src/lib.rs +++ b/crypter/src/lib.rs @@ -1,12 +1,13 @@ pub mod chacha; pub mod ecdh; +pub use secp256k1; #[cfg(test)] mod tests { use crate::chacha::{decrypt, encrypt, MSG_LEN, NONCE_END_LEN}; use crate::ecdh::derive_shared_secret_from_slice; - use rand::{rngs::OsRng, RngCore, thread_rng}; + use rand::{rngs::OsRng, thread_rng, RngCore}; use secp256k1::Secp256k1; #[test] @@ -17,12 +18,8 @@ mod tests { let (sk2, pk2) = s.generate_keypair(&mut thread_rng()); // derive shared secrets - let sec1 = derive_shared_secret_from_slice( - pk2.serialize(), sk1.secret_bytes() - )?; - let sec2 = derive_shared_secret_from_slice( - pk1.serialize(), sk2.secret_bytes() - )?; + let sec1 = derive_shared_secret_from_slice(pk2.serialize(), sk1.secret_bytes())?; + let sec2 = derive_shared_secret_from_slice(pk1.serialize(), sk2.secret_bytes())?; assert_eq!(sec1, sec2); // encrypt plaintext with sec1 @@ -38,5 +35,4 @@ mod tests { println!("PLAINTEXT MATCHES!"); Ok(()) } - -} \ No newline at end of file +} diff --git a/tester/Cargo.toml b/tester/Cargo.toml index 7b767e0..03b36c0 100644 --- a/tester/Cargo.toml +++ b/tester/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] sphinx-key-signer = { path = "../signer" } sphinx-key-parser = { path = "../parser" } +sphinx-key-crypter = { path = "../crypter" } vls-protocol = { git = "https://gitlab.com/Evanfeenstra/validating-lightning-signer", branch = "partial-std" } vls-protocol-signer = { git = "https://gitlab.com/Evanfeenstra/validating-lightning-signer", branch = "partial-std", default-features = false, features = ["std", "secp-lowmemory"] } # vls-protocol = { path = "../../../evanf/validating-lightning-signer/vls-protocol" } @@ -20,3 +21,14 @@ clap = "3.2.6" clap_derive = "3.2.6" fern = { version = "0.6", features = ["colored"] } chrono = "0.4" +rand = "0.8" +reqwest = { version = "0.11.11", features = ["json"] } +hex = "0.4.3" +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0" +urlencoding = "2.1.0" +dotenv = "0.15.0" + +[[bin]] +name = "config" +path = "src/config.rs" diff --git a/tester/src/config.rs b/tester/src/config.rs new file mode 100644 index 0000000..61bb0c6 --- /dev/null +++ b/tester/src/config.rs @@ -0,0 +1,86 @@ +use rand::{rngs::OsRng, thread_rng, RngCore}; +use serde::{Deserialize, Serialize}; +use sphinx_key_crypter::chacha::{encrypt, MSG_LEN, NONCE_END_LEN}; +use sphinx_key_crypter::ecdh::{derive_shared_secret_from_slice, PUBLIC_KEY_LEN}; +use sphinx_key_crypter::secp256k1::Secp256k1; +use std::convert::TryInto; +use std::time::Duration; +use dotenv::dotenv; +use std::env; + +const URL: &str = "http://192.168.71.1/"; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct EcdhBody { + pub pubkey: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ConfigBody { + pub seed: String, + pub ssid: String, + pub pass: String, + pub broker: String, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ConfigResponse { + pub success: bool, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + dotenv().ok(); + + let ssid: String = env::var("SSID").expect("no ssid"); + let pass: String = env::var("PASS").expect("no pass"); + let broker: String = env::var("BROKER").expect("no broker"); + + let s = Secp256k1::new(); + let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); + + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(10)) + .build() + .expect("couldnt build reqwest client"); + + let body = EcdhBody { + pubkey: hex::encode(pk1.serialize()), + }; + let res = client + .post(format!("{}{}", URL, "ecdh")) + .json(&body) + .header("Content-Type", "application/json") + .send() + .await?; + let their_ecdh: EcdhBody = res.json().await?; + let their_pk = hex::decode(their_ecdh.pubkey)?; + + let their_pk_bytes: [u8; PUBLIC_KEY_LEN] = their_pk[..PUBLIC_KEY_LEN].try_into()?; + let shared_secret = derive_shared_secret_from_slice(their_pk_bytes, sk1.secret_bytes())?; + + let plaintext = [1; MSG_LEN]; + let mut nonce_end = [0; NONCE_END_LEN]; + OsRng.fill_bytes(&mut nonce_end); + let cipher = encrypt(plaintext, shared_secret, nonce_end)?; + + let cipher_seed = hex::encode(cipher); + let config = ConfigBody { + seed: cipher_seed, + ssid, pass, broker, + }; + + let conf_string = serde_json::to_string(&config)?; + let conf_encoded = urlencoding::encode(&conf_string).to_owned(); + + let res2 = client + .post(format!("{}{}{}", URL, "/config?config=", conf_encoded)) + .send() + .await?; + let conf_res: ConfigResponse = res2.json().await?; + + if conf_res.success { + println!("SUCCESS!") + } + + Ok(()) +}