karak_kms/keystore/
local.rs1use std::{
2 fs::File,
3 io::{Read, Write},
4 path::PathBuf,
5};
6
7use crate::keypair::traits::Encryptable;
8
9use super::traits::EncryptedKeystore;
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13pub enum LocalKeystoreError<Keypair: Encryptable + Send + Sync> {
14 #[error("Encryption error: {0}")]
15 EncryptionError(Keypair::EncryptionError),
16
17 #[error("IO error: {0}")]
18 IoError(#[from] std::io::Error),
19
20 #[error("Decoding error: {0}")]
21 DecodingError(#[from] bs58::decode::Error),
22}
23
24pub struct LocalEncryptedKeystore {
25 file_path: PathBuf,
26}
27
28impl LocalEncryptedKeystore {
29 pub fn new(file_path: PathBuf) -> Self {
30 Self { file_path }
31 }
32}
33
34impl<Keypair: Encryptable + Send + Sync + std::fmt::Debug> EncryptedKeystore<Keypair>
35 for LocalEncryptedKeystore
36{
37 type StorageError = LocalKeystoreError<Keypair>;
38
39 fn store(&self, keypair: &Keypair, passphrase: &str) -> Result<(), Self::StorageError> {
40 let encrypted_keypair = keypair
41 .encrypt(passphrase)
42 .map_err(|err| LocalKeystoreError::EncryptionError(err))?;
44
45 let mut file = File::create(&self.file_path)?;
46
47 file.write_all(bs58::encode(&encrypted_keypair).into_vec().as_slice())?;
48
49 Ok(())
50 }
51
52 fn retrieve(&self, passphrase: &str) -> Result<Keypair, Self::StorageError> {
53 let mut file = File::open(&self.file_path)?;
54 let mut buf = vec![];
55 file.read_to_end(&mut buf)?;
56
57 let encrypted_keypair = bs58::decode(buf).into_vec()?;
58
59 Keypair::decrypt(&encrypted_keypair, passphrase)
60 .map_err(|err| LocalKeystoreError::EncryptionError(err))
62 }
63}