Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ledger integration into KMS #172

Merged
merged 12 commits into from Feb 20, 2019
@@ -41,7 +41,7 @@ jobs:
command: |
rustc --version
cargo --version
cargo test --all --all-features
cargo test --all --features "default softsign yubihsm yubihsm-mock"

This comment has been minimized.

Copy link
@Liamsi

Liamsi Feb 15, 2019

Member

Why is this change necessary?

This comment has been minimized.

Copy link
@adrianbrink

adrianbrink Feb 15, 2019

Author Contributor

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

- run:
name: audit
command: |
@@ -4,3 +4,5 @@ tmkms.toml

# Ignore VIM swap files
*.swp

\.idea/

Some generated files are not rendered by default. Learn more.

@@ -35,6 +35,7 @@ signal-hook = "0.1.7"
signatory = { version = "0.11", features = ["ed25519"] }
signatory-dalek = "0.11"
signatory-yubihsm = { version = "0.11", optional = true }
signatory-ledger-tm = { version = "0.11", optional = true }
subtle-encoding = "0.3"
tendermint = { version = "0.2", path = "tendermint-rs" }

@@ -43,10 +44,11 @@ tempfile = "3"
rand = "0.6"

[features]
default = ["softsign", "yubihsm"]
default = ["softsign"]
softsign = []
yubihsm = ["signatory-yubihsm/usb"] # USB only for now
yubihsm-mock = ["yubihsm", "signatory-yubihsm/mockhsm"]
ledgertm = ["signatory-ledger-tm"]

# Enable integer overflow checks in release builds for security reasons
[profile.release]
@@ -0,0 +1,16 @@
use abscissa::Callable;

/// The `ledgertm detect` subcommand
#[derive(Debug, Default, Options)]
pub struct DetectCommand {
/// Print debugging information
#[options(short = "v", long = "verbose")]
pub verbose: bool,
}

impl Callable for DetectCommand {
/// Detect all Ledger devices running the Tendermint app
fn call(&self) {
println!("This feature will be soon available");

This comment has been minimized.

Copy link
@Liamsi

Liamsi Feb 19, 2019

Member

Why include the detect command if it does not do anything yet?

}
}
@@ -0,0 +1,17 @@
use abscissa::{Callable, Command};

use super::LedgertmCommand;

/// The `ledgertm help` subcommand
#[derive(Debug, Default, Options)]
pub struct HelpCommand {
#[options(free)]
pub args: Vec<String>,
}

impl Callable for HelpCommand {
/// Print help for the `ledgertm` subcommand
fn call(&self) {
LedgertmCommand::print_usage(self.args.as_slice());
}
}
@@ -0,0 +1,32 @@
//! The KMS `ledgertm` subcommand

use abscissa::Callable;

mod detect;
mod help;

pub use self::{detect::DetectCommand, help::HelpCommand};

/// The `ledgertm` subcommand
#[derive(Debug, Options)]
pub enum LedgertmCommand {
#[options(help = "detect connected Ledger devices running the Tendermint app")]
Detect(DetectCommand),

#[options(help = "show help for the 'ledgertm' subcommand")]
Help(HelpCommand),
}

impl_command!(LedgertmCommand);

impl Callable for LedgertmCommand {
/// Call the given command chosen via the CLI
fn call(&self) {
match self {
LedgertmCommand::Detect(detect) => detect.call(),
LedgertmCommand::Help(help) => help.call(),
}
}
}

impl LedgertmCommand {}
@@ -11,9 +11,14 @@ mod start;
mod version;
#[cfg(feature = "yubihsm")]
mod yubihsm;

#[cfg(feature = "yubihsm")]
pub use self::yubihsm::YubihsmCommand;

#[cfg(feature = "ledgertm")]
mod ledgertm;
#[cfg(feature = "ledgertm")]
pub use self::ledgertm::LedgertmCommand;

pub use self::{
help::HelpCommand, keygen::KeygenCommand, start::StartCommand, version::VersionCommand,
};
@@ -37,6 +42,10 @@ pub enum KmsCommand {
#[cfg(feature = "yubihsm")]
#[options(help = "subcommands for YubiHSM2")]
Yubihsm(YubihsmCommand),

#[cfg(feature = "ledgertm")]
#[options(help = "subcommands for Ledger Tendermint app")]
Ledgertm(LedgertmCommand),
}

// TODO: refactor abscissa internally so this is all part of the proc macro
@@ -80,6 +89,8 @@ impl Callable for KmsCommand {
KmsCommand::Version(version) => version.call(),
#[cfg(feature = "yubihsm")]
KmsCommand::Yubihsm(yubihsm) => yubihsm.call(),
#[cfg(feature = "ledgertm")]
KmsCommand::Ledgertm(ledgertm) => ledgertm.call(),
}
}
}
@@ -0,0 +1,5 @@
//! Configuration for Ledger Tendermint signer

/// Ledger Tendermint signer configuration
#[derive(Clone, Deserialize, Debug)]
pub struct LedgerTendermintConfig {}
@@ -1,8 +1,12 @@
#[cfg(feature = "ledgertm")]
pub mod ledgertm;
#[cfg(feature = "softsign")]
pub mod softsign;
#[cfg(feature = "yubihsm")]
pub mod yubihsm;

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

/// Map of ledger-tm labels to their configurations
#[cfg(feature = "ledgertm")]
#[serde(default)]
pub ledgertm: Vec<LedgerTendermintConfig>,
}
@@ -0,0 +1,22 @@
//! Ledger Tendermint signer

use signatory::PublicKeyed;
use signatory_ledger_tm::{self, Ed25519LedgerTmAppSigner};

use crate::{
config::provider::ledgertm::LedgerTendermintConfig,
error::KmsError,
keyring::{ed25519::Signer, KeyRing},
};

pub const LEDGER_TM_PROVIDER_LABEL: &str = "ledgertm";
pub const LEDGER_TM_ID: &str = "ledgertm";

This comment has been minimized.

Copy link
@Liamsi

Liamsi Feb 19, 2019

Member

Shouldn't the ID come from the config? An ID that is always the same (and the same as the constant LEDGER_TM_PROVIDER_LABEL), feels wrong.


/// Create Ledger Tendermint signer object from the given configuration
pub fn init(keyring: &mut KeyRing, _config: &[LedgerTendermintConfig]) -> Result<(), KmsError> {
let provider = Box::new(Ed25519LedgerTmAppSigner::connect()?);
let pk = provider.public_key()?;
let signer = Signer::new(LEDGER_TM_PROVIDER_LABEL, LEDGER_TM_ID.to_string(), provider);
keyring.add(pk, signer)?;
Ok(())
}
@@ -1,5 +1,7 @@
pub use signatory::ed25519::{PublicKey, Seed, PUBLIC_KEY_SIZE};

#[cfg(feature = "ledgertm")]
pub mod ledgertm;
mod signer;
#[cfg(feature = "softsign")]
pub mod softsign;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.