Fix Secret Key decode rejecting valid keys; verify build
The first base32 symbol carries 3 data bits (26 symbols = 130 bits, 2 spare), but decode only accepted values 0-3, so ~half of generated keys failed to parse. Adds an edge-case test, rustfmt config, Cargo.lock, and on-demand cross targets instead of installing all seven in rust-toolchain.toml. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -74,7 +74,12 @@ impl AccountKeyset {
|
||||
let mut pt = Zeroizing::new(Vec::with_capacity(48));
|
||||
pt.extend_from_slice(vk.id.as_bytes());
|
||||
pt.extend_from_slice(vk.expose());
|
||||
seal_to(self.enc.id, &self.enc.public_bytes(), &pt, &Aad::build(ObjectType::VaultKey, self.account_id, Some(vault_id), None))
|
||||
seal_to(
|
||||
self.enc.id,
|
||||
&self.enc.public_bytes(),
|
||||
&pt,
|
||||
&Aad::build(ObjectType::VaultKey, self.account_id, Some(vault_id), None),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn open_vault_key(&self, vault_id: Uuid, env: &Envelope) -> Result<SymKey> {
|
||||
@@ -100,26 +105,40 @@ pub struct SealedItem {
|
||||
}
|
||||
|
||||
/// Encrypts an item's plaintext (already serialized) with a fresh per-item key.
|
||||
pub fn seal_item(account_id: Uuid, vault_id: Uuid, item_id: Uuid, vault_key: &SymKey, plaintext: &[u8]) -> Result<SealedItem> {
|
||||
pub fn seal_item(
|
||||
account_id: Uuid,
|
||||
vault_id: Uuid,
|
||||
item_id: Uuid,
|
||||
vault_key: &SymKey,
|
||||
plaintext: &[u8],
|
||||
) -> Result<SealedItem> {
|
||||
let item_key = SymKey::generate();
|
||||
let mut key_pt = Zeroizing::new(Vec::with_capacity(48));
|
||||
key_pt.extend_from_slice(item_key.id.as_bytes());
|
||||
key_pt.extend_from_slice(item_key.expose());
|
||||
let wrapped_item_key =
|
||||
vault_key.seal(&key_pt, &Aad::build(ObjectType::ItemKey, account_id, Some(vault_id), Some(item_id)))?;
|
||||
let payload = item_key.seal(&pad(plaintext), &Aad::build(ObjectType::Item, account_id, Some(vault_id), Some(item_id)))?;
|
||||
let payload =
|
||||
item_key.seal(&pad(plaintext), &Aad::build(ObjectType::Item, account_id, Some(vault_id), Some(item_id)))?;
|
||||
Ok(SealedItem { wrapped_item_key, payload })
|
||||
}
|
||||
|
||||
pub fn open_item(account_id: Uuid, vault_id: Uuid, item_id: Uuid, vault_key: &SymKey, sealed: &SealedItem) -> Result<Zeroizing<Vec<u8>>> {
|
||||
let key_pt =
|
||||
vault_key.open(&sealed.wrapped_item_key, &Aad::build(ObjectType::ItemKey, account_id, Some(vault_id), Some(item_id)))?;
|
||||
pub fn open_item(
|
||||
account_id: Uuid,
|
||||
vault_id: Uuid,
|
||||
item_id: Uuid,
|
||||
vault_key: &SymKey,
|
||||
sealed: &SealedItem,
|
||||
) -> Result<Zeroizing<Vec<u8>>> {
|
||||
let key_pt = vault_key
|
||||
.open(&sealed.wrapped_item_key, &Aad::build(ObjectType::ItemKey, account_id, Some(vault_id), Some(item_id)))?;
|
||||
if key_pt.len() != 48 {
|
||||
return Err(CryptoError::Malformed);
|
||||
}
|
||||
let id = Uuid::from_slice(&key_pt[..16]).map_err(|_| CryptoError::Malformed)?;
|
||||
let item_key = SymKey::from_bytes(id, key_pt[16..].try_into().map_err(|_| CryptoError::Malformed)?);
|
||||
let padded = item_key.open(&sealed.payload, &Aad::build(ObjectType::Item, account_id, Some(vault_id), Some(item_id)))?;
|
||||
let padded =
|
||||
item_key.open(&sealed.payload, &Aad::build(ObjectType::Item, account_id, Some(vault_id), Some(item_id)))?;
|
||||
unpad(&padded)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user