From 98a1de91a2dae06323558422c239e5a45fc86e7b Mon Sep 17 00:00:00 2001 From: hozan23 Date: Tue, 28 Nov 2023 22:41:33 +0300 Subject: implement TLS for inbound and outbound connections --- core/src/key_pair.rs | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 core/src/key_pair.rs (limited to 'core/src/key_pair.rs') diff --git a/core/src/key_pair.rs b/core/src/key_pair.rs new file mode 100644 index 0000000..4016351 --- /dev/null +++ b/core/src/key_pair.rs @@ -0,0 +1,189 @@ +use ed25519_dalek::{Signer as _, Verifier as _}; +use rand::rngs::OsRng; + +use crate::{error::Error, Result}; + +/// key cryptography type +pub enum KeyPairType { + Ed25519, +} + +/// A Public key +pub struct PublicKey(PublicKeyInner); + +/// A Secret key +pub struct SecretKey(Vec); + +impl PublicKey { + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } + + /// Verify a signature on a message with this public key. + pub fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { + self.0.verify(msg, signature) + } +} + +impl PublicKey { + pub fn from_bytes(kp_type: &KeyPairType, pk: &[u8]) -> Result { + Ok(Self(PublicKeyInner::from_bytes(kp_type, pk)?)) + } +} + +/// A KeyPair. +#[derive(Clone)] +pub struct KeyPair(KeyPairInner); + +impl KeyPair { + /// Generate a new random keypair. + pub fn generate(kp_type: &KeyPairType) -> Self { + Self(KeyPairInner::generate(kp_type)) + } + + /// Sign a message using the private key. + pub fn sign(&self, msg: &[u8]) -> Vec { + self.0.sign(msg) + } + + /// Get the public key of this keypair. + pub fn public(&self) -> PublicKey { + self.0.public() + } + + /// Get the secret key of this keypair. + pub fn secret(&self) -> SecretKey { + self.0.secret() + } +} + +/// An extension trait, adding essential methods to all [`KeyPair`] types. +trait KeyPairExt { + /// Sign a message using the private key. + fn sign(&self, msg: &[u8]) -> Vec; + + /// Get the public key of this keypair. + fn public(&self) -> PublicKey; + + /// Get the secret key of this keypair. + fn secret(&self) -> SecretKey; +} + +#[derive(Clone)] +enum KeyPairInner { + Ed25519(Ed25519KeyPair), +} + +impl KeyPairInner { + fn generate(kp_type: &KeyPairType) -> Self { + match kp_type { + KeyPairType::Ed25519 => Self::Ed25519(Ed25519KeyPair::generate()), + } + } +} + +impl KeyPairExt for KeyPairInner { + fn sign(&self, msg: &[u8]) -> Vec { + match self { + KeyPairInner::Ed25519(kp) => kp.sign(msg), + } + } + + fn public(&self) -> PublicKey { + match self { + KeyPairInner::Ed25519(kp) => kp.public(), + } + } + + fn secret(&self) -> SecretKey { + match self { + KeyPairInner::Ed25519(kp) => kp.secret(), + } + } +} + +#[derive(Clone)] +struct Ed25519KeyPair(ed25519_dalek::SigningKey); + +impl Ed25519KeyPair { + fn generate() -> Self { + Self(ed25519_dalek::SigningKey::generate(&mut OsRng)) + } +} + +impl KeyPairExt for Ed25519KeyPair { + fn sign(&self, msg: &[u8]) -> Vec { + self.0.sign(msg).to_bytes().to_vec() + } + + fn public(&self) -> PublicKey { + PublicKey(PublicKeyInner::Ed25519(Ed25519PublicKey( + self.0.verifying_key(), + ))) + } + + fn secret(&self) -> SecretKey { + SecretKey(self.0.to_bytes().to_vec()) + } +} + +/// An extension trait, adding essential methods to all [`PublicKey`] types. +trait PublicKeyExt { + fn as_bytes(&self) -> &[u8]; + + /// Verify a signature on a message with this public key. + fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()>; +} + +enum PublicKeyInner { + Ed25519(Ed25519PublicKey), +} + +impl PublicKeyInner { + pub fn from_bytes(kp_type: &KeyPairType, pk: &[u8]) -> Result { + match kp_type { + KeyPairType::Ed25519 => Ok(Self::Ed25519(Ed25519PublicKey::from_bytes(pk)?)), + } + } +} + +impl PublicKeyExt for PublicKeyInner { + fn as_bytes(&self) -> &[u8] { + match self { + Self::Ed25519(pk) => pk.as_bytes(), + } + } + + fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { + match self { + Self::Ed25519(pk) => pk.verify(msg, signature), + } + } +} + +struct Ed25519PublicKey(ed25519_dalek::VerifyingKey); + +impl Ed25519PublicKey { + pub fn from_bytes(pk: &[u8]) -> Result { + let pk_bytes: [u8; 32] = pk + .try_into() + .map_err(|_| Error::TryInto("Failed to convert slice to [u8; 32]"))?; + + Ok(Self(ed25519_dalek::VerifyingKey::from_bytes(&pk_bytes)?)) + } +} + +impl PublicKeyExt for Ed25519PublicKey { + fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } + + fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { + let sig_bytes: [u8; 64] = signature + .try_into() + .map_err(|_| Error::TryInto("Failed to convert slice to [u8; 64]"))?; + self.0 + .verify(msg, &ed25519_dalek::Signature::from_bytes(&sig_bytes))?; + Ok(()) + } +} -- cgit v1.2.3