diem_secure_storage/
crypto_kv_storage.rs1use crate::{CryptoStorage, Error, KVStorage, PublicKeyResponse};
9use diem_crypto::{hash::CryptoHash, PrivateKey, SigningKey, Uniform};
10use diem_types::validator_config::{
11 ConsensusPrivateKey, ConsensusPublicKey, ConsensusSignature,
12};
13use rand::{rngs::OsRng, Rng, SeedableRng};
14use serde::ser::Serialize;
15
16pub trait CryptoKVStorage: KVStorage {}
21
22impl<T: CryptoKVStorage> CryptoStorage for T {
23 fn create_key(&mut self, name: &str) -> Result<ConsensusPublicKey, Error> {
24 let (private_key, public_key) = new_key_pair::<ConsensusPrivateKey>();
26 self.import_private_key(name, private_key)?;
27 Ok(public_key)
28 }
29
30 fn export_private_key(
31 &self, name: &str,
32 ) -> Result<ConsensusPrivateKey, Error> {
33 self.get(name).map(|v| v.value)
34 }
35
36 fn export_private_key_for_version(
37 &self, name: &str, version: ConsensusPublicKey,
38 ) -> Result<ConsensusPrivateKey, Error> {
39 let current_private_key = self.export_private_key(name)?;
40 if current_private_key.public_key().eq(&version) {
41 return Ok(current_private_key);
42 }
43
44 match self.export_private_key(&get_previous_version_name(name)) {
45 Ok(previous_private_key) => {
46 if previous_private_key.public_key().eq(&version) {
47 Ok(previous_private_key)
48 } else {
49 Err(Error::KeyVersionNotFound(
50 name.into(),
51 version.to_string(),
52 ))
53 }
54 }
55 Err(Error::KeyNotSet(_)) => {
56 Err(Error::KeyVersionNotFound(name.into(), version.to_string()))
57 }
58 Err(e) => Err(e),
59 }
60 }
61
62 fn import_private_key(
63 &mut self, name: &str, key: ConsensusPrivateKey,
64 ) -> Result<(), Error> {
65 self.set(name, key)
66 }
67
68 fn get_public_key(&self, name: &str) -> Result<PublicKeyResponse, Error> {
69 let response = self.get(name)?;
70 let key: ConsensusPrivateKey = response.value;
71
72 Ok(PublicKeyResponse {
73 last_update: response.last_update,
74 public_key: key.public_key(),
75 })
76 }
77
78 fn get_public_key_previous_version(
79 &self, name: &str,
80 ) -> Result<ConsensusPublicKey, Error> {
81 match self.export_private_key(&get_previous_version_name(name)) {
82 Ok(previous_private_key) => Ok(previous_private_key.public_key()),
83 Err(Error::KeyNotSet(_)) => Err(Error::KeyVersionNotFound(
84 name.into(),
85 "previous version".into(),
86 )),
87 Err(e) => Err(e),
88 }
89 }
90
91 fn rotate_key(&mut self, name: &str) -> Result<ConsensusPublicKey, Error> {
92 let private_key: ConsensusPrivateKey = self.get(name)?.value;
93 let (new_private_key, new_public_key) =
94 new_key_pair::<ConsensusPrivateKey>();
95 self.set(&get_previous_version_name(name), private_key)?;
96 self.set(name, new_private_key)?;
97 Ok(new_public_key)
98 }
99
100 fn sign<U: CryptoHash + Serialize>(
101 &self, name: &str, message: &U,
102 ) -> Result<ConsensusSignature, Error> {
103 let private_key = self.export_private_key(name)?;
104 Ok(private_key.sign(message))
105 }
106
107 fn sign_using_version<U: CryptoHash + Serialize>(
108 &self, name: &str, version: ConsensusPublicKey, message: &U,
109 ) -> Result<ConsensusSignature, Error> {
110 let private_key = self.export_private_key_for_version(name, version)?;
111 Ok(private_key.sign(message))
112 }
113}
114
115fn new_key_pair<SK: SigningKey + Uniform>() -> (SK, SK::PublicKeyMaterial) {
116 let mut seed_rng = OsRng;
117 let mut rng = rand::rngs::StdRng::from_seed(seed_rng.gen());
118 let private_key = SK::generate(&mut rng);
119 let public_key = private_key.public_key();
120 (private_key, public_key)
121}
122
123fn get_previous_version_name(name: &str) -> String {
126 format!("{}_previous", name)
127}