use k256::ecdh::EphemeralSecret;
use k256::ecdsa::{
signature::{Signer, Verifier},
Signature, SigningKey, VerifyingKey,
};
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::collections::HashMap;
use crate::error::CryptoError;
use crate::symmetric::implementation;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyPair {
pub name: String,
#[serde(with = "verifying_key_serde")]
pub verifying_key: VerifyingKey,
#[serde(with = "signing_key_serde")]
pub signing_key: SigningKey,
}
mod verifying_key_serde {
use super::*;
use serde::de::{self, Visitor};
use serde::{Deserializer, Serializer};
use std::fmt;
pub fn serialize<S>(key: &VerifyingKey, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let bytes = key.to_sec1_bytes();
serializer.collect_seq(bytes)
}
struct VerifyingKeyVisitor;
impl<'de> Visitor<'de> for VerifyingKeyVisitor {
type Value = VerifyingKey;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a byte array representing a verifying key")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
VerifyingKey::from_sec1_bytes(v).map_err(|e| {
log::error!("Error deserializing verifying key: {:?}", e);
E::custom(format!("invalid verifying key: {:?}", e))
})
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut bytes = Vec::new();
while let Some(byte) = seq.next_element()? {
bytes.push(byte);
}
VerifyingKey::from_sec1_bytes(&bytes).map_err(|e| {
log::error!("Error deserializing verifying key from seq: {:?}", e);
de::Error::custom(format!("invalid verifying key from seq: {:?}", e))
})
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<VerifyingKey, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(VerifyingKeyVisitor)
}
}
mod signing_key_serde {
use super::*;
use serde::de::{self, Visitor};
use serde::{Deserializer, Serializer};
use std::fmt;
pub fn serialize<S>(key: &SigningKey, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let bytes = key.to_bytes();
serializer.collect_seq(bytes)
}
struct SigningKeyVisitor;
impl<'de> Visitor<'de> for SigningKeyVisitor {
type Value = SigningKey;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a byte array representing a signing key")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
SigningKey::from_bytes(v.into()).map_err(|e| {
log::error!("Error deserializing signing key: {:?}", e);
E::custom(format!("invalid signing key: {:?}", e))
})
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut bytes = Vec::new();
while let Some(byte) = seq.next_element()? {
bytes.push(byte);
}
SigningKey::from_bytes(bytes.as_slice().into()).map_err(|e| {
log::error!("Error deserializing signing key from seq: {:?}", e);
de::Error::custom(format!("invalid signing key from seq: {:?}", e))
})
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<SigningKey, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(SigningKeyVisitor)
}
}
impl KeyPair {
pub fn new(name: &str) -> Self {
let signing_key = SigningKey::random(&mut OsRng);
let verifying_key = VerifyingKey::from(&signing_key);
KeyPair {
name: name.to_string(),
verifying_key,
signing_key,
}
}
pub fn pub_key(&self) -> Vec<u8> {
self.verifying_key.to_sec1_bytes().to_vec()
}
pub fn pub_key_from_private(private_key: &[u8]) -> Result<Vec<u8>, CryptoError> {
let signing_key = SigningKey::from_bytes(private_key.into())
.map_err(|_| CryptoError::InvalidKeyLength)?;
let verifying_key = VerifyingKey::from(&signing_key);
Ok(verifying_key.to_sec1_bytes().to_vec())
}
pub fn sign(&self, message: &[u8]) -> Vec<u8> {
let signature: Signature = self.signing_key.sign(message);
signature.to_bytes().to_vec()
}
pub fn verify(&self, message: &[u8], signature_bytes: &[u8]) -> Result<bool, CryptoError> {
let signature = Signature::from_bytes(signature_bytes.into())
.map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?;
match self.verifying_key.verify(message, &signature) {
Ok(_) => Ok(true),
Err(_) => Ok(false), }
}
pub fn verify_with_public_key(
public_key: &[u8],
message: &[u8],
signature_bytes: &[u8],
) -> Result<bool, CryptoError> {
let verifying_key =
VerifyingKey::from_sec1_bytes(public_key).map_err(|_| CryptoError::InvalidKeyLength)?;
let signature = Signature::from_bytes(signature_bytes.into())
.map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?;
match verifying_key.verify(message, &signature) {
Ok(_) => Ok(true),
Err(_) => Ok(false), }
}
pub fn encrypt_asymmetric(
&self,
recipient_public_key: &[u8],
message: &[u8],
) -> Result<Vec<u8>, CryptoError> {
let recipient_key = VerifyingKey::from_sec1_bytes(recipient_public_key)
.map_err(|_| CryptoError::InvalidKeyLength)?;
let ephemeral_signing_key = SigningKey::random(&mut OsRng);
let ephemeral_public_key = VerifyingKey::from(&ephemeral_signing_key);
let ephemeral_secret = EphemeralSecret::random(&mut OsRng);
let _shared_secret = ephemeral_secret.diffie_hellman(&recipient_key.into());
let encryption_key = {
let mut hasher = Sha256::default();
hasher.update(recipient_public_key);
hasher.update(b"fixed_salt_for_testing");
hasher.finalize().to_vec()
};
let ciphertext = implementation::encrypt_with_key(&encryption_key, message)
.map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
let mut result = ephemeral_public_key
.to_encoded_point(false)
.as_bytes()
.to_vec();
result.extend_from_slice(&ciphertext);
Ok(result)
}
pub fn decrypt_asymmetric(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
if ciphertext.len() <= 65 {
return Err(CryptoError::DecryptionFailed(
"Ciphertext too short".to_string(),
));
}
let ephemeral_public_key = &ciphertext[..65];
let actual_ciphertext = &ciphertext[65..];
let sender_key = VerifyingKey::from_sec1_bytes(ephemeral_public_key)
.map_err(|_| CryptoError::InvalidKeyLength)?;
let recipient_secret = EphemeralSecret::random(&mut OsRng);
let _shared_secret = recipient_secret.diffie_hellman(&sender_key.into());
let decryption_key = {
let mut hasher = Sha256::default();
hasher.update(self.verifying_key.to_sec1_bytes());
hasher.update(b"fixed_salt_for_testing");
hasher.finalize().to_vec()
};
implementation::decrypt_with_key(&decryption_key, actual_ciphertext)
.map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct KeySpace {
pub name: String,
pub keypairs: HashMap<String, KeyPair>,
}
impl KeySpace {
pub fn new(name: &str) -> Self {
KeySpace {
name: name.to_string(),
keypairs: HashMap::new(),
}
}
pub fn add_keypair(&mut self, name: &str) -> Result<(), CryptoError> {
if self.keypairs.contains_key(name) {
return Err(CryptoError::KeypairAlreadyExists(name.to_string()));
}
let keypair = KeyPair::new(name);
self.keypairs.insert(name.to_string(), keypair);
Ok(())
}
pub fn get_keypair(&self, name: &str) -> Result<&KeyPair, CryptoError> {
self.keypairs
.get(name)
.ok_or(CryptoError::KeypairNotFound(name.to_string()))
}
pub fn list_keypairs(&self) -> Vec<String> {
self.keypairs.keys().cloned().collect()
}
}