diff --git a/src/commands/hashicorp/pubkey.rs b/src/commands/hashicorp/pubkey.rs index c2a581c5..6dcd8ecd 100644 --- a/src/commands/hashicorp/pubkey.rs +++ b/src/commands/hashicorp/pubkey.rs @@ -58,6 +58,7 @@ impl Runnable for PubkeyCommand { &cfg.adapter.vault_addr, &signing_key.auth.access_token(), &self.key_name, + cfg.adapter.endpoints, cfg.adapter.vault_cacert, cfg.adapter.vault_skip_verify, cfg.adapter.cache_pk, diff --git a/src/commands/hashicorp/test.rs b/src/commands/hashicorp/test.rs index c007a8d4..020a2a62 100644 --- a/src/commands/hashicorp/test.rs +++ b/src/commands/hashicorp/test.rs @@ -63,6 +63,7 @@ impl Runnable for TestCommand { &cfg.adapter.vault_addr, &signing_key.auth.access_token(), &self.key_name, + cfg.adapter.endpoints, cfg.adapter.vault_cacert, cfg.adapter.vault_skip_verify, cfg.adapter.cache_pk, diff --git a/src/commands/hashicorp/upload.rs b/src/commands/hashicorp/upload.rs index 040d0ab1..ee6b19e2 100644 --- a/src/commands/hashicorp/upload.rs +++ b/src/commands/hashicorp/upload.rs @@ -110,6 +110,7 @@ impl UploadCommand { .auth .access_token(), &self.key_name, + config.adapter.endpoints.to_owned(), config.adapter.vault_cacert.to_owned(), config.adapter.vault_skip_verify.to_owned(), config.adapter.cache_pk, @@ -284,6 +285,7 @@ mod tests { vault_cacert: None, vault_skip_verify: Some(false), cache_pk: Some(false), + endpoints: None, }, keys: [SigningKeyConfig { chain_id: tendermint::chain::Id::try_from(CHAIN_ID).unwrap(), diff --git a/src/commands/hashicorp/util.rs b/src/commands/hashicorp/util.rs index c0a426be..5955879c 100644 --- a/src/commands/hashicorp/util.rs +++ b/src/commands/hashicorp/util.rs @@ -52,6 +52,7 @@ pub fn read_config(config_path: &Option, key_name: &str) -> HashiCorpCo vault_cacert, vault_skip_verify, cache_pk: Some(false), + endpoints: None, }, } } diff --git a/src/config/provider/hashicorp.rs b/src/config/provider/hashicorp.rs index 552051ae..25f6fa29 100644 --- a/src/config/provider/hashicorp.rs +++ b/src/config/provider/hashicorp.rs @@ -45,7 +45,35 @@ impl AuthConfig { } } -/// Configuration for an individual YubiHSM +/// Endpoints configuration for Hashicorp Vault instance +#[derive(Clone, Deserialize, Debug)] +#[serde(deny_unknown_fields)] +pub struct VaultEndpointConfig { + /// HashiCorp Vault API endpoint path to retrieve public keys etc. + pub keys: String, + + /// HashiCorp Vault API endpoint path to perform a handshake + pub hand_shake: String, + + /// HashiCorp Vault API endpoint path to recieve a wrapping key + pub wrapping_key: String, + + /// HashiCorp Vault API endpoint path to sign a message (e.g. prevote) + pub sign: String, +} + +impl Default for VaultEndpointConfig { + fn default() -> Self { + VaultEndpointConfig { + keys: "/v1/transit/keys".into(), + hand_shake: "/v1/auth/token/lookup-self".into(), + wrapping_key: "/v1/transit/wrapping_key".into(), + sign: "/v1/transit/sign".into(), + } + } +} + +/// Configuration for Hashicorp Vault instance #[derive(Clone, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct AdapterConfig { @@ -60,6 +88,9 @@ pub struct AdapterConfig { /// Enable tmkms in-memory public key caching. Vault API returns all key versions which may be expensive, in such case you can cache the public key and return it from tmkms cache pub cache_pk: Option, + + /// Endpoints configuration for Vault core operations + pub endpoints: Option, } /// Signing key configuration diff --git a/src/keyring/providers/hashicorp.rs b/src/keyring/providers/hashicorp.rs index 5ad57595..9bfcc54d 100644 --- a/src/keyring/providers/hashicorp.rs +++ b/src/keyring/providers/hashicorp.rs @@ -57,6 +57,7 @@ pub fn init( &config.adapter.vault_addr, &key_config.auth.access_token(), &key_config.key, + config.adapter.endpoints.to_owned(), config.adapter.vault_cacert.to_owned(), config.adapter.vault_skip_verify.to_owned(), config.adapter.cache_pk, diff --git a/src/keyring/providers/hashicorp/client.rs b/src/keyring/providers/hashicorp/client.rs index 51094637..235a1ca2 100644 --- a/src/keyring/providers/hashicorp/client.rs +++ b/src/keyring/providers/hashicorp/client.rs @@ -1,6 +1,7 @@ use super::error::Error; use crate::keyring::ed25519; use crate::keyring::providers::hashicorp::vault_client::{CreateKeyType, VaultClient}; +use crate::config::provider::hashicorp::VaultEndpointConfig; use abscissa_core::prelude::*; pub(crate) struct TendermintValidatorApp { @@ -20,11 +21,12 @@ impl TendermintValidatorApp { api_endpoint: &str, token: &str, key_name: &str, + endpoints: Option, ca_cert: Option, skip_verify: Option, enable_pk_cache: Option, ) -> Result { - let vault_client = VaultClient::new(api_endpoint, token, ca_cert, skip_verify); + let vault_client = VaultClient::new(api_endpoint, token, endpoints, ca_cert, skip_verify); let app = TendermintValidatorApp { vault_client, @@ -119,6 +121,7 @@ mod tests { TEST_KEY_NAME, None, None, + None, Some(false), ); @@ -141,6 +144,7 @@ mod tests { TEST_KEY_NAME, None, None, + None, Some(true), ) .expect("Failed to connect"); @@ -190,6 +194,7 @@ mod tests { TEST_KEY_NAME, None, None, + None, Some(false), ) .expect("Failed to connect"); @@ -235,6 +240,7 @@ mod tests { TEST_KEY_NAME, None, None, + None, Some(false), ) .expect("Failed to connect"); diff --git a/src/keyring/providers/hashicorp/vault_client.rs b/src/keyring/providers/hashicorp/vault_client.rs index 89b2c881..6f8a3b6a 100644 --- a/src/keyring/providers/hashicorp/vault_client.rs +++ b/src/keyring/providers/hashicorp/vault_client.rs @@ -10,6 +10,7 @@ use ureq::Agent; use crate::keyring::ed25519; use serde::{Deserialize, Serialize}; use serde_json::Value; +use crate::config::provider::hashicorp::VaultEndpointConfig; use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; use rustls::pki_types::{pem::PemObject, CertificateDer, ServerName, UnixTime}; @@ -167,6 +168,7 @@ impl ServerCertVerifier for NoVerification { pub(crate) struct VaultClient { agent: Agent, api_endpoint: String, + endpoints: VaultEndpointConfig, token: String, } @@ -177,6 +179,7 @@ impl VaultClient { pub fn new( api_endpoint: &str, token: &str, + endpoints: Option, ca_cert: Option, skip_verify: Option, ) -> Self { @@ -227,6 +230,7 @@ impl VaultClient { VaultClient { api_endpoint: api_endpoint.into(), + endpoints: endpoints.unwrap_or_default(), agent, token: token.into(), } @@ -246,8 +250,8 @@ impl VaultClient { let data = if let Some(data) = self .agent .get(&format!( - "{}/v1/transit/keys/{}", - self.api_endpoint, key_name + "{}{}/{}", + self.api_endpoint, self.endpoints.keys, key_name )) .set(VAULT_TOKEN, &self.token) .call()? @@ -311,7 +315,10 @@ impl VaultClient { pub fn hand_shake(&self) -> Result<(), Error> { let _ = self .agent - .get(&format!("{}/v1/auth/token/lookup-self", self.api_endpoint)) + .get(&format!( + "{}{}", + self.api_endpoint, self.endpoints.hand_shake, + )) .set(VAULT_TOKEN, &self.token) .call() .map_err(|e| { @@ -345,8 +352,8 @@ impl VaultClient { let data = if let Some(data) = self .agent .post(&format!( - "{}/v1/transit/sign/{}", - self.api_endpoint, key_name + "{}{}/{}", + self.api_endpoint, self.endpoints.sign, key_name )) .set(VAULT_TOKEN, &self.token) .send_json(body)? @@ -397,7 +404,10 @@ impl VaultClient { let data = if let Some(data) = self .agent - .get(&format!("{}/v1/transit/wrapping_key", self.api_endpoint)) + .get(&format!( + "{}{}", + self.api_endpoint, self.endpoints.wrapping_key + )) .set(VAULT_TOKEN, &self.token) .call()? .into_json::>()? @@ -428,8 +438,8 @@ impl VaultClient { let _ = self .agent .post(&format!( - "{}/v1/transit/keys/{}/import", - self.api_endpoint, key_name + "{}{}/{}/import", + self.api_endpoint, self.endpoints.keys, key_name )) .set(VAULT_TOKEN, &self.token) .send_json(body)?;