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}