Skip to content

Commit

Permalink
Migrate to age encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
cypherkitty committed Dec 29, 2024
1 parent 1d7cfe2 commit 6719700
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 228 deletions.
2 changes: 1 addition & 1 deletion meta-secret/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ async-mutex = "1.4.0"

# Cryptography
ed25519-dalek = "2.1.1"
crypto_box = { version = "0.8.2", features = ["std"] }
rand = "0.8.5"
getrandom = { version = "0.2.15", features = ["js"] }
sha2 = { version = "0.10.8", features = ["oid"] }
base64 = "0.20.0"
hex = "0.4.3"
#https://github.com/dsprenkels/sss-rs
shamirsecretsharing = "0.1.5"
age = { version = "0.11.1", features = ["curve25519-dalek", "armor", "cli-common"] }

# Networking
axum = "0.7.9"
Expand Down
1 change: 0 additions & 1 deletion meta-secret/core-swift-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ serde_json.workspace = true
serde_derive.workspace = true

ed25519-dalek.workspace = true
crypto_box.workspace = true
base64.workspace = true
sha2.workspace = true
hex.workspace = true
2 changes: 1 addition & 1 deletion meta-secret/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ tracing-attributes = "0.1.27"


ed25519-dalek.workspace = true
crypto_box.workspace = true
rand.workspace = true
getrandom.workspace = true
sha2.workspace = true
base64.workspace = true
hex.workspace = true
#https://github.com/dsprenkels/sss-rs
shamirsecretsharing.workspace = true
age.workspace = true

serde_bytes = "0.11"
serde-big-array = "0.4"
Expand Down
51 changes: 13 additions & 38 deletions meta-secret/core/src/crypto/encoding.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crypto_box::KEY_SIZE as KEY_SIZE_32_BYTES;
const KEY_SIZE_32_BYTES: usize = 32;

pub type Array256Bit = [u8; KEY_SIZE_32_BYTES];
pub type Base64String = String;
Expand Down Expand Up @@ -217,13 +217,14 @@ pub mod serialized_key_manager {
use crate::crypto::encoding::base64::Base64Text;
use crate::crypto::encoding::Array256Bit;
use crate::crypto::key_pair::{
CryptoBoxSecretKey, DalekKeyPair, DalekPublicKey, DalekSignature, DsaKeyPair,
TransportDsaKeyPair,
DalekKeyPair, DalekPublicKey, DalekSignature, DsaKeyPair, TransportDsaKeyPair,
};
use crate::crypto::keys::{
KeyManager, SecretBox, SerializedDsaKeyPair, SerializedTransportKeyPair,
};
use crate::errors::CoreError;
use age::x25519::Identity;
use std::str::FromStr;

impl TryFrom<&SerializedDsaKeyPair> for DsaKeyPair {
type Error = CoreError;
Expand Down Expand Up @@ -261,11 +262,15 @@ pub mod serialized_key_manager {
fn try_from(
serialized_transport: &SerializedTransportKeyPair,
) -> Result<Self, Self::Error> {
let sk_bytes = Array256Bit::try_from(&serialized_transport.sk.0)?;
let secret_key = CryptoBoxSecretKey::from(sk_bytes);
let key_pair = Self { secret_key };

Ok(key_pair)
let sk_bytes = String::try_from(&serialized_transport.sk.0)?;
let sk_res = Identity::from_str(sk_bytes.as_str());

match sk_res {
Ok(secret_key) => Ok(Self { secret_key }),
Err(err_str) => Err(CoreError::InvalidSizeEncryptionError {
err_msg: err_str.to_string(),
}),
}
}
}

Expand Down Expand Up @@ -313,33 +318,3 @@ pub mod serialized_key_manager {
}
}
}

pub mod cryptobox {
pub mod decoder {
use crypto_box::Nonce;

use crate::crypto::encoding::base64::Base64Text;
use crate::crypto::encoding::Array256Bit;
use crate::crypto::key_pair::CryptoBoxSecretKey;
use crate::errors::CoreError;

impl TryFrom<&Base64Text> for CryptoBoxSecretKey {
type Error = CoreError;

fn try_from(encoded: &Base64Text) -> Result<Self, Self::Error> {
let byte_array = Array256Bit::try_from(encoded)?;
Ok(CryptoBoxSecretKey::from(byte_array))
}
}

impl TryFrom<&Base64Text> for Nonce {
type Error = CoreError;

fn try_from(encoded: &Base64Text) -> Result<Self, Self::Error> {
let vec = Vec::try_from(encoded)?;
let byte_array: [u8; 24] = vec.as_slice().try_into()?;
Ok(Nonce::from(byte_array))
}
}
}
}
37 changes: 18 additions & 19 deletions meta-secret/core/src/crypto/key_pair.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
use crypto_box::aead::OsRng as CryptoBoxOsRng;
use age::secrecy::ExposeSecret;
use age::x25519::Identity;
use ed25519_dalek::{SecretKey, Signer, SigningKey};
use rand::rngs::OsRng as RandOsRng;
use rand::RngCore;

use crate::crypto::encoding::base64::Base64Text;
use crate::crypto::keys::{DsaPk, DsaSk, TransportPk, TransportSk};
use crate::node::common::model::crypto::aead::{AeadAuthData, AeadCipherText, AeadPlainText};
use crate::node::common::model::crypto::aead::{AeadCipherText, AeadPlainText};
use crate::node::common::model::crypto::channel::CommunicationChannel;
use crate::secret::shared_secret::PlainText;
use crate::CoreResult;

pub type CryptoBoxPublicKey = crypto_box::PublicKey;
pub type CryptoBoxSecretKey = crypto_box::SecretKey;

pub type DalekKeyPair = SigningKey;
pub type DalekPublicKey = ed25519_dalek::VerifyingKey;
pub type DalekSecretKey = SecretKey;
Expand Down Expand Up @@ -71,28 +69,29 @@ impl KeyPair<DsaPk, DsaSk> for DsaKeyPair {
}

pub struct TransportDsaKeyPair {
pub secret_key: CryptoBoxSecretKey,
pub secret_key: Identity,
}

impl TransportDsaKeyPair {
pub fn sk(&self) -> TransportSk {
let raw_sk = Base64Text::from(self.secret_key.as_bytes());
let raw_sk = Base64Text::from(self.secret_key.to_string().expose_secret());
TransportSk(raw_sk)
}
}

impl KeyPair<TransportPk, TransportSk> for TransportDsaKeyPair {
fn generate() -> Self {
let secret_key = CryptoBoxSecretKey::generate(&mut CryptoBoxOsRng);
let secret_key = Identity::generate();
Self { secret_key }
}

fn pk(&self) -> TransportPk {
TransportPk::from(&self.secret_key.public_key())
let base64 = Base64Text::from(self.secret_key.to_public().to_string());
TransportPk::from(base64)
}

fn sk(&self) -> TransportSk {
let raw_sk = Base64Text::from(self.secret_key.as_bytes());
let raw_sk = Base64Text::from(self.secret_key.to_string().expose_secret());
TransportSk(raw_sk)
}
}
Expand All @@ -108,14 +107,14 @@ impl TransportDsaKeyPair {
plain_text: PlainText,
receiver_pk: &TransportPk,
) -> anyhow::Result<AeadCipherText> {
let channel = CommunicationChannel::build(self.pk(), receiver_pk.clone());
let channel = CommunicationChannel::end_to_end(self.pk(), receiver_pk.clone());

let plain_text = AeadPlainText {
msg: Base64Text::from(plain_text),
auth_data: AeadAuthData::from(channel),
channel,
};

plain_text.encrypt(&self.secret_key)
plain_text.encrypt()
}
}

Expand All @@ -124,7 +123,7 @@ pub mod test {
use crate::crypto::encoding::base64::Base64Text;
use crate::crypto::key_pair::KeyPair;
use crate::crypto::keys::KeyManager;
use crate::node::common::model::crypto::aead::{AeadAuthData, AeadCipherText, AeadPlainText};
use crate::node::common::model::crypto::aead::{AeadCipherText, AeadPlainText};
use crate::node::common::model::crypto::channel::CommunicationChannel;
use crate::secret::shared_secret::PlainText;

Expand All @@ -148,17 +147,17 @@ pub mod test {
let alice_km = KeyManager::generate();
let bob_km = KeyManager::generate();

let channel = CommunicationChannel::build(alice_km.transport.pk(), bob_km.transport.pk());
let channel =
CommunicationChannel::end_to_end(alice_km.transport.pk(), bob_km.transport.pk());

let plain_text = {
let auth_data = AeadAuthData::from(channel);
AeadPlainText {
msg: Base64Text::from("t0p$3cr3t"),
auth_data,
channel,
}
};

let cipher_text = plain_text.encrypt(&alice_km.transport.secret_key)?;
let cipher_text = plain_text.encrypt()?;

let decrypted_text = cipher_text.decrypt(&bob_km.transport.sk())?;
assert_eq!(plain_text, decrypted_text);
Expand All @@ -168,7 +167,7 @@ pub mod test {

let cipher_text = AeadCipherText {
msg: cipher_text.msg,
auth_data: cipher_text.auth_data.with_inverse_channel(),
channel: cipher_text.channel.inverse(),
};

let decrypted_text = cipher_text.decrypt(&bob_km.transport.sk())?;
Expand Down
46 changes: 26 additions & 20 deletions meta-secret/core/src/crypto/keys.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use crate::crypto::encoding::base64::Base64Text;
use crate::crypto::encoding::Array256Bit;
use crate::crypto::key_pair::{
CryptoBoxPublicKey, CryptoBoxSecretKey, DsaKeyPair, KeyPair, TransportDsaKeyPair,
};
use crate::crypto::key_pair::{DsaKeyPair, KeyPair, TransportDsaKeyPair};
use crate::crypto::utils::U64IdUrlEnc;
use crate::node::common::model::crypto::aead::{AeadPlainText, EncryptedMessage};
use crate::node::common::model::crypto::channel::{CommunicationChannel, LoopbackChannel};
use crate::node::common::model::device::common::DeviceId;
use crate::secret::shared_secret::PlainText;
use anyhow::Result;
use age::x25519::{Identity, Recipient};
use anyhow::{anyhow, bail, Result};
use std::str::FromStr;
use wasm_bindgen::prelude::wasm_bindgen;

pub struct KeyManager {
Expand All @@ -34,17 +33,12 @@ pub struct DsaPk(pub Base64Text);
#[wasm_bindgen(getter_with_clone)]
pub struct DsaSk(pub Base64Text);

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[wasm_bindgen(getter_with_clone)]
pub struct TransportPk(Base64Text);

impl TransportPk {
pub fn as_crypto_box_pk(&self) -> Result<CryptoBoxPublicKey> {
let byte_array = Array256Bit::try_from(&self.0)?;
Ok(CryptoBoxPublicKey::from(byte_array))
}

pub fn to_device_id(&self) -> DeviceId {
let pk_id = U64IdUrlEnc::from(self.0.base64_str());
DeviceId(pk_id)
Expand All @@ -53,12 +47,17 @@ impl TransportPk {
pub fn to_loopback_channel(self) -> LoopbackChannel {
CommunicationChannel::single_device(self)
}

pub fn as_recipient(&self) -> Result<Recipient> {
let pk_base64 = &self.0;
let pk_str = String::try_from(pk_base64)?;
Recipient::from_str(pk_str.as_str()).map_err(|err_str| anyhow!(err_str))
}
}

impl From<&CryptoBoxPublicKey> for TransportPk {
fn from(pk: &CryptoBoxPublicKey) -> Self {
let pk_url_enc = Base64Text::from(pk.as_bytes());
Self(pk_url_enc)
impl From<Base64Text> for TransportPk {
fn from(pk_b64: Base64Text) -> Self {
Self(pk_b64)
}
}

Expand All @@ -69,13 +68,20 @@ pub struct TransportSk(pub Base64Text);

impl TransportSk {
pub fn pk(&self) -> Result<TransportPk> {
let sk = self.as_crypto_box_sk()?;
Ok(TransportPk::from(&sk.public_key()))
let sk = self.as_age()?;
let pk = Base64Text::from(sk.to_public().to_string());
Ok(TransportPk::from(pk))
}

pub fn as_crypto_box_sk(&self) -> Result<CryptoBoxSecretKey> {
let sk = CryptoBoxSecretKey::try_from(&self.0)?;
Ok(sk)
pub fn as_age(&self) -> Result<Identity> {
let decoded_sk = String::try_from(&self.0)?;
let sk_result = Identity::from_str(decoded_sk.as_str());
match sk_result {
Ok(sk) => Ok(sk),
Err(err_str) => {
bail!(err_str)
}
}
}
}

Expand Down
7 changes: 2 additions & 5 deletions meta-secret/core/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ pub enum CoreError {
source: std::str::Utf8Error,
},

#[error(transparent)]
EncryptionError {
#[from]
source: crypto_box::aead::Error,
},
#[error("Invalid key size")]
InvalidSizeEncryptionError { err_msg: String },

#[error("The key manager: {key_manager_pk:?} is not a component of the secure communication channel: {channel:?}")]
ThirdPartyEncryptionError {
Expand Down
7 changes: 1 addition & 6 deletions meta-secret/core/src/node/app/virtual_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,7 @@ impl<Repo: KvLogEventRepo> VirtualDevice<Repo> {
let KvLogEvent { value: share, .. } = dist_event;

// re encrypt message?
let msg_receiver = share
.secret_message
.cipher_text()
.auth_data
.channel()
.receiver();
let msg_receiver = share.secret_message.cipher_text().channel.receiver();
let msg_receiver_device = msg_receiver.to_device_id();

let msg = if msg_receiver_device.eq(&claim.sender) {
Expand Down
Loading

0 comments on commit 6719700

Please sign in to comment.