1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
pub mod ed25519;
pub mod format;
pub mod providers;
use self::ed25519::Signer;
pub use self::{format::Format, providers::SigningProvider};
use crate::{
chain,
config::provider::ProviderConfig,
error::{Error, ErrorKind::*},
prelude::*,
};
use std::collections::BTreeMap;
use subtle_encoding;
use tendermint::TendermintKey;
pub type SecretKeyEncoding = subtle_encoding::Base64;
pub struct KeyRing {
keys: BTreeMap<TendermintKey, Signer>,
format: Format,
}
impl KeyRing {
pub fn new(format: Format) -> Self {
Self {
keys: BTreeMap::new(),
format,
}
}
pub fn add(&mut self, signer: Signer) -> Result<(), Error> {
let provider = signer.provider();
let public_key = signer.public_key();
let public_key_serialized = self.format.serialize(public_key);
let key_type = match public_key {
TendermintKey::AccountKey(_) => "account",
TendermintKey::ConsensusKey(_) => "consensus",
};
info!(
"[keyring:{}] added {} key {}",
provider, key_type, public_key_serialized
);
if let Some(other) = self.keys.insert(public_key, signer) {
fail!(
InvalidKey,
"[keyring:{}] duplicate key {} already registered as {}",
provider,
public_key_serialized,
other.provider(),
)
} else {
Ok(())
}
}
pub fn default_pubkey(&self) -> Result<TendermintKey, Error> {
let mut keys = self.keys.keys();
if keys.len() == 1 {
Ok(*keys.next().unwrap())
} else {
fail!(InvalidKey, "expected only one key in keyring");
}
}
pub fn sign_ed25519(
&self,
public_key: Option<&TendermintKey>,
msg: &[u8],
) -> Result<ed25519::Signature, Error> {
let signer = match public_key {
Some(public_key) => self.keys.get(public_key).ok_or_else(|| {
format_err!(InvalidKey, "not in keyring: {}", public_key.to_bech32(""))
})?,
None => {
let mut vals = self.keys.values();
if vals.len() > 1 {
fail!(SigningError, "expected only one key in keyring");
} else {
vals.next()
.ok_or_else(|| format_err!(InvalidKey, "keyring is empty"))?
}
}
};
signer.sign(msg)
}
}
pub fn load_config(registry: &mut chain::Registry, config: &ProviderConfig) -> Result<(), Error> {
#[cfg(feature = "softsign")]
ed25519::softsign::init(registry, &config.softsign)?;
#[cfg(feature = "yubihsm")]
ed25519::yubihsm::init(registry, &config.yubihsm)?;
#[cfg(feature = "ledgertm")]
ed25519::ledgertm::init(registry, &config.ledgertm)?;
Ok(())
}