diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-02-18 11:05:09 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-02-18 11:23:03 +0100 |
commit | 32174f69cd4d94b4f621f3273781d487e97fa031 (patch) | |
tree | 0d3aaec16fbd743609cce0539f55422daabb596c /tool | |
parent | 363110b87dd5228e5a22f336fa96fc53a17149be (diff) |
openpgp: Improve tracking of secret keys.
- We use marker traits to track with the type system if a Key has
secret key material attached. Previously, it was possible to
subvert that by taking the secret key material using
Key4::set_secret, creating a Key4<SecretParts, ..> without any
secrets.
- Related, the accessor functions returned an
Option<SecretKeyMaterial> even for Key4<SecretParts, ..>.
- Replace set_secret by add_secret and take_secret that also change
the Key's type accordingly. Make the accessors infallible if we
know we have a secret key, rename Key4<P, R>::secret to
Key4<P, R>::optional_secret to make the distinction clear.
- Fixes #435.
Diffstat (limited to 'tool')
-rw-r--r-- | tool/src/commands/decrypt.rs | 18 | ||||
-rw-r--r-- | tool/src/commands/dump.rs | 2 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 2 | ||||
-rw-r--r-- | tool/tests/sq-sign.rs | 2 |
4 files changed, 9 insertions, 15 deletions
diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs index 6c459967..65b9d579 100644 --- a/tool/src/commands/decrypt.rs +++ b/tool/src/commands/decrypt.rs @@ -147,7 +147,7 @@ impl<'a> DecryptionHelper for Helper<'a> { for pkesk in pkesks { let keyid = pkesk.recipient(); if let Some(key) = self.secret_keys.get(&keyid) { - if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) { + if ! key.secret().is_encrypted() { if let Ok(fp) = key.clone().into_keypair() .and_then(|mut k| self.try_decrypt(pkesk, sym_algo, &mut k, &mut decrypt)) @@ -169,8 +169,7 @@ impl<'a> DecryptionHelper for Helper<'a> { let keyid = pkesk.recipient(); if let Some(key) = self.secret_keys.get_mut(&keyid) { let mut keypair = loop { - if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) - { + if ! key.secret().is_encrypted() { break key.clone().into_keypair().unwrap(); } @@ -181,9 +180,7 @@ impl<'a> DecryptionHelper for Helper<'a> { let algo = key.pk_algo(); if let Some(()) = - key.secret_mut() - .and_then(|s| s.decrypt_in_place(algo, &p).ok()) - { + key.secret_mut().decrypt_in_place(algo, &p).ok() { break key.clone().into_keypair().unwrap() } else { eprintln!("Bad password."); @@ -202,7 +199,7 @@ impl<'a> DecryptionHelper for Helper<'a> { // prompting for a password. for pkesk in pkesks.iter().filter(|p| p.recipient().is_wildcard()) { for key in self.secret_keys.values() { - if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) { + if ! key.secret().is_encrypted() { if let Ok(fp) = key.clone().into_keypair() .and_then(|mut k| self.try_decrypt(pkesk, sym_algo, &mut k, &mut decrypt)) @@ -229,8 +226,7 @@ impl<'a> DecryptionHelper for Helper<'a> { let mut keypair = loop { let key = self.secret_keys.get_mut(&keyid).unwrap(); // Yuck - if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) - { + if ! key.secret().is_encrypted() { break key.clone().into_keypair().unwrap(); } @@ -241,9 +237,7 @@ impl<'a> DecryptionHelper for Helper<'a> { let algo = key.pk_algo(); if let Some(()) = - key.secret_mut() - .and_then(|s| s.decrypt_in_place(algo, &p).ok()) - { + key.secret_mut().decrypt_in_place(algo, &p).ok() { break key.clone().into_keypair().unwrap() } else { eprintln!("Bad password."); diff --git a/tool/src/commands/dump.rs b/tool/src/commands/dump.rs index 349255b9..e8a0a970 100644 --- a/tool/src/commands/dump.rs +++ b/tool/src/commands/dump.rs @@ -352,7 +352,7 @@ impl PacketDumper { }, } - if let Some(secrets) = k.secret() { + if let Some(secrets) = k.optional_secret() { use self::openpgp::packet::key::SecretKeyMaterial; writeln!(output, "{}", i)?; writeln!(output, "{} Secret Key:", i)?; diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index d6c6f2b5..db2c4f10 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -55,7 +55,7 @@ fn get_signing_keys(certs: &[openpgp::Cert], p: &dyn Policy, .for_signing() .map(|ka| ka.key()) { - if let Some(secret) = key.secret() { + if let Some(secret) = key.optional_secret() { let unencrypted = match secret { SecretKeyMaterial::Encrypted(ref e) => { let password = rpassword::read_password_from_tty(Some( diff --git a/tool/tests/sq-sign.rs b/tool/tests/sq-sign.rs index 49dc0714..1b1ff820 100644 --- a/tool/tests/sq-sign.rs +++ b/tool/tests/sq-sign.rs @@ -212,7 +212,7 @@ fn sq_sign_append_on_compress_then_sign() { let tsk = Cert::from_file(&artifact("keys/dennis-simon-anton-private.pgp")) .unwrap(); let key = tsk.keys().with_policy(p, None).for_signing().nth(0).unwrap().key(); - let sec = match key.secret() { + let sec = match key.optional_secret() { Some(SecretKeyMaterial::Unencrypted(ref u)) => u.clone(), _ => unreachable!(), }; |