Skip to content
This repository has been archived by the owner on Jun 3, 2020. It is now read-only.

Ledger integration into KMS #172

Merged
merged 12 commits into from Feb 20, 2019
2 changes: 1 addition & 1 deletion .circleci/config.yml
Expand Up @@ -41,7 +41,7 @@ jobs:
command: |
rustc --version
cargo --version
cargo test --all --all-features
cargo test --all --features "default softsign yubihsm yubihsm-mock"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test harness does not work with the Ledger since I haven't implemented a ledger-mock.

- run:
name: audit
command: |
Expand Down
113 changes: 100 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion Cargo.toml
Expand Up @@ -35,15 +35,23 @@ signal-hook = "0.1.7"
signatory = { version = "0.11", features = ["ed25519"] }
signatory-dalek = "0.11"
signatory-yubihsm = { version = "0.11", optional = true }
signatory-ledger-cosval = { version = "0.11", optional = true }
subtle-encoding = "0.3"
tendermint = { version = "0.2", path = "tendermint-rs" }

[patch.crates-io]
signatory = { git = "https://github.com/cryptiumlabs/signatory" }
signatory-dalek = { git = "https://github.com/cryptiumlabs/signatory" }
signatory-yubihsm = { git = "https://github.com/cryptiumlabs/signatory" }
signatory-ledger-cosval = { git = "https://github.com/cryptiumlabs/signatory" }
Copy link
Contributor

@liamsi liamsi Feb 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not introduce external versions/forks of these crates.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is waiting on the release of the correct upstream crates, specifically the new release of signatory-ledger-cosval.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


[dev-dependencies]
tempfile = "3"
rand = "0.6"

[features]
default = ["softsign", "yubihsm"]
default = ["softsign"]
ledger = ["signatory-ledger-cosval"]
softsign = []
yubihsm = ["signatory-yubihsm/usb"] # USB only for now
yubihsm-mock = ["yubihsm", "signatory-yubihsm/mockhsm"]
Expand Down
7 changes: 7 additions & 0 deletions src/config/provider/ledger.rs
@@ -0,0 +1,7 @@
//! Configuration for ledger-backed signer

/// Ledger signer configuration
#[derive(Clone, Deserialize, Debug)]
pub struct LedgerConfig {
pub active: bool,
}
8 changes: 8 additions & 0 deletions src/config/provider/mod.rs
@@ -1,8 +1,12 @@
#[cfg(feature = "ledger")]
pub mod ledger;
#[cfg(feature = "softsign")]
pub mod softsign;
#[cfg(feature = "yubihsm")]
pub mod yubihsm;

#[cfg(feature = "ledger")]
use self::ledger::LedgerConfig;
#[cfg(feature = "softsign")]
use self::softsign::SoftSignConfig;
#[cfg(feature = "yubihsm")]
Expand All @@ -20,4 +24,8 @@ pub struct ProviderConfig {
#[cfg(feature = "yubihsm")]
#[serde(default)]
pub yubihsm: Vec<YubihsmConfig>,

#[cfg(feature = "ledger")]
#[serde(default)]
pub ledger: Vec<LedgerConfig>,
}
32 changes: 32 additions & 0 deletions src/keyring/ed25519/ledger.rs
@@ -0,0 +1,32 @@
//! Ledger-based signer

use signatory::PublicKeyed;
use signatory_ledger_cosval::Ed25519CosmosAppSigner;

use crate::{
config::provider::ledger::LedgerConfig,
error::KmsError,
keyring::{ed25519::Signer, KeyRing},
};

/// Label for ed25519-dalek provider
// TODO: use a non-string type for these, e.g. an enum
pub const LEDGER_PROVIDER_LABEL: &str = "ledger";

// TODO: Maybe make this depend on the app. This may not matter since the Ledger doesn't hold multiple keys. Could work with HD deriv path.
pub const LEDGER_ID: &str = "1";

/// Create hardware-backed YubiHSM signer objects from the given configuration
adrianbrink marked this conversation as resolved.
Show resolved Hide resolved
pub fn init(keyring: &mut KeyRing, _ledger_configs: &[LedgerConfig]) -> Result<(), KmsError> {
// TODO: Maybe use the active field from the config.
let provider = Ed25519CosmosAppSigner::connect().unwrap();
keyring.add(
provider.public_key().unwrap(),
Signer::new(
LEDGER_PROVIDER_LABEL,
LEDGER_ID.to_owned(),
Box::new(provider),
),
)?;
Ok(())
}
2 changes: 2 additions & 0 deletions src/keyring/ed25519/mod.rs
@@ -1,5 +1,7 @@
pub use signatory::ed25519::{PublicKey, Seed, PUBLIC_KEY_SIZE};

#[cfg(feature = "ledger")]
pub mod ledger;
mod signer;
#[cfg(feature = "softsign")]
pub mod softsign;
Expand Down
6 changes: 6 additions & 0 deletions src/keyring/mod.rs
Expand Up @@ -12,6 +12,8 @@ use crate::{
error::{KmsError, KmsErrorKind::*},
};

#[cfg(feature = "ledger")]
use self::ed25519::ledger;
#[cfg(feature = "yubihsm")]
use self::ed25519::yubihsm;
use self::ed25519::{softsign, Signer};
Expand Down Expand Up @@ -42,6 +44,9 @@ impl KeyRing {
#[cfg(feature = "yubihsm")]
yubihsm::init(&mut keyring, &config.yubihsm)?;

#[cfg(feature = "ledger")]
ledger::init(&mut keyring, &config.ledger)?;

if keyring.0.is_empty() {
fail!(ConfigError, "no signing keys configured!")
} else {
Expand Down Expand Up @@ -106,6 +111,7 @@ impl KeyRing {
}
}
};
debug!("Successfully got signer and now trying to sign message");

signer.sign(msg)
}
Expand Down
15 changes: 15 additions & 0 deletions src/ledger.rs
@@ -0,0 +1,15 @@
use std::sync::Mutex;

use signatory_ledger_cosval::Ed25519CosmosAppSigner;

lazy_static! {
static ref HSM_CLIENT: Mutex<Ed25519CosmosAppSigner> = Mutex::new(create_hsm_client());
}

// pub fn get_hsm_client() -> MutexGuard<'static, Ed25519CosmosAppSigner> {
// HSM_CLIENT.lock().unwrap()
// }

fn create_hsm_client() -> Ed25519CosmosAppSigner {
Ed25519CosmosAppSigner::connect().unwrap()
}
4 changes: 4 additions & 0 deletions src/lib.rs
Expand Up @@ -29,6 +29,8 @@ extern crate sha2;
extern crate signal_hook;
extern crate signatory;
extern crate signatory_dalek;
#[cfg(feature = "ledger")]
extern crate signatory_ledger_cosval;
#[cfg(feature = "yubihsm")]
extern crate signatory_yubihsm;
extern crate subtle_encoding;
Expand All @@ -42,6 +44,8 @@ mod client;
mod commands;
mod config;
mod keyring;
#[cfg(feature = "ledger")]
mod ledger;
mod rpc;
mod session;
mod unix_connection;
Expand Down