feat(alknet-secret): make DerivedKey zeroize-on-drop, non-Clone, with redacted serialization
Per ADR-038, DerivedKey.private_key now derives Zeroize with #[zeroize(drop)] ensuring sensitive key material is zeroized before deallocation. DerivedKey is now move-only (no Clone), and JSON/debug output redacts private_key as "[REDACTED]". Deserialization still works for postcard/irpc wire format. Also fixes clippy needless_borrows_for_generic_args in encryption.rs and applies cargo fmt to existing code.
This commit is contained in:
@@ -167,7 +167,10 @@ impl SecretServiceHandle {
|
||||
if !inner.unlocked {
|
||||
return Err(SecretServiceError::ServiceLocked);
|
||||
}
|
||||
let seed = inner.seed.as_ref().ok_or(SecretServiceError::ServiceLocked)?;
|
||||
let seed = inner
|
||||
.seed
|
||||
.as_ref()
|
||||
.ok_or(SecretServiceError::ServiceLocked)?;
|
||||
|
||||
let key = derivation::derive_path_from_seed(seed.as_bytes(), path)?;
|
||||
Ok(DerivedKey {
|
||||
@@ -183,7 +186,10 @@ impl SecretServiceHandle {
|
||||
if !inner.unlocked {
|
||||
return Err(SecretServiceError::ServiceLocked);
|
||||
}
|
||||
let seed = inner.seed.as_ref().ok_or(SecretServiceError::ServiceLocked)?;
|
||||
let seed = inner
|
||||
.seed
|
||||
.as_ref()
|
||||
.ok_or(SecretServiceError::ServiceLocked)?;
|
||||
|
||||
let key = derivation::derive_path_from_seed(seed.as_bytes(), path)?;
|
||||
Ok(DerivedKey {
|
||||
@@ -199,7 +205,10 @@ impl SecretServiceHandle {
|
||||
if !inner.unlocked {
|
||||
return Err(SecretServiceError::ServiceLocked);
|
||||
}
|
||||
let seed = inner.seed.as_ref().ok_or(SecretServiceError::ServiceLocked)?;
|
||||
let seed = inner
|
||||
.seed
|
||||
.as_ref()
|
||||
.ok_or(SecretServiceError::ServiceLocked)?;
|
||||
|
||||
let key = derivation::derive_path_from_seed(seed.as_bytes(), path)?;
|
||||
Ok(DerivedKey {
|
||||
@@ -212,12 +221,19 @@ impl SecretServiceHandle {
|
||||
/// Encrypt plaintext using the derived encryption key.
|
||||
///
|
||||
/// Uses the key at path `m/74'/2'/0'/0'` (PATHS::ENCRYPTION) by default.
|
||||
pub fn encrypt(&self, plaintext: &str, key_version: u32) -> Result<EncryptedData, SecretServiceError> {
|
||||
pub fn encrypt(
|
||||
&self,
|
||||
plaintext: &str,
|
||||
key_version: u32,
|
||||
) -> Result<EncryptedData, SecretServiceError> {
|
||||
let inner = self.inner.read().unwrap();
|
||||
if !inner.unlocked {
|
||||
return Err(SecretServiceError::ServiceLocked);
|
||||
}
|
||||
let seed = inner.seed.as_ref().ok_or(SecretServiceError::ServiceLocked)?;
|
||||
let seed = inner
|
||||
.seed
|
||||
.as_ref()
|
||||
.ok_or(SecretServiceError::ServiceLocked)?;
|
||||
|
||||
let derived = derivation::derive_path_from_seed(seed.as_bytes(), PATHS::ENCRYPTION)?;
|
||||
let enc_key = EncryptionKey::from_derived_bytes(derived.private_key(), key_version);
|
||||
@@ -231,10 +247,14 @@ impl SecretServiceHandle {
|
||||
if !inner.unlocked {
|
||||
return Err(SecretServiceError::ServiceLocked);
|
||||
}
|
||||
let seed = inner.seed.as_ref().ok_or(SecretServiceError::ServiceLocked)?;
|
||||
let seed = inner
|
||||
.seed
|
||||
.as_ref()
|
||||
.ok_or(SecretServiceError::ServiceLocked)?;
|
||||
|
||||
let derived = derivation::derive_path_from_seed(seed.as_bytes(), PATHS::ENCRYPTION)?;
|
||||
let enc_key = EncryptionKey::from_derived_bytes(derived.private_key(), encrypted.key_version);
|
||||
let enc_key =
|
||||
EncryptionKey::from_derived_bytes(derived.private_key(), encrypted.key_version);
|
||||
|
||||
encryption::decrypt(encrypted, &enc_key).map_err(|e| e.into())
|
||||
}
|
||||
@@ -379,4 +399,4 @@ mod tests {
|
||||
service.lock();
|
||||
assert!(service.decrypt(&encrypted).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user