auths_core/crypto/
signer.rs1use crate::config::current_algorithm;
4use crate::crypto::encryption::{decrypt_bytes, encrypt_bytes_argon2};
5use crate::crypto::provider_bridge;
6use crate::error::AgentError;
7use auths_crypto::SecureSeed;
8use ssh_agent_lib::ssh_key::Algorithm as SshAlgorithm;
9use zeroize::Zeroizing;
10
11pub trait SignerKey: Send + Sync + 'static {
13 fn public_key_bytes(&self) -> Vec<u8>;
15
16 fn kind(&self) -> SshAlgorithm;
18
19 fn sign(&self, message: &[u8]) -> Result<Vec<u8>, AgentError>;
21}
22
23pub struct SeedSignerKey {
25 seed: SecureSeed,
26 public_key: [u8; 32],
27}
28
29impl SeedSignerKey {
30 pub fn new(seed: SecureSeed, public_key: [u8; 32]) -> Self {
32 Self { seed, public_key }
33 }
34
35 pub fn from_seed(seed: SecureSeed) -> Result<Self, AgentError> {
37 let public_key =
38 provider_bridge::ed25519_public_key_from_seed_sync(&seed).map_err(|e| {
39 AgentError::CryptoError(format!("Failed to derive public key from seed: {}", e))
40 })?;
41 Ok(Self { seed, public_key })
42 }
43}
44
45impl SignerKey for SeedSignerKey {
46 fn public_key_bytes(&self) -> Vec<u8> {
47 self.public_key.to_vec()
48 }
49
50 fn kind(&self) -> SshAlgorithm {
51 SshAlgorithm::Ed25519
52 }
53
54 fn sign(&self, message: &[u8]) -> Result<Vec<u8>, AgentError> {
55 provider_bridge::sign_ed25519_sync(&self.seed, message)
56 .map_err(|e| AgentError::CryptoError(format!("Ed25519 signing failed: {}", e)))
57 }
58}
59
60pub fn extract_seed_from_key_bytes(bytes: &[u8]) -> Result<SecureSeed, AgentError> {
64 auths_crypto::parse_ed25519_seed(bytes)
65 .map_err(|e| AgentError::KeyDeserializationError(format!("{}", e)))
66}
67
68pub fn load_seed_and_pubkey(bytes: &[u8]) -> Result<(SecureSeed, [u8; 32]), AgentError> {
73 let (seed, maybe_pk) = auths_crypto::parse_ed25519_key_material(bytes)
74 .map_err(|e| AgentError::KeyDeserializationError(format!("{}", e)))?;
75
76 let pubkey = match maybe_pk {
77 Some(pk) => pk,
78 None => provider_bridge::ed25519_public_key_from_seed_sync(&seed).map_err(|e| {
79 AgentError::CryptoError(format!("Failed to derive public key from seed: {}", e))
80 })?,
81 };
82
83 Ok((seed, pubkey))
84}
85
86pub fn encrypt_keypair(raw: &[u8], passphrase: &str) -> Result<Vec<u8>, AgentError> {
88 encrypt_bytes_argon2(raw, passphrase, current_algorithm())
89}
90
91pub fn decrypt_keypair(
93 encrypted: &[u8],
94 passphrase: &str,
95) -> Result<Zeroizing<Vec<u8>>, AgentError> {
96 Ok(Zeroizing::new(decrypt_bytes(encrypted, passphrase)?))
97}