diem_crypto/
key_file.rs

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
13// TODO(lpl): Store crypto parameters.
14fn algorithm_identifier() -> AlgorithmIdentifier<'static> {
15    AlgorithmIdentifier {
16        oid: ObjectIdentifier::new(OID),
17        parameters: None,
18    }
19}
20
21/// Encrypt `pri_key` with `passwd`, and save it to `path`.
22pub 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
34/// Load `passwd` encrypted private key from `path`.
35pub 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}