tpfs_krypt 7.1.8

An interface for accessing secrets
Documentation
use crate::crypto::KeyPairValue;
use crate::{
    crypto::translator::KeyPairInstance,
    errors::{KeyManagementError, Result},
    DecryptionStrategy, EncryptedMessage, KeyIdentifier, KeyManagement, KeyType, NewKeyId,
    SharedEncryption, Signature, Signing,
};
use secrecy::Secret;

/// This defines what we expect a KeyPair to be defined with in order to make a simple interface
/// for KeyManagers. This interface can be worked with in trait objects since the lengths of the
/// bytes aren't enforced. See crypto/translator for performing translations to the raw types that a
/// RawKeyPair expects to work with.
pub trait KeyPair {
    /// Returns the key identifier
    fn identifier(&self) -> KeyIdentifier;
    /// Extracts the secret portion of the key
    fn to_secret(&self) -> Result<Secret<String>>;
    /// Returns the pubkey bytes of the key
    fn public(&self) -> Vec<u8>;
    /// Returns the type of key this is
    fn get_key_type(&self) -> KeyType;
}

pub(crate) trait SharedEncryptor {
    /// Creates a shared key using this key pair, the public key passed in, and some public
    /// information that must be the same when decrypting.
    ///
    /// Then uses that shared key to encrypt the message.
    fn shared_encrypt(
        &self,
        other_public_key: &[u8],
        message: &[u8],
        public_input: &[u8],
    ) -> Result<EncryptedMessage>;

    /// Creates a shared key using this key pair, the public key passed in, and some public
    /// information that must be the same when encrypting.
    ///
    /// Then uses that shared key to decrypt the cipher.
    fn shared_decrypt(&self, decryption_strategy: DecryptionStrategy) -> Result<Secret<Vec<u8>>>;
}

/// Implementors are capable of signing a message
pub trait Signer {
    /// Given bytes to sign, return the signature
    fn sign(&self, message: &[u8]) -> Result<Box<dyn Signature>>;
}

pub trait KeyStorage: Send + Sync {
    fn store_has_key(&self, id: &KeyIdentifier) -> Result<bool>;
    fn get_key(&self, id: &KeyIdentifier) -> Result<KeyPairInstance>;
    fn get_keys(&self) -> Result<Vec<KeyIdentifier>>;
    fn save_key(&mut self, key_pair: &KeyPairInstance) -> Result<NewKeyId>;
}

impl<T: KeyStorage> SharedEncryption for T {
    fn shared_encrypt(
        &self,
        your_key_id: &KeyIdentifier,
        other_pubkey: &[u8],
        message: &[u8],
        ephemeral_key_input: &[u8],
    ) -> Result<EncryptedMessage> {
        let key_pair = self.get_key(your_key_id)?;
        key_pair.shared_encrypt(other_pubkey, message, ephemeral_key_input)
    }

    fn shared_decrypt(
        &self,
        your_key_id: &KeyIdentifier,
        decryption_strategy: DecryptionStrategy,
    ) -> Result<Secret<Vec<u8>>> {
        let key_pair = self.get_key(your_key_id)?;
        key_pair.shared_decrypt(decryption_strategy)
    }
}

impl<T: KeyStorage> Signing for T {
    fn sign(&self, address: &KeyIdentifier, message: &[u8]) -> Result<Box<dyn Signature>> {
        if !self.store_has_key(address)? {
            return Err(KeyManagementError::AddressNotFound {
                address: address.value.clone(),
            });
        }

        let key_pair = self.get_key(address)?;

        key_pair.sign(message)
    }
}

impl<T: KeyStorage> KeyManagement for T {
    fn get_key_ids(&self) -> Result<Vec<KeyIdentifier>> {
        self.get_keys()
    }

    fn has_key(&self, address: &KeyIdentifier) -> Result<bool> {
        self.store_has_key(address)
    }

    fn generate_keypair(&mut self, key_type: KeyType) -> Result<NewKeyId> {
        let key_pair = KeyPairInstance::generate(key_type)?;

        self.save_key(&key_pair)
    }

    fn import_keypair(&mut self, secret: Secret<String>, key_type: KeyType) -> Result<NewKeyId> {
        let key_pair = KeyPairInstance::from_secret(secret, key_type)?;

        self.save_key(&key_pair)
    }

    fn get_keypair_by_id(
        &self,
        key_id: &KeyIdentifier,
    ) -> Result<KeyPairValue, KeyManagementError> {
        self.get_key(key_id).map(|key| key.0)
    }
}