use super::KeyType;
use crate::{chain, prelude::*};
use serde::Deserialize;
use std::{fmt, fs, path::PathBuf, process};
use yubihsm::Credentials;
use zeroize::{Zeroize, Zeroizing};
use cometbft_config::net;
#[derive(Clone, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct YubihsmConfig {
pub adapter: AdapterConfig,
pub auth: AuthConfig,
#[serde(default)]
pub keys: Vec<SigningKeyConfig>,
pub serial_number: Option<String>,
#[cfg(feature = "yubihsm-server")]
pub connector_server: Option<ConnectorServerConfig>,
}
#[derive(Clone, Deserialize, Debug)]
#[serde(deny_unknown_fields, tag = "type")]
pub enum AdapterConfig {
#[serde(rename = "usb")]
Usb {
#[serde(default = "usb_timeout_ms_default")]
timeout_ms: u64,
},
#[serde(rename = "http")]
Http {
addr: net::Address,
},
}
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields, untagged)]
pub enum AuthConfig {
Path {
key: u16,
password_file: PathBuf,
},
String {
key: u16,
password: Password,
},
}
impl AuthConfig {
pub fn credentials(&self) -> Credentials {
match self {
AuthConfig::Path { key, password_file } => {
let password =
Zeroizing::new(fs::read_to_string(password_file).unwrap_or_else(|e| {
status_err!("couldn't read key from {}: {}", password_file.display(), e);
process::exit(1);
}));
let password_trimmed = password.trim_end();
Credentials::from_password(*key, password_trimmed.as_bytes())
}
AuthConfig::String { key, password } => {
Credentials::from_password(*key, password.0.as_bytes())
}
}
}
}
#[derive(Clone, Deserialize, Zeroize)]
#[serde(deny_unknown_fields)]
#[zeroize(drop)]
pub struct Password(String);
impl fmt::Debug for Password {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("REDACTED PASSWORD")
}
}
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SigningKeyConfig {
pub chain_ids: Vec<chain::Id>,
pub key: u16,
#[serde(default, rename = "type")]
pub key_type: KeyType,
}
fn usb_timeout_ms_default() -> u64 {
1000
}
#[cfg(feature = "yubihsm-server")]
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ConnectorServerConfig {
pub laddr: net::Address,
pub cli: Option<CliConfig>,
}
#[cfg(feature = "yubihsm-server")]
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CliConfig {
pub auth_key: Option<u16>,
}