mirror of
https://github.com/stakwork/sphinx-key.git
synced 2026-02-23 16:44:21 +01:00
separate config and seed store, simplify flash access, more methods in FlashPersister
This commit is contained in:
@@ -1,8 +1,18 @@
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sphinx_auther::nonce;
|
||||
use sphinx_auther::secp256k1::{PublicKey, SecretKey};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
|
||||
pub struct Config {
|
||||
pub broker: String,
|
||||
pub ssid: String,
|
||||
pub pass: String,
|
||||
pub network: String,
|
||||
// pub seed: [u8; 32],
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub enum ControlMessage {
|
||||
Nonce,
|
||||
@@ -105,9 +115,29 @@ impl Controller {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FlashKey {
|
||||
Config,
|
||||
Seed,
|
||||
Nonce,
|
||||
}
|
||||
impl FlashKey {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
FlashKey::Config => "config",
|
||||
FlashKey::Seed => "seed",
|
||||
FlashKey::Nonce => "nonce",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ControlPersist: Sync + Send {
|
||||
fn reset(&mut self);
|
||||
fn set_nonce(&mut self, nonce: u64);
|
||||
fn read_config(&self) -> Result<Config>;
|
||||
fn write_config(&mut self, c: Config) -> Result<()>;
|
||||
fn read_seed(&self) -> Result<[u8; 32]>;
|
||||
fn write_seed(&mut self, s: [u8; 32]) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct DummyPersister;
|
||||
@@ -115,4 +145,16 @@ pub struct DummyPersister;
|
||||
impl ControlPersist for DummyPersister {
|
||||
fn reset(&mut self) {}
|
||||
fn set_nonce(&mut self, _nonce: u64) {}
|
||||
fn read_config(&self) -> Result<Config> {
|
||||
Ok(Default::default())
|
||||
}
|
||||
fn write_config(&mut self, _conf: Config) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn read_seed(&self) -> Result<[u8; 32]> {
|
||||
Ok([0; 32])
|
||||
}
|
||||
fn write_seed(&mut self, _s: [u8; 32]) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::conn::html;
|
||||
use crate::core::config::{decrypt_seed, ecdh_keypair, Config, ConfigDTO};
|
||||
use crate::core::config::{decrypt_seed, ecdh_keypair, ConfigDTO};
|
||||
use sphinx_key_signer::control::Config;
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
@@ -18,7 +19,9 @@ pub struct Params {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn config_server(mutex: Arc<(Mutex<Option<Config>>, Condvar)>) -> Result<idf::Server> {
|
||||
pub fn config_server(
|
||||
mutex: Arc<(Mutex<Option<(Config, [u8; 32])>>, Condvar)>,
|
||||
) -> Result<idf::Server> {
|
||||
let (sk1, pk1) = ecdh_keypair();
|
||||
|
||||
let server = idf::ServerRegistry::new()
|
||||
@@ -42,10 +45,10 @@ pub fn config_server(mutex: Arc<(Mutex<Option<Config>>, Condvar)>) -> Result<idf
|
||||
|
||||
let dto = serde_json::from_str::<ConfigDTO>(¶ms.config)?;
|
||||
|
||||
let conf = decrypt_seed(dto, sk1)?;
|
||||
let conf_seed_tuple = decrypt_seed(dto, sk1)?;
|
||||
|
||||
let mut wait = mutex.0.lock().unwrap();
|
||||
*wait = Some(conf);
|
||||
*wait = Some(conf_seed_tuple);
|
||||
mutex.1.notify_one();
|
||||
Ok("{\"success\":true}".to_owned().into())
|
||||
})?;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::core::config::Config;
|
||||
use sphinx_key_signer::control::Config;
|
||||
|
||||
use esp_idf_svc::netif::*;
|
||||
use esp_idf_svc::nvs::EspDefaultNvs;
|
||||
|
||||
@@ -15,14 +15,15 @@ use sphinx_crypter::ecdh::{derive_shared_secret_from_slice, PUBLIC_KEY_LEN};
|
||||
use sphinx_crypter::secp256k1::rand::thread_rng;
|
||||
use sphinx_crypter::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub broker: String,
|
||||
pub ssid: String,
|
||||
pub pass: String,
|
||||
pub seed: [u8; 32],
|
||||
pub network: String,
|
||||
}
|
||||
use sphinx_key_signer::control::Config;
|
||||
// #[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
// pub struct Config {
|
||||
// pub broker: String,
|
||||
// pub ssid: String,
|
||||
// pub pass: String,
|
||||
// pub seed: [u8; 32],
|
||||
// pub network: String,
|
||||
// }
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct ConfigDTO {
|
||||
pub broker: String,
|
||||
@@ -49,7 +50,7 @@ pub fn ecdh_keypair() -> (SecretKey, PublicKey) {
|
||||
s.generate_keypair(&mut thread_rng())
|
||||
}
|
||||
|
||||
pub fn decrypt_seed(dto: ConfigDTO, sk1: SecretKey) -> Result<Config> {
|
||||
pub fn decrypt_seed(dto: ConfigDTO, sk1: SecretKey) -> Result<(Config, [u8; 32])> {
|
||||
let their_pk = hex::decode(dto.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())?;
|
||||
@@ -58,18 +59,20 @@ pub fn decrypt_seed(dto: ConfigDTO, sk1: SecretKey) -> Result<Config> {
|
||||
let cipher: [u8; PAYLOAD_LEN] = cipher_seed[..PAYLOAD_LEN].try_into()?;
|
||||
let seed = decrypt(cipher, shared_secret)?;
|
||||
|
||||
Ok(Config {
|
||||
broker: dto.broker,
|
||||
ssid: dto.ssid,
|
||||
pass: dto.pass,
|
||||
network: dto.network,
|
||||
seed: seed,
|
||||
})
|
||||
Ok((
|
||||
Config {
|
||||
broker: dto.broker,
|
||||
ssid: dto.ssid,
|
||||
pass: dto.pass,
|
||||
network: dto.network,
|
||||
},
|
||||
seed,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn start_config_server_and_wait(
|
||||
default_nvs: Arc<EspDefaultNvs>,
|
||||
) -> Result<(Box<EspWifi>, Config)> {
|
||||
) -> Result<(Box<EspWifi>, Config, [u8; 32])> {
|
||||
let mutex = Arc::new((Mutex::new(None), Condvar::new()));
|
||||
|
||||
#[allow(clippy::redundant_clone)]
|
||||
@@ -80,7 +83,7 @@ pub fn start_config_server_and_wait(
|
||||
let mut wait = mutex.0.lock().unwrap();
|
||||
log::info!("Waiting for data from the phone!");
|
||||
|
||||
let config: &Config = loop {
|
||||
let config_seed_tuple: &(Config, [u8; 32]) = loop {
|
||||
if let Some(conf) = &*wait {
|
||||
break conf;
|
||||
} else {
|
||||
@@ -95,6 +98,10 @@ pub fn start_config_server_and_wait(
|
||||
drop(httpd);
|
||||
// drop(wifi);
|
||||
// thread::sleep(Duration::from_secs(1));
|
||||
println!("===> config! {:?}", config);
|
||||
Ok((wifi, config.clone()))
|
||||
println!("===> config! {:?}", config_seed_tuple.0);
|
||||
Ok((
|
||||
wifi,
|
||||
config_seed_tuple.0.clone(),
|
||||
config_seed_tuple.1.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use embedded_svc::storage::RawStorage;
|
||||
use embedded_svc::storage::StorageBase;
|
||||
use esp_idf_svc::nvs::EspDefaultNvs;
|
||||
use esp_idf_svc::nvs_storage::EspNvsStorage;
|
||||
use sphinx_key_signer::control::{ControlPersist, Controller};
|
||||
use sphinx_key_signer::control::{Config, ControlPersist, Controller, FlashKey};
|
||||
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
||||
use std::convert::TryInto;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
// the controller validates Control messages
|
||||
pub fn controller_from_seed(
|
||||
network: &Network,
|
||||
@@ -16,11 +19,47 @@ pub fn controller_from_seed(
|
||||
|
||||
pub struct FlashPersister(pub EspNvsStorage);
|
||||
|
||||
impl ControlPersist for FlashPersister {
|
||||
fn reset(&mut self) {
|
||||
self.0.remove("config").expect("couldnt remove config 1");
|
||||
}
|
||||
fn set_nonce(&mut self, nonce: u64) {
|
||||
// self.0.remove("config").expect("couldnt remove config 1");
|
||||
impl FlashPersister {
|
||||
pub fn new(nvs: Arc<EspDefaultNvs>) -> Self {
|
||||
let store = EspNvsStorage::new_default(nvs, "sphinx", true).expect("no storage");
|
||||
Self(store)
|
||||
}
|
||||
}
|
||||
|
||||
impl ControlPersist for FlashPersister {
|
||||
fn reset(&mut self) {
|
||||
self.0
|
||||
.remove(FlashKey::Config.as_str())
|
||||
.expect("couldnt remove config 1");
|
||||
}
|
||||
fn set_nonce(&mut self, nonce: u64) {
|
||||
// self.0.set
|
||||
//
|
||||
}
|
||||
fn read_config(&self) -> Result<Config> {
|
||||
let mut buf = [0u8; 250];
|
||||
let existing = self.0.get_raw(FlashKey::Config.as_str(), &mut buf)?;
|
||||
if let None = existing {
|
||||
return Err(anyhow!("no existing config"));
|
||||
}
|
||||
Ok(rmp_serde::from_slice(existing.unwrap().0)?)
|
||||
}
|
||||
fn write_config(&mut self, conf: Config) -> Result<()> {
|
||||
let conf1 = rmp_serde::to_vec(&conf)?;
|
||||
self.0.put_raw(FlashKey::Config.as_str(), &conf1[..])?;
|
||||
Ok(())
|
||||
}
|
||||
fn read_seed(&self) -> Result<[u8; 32]> {
|
||||
let mut buf = [0u8; 32];
|
||||
let s = self.0.get_raw(FlashKey::Seed.as_str(), &mut buf)?;
|
||||
if let None = s {
|
||||
return Err(anyhow!("no existing seed"));
|
||||
}
|
||||
let r: [u8; 32] = s.unwrap().0.try_into()?;
|
||||
Ok(r)
|
||||
}
|
||||
fn write_seed(&mut self, s: [u8; 32]) -> Result<()> {
|
||||
self.0.put_raw(FlashKey::Seed.as_str(), &s[..])?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
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 sphinx_key_signer::control::Config;
|
||||
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 sphinx_key_signer::{self, make_init_msg, InitResponse};
|
||||
use std::sync::{mpsc, Arc, Mutex};
|
||||
|
||||
use embedded_svc::httpd::Result;
|
||||
@@ -45,6 +44,7 @@ pub fn make_event_loop(
|
||||
do_log: bool,
|
||||
led_tx: mpsc::Sender<Status>,
|
||||
config: Config,
|
||||
seed: [u8; 32],
|
||||
flash: Arc<Mutex<FlashPersister>>,
|
||||
) -> Result<()> {
|
||||
while let Ok(event) = rx.recv() {
|
||||
@@ -65,14 +65,14 @@ pub fn make_event_loop(
|
||||
}
|
||||
|
||||
// initialize the RootHandler
|
||||
let init_msg = make_init_msg(network, config.seed).expect("failed to make init msg");
|
||||
let init_msg = make_init_msg(network, seed).expect("failed to make init msg");
|
||||
let InitResponse {
|
||||
root_handler,
|
||||
init_reply: _,
|
||||
} = sphinx_key_signer::init(init_msg, network).expect("failed to init signer");
|
||||
|
||||
// make the controller to validate Control messages
|
||||
let mut ctrlr = controller_from_seed(&network, &config.seed[..], flash);
|
||||
let mut ctrlr = controller_from_seed(&network, &seed[..], flash);
|
||||
|
||||
// signing loop
|
||||
let dummy_peer = PubKey([0; 33]);
|
||||
|
||||
@@ -16,11 +16,10 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use embedded_svc::storage::RawStorage;
|
||||
use esp_idf_hal::peripherals::Peripherals;
|
||||
use esp_idf_svc::nvs::*;
|
||||
use esp_idf_svc::nvs_storage::EspNvsStorage;
|
||||
|
||||
use sphinx_key_signer::control::{Config, ControlPersist};
|
||||
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
||||
|
||||
#[cfg(not(feature = "pingpong"))]
|
||||
@@ -54,18 +53,13 @@ fn main() -> Result<()> {
|
||||
println!("SD card mounted!");
|
||||
|
||||
let default_nvs = Arc::new(EspDefaultNvs::new()?);
|
||||
let mut store =
|
||||
EspNvsStorage::new_default(default_nvs.clone(), "sphinx", true).expect("no storage");
|
||||
let mut buf = [0u8; 250];
|
||||
// let existing: Option<Config> = store.get_raw("config", buf).expect("failed");
|
||||
let existing = store.get_raw("config", &mut buf).expect("failed");
|
||||
if let Some((exist_bytes, _)) = existing {
|
||||
let exist: Config = rmp_serde::from_slice(exist_bytes).expect("failed to parse Config");
|
||||
let mut flash = FlashPersister::new(default_nvs.clone());
|
||||
if let Ok(exist) = flash.read_config() {
|
||||
let seed = flash.read_seed().expect("no seed...");
|
||||
println!(
|
||||
"=============> START CLIENT NOW <============== {:?}",
|
||||
exist
|
||||
);
|
||||
// store.remove("config").expect("couldnt remove config");
|
||||
led_tx.send(Status::ConnectingToWifi).unwrap();
|
||||
let _wifi = loop {
|
||||
if let Ok(wifi) = start_wifi_client(default_nvs.clone(), &exist) {
|
||||
@@ -88,10 +82,12 @@ fn main() -> Result<()> {
|
||||
);
|
||||
|
||||
led_tx.send(Status::ConnectingToMqtt).unwrap();
|
||||
// _conn needs to stay in scope or its dropped
|
||||
let flash = Arc::new(Mutex::new(FlashPersister(store)));
|
||||
|
||||
let flash_arc = Arc::new(Mutex::new(flash));
|
||||
loop {
|
||||
if let Ok(()) = make_and_launch_client(exist.clone(), led_tx.clone(), flash.clone()) {
|
||||
if let Ok(()) =
|
||||
make_and_launch_client(exist.clone(), seed, led_tx.clone(), flash_arc.clone())
|
||||
{
|
||||
println!("Exited out of the event loop, trying again in 5 seconds...");
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
} else {
|
||||
@@ -102,11 +98,9 @@ fn main() -> Result<()> {
|
||||
} else {
|
||||
led_tx.send(Status::WifiAccessPoint).unwrap();
|
||||
println!("=============> START SERVER NOW AND WAIT <==============");
|
||||
if let Ok((_wifi, config)) = start_config_server_and_wait(default_nvs.clone()) {
|
||||
let conf = rmp_serde::to_vec(&config).expect("couldnt rmp Config");
|
||||
store
|
||||
.put_raw("config", &conf[..])
|
||||
.expect("could not store config");
|
||||
if let Ok((_wifi, config, seed)) = start_config_server_and_wait(default_nvs.clone()) {
|
||||
flash.write_config(config).expect("could not store config");
|
||||
flash.write_seed(seed).expect("could not store seed");
|
||||
println!("CONFIG SAVED");
|
||||
loop {}
|
||||
}
|
||||
@@ -117,6 +111,7 @@ fn main() -> Result<()> {
|
||||
|
||||
fn make_and_launch_client(
|
||||
config: Config,
|
||||
seed: [u8; 32],
|
||||
led_tx: mpsc::Sender<Status>,
|
||||
flash: Arc<Mutex<FlashPersister>>,
|
||||
) -> anyhow::Result<()> {
|
||||
@@ -137,6 +132,15 @@ fn make_and_launch_client(
|
||||
log::info!("Network set to {:?}", network);
|
||||
log::info!(">>>>>>>>>>> blocking forever...");
|
||||
log::info!("{:?}", config);
|
||||
make_event_loop(mqtt_client, rx, network, do_log, led_tx, config, flash)?;
|
||||
make_event_loop(
|
||||
mqtt_client,
|
||||
rx,
|
||||
network,
|
||||
do_log,
|
||||
led_tx,
|
||||
config,
|
||||
seed,
|
||||
flash,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user