diff --git a/FORK.md b/FORK.md index 82d5c890..d0f1db37 100644 --- a/FORK.md +++ b/FORK.md @@ -192,7 +192,7 @@ Signing is unaffected either way. - `cargo fmt --all -- --check` — clean. - `cargo clippy --all-features --all-targets` — clean. -- `cargo test --all-features -- --test-threads 1` — 68 unit + 23 integration tests +- `cargo test --all-features -- --test-threads 1` — 68 unit + 24 integration tests pass (10 ignored, all hardware-dependent). - The published image is pulled and checked on every release: it reports its own version, keeps `tmkms` as the entrypoint, and links the USB libraries the diff --git a/src/commands/yubihsm/keys/import.rs b/src/commands/yubihsm/keys/import.rs index 00e96eea..6adf7976 100644 --- a/src/commands/yubihsm/keys/import.rs +++ b/src/commands/yubihsm/keys/import.rs @@ -172,9 +172,17 @@ impl ImportCommand { }) .priv_key; + // `PrivValidatorKey` also accepts secp256k1, so this is reachable with a + // legitimate key file let seed = match private_key { PrivateKey::Ed25519(pk) => pk, - _ => unreachable!(), + _ => { + status_err!( + "unsupported key type in `{}`: an Ed25519 consensus key is required", + self.path.display() + ); + process::exit(1); + } }; let label = object::Label::from(self.label.as_ref().map(|l| l.as_ref()).unwrap_or("")); diff --git a/tests/cli/yubihsm.rs b/tests/cli/yubihsm.rs index 3ea86847..9a459256 100644 --- a/tests/cli/yubihsm.rs +++ b/tests/cli/yubihsm.rs @@ -10,6 +10,9 @@ pub const KMS_GNO_PREFIX_CONFIG_PATH: &str = "tests/support/kms_yubihsm_mock_gno #[allow(dead_code)] pub const PRIV_VALIDATOR_CONFIG_PATH: &str = "tests/support/priv_validator_mock.json"; +/// A priv_validator key file holding a secp256k1 key rather than an Ed25519 one +pub const SECP256K1_PRIV_VALIDATOR_PATH: &str = "tests/support/priv_validator_secp256k1_mock.json"; + // This test requires USB access to a YubiHSM2 #[cfg(not(feature = "yubihsm-mock"))] mod detect; diff --git a/tests/cli/yubihsm/keys.rs b/tests/cli/yubihsm/keys.rs index a27e8821..21dc0d12 100644 --- a/tests/cli/yubihsm/keys.rs +++ b/tests/cli/yubihsm/keys.rs @@ -4,7 +4,7 @@ mod generate; mod import; mod list; -pub use super::{KMS_CONFIG_PATH, PRIV_VALIDATOR_CONFIG_PATH}; +pub use super::{KMS_CONFIG_PATH, PRIV_VALIDATOR_CONFIG_PATH, SECP256K1_PRIV_VALIDATOR_PATH}; use crate::cli; #[test] diff --git a/tests/cli/yubihsm/keys/import.rs b/tests/cli/yubihsm/keys/import.rs index 6e0a7272..848e6384 100644 --- a/tests/cli/yubihsm/keys/import.rs +++ b/tests/cli/yubihsm/keys/import.rs @@ -3,8 +3,8 @@ use crate::cli; use std::str; -#[test] -fn keys_import_priv_validator_test() { +/// Arguments to import the given priv_validator key file as key 0x0001 +fn import_json_args(path: &str) -> Vec<&str> { #[allow(unused_mut)] let mut args = vec!["yubihsm", "keys", "import"]; @@ -12,7 +12,13 @@ fn keys_import_priv_validator_test() { args.extend_from_slice(&["-c", super::KMS_CONFIG_PATH]); args.extend_from_slice(&["-t", "json"]); args.extend_from_slice(&["-i", "1"]); // key ID - args.extend_from_slice(&[super::PRIV_VALIDATOR_CONFIG_PATH]); + args.push(path); + args +} + +#[test] +fn keys_import_priv_validator_test() { + let args = import_json_args(super::PRIV_VALIDATOR_CONFIG_PATH); let out = cli::run_successfully(args.as_slice()); @@ -21,3 +27,24 @@ fn keys_import_priv_validator_test() { let message = str::from_utf8(&out.stderr).unwrap().trim().to_owned(); assert!(message.contains("key 0x0001")); } + +/// A priv_validator key file can hold a secp256k1 key, which cannot be imported as +/// an Ed25519 consensus key: that has to be an error the operator can act on, not +/// a panic +#[test] +fn keys_import_rejects_a_secp256k1_priv_validator() { + let args = import_json_args(super::SECP256K1_PRIV_VALIDATOR_PATH); + + let out = cli::run(args.as_slice()); + let message = str::from_utf8(&out.stderr).unwrap(); + + assert_eq!(out.status.code(), Some(1), "{message}"); + assert!( + message.contains("Ed25519 consensus key is required"), + "{message}" + ); + assert!( + message.contains(super::SECP256K1_PRIV_VALIDATOR_PATH), + "{message}" + ); +} diff --git a/tests/support/priv_validator_secp256k1_mock.json b/tests/support/priv_validator_secp256k1_mock.json new file mode 100644 index 00000000..2279a223 --- /dev/null +++ b/tests/support/priv_validator_secp256k1_mock.json @@ -0,0 +1,12 @@ +{ + "comment": "TEST KEY ONLY: DO **NOT** USE!! secp256k1, secret = 32 bytes of 0x01", + "address": "79B000887626B294A914501A4CD226B58B235983", + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AxuExVZ7EmRAmV0+1aq6BWXXHhg0YEgZ/5wX9enV3QeP" + }, + "priv_key": { + "type": "tendermint/PrivKeySecp256k1", + "value": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=" + } +}