|
|
@@ -22,7 +22,7 @@ use std::{
|
|
|
time::UNIX_EPOCH,
|
|
|
};
|
|
|
|
|
|
-use crypto_box::{ChaChaBox, PublicKey};
|
|
|
+use crypto_box::PublicKey;
|
|
|
use darkfi::{Error::ParseFailed, Result};
|
|
|
use darkfi_sdk::{crypto::pasta_prelude::PrimeField, pasta::pallas};
|
|
|
use log::info;
|
|
|
@@ -64,39 +64,9 @@ pub fn parse_autojoin_channels(data: &toml::Value) -> Result<Vec<String>> {
|
|
|
Ok(ret)
|
|
|
}
|
|
|
|
|
|
-/// Parse a DM secret key from a TOML map.
|
|
|
-///
|
|
|
-/// ```toml
|
|
|
-/// [crypto]
|
|
|
-/// dm_chacha_secret = "7CkVuFgwTUpJn5Sv67Q3fyEDpa28yrSeL5Hg2GqQ4jfM"
|
|
|
-/// ```
|
|
|
-fn parse_dm_chacha_secret(data: &toml::Value) -> Result<Option<crypto_box::SecretKey>> {
|
|
|
- let Some(table) = data.as_table() else { return Err(ParseFailed("TOML not a map")) };
|
|
|
- let Some(crypto) = table.get("crypto") else { return Ok(None) };
|
|
|
- let Some(crypto) = crypto.as_table() else { return Err(ParseFailed("`crypto` not a map")) };
|
|
|
-
|
|
|
- if !crypto.contains_key("dm_chacha_secret") {
|
|
|
- return Ok(None)
|
|
|
- }
|
|
|
-
|
|
|
- let Some(secret_str) = crypto["dm_chacha_secret"].as_str() else {
|
|
|
- return Err(ParseFailed("dm_chacha_secret not a string"))
|
|
|
- };
|
|
|
-
|
|
|
- let Ok(secret_bytes) = bs58::decode(secret_str).into_vec() else {
|
|
|
- return Err(ParseFailed("dm_chacha_secret not valid base58"))
|
|
|
- };
|
|
|
-
|
|
|
- if secret_bytes.len() != 32 {
|
|
|
- return Err(ParseFailed("dm_chacha_secret not 32 bytes long"))
|
|
|
- }
|
|
|
-
|
|
|
- let secret_bytes: [u8; 32] = secret_bytes.try_into().unwrap();
|
|
|
-
|
|
|
- Ok(Some(crypto_box::SecretKey::from(secret_bytes)))
|
|
|
-}
|
|
|
-
|
|
|
-pub fn list_configured_contacts(data: &toml::Value) -> Result<HashMap<String, PublicKey>> {
|
|
|
+pub fn list_configured_contacts(
|
|
|
+ data: &toml::Value,
|
|
|
+) -> Result<HashMap<String, (PublicKey, crypto_box::SecretKey)>> {
|
|
|
let mut ret = HashMap::new();
|
|
|
|
|
|
let Some(table) = data.as_table() else { return Err(ParseFailed("TOML not a map")) };
|
|
|
@@ -107,11 +77,11 @@ pub fn list_configured_contacts(data: &toml::Value) -> Result<HashMap<String, Pu
|
|
|
|
|
|
for (name, items) in contacts {
|
|
|
let Some(public_str) = items.get("dm_chacha_public") else {
|
|
|
- return Err(ParseFailed("Invalid contact configuration"))
|
|
|
+ return Err(ParseFailed("Invalid contact configuration dm_chacha_public missing"))
|
|
|
};
|
|
|
|
|
|
let Some(public_str) = public_str.as_str() else {
|
|
|
- return Err(ParseFailed("Invalid contact configuration"))
|
|
|
+ return Err(ParseFailed("dm_chacha_public not a string"))
|
|
|
};
|
|
|
|
|
|
let Ok(public_bytes) = bs58::decode(public_str).into_vec() else {
|
|
|
@@ -130,7 +100,29 @@ pub fn list_configured_contacts(data: &toml::Value) -> Result<HashMap<String, Pu
|
|
|
return Err(ParseFailed("Duplicate contact found"))
|
|
|
}
|
|
|
|
|
|
- ret.insert(name.to_string(), public);
|
|
|
+ // parse the secret key for that specific contact
|
|
|
+ let Some(contact_secret) = items.get("dm_chacha_secret") else {
|
|
|
+ return Err(ParseFailed("Invalid contact configuration dm_chacha_secret missing. \
|
|
|
+ You can generate a keypair with: 'darkirc --gen-chacha-keypair' and then add that keypair to your config toml file."))
|
|
|
+ };
|
|
|
+
|
|
|
+ let Some(contact_secret_str) = contact_secret.as_str() else {
|
|
|
+ return Err(ParseFailed("dm_chacha_secret not a string"))
|
|
|
+ };
|
|
|
+
|
|
|
+ let Ok(contact_secret_bytes) = bs58::decode(contact_secret_str).into_vec() else {
|
|
|
+ return Err(ParseFailed("dm_chacha_secret not valid base58"))
|
|
|
+ };
|
|
|
+
|
|
|
+ if contact_secret_bytes.len() != 32 {
|
|
|
+ return Err(ParseFailed("dm_chacha_secret not 32 bytes long"))
|
|
|
+ }
|
|
|
+
|
|
|
+ let contact_secret_bytes: [u8; 32] = contact_secret_bytes.try_into().unwrap();
|
|
|
+
|
|
|
+ let contact_secret = crypto_box::SecretKey::from(contact_secret_bytes);
|
|
|
+
|
|
|
+ ret.insert(name.to_string(), (public, contact_secret));
|
|
|
}
|
|
|
|
|
|
Ok(ret)
|
|
|
@@ -144,30 +136,29 @@ pub fn list_configured_contacts(data: &toml::Value) -> Result<HashMap<String, Pu
|
|
|
/// dm_chacha_public = "7CkVuFgwTUpJn5Sv67Q3fyEDpa28yrSeL5Hg2GqQ4jfM"
|
|
|
/// ```
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
-pub fn parse_configured_contacts(
|
|
|
- data: &toml::Value,
|
|
|
-) -> Result<(HashMap<String, IrcContact>, Option<Arc<ChaChaBox>>)> {
|
|
|
+pub fn parse_configured_contacts(data: &toml::Value) -> Result<HashMap<String, IrcContact>> {
|
|
|
let mut ret = HashMap::new();
|
|
|
|
|
|
let contacts = list_configured_contacts(data)?;
|
|
|
if contacts.is_empty() {
|
|
|
- return Ok((ret, None));
|
|
|
+ return Ok(ret);
|
|
|
}
|
|
|
- let Some(secret) = parse_dm_chacha_secret(data)? else {
|
|
|
- return Err(ParseFailed("You have specified some contacts but you did not set up a valid chacha secret for yourself. You can generate a keypair with: 'darkirc --gen-chacha-keypair' and then add that keypair to your config toml file."))
|
|
|
- };
|
|
|
- for (name, public) in contacts {
|
|
|
- let saltbox = Some(Arc::new(crypto_box::ChaChaBox::new(&public, &secret)));
|
|
|
+
|
|
|
+ for (name, (public, contact_secret)) in contacts {
|
|
|
+ let saltbox: Arc<crypto_box::ChaChaBox> =
|
|
|
+ Arc::new(crypto_box::ChaChaBox::new(&public, &contact_secret));
|
|
|
+ let self_saltbox: Arc<crypto_box::ChaChaBox> =
|
|
|
+ Arc::new(crypto_box::ChaChaBox::new(&contact_secret.public_key(), &contact_secret));
|
|
|
|
|
|
if ret.contains_key(&name) {
|
|
|
return Err(ParseFailed("Duplicate contact found"))
|
|
|
}
|
|
|
|
|
|
info!("Instantiated ChaChaBox for contact \"{}\"", name);
|
|
|
- ret.insert(name.to_string(), IrcContact { saltbox });
|
|
|
+ ret.insert(name.to_string(), IrcContact { saltboxes: (saltbox, self_saltbox) });
|
|
|
}
|
|
|
|
|
|
- Ok((ret, Some(Arc::new(crypto_box::ChaChaBox::new(&secret.public_key(), &secret)))))
|
|
|
+ Ok(ret)
|
|
|
}
|
|
|
|
|
|
/// Parse configured RLN identity from a TOML map.
|