tpfs_krypt 7.1.8

An interface for accessing secrets
Documentation
use crate::{
    core::KeyPair,
    crypto::translator::KeyPairInstance,
    errors::{JsonError, Result},
    KeyType,
};
use secrecy::{ExposeSecret, Secret};
use snafu::ResultExt;
use zeroize::Zeroize;

/// By default all keypair files that are written without at explicit filename are prefixed with
/// this constant
pub const KEYPAIR_FILE_PREFIX: &str = "kp-";

#[derive(Deserialize, PartialEq, Serialize, Zeroize)]
pub(crate) struct PersistedKeyPair {
    public_key: String,
    private_key: String,
    key_type: KeyType,
}

pub(crate) fn serialize_keypair(key_pair: &KeyPairInstance) -> Result<Secret<String>> {
    let secret_private_key = key_pair.to_secret()?;
    let address = key_pair.identifier();

    let persisted = Secret::new(PersistedKeyPair {
        public_key: address.value.clone(),
        private_key: secret_private_key.expose_secret().to_string(),
        key_type: key_pair.get_key_type(),
    });

    let serialized = serde_json::to_value(persisted.expose_secret()).context(JsonError {
        message: format!("Cound not serialize keypair with address {}", address.value),
    })?;

    Ok(Secret::new(serialized.to_string()))
}

pub(crate) fn deserialize_keypair(serialized: Secret<String>) -> Result<KeyPairInstance> {
    let persisted: Secret<PersistedKeyPair> = Secret::new(
        serde_json::from_str(serialized.expose_secret()).context(JsonError {
            message: "Could not deserialize. Not printing keypair to avoid leaking secrets.",
        })?,
    );

    let private_key_secret = Secret::new(persisted.expose_secret().private_key.clone());
    let translator =
        KeyPairInstance::from_strings(private_key_secret, persisted.expose_secret().key_type)?;

    Ok(translator)
}