diff --git a/radicle-crypto/src/ssh/keystore.rs b/radicle-crypto/src/ssh/keystore.rs index 7bbb3e51..7c0ea3d3 100644 --- a/radicle-crypto/src/ssh/keystore.rs +++ b/radicle-crypto/src/ssh/keystore.rs @@ -7,6 +7,9 @@ use zeroize::Zeroizing; use crate::{KeyPair, PublicKey, SecretKey, Signature, Signer, SignerError}; +/// A secret key passphrase. +pub type Passphrase = Zeroizing; + #[derive(Debug, Error)] pub enum Error { #[error(transparent)] @@ -83,7 +86,10 @@ impl Keystore { /// Load the secret key from the store, decrypting it with the given passphrase. /// Returns `None` if it wasn't found. - pub fn secret_key(&self, passphrase: &str) -> Result>, Error> { + pub fn secret_key( + &self, + passphrase: Passphrase, + ) -> Result>, Error> { let path = self.path.join("radicle"); if !path.exists() { return Ok(None); @@ -135,7 +141,7 @@ impl Signer for MemorySigner { impl MemorySigner { /// Load this signer from a keystore, given a secret key passphrase. - pub fn load(keystore: &Keystore, passphrase: &str) -> Result { + pub fn load(keystore: &Keystore, passphrase: Passphrase) -> Result { let public = keystore .public_key()? .ok_or_else(|| MemorySignerError::NotFound(keystore.path().to_path_buf()))?; @@ -177,10 +183,13 @@ mod tests { let public = store.init("test", "hunter").unwrap(); assert_eq!(public, store.public_key().unwrap().unwrap()); - let secret = store.secret_key("hunter").unwrap().unwrap(); + let secret = store + .secret_key("hunter".to_owned().into()) + .unwrap() + .unwrap(); assert_eq!(PublicKey::from(secret.public_key()), public); - store.secret_key("blunder").unwrap_err(); // Wrong passphrase. + store.secret_key("blunder".to_owned().into()).unwrap_err(); // Wrong passphrase. } #[test] @@ -189,7 +198,7 @@ mod tests { let store = Keystore::new(&tmp.path()); let public = store.init("test", "hunter").unwrap(); - let signer = MemorySigner::load(&store, "hunter").unwrap(); + let signer = MemorySigner::load(&store, "hunter".to_owned().into()).unwrap(); assert_eq!(public, *signer.public_key()); } diff --git a/radicle-node/src/main.rs b/radicle-node/src/main.rs index f63fede2..30362e43 100644 --- a/radicle-node/src/main.rs +++ b/radicle-node/src/main.rs @@ -57,8 +57,9 @@ fn main() -> anyhow::Result<()> { Err(err) => { let passphrase = env::var(profile::env::RAD_PASSPHRASE) .context("Either ssh-agent must be initialized, or `RAD_PASSPHRASE` must be set") - .context(err)?; - MemorySigner::load(&profile.keystore, &passphrase)?.boxed() + .context(err)? + .into(); + MemorySigner::load(&profile.keystore, passphrase)?.boxed() } }; let handle = client.handle(); diff --git a/radicle-tools/src/rad-agent.rs b/radicle-tools/src/rad-agent.rs index 23432ba6..15216efb 100644 --- a/radicle-tools/src/rad-agent.rs +++ b/radicle-tools/src/rad-agent.rs @@ -18,9 +18,10 @@ fn main() -> anyhow::Result<()> { let mut passphrase = String::new(); io::stdin().lock().read_line(&mut passphrase)?; + let passphrase = passphrase.trim().to_owned().into(); let secret = profile .keystore - .secret_key(passphrase.trim())? + .secret_key(passphrase)? .ok_or_else(|| anyhow!("Key not found in {:?}", profile.keystore.path()))?; agent.register(&secret)?;