Skip to main content

ave_bridge/
utils.rs

1use ave_common::identity::KeyPair;
2use pkcs8::{Document, EncryptedPrivateKeyInfo, PrivateKeyInfo, pkcs5};
3
4use getrandom::fill;
5use std::fs;
6
7use crate::config::Config;
8use crate::error::BridgeError;
9
10const PBKDF2_ITERATIONS: u32 = 200_000;
11
12pub fn key_pair(
13    config: &Config,
14    password: &str,
15) -> Result<KeyPair, BridgeError> {
16    if fs::metadata(&config.keys_path).is_err() {
17        fs::create_dir_all(&config.keys_path)
18            .map_err(|e| BridgeError::KeyDirectoryCreation(e.to_string()))?;
19    }
20
21    let path = config.keys_path.join("node_private.der");
22    match fs::metadata(&path) {
23        Ok(_) => {
24            let document = Document::read_der_file(path)
25                .map_err(|e| BridgeError::KeyRead(e.to_string()))?;
26            let enc_pk = EncryptedPrivateKeyInfo::try_from(document.as_bytes())
27                .map_err(|e| BridgeError::KeyRead(e.to_string()))?;
28            let dec_pk = enc_pk
29                .decrypt(password)
30                .map_err(|e| BridgeError::KeyDecrypt(e.to_string()))?;
31
32            let key_pair = KeyPair::from_secret_der(dec_pk.as_bytes())
33                .map_err(|e| BridgeError::KeyRestore(e.to_string()))?;
34            Ok(key_pair)
35        }
36        Err(_) => {
37            let key_pair = config
38                .node
39                .keypair_algorithm
40                .generate_keypair()
41                .map_err(|e| BridgeError::KeyGeneration(e.to_string()))?;
42
43            let der = key_pair
44                .to_secret_der()
45                .map_err(|e| BridgeError::KeyGeneration(e.to_string()))?;
46            let pk = PrivateKeyInfo::try_from(der.as_slice())
47                .map_err(|e| BridgeError::KeyGeneration(e.to_string()))?;
48            let mut salt = [0u8; 32];
49            let mut iv = [0u8; 16];
50            fill(&mut salt)
51                .map_err(|e| BridgeError::KeyEncrypt(e.to_string()))?;
52            fill(&mut iv)
53                .map_err(|e| BridgeError::KeyEncrypt(e.to_string()))?;
54
55            let params = pkcs5::pbes2::Parameters::pbkdf2_sha256_aes256cbc(
56                PBKDF2_ITERATIONS,
57                &salt,
58                &iv,
59            )
60            .map_err(|e| BridgeError::KeyEncrypt(e.to_string()))?;
61            let enc_pk =
62                pk.encrypt_with_params(params, password).map_err(|_| {
63                    BridgeError::KeyEncrypt(
64                        "encryption algorithm failed".to_owned(),
65                    )
66                })?;
67            enc_pk
68                .write_der_file(path)
69                .map_err(|e| BridgeError::KeyWrite(e.to_string()))?;
70            Ok(key_pair)
71        }
72    }
73}