crypto: RefCell instead of Mutex in Agent

This commit is contained in:
Lorenz Leutgeb 2025-01-20 22:29:57 +01:00 committed by cloudhead
parent 62d000f7cb
commit 3b5fac178e
No known key found for this signature in database
3 changed files with 24 additions and 21 deletions

View File

@ -39,7 +39,7 @@ impl SignerError {
} }
} }
pub trait Signer: Send + Sync { pub trait Signer: Send {
/// Return this signer's public/verification key. /// Return this signer's public/verification key.
fn public_key(&self) -> &PublicKey; fn public_key(&self) -> &PublicKey;
/// Sign a message and return the signature. /// Sign a message and return the signature.

View File

@ -1,5 +1,4 @@
use std::ops::{Deref, DerefMut}; use std::cell::RefCell;
use std::sync::Mutex;
pub use radicle_ssh::agent::client::AgentClient; pub use radicle_ssh::agent::client::AgentClient;
pub use radicle_ssh::agent::client::Error; pub use radicle_ssh::agent::client::Error;
@ -27,41 +26,47 @@ impl Agent {
self.client.add_identity(key, &[]) self.client.add_identity(key, &[])
} }
pub fn unregister(&mut self, key: &PublicKey) -> Result<(), ssh::Error> {
self.client.remove_identity(key)
}
pub fn unregister_all(&mut self) -> Result<(), ssh::Error> {
self.client.remove_all_identities()
}
pub fn sign(&mut self, key: &PublicKey, data: &[u8]) -> Result<[u8; 64], ssh::Error> {
self.client.sign(key, data)
}
/// Get a signer from this agent, given the public key. /// Get a signer from this agent, given the public key.
pub fn signer(self, key: PublicKey) -> AgentSigner { pub fn signer(self, key: PublicKey) -> AgentSigner {
AgentSigner::new(self, key) AgentSigner::new(self, key)
} }
}
impl Deref for Agent { pub fn pid(&self) -> Option<u32> {
type Target = AgentClient<Stream>; self.client.pid()
fn deref(&self) -> &Self::Target {
&self.client
} }
}
impl DerefMut for Agent { pub fn request_identities(&mut self) -> Result<Vec<PublicKey>, ssh::agent::client::Error> {
fn deref_mut(&mut self) -> &mut Self::Target { self.client.request_identities()
&mut self.client
} }
} }
/// A [`Signer`] that uses `ssh-agent`. /// A [`Signer`] that uses `ssh-agent`.
pub struct AgentSigner { pub struct AgentSigner {
agent: Mutex<Agent>, agent: RefCell<Agent>,
public: PublicKey, public: PublicKey,
} }
impl AgentSigner { impl AgentSigner {
pub fn new(agent: Agent, public: PublicKey) -> Self { pub fn new(agent: Agent, public: PublicKey) -> Self {
let agent = Mutex::new(agent); let agent = RefCell::new(agent);
Self { agent, public } Self { agent, public }
} }
pub fn is_ready(&self) -> Result<bool, Error> { pub fn is_ready(&self) -> Result<bool, Error> {
let ids = self.agent.lock().unwrap().request_identities()?; let ids = self.agent.borrow_mut().request_identities()?;
Ok(ids.contains(&self.public)) Ok(ids.contains(&self.public))
} }
@ -84,9 +89,7 @@ impl Signer for AgentSigner {
fn try_sign(&self, msg: &[u8]) -> Result<Signature, SignerError> { fn try_sign(&self, msg: &[u8]) -> Result<Signature, SignerError> {
let sig = self let sig = self
.agent .agent
.lock() .borrow_mut()
// We'll take our chances here; the worse that can happen is the agent returns an error.
.unwrap_or_else(|e| e.into_inner())
.sign(&self.public, msg) .sign(&self.public, msg)
.map_err(SignerError::new)?; .map_err(SignerError::new)?;

View File

@ -28,11 +28,11 @@ fn main() -> anyhow::Result<()> {
println!("ok"); println!("ok");
} }
Some("remove") => { Some("remove") => {
agent.remove_identity(profile.id())?; agent.unregister(profile.id())?;
println!("ok"); println!("ok");
} }
Some("remove-all") => { Some("remove-all") => {
agent.remove_all_identities()?; agent.unregister_all()?;
println!("ok"); println!("ok");
} }
Some("sign") => { Some("sign") => {