summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-02-18 11:05:09 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-02-18 11:23:03 +0100
commit32174f69cd4d94b4f621f3273781d487e97fa031 (patch)
tree0d3aaec16fbd743609cce0539f55422daabb596c /tool
parent363110b87dd5228e5a22f336fa96fc53a17149be (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.rs18
-rw-r--r--tool/src/commands/dump.rs2
-rw-r--r--tool/src/commands/mod.rs2
-rw-r--r--tool/tests/sq-sign.rs2
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!(),
};