diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 27dca4a..884bf7a 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -8,7 +8,7 @@ vls-protocol = { git = "https://gitlab.com/lightning-signer/validating-lightning serde = { version = "1.0", default-features = false } rmp-serde = "1.1.0" serde_bolt = { version = "0.2", default-features = false } -sphinx-auther = "0.1.9" +sphinx-auther = "0.1.10" anyhow = "1" [features] diff --git a/parser/src/control.rs b/parser/src/control.rs index a3f7e59..58b66f4 100644 --- a/parser/src/control.rs +++ b/parser/src/control.rs @@ -68,21 +68,39 @@ impl Controller { self.2 = self.2 + 1; Ok(ret) } + pub fn parse_msg_no_nonce(&mut self, input: &[u8]) -> anyhow::Result { + let (msg, _nonce) = nonce::parse_msg_no_nonce(input, &self.1)?; + let ret = rmp_serde::from_slice(&msg)?; + Ok(ret) + } pub fn parse_response(&self, input: &[u8]) -> anyhow::Result { Ok(rmp_serde::from_slice(input)?) } - pub fn handle(&mut self, input: &[u8]) -> anyhow::Result> { - let msg = self.parse_msg(input)?; + pub fn handle(&mut self, input: &[u8]) -> anyhow::Result<(Vec, Option)> { + let msg = self.parse_msg_no_nonce(input)?; + // increment the nonce EXCEPT for Nonce requests + match msg { + ControlMessage::Nonce => (), + _ => { + self.2 = self.2 + 1; + } + } let mut store = self.3.lock().unwrap(); + let mut new_policy = None; let res = match msg { ControlMessage::Nonce => ControlResponse::Nonce(self.2), ControlMessage::ResetWifi => { store.reset(); ControlResponse::ResetWifi } + ControlMessage::UpdatePolicy(np) => { + new_policy = Some(np.clone()); + ControlResponse::PolicyUpdated(np) + } _ => ControlResponse::Nonce(self.2), }; - Ok(self.build_response(res)?) + let response = self.build_response(res)?; + Ok((response, new_policy)) } } diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 6e20b96..a0d1d56 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -10,7 +10,7 @@ use lightning_signer::util::clock::StandardClock; use lightning_signer::util::velocity::{VelocityControlIntervalType, VelocityControlSpec}; use randomstartingtime::RandomStartingTimeFactory; use std::sync::Arc; -use vls_protocol::model::PubKey; +use vls_protocol::model::{PubKey, Secret}; use vls_protocol::msgs::{self, read_serial_request_header, write_serial_response_header, Message}; use vls_protocol::serde_bolt::WireString; use vls_protocol_signer::handler::{Handler, RootHandler}; @@ -141,6 +141,22 @@ pub fn handle( Ok(out_md.bytes()) } +pub fn make_init_msg(network: Network, seed: [u8; 32]) -> anyhow::Result> { + let allowlist = Vec::new(); + log::info!("allowlist {:?} seed {:?}", allowlist, seed); + let init = msgs::HsmdInit2 { + derivation_style: 0, + network_name: WireString(network.to_string().as_bytes().to_vec()), + dev_seed: Some(Secret(seed)), + dev_allowlist: allowlist, + }; + let sequence = 0; + let mut md = MsgDriver::new_empty(); + msgs::write_serial_request_header(&mut md, sequence, 0)?; + msgs::write(&mut md, init)?; + Ok(md.bytes()) +} + pub fn parse_ping_and_form_response(msg_bytes: Vec) -> Vec { let mut m = MsgDriver::new(msg_bytes); let (sequence, _dbid) = msgs::read_serial_request_header(&mut m).expect("read ping header"); diff --git a/sphinx-key/Cargo.lock b/sphinx-key/Cargo.lock index 596c9fa..09a2339 100644 --- a/sphinx-key/Cargo.lock +++ b/sphinx-key/Cargo.lock @@ -1971,9 +1971,9 @@ dependencies = [ [[package]] name = "sphinx-auther" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ba95c8bd0600a9853ed6320701423362bfeac8d69034ed9585cb289d849701" +checksum = "452ac3986f03e8d403a21f81883d0f5058152af4ae006a26ee00e3a31af20302" dependencies = [ "anyhow", "base64", diff --git a/sphinx-key/src/core/events.rs b/sphinx-key/src/core/events.rs index 31b7b78..31d61fd 100644 --- a/sphinx-key/src/core/events.rs +++ b/sphinx-key/src/core/events.rs @@ -1,9 +1,9 @@ use crate::conn::mqtt::{CONTROL_RETURN_TOPIC, CONTROL_TOPIC, QOS, RETURN_TOPIC, VLS_TOPIC}; use crate::core::config::Config; use crate::core::control::{controller_from_seed, FlashPersister}; -use crate::core::init::make_init_msg; use sphinx_key_signer::lightning_signer::bitcoin::Network; +use sphinx_key_signer::make_init_msg; use sphinx_key_signer::vls_protocol::model::PubKey; use sphinx_key_signer::{self, InitResponse}; use std::sync::{mpsc, Arc, Mutex}; @@ -111,7 +111,7 @@ pub fn make_event_loop( Event::Control(ref msg_bytes) => { log::info!("GOT A CONTROL MSG"); match ctrlr.handle(msg_bytes) { - Ok(response) => { + Ok((response, _new_policy)) => { // log::info!("CONTROL MSG {:?}", response); mqtt.publish(CONTROL_RETURN_TOPIC, QOS, false, &response) .expect("could not publish control response"); diff --git a/sphinx-key/src/core/init.rs b/sphinx-key/src/core/init.rs deleted file mode 100644 index c0053b7..0000000 --- a/sphinx-key/src/core/init.rs +++ /dev/null @@ -1,20 +0,0 @@ -use sphinx_key_signer::lightning_signer::bitcoin::Network; -use sphinx_key_signer::vls_protocol::model::Secret; -use sphinx_key_signer::vls_protocol::{msgs, serde_bolt::WireString}; -use sphinx_key_signer::MsgDriver; - -pub fn make_init_msg(network: Network, seed: [u8; 32]) -> anyhow::Result> { - let allowlist = Vec::new(); - log::info!("allowlist {:?} seed {:?}", allowlist, seed); - let init = msgs::HsmdInit2 { - derivation_style: 0, - network_name: WireString(network.to_string().as_bytes().to_vec()), - dev_seed: Some(Secret(seed)), - dev_allowlist: allowlist, - }; - let sequence = 0; - let mut md = MsgDriver::new_empty(); - msgs::write_serial_request_header(&mut md, sequence, 0)?; - msgs::write(&mut md, init)?; - Ok(md.bytes()) -} diff --git a/sphinx-key/src/core/mod.rs b/sphinx-key/src/core/mod.rs index 26d5495..d4a4dc3 100644 --- a/sphinx-key/src/core/mod.rs +++ b/sphinx-key/src/core/mod.rs @@ -1,4 +1,3 @@ pub mod config; pub mod control; pub mod events; -pub mod init; diff --git a/tester/src/main.rs b/tester/src/main.rs index 7d2630b..4f3f76e 100644 --- a/tester/src/main.rs +++ b/tester/src/main.rs @@ -7,6 +7,7 @@ use rumqttc::{self, AsyncClient, Event, MqttOptions, Packet, QoS}; use sphinx_key_signer::control::Controller; use sphinx_key_signer::vls_protocol::{model::PubKey, msgs}; use sphinx_key_signer::{self, InitResponse}; +use std::convert::TryInto; use std::env; use std::error::Error; use std::str::FromStr; @@ -68,10 +69,11 @@ async fn main() -> Result<(), Box> { .await .expect("could not mqtt subscribe"); + let network = Network::Regtest; let seed_string: String = env::var("SEED").expect("no seed"); let seed = hex::decode(seed_string).expect("couldnt decode seed"); // make the controller to validate Control messages - let mut ctrlr = controller_from_seed(&Network::Regtest, &seed); + let mut ctrlr = controller_from_seed(&network, &seed); if is_test { // test handler loop @@ -103,7 +105,7 @@ async fn main() -> Result<(), Box> { } CONTROL_TOPIC => { match ctrlr.handle(&msg_bytes) { - Ok(response) => { + Ok((response, _new_policy)) => { client .publish( CONTROL_PUB_TOPIC, @@ -129,59 +131,59 @@ async fn main() -> Result<(), Box> { } } } else { - // once the init loop is done, the root_handler is returned - let root_handler = loop { - if let Ok(init_event) = eventloop.poll().await { - // this may be another kind of message like MQTT ConnAck - // loop around again and wait for the init - if let Some((_topic, init_msg_bytes)) = incoming_bytes(init_event) { - let InitResponse { - root_handler, - init_reply, - } = sphinx_key_signer::init(init_msg_bytes, Network::Regtest) - .expect("failed to init signer"); - client - .publish(PUB_TOPIC, QoS::AtMostOnce, false, init_reply) - .await - .expect("could not publish init response"); - // return the root_handler and finish the init loop - break Some(root_handler); - } - } else { - tokio::time::sleep(Duration::from_secs(1)).await; - log::warn!("failed to initialize! Lost connection"); - break None; - } - }; + let seed32: [u8; 32] = seed.try_into().expect("wrong seed"); + let init_msg = + sphinx_key_signer::make_init_msg(network, seed32).expect("failed to make init msg"); + let InitResponse { + root_handler, + init_reply: _, + } = sphinx_key_signer::init(init_msg, network).expect("failed to init signer"); // the actual handler loop loop { - if let Some(rh) = &root_handler { - match eventloop.poll().await { - Ok(event) => { - let dummy_peer = PubKey([0; 33]); - if let Some((_topic, msg_bytes)) = incoming_bytes(event) { - match sphinx_key_signer::handle( - rh, - msg_bytes, - dummy_peer.clone(), - is_log, - ) { - Ok(b) => client - .publish(PUB_TOPIC, QoS::AtMostOnce, false, b) - .await - .expect("could not publish init response"), - Err(e) => panic!("HANDLE FAILED {:?}", e), - }; + match eventloop.poll().await { + Ok(event) => { + let dummy_peer = PubKey([0; 33]); + if let Some((topic, msg_bytes)) = incoming_bytes(event) { + match topic.as_str() { + SUB_TOPIC => { + match sphinx_key_signer::handle( + &root_handler, + msg_bytes, + dummy_peer.clone(), + is_log, + ) { + Ok(b) => client + .publish(PUB_TOPIC, QoS::AtMostOnce, false, b) + .await + .expect("could not publish init response"), + Err(e) => panic!("HANDLE FAILED {:?}", e), + }; + } + CONTROL_TOPIC => { + match ctrlr.handle(&msg_bytes) { + Ok((response, _new_policy)) => { + client + .publish( + CONTROL_PUB_TOPIC, + QoS::AtMostOnce, + false, + response, + ) + .await + .expect("could not mqtt publish"); + } + Err(e) => log::warn!("error parsing ctrl msg {:?}", e), + }; + } + _ => log::info!("invalid topic"), } } - Err(e) => { - log::warn!("diconnected {:?}", e); - tokio::time::sleep(Duration::from_secs(1)).await; - break; // break out of this loop to reconnect - } } - } else { - break; + Err(e) => { + log::warn!("diconnected {:?}", e); + tokio::time::sleep(Duration::from_secs(1)).await; + break; // break out of this loop to reconnect + } } } }