diem_config/
keys.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8//! This file implements a KeyPair data structure.
9//!
10//! The point of a KeyPair is to deserialize a private key into a structure
11//! that will only allow the private key to be moved out once
12//! (hence providing good key hygiene)
13//! while allowing access to the public key part forever.
14//!
15//! The public key part is dynamically derived during deserialization,
16//! while ignored during serialization.
17
18use diem_crypto::PrivateKey;
19use serde::{de::DeserializeOwned, Deserialize, Serialize};
20
21/// ConfigKey places a clonable wrapper around PrivateKeys for config purposes
22/// only. The only time configs have keys is either for testing or for low
23/// security requirements. Diem recommends that keys be stored in key managers.
24/// If we make keys unclonable, then the configs must be mutable
25/// and that becomes a requirement strictly as a result of supporting test
26/// environments, which is undesirable. Hence this internal wrapper allows for
27/// keys to be clonable but only from configs.
28#[derive(Debug, Deserialize, Serialize)]
29pub struct ConfigKey<T: PrivateKey + Serialize> {
30    // Skip private key serde to avoid printing out private key accidentally
31    #[serde(skip_serializing, bound(deserialize = "T: Deserialize<'de>"))]
32    pub(crate) key: T,
33}
34
35impl<T: DeserializeOwned + PrivateKey + Serialize> ConfigKey<T> {
36    pub fn new(key: T) -> Self { Self { key } }
37
38    pub fn private_key(&self) -> T { self.clone().key }
39
40    pub fn public_key(&self) -> T::PublicKeyMaterial {
41        diem_crypto::PrivateKey::public_key(&self.key)
42    }
43}
44
45impl<T: DeserializeOwned + PrivateKey + Serialize> Clone for ConfigKey<T> {
46    fn clone(&self) -> Self {
47        Self::new(bcs::from_bytes(&bcs::to_bytes(&self.key).unwrap()).unwrap())
48    }
49}
50
51#[cfg(test)]
52impl<T: PrivateKey + Serialize + diem_crypto::Uniform> Default
53    for ConfigKey<T>
54{
55    fn default() -> Self {
56        Self {
57            key: diem_crypto::Uniform::generate_for_testing(),
58        }
59    }
60}
61
62impl<T: PrivateKey + Serialize> PartialEq for ConfigKey<T> {
63    fn eq(&self, other: &Self) -> bool {
64        bcs::to_bytes(&self).unwrap() == bcs::to_bytes(&other).unwrap()
65    }
66}