aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWill Dillon <william@housedillon.com>2025-11-07 19:56:31 +0000
committerWill Dillon <william@housedillon.com>2025-11-07 19:56:31 +0000
commitc76a6ef610768d529ebb75b2af5d721d09797e06 (patch)
tree9f6e22e4ab5ce185c21fd8f1677c020a259f9c60 /src
parentDecryption is working! (diff)
downloadmeshcore-rs-c76a6ef610768d529ebb75b2af5d721d09797e06.tar.gz
meshcore-rs-c76a6ef610768d529ebb75b2af5d721d09797e06.zip
Switching to Mac
Diffstat (limited to 'src')
-rw-r--r--src/crypto.rs14
-rw-r--r--src/identity.rs80
2 files changed, 88 insertions, 6 deletions
diff --git a/src/crypto.rs b/src/crypto.rs
index 8215f94..d428c20 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -1,5 +1,6 @@
-use std::str::FromStr;
+use std::{fmt::{Debug, Display}, str::FromStr};
use ed25519_dalek::{VerifyingKey, hazmat::ExpandedSecretKey};
+use serde::Deserialize;
use tokio_util::bytes::{Buf, BufMut, Bytes, BytesMut};
use hex::{decode, decode_to_slice, encode};
@@ -23,6 +24,17 @@ pub enum MeshcoreCryptoError {
KeyCreationError,
}
+impl Display for MeshcoreCryptoError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ MeshcoreCryptoError::KeyLengthError => f.write_str("Key Length Error"),
+ MeshcoreCryptoError::TryFromSliceError => f.write_str("Try From Slice Error"),
+ MeshcoreCryptoError::HexDecodeError => f.write_str("Hex Decode Error"),
+ MeshcoreCryptoError::KeyCreationError => f.write_str("Key Creation Error"),
+ }
+ }
+}
+
#[derive(PartialEq)]
pub struct PrivateKey(ExpandedSecretKey);
diff --git a/src/identity.rs b/src/identity.rs
index ea88164..5737ec0 100644
--- a/src/identity.rs
+++ b/src/identity.rs
@@ -1,30 +1,100 @@
-use std::collections::{HashMap};
+use std::{collections::HashMap, str::FromStr};
+use serde::{Deserialize, de};
use x25519_dalek::PublicKey;
-use crate::crypto::{PrivateKey, SharedSecret};
+use crate::crypto::{MeshcoreCryptoError, PrivateKey, SharedSecret};
-#[derive(PartialEq, Debug, Clone)]
+#[derive(PartialEq, Debug, Clone, Deserialize)]
+/// The Identity structure contains the information to decrypt
+/// incoming messages and sign and encrypt outgoing messages.
+///
+/// It has the necessary cryptographic material needed to appear
+/// as this identity when creating messages.
pub struct Identity {
+ /// The display name if this user identity.
pub name: String,
- pub private_key: PrivateKey
+
+ /// The private key of this identity. There are currently
+ /// no ways in this library to generate a new private key
+ /// from scratch (while ensuing it's sound) so it must be
+ /// provided by the user.
+ #[serde(deserialize_with = "private_key")]
+ pub private_key: PrivateKey,
+
+ /// The derived public key given this identity's
+ /// private key. The hash prefix of this (typically 1-byte)
+ /// is used as a first-pass to identity the recipient.
+ #[serde(deserialize_with = "public_key")]
+ pub public_key: PublicKey,
+
+ /// The secrets has is a collection of shared secrets
+ /// indexed by the public key of the other side of the
+ /// connection. The whole remote public key must be
+ /// used because there are many many hash collisions
+ /// when using just the 1-byte hash prefix.
+ #[serde(skip)]
+ pub secrets: HashMap<String, SharedSecret>
}
#[derive(PartialEq, Debug, Clone)]
+
+/// The Contact structure contains the information needed
+/// to decrypt messages from a remote user intended for
+/// either an identity or a channel.
+///
+/// It's cryptographic material is also needed to uniquely
+/// identify the origin of a message. Most source values
+/// are only one byte, so that information just limits the
+/// number of entries in the contact list that must be searched
+/// before the correct contact is found.
pub struct Contact {
+ /// The display name of the contact
pub name: String,
+
+ /// The provided public key of the remote contact
pub public_key: PublicKey
}
#[derive(PartialEq, Debug, Clone)]
+/// A Group in MeshCore is a kind of contact, except that its
+/// secret is fixed and shared directly. It's not derived via
+/// a public and private key. Otherwise, it behaves more like a
+/// contact in the sense that it's full identity is discovered
+/// by whether its secret can correctly decrypt messages.
pub struct Group {
+ /// The display name of the group
pub name: String,
+
+ /// The group's shared secret
pub secret: SharedSecret
}
pub struct Keystore {
identities: HashMap<String, Identity>,
contacts: HashMap<String, Contact>,
- groups: HashMap<String, Group>
+ groups: HashMap<String, Group>,
+
+}
+
+impl Identity {
+ fn private_key<'de, D>(deserializer: D) -> Result<PrivateKey, D::Error>
+ where D: de::Deserializer<'de> {
+ let s: &str = de::Deserialize::deserialize(deserializer)?;
+ let key = PrivateKey::from_str(s).map_err(de::Error::custom)?
+ }
+}
+
+impl<'de> Deserialize<'de> for Contact {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where D: serde::Deserializer<'de> {
+ todo!()
+ }
}
+impl<'de> Deserialize<'de> for Group {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where D: serde::Deserializer<'de> {
+ todo!()
+ }
+} \ No newline at end of file