1use std::path::Path;
2
3use anyhow::{anyhow, Result};
4use pkcs8::{
5 AlgorithmIdentifier, EncryptedPrivateKeyDocument, ObjectIdentifier,
6 PrivateKeyInfo,
7};
8use rand::{prelude::StdRng, rngs::OsRng, SeedableRng};
9use serde::{de::DeserializeOwned, Serialize};
10
11const OID: &str = "1.0.0";
12
13fn algorithm_identifier() -> AlgorithmIdentifier<'static> {
15 AlgorithmIdentifier {
16 oid: ObjectIdentifier::new(OID),
17 parameters: None,
18 }
19}
20
21pub fn save_pri_key<P: AsRef<Path>, K: Serialize>(
23 path: P, passwd: impl AsRef<[u8]>, pri_key: &K,
24) -> Result<()> {
25 let encoded_pri_keys = bcs::to_bytes(pri_key)?;
26 let pri_key_info =
27 PrivateKeyInfo::new(algorithm_identifier(), encoded_pri_keys.as_ref());
28 let encrypted =
29 pri_key_info.encrypt(StdRng::from_rng(OsRng).unwrap(), passwd)?;
30 encrypted.write_der_file(path)?;
31 Ok(())
32}
33
34pub fn load_pri_key<'de, P: AsRef<Path>, K: DeserializeOwned>(
36 path: P, passwd: impl AsRef<[u8]>,
37) -> Result<K> {
38 let encrypted = EncryptedPrivateKeyDocument::read_der_file(path)
39 .map_err(|e| anyhow!("read file with error {}", e))?;
40 let encoded_keys = encrypted
41 .decrypt(passwd)
42 .map_err(|e| anyhow!("decrypt with error {}", e))?;
43 Ok(bcs::from_bytes(
44 encoded_keys.private_key_info().private_key,
45 )?)
46}