Support GnuPG AEAD password entries
This commit is contained in:
@@ -504,6 +504,69 @@ fn missing_openpgp_passphrases_are_prompted_verified_and_only_then_persisted() -
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnupg_aead_passphrases_are_persisted_only_after_authenticated_decryption() -> TestResult {
|
||||
let fixture = FixtureSet::load()?;
|
||||
let key = fixture.key("alice")?;
|
||||
let keys = KeyStore::load(fixture.path(&key.secret_armor))?;
|
||||
let ciphertext = fixture.read(&fixture.gnupg_aead.entry)?;
|
||||
let expected = fixture.read(&fixture.gnupg_aead.plaintext)?;
|
||||
let reference = SecretReference::openpgp_passphrase(&key.primary_fingerprint)?;
|
||||
|
||||
let prompt = MemoryPrompt::responding(Ok(key.passphrase.as_bytes()));
|
||||
let mut provisioned =
|
||||
store(MemoryBackend::default()).with_openpgp_passphrase_prompt(prompt.clone());
|
||||
provisioned.unlock()?;
|
||||
assert_eq!(
|
||||
keys.decrypt(&EncryptedEntry::new(ciphertext.clone()), &mut provisioned)?
|
||||
.expose(),
|
||||
expected
|
||||
);
|
||||
assert_eq!(
|
||||
provisioned.retrieve(&reference)?.expose(),
|
||||
key.passphrase.as_bytes()
|
||||
);
|
||||
assert_eq!(
|
||||
prompt.requested(),
|
||||
std::slice::from_ref(&key.primary_fingerprint)
|
||||
);
|
||||
|
||||
let wrong_prompt = MemoryPrompt::responding(Ok(b"incorrect AEAD passphrase"));
|
||||
let mut wrong =
|
||||
store(MemoryBackend::default()).with_openpgp_passphrase_prompt(wrong_prompt.clone());
|
||||
wrong.unlock()?;
|
||||
assert!(matches!(
|
||||
keys.decrypt(&EncryptedEntry::new(ciphertext.clone()), &mut wrong),
|
||||
Err(CryptoError::DecryptionFailed)
|
||||
));
|
||||
assert!(matches!(
|
||||
wrong.retrieve(&reference),
|
||||
Err(SecretStoreError::Missing)
|
||||
));
|
||||
assert_eq!(
|
||||
wrong_prompt.requested(),
|
||||
std::slice::from_ref(&key.primary_fingerprint)
|
||||
);
|
||||
|
||||
let mut tampered_ciphertext = ciphertext;
|
||||
*tampered_ciphertext
|
||||
.last_mut()
|
||||
.expect("non-empty AEAD fixture") ^= 0x01;
|
||||
let tampered_prompt = MemoryPrompt::responding(Ok(key.passphrase.as_bytes()));
|
||||
let mut tampered =
|
||||
store(MemoryBackend::default()).with_openpgp_passphrase_prompt(tampered_prompt);
|
||||
tampered.unlock()?;
|
||||
assert!(matches!(
|
||||
keys.decrypt(&EncryptedEntry::new(tampered_ciphertext), &mut tampered),
|
||||
Err(CryptoError::DecryptionFailed)
|
||||
));
|
||||
assert!(matches!(
|
||||
tampered.retrieve(&reference),
|
||||
Err(SecretStoreError::Missing)
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fs_config(temporary: &tempfile::TempDir) -> TestResult {
|
||||
std::fs::create_dir_all(temporary.path().join("keys"))?;
|
||||
std::fs::create_dir_all(temporary.path().join("vault"))?;
|
||||
|
||||
Reference in New Issue
Block a user