summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2019-08-12 13:39:14 +0200
committerNeal H. Walfield <neal@pep.foundation>2019-08-23 19:15:13 +0200
commit05cf492f3417fd61f6b1e7dc4913a16fd5f201ea (patch)
treeeca0c2e0481e10b54884a766e7e864020089fe84 /tool
parent102dea398e920e91b34e5602033c2e7e53c50bb1 (diff)
openpgp: Use marker types to denote a Key's type.
- In addition to providing some added protection, this allows us to implement 'From<Key<_, _>> for Packet'.
Diffstat (limited to 'tool')
-rw-r--r--tool/src/commands/decrypt.rs19
-rw-r--r--tool/src/commands/dump.rs266
-rw-r--r--tool/src/commands/inspect.rs19
-rw-r--r--tool/src/commands/mod.rs9
-rw-r--r--tool/src/commands/sign.rs6
5 files changed, 171 insertions, 148 deletions
diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs
index 9ffa6303..3c4b3658 100644
--- a/tool/src/commands/decrypt.rs
+++ b/tool/src/commands/decrypt.rs
@@ -10,7 +10,7 @@ use crate::openpgp::constants::SymmetricAlgorithm;
use crate::openpgp::conversions::hex;
use crate::openpgp::crypto::SessionKey;
use crate::openpgp::{Fingerprint, TPK, KeyID, Result};
-use crate::openpgp::packet::{Key, key::SecretKeyMaterial, Signature, PKESK, SKESK};
+use crate::openpgp::packet::prelude::*;
use crate::openpgp::parse::PacketParser;
use crate::openpgp::parse::stream::{
VerificationHelper, DecryptionHelper, Decryptor, MessageStructure,
@@ -21,7 +21,8 @@ use super::{dump::PacketDumper, VHelper};
struct Helper<'a> {
vhelper: VHelper<'a>,
- secret_keys: HashMap<KeyID, Key>,
+ secret_keys:
+ HashMap<KeyID, key::UnspecifiedSecret>,
key_identities: HashMap<KeyID, Fingerprint>,
key_hints: HashMap<KeyID, String>,
dump_session_key: bool,
@@ -34,18 +35,22 @@ impl<'a> Helper<'a> {
signatures: usize, tpks: Vec<TPK>, secrets: Vec<TPK>,
dump_session_key: bool, dump: bool, hex: bool)
-> Self {
- let mut keys: HashMap<KeyID, Key> = HashMap::new();
+ let mut keys: HashMap<KeyID, key::UnspecifiedSecret>
+ = HashMap::new();
let mut identities: HashMap<KeyID, Fingerprint> = HashMap::new();
let mut hints: HashMap<KeyID, String> = HashMap::new();
for tsk in secrets {
- let can_encrypt = |_: &Key, sig: Option<&Signature>| -> bool {
+ fn can_encrypt<R, P>(_: &Key<P, R>, sig: Option<&Signature>) -> bool
+ where P: key::KeyParts,
+ R: key::KeyRole,
+ {
if let Some(sig) = sig {
sig.key_flags().can_encrypt_at_rest()
|| sig.key_flags().can_encrypt_for_transport()
} else {
false
}
- };
+ }
let hint = match tsk.userids().nth(0) {
Some(uid) => format!("{} ({})", uid.userid(),
@@ -55,7 +60,7 @@ impl<'a> Helper<'a> {
if can_encrypt(tsk.primary().key(), tsk.primary_key_signature()) {
let id = tsk.fingerprint().to_keyid();
- keys.insert(id.clone(), tsk.primary().key().clone());
+ keys.insert(id.clone(), tsk.primary().key().clone().into());
identities.insert(id.clone(), tsk.fingerprint());
hints.insert(id, hint.clone());
}
@@ -64,7 +69,7 @@ impl<'a> Helper<'a> {
let key = skb.key();
if can_encrypt(key, skb.binding_signature()) {
let id = key.fingerprint().to_keyid();
- keys.insert(id.clone(), key.clone());
+ keys.insert(id.clone(), key.clone().into());
identities.insert(id.clone(), tsk.fingerprint());
hints.insert(id, hint.clone());
}
diff --git a/tool/src/commands/dump.rs b/tool/src/commands/dump.rs
index 8fb98ffe..579b9ad7 100644
--- a/tool/src/commands/dump.rs
+++ b/tool/src/commands/dump.rs
@@ -6,6 +6,7 @@ use self::openpgp::constants::SymmetricAlgorithm;
use self::openpgp::conversions::hex;
use self::openpgp::crypto::mpis;
use self::openpgp::{Packet, Result};
+use self::openpgp::packet::prelude::*;
use self::openpgp::packet::ctb::CTB;
use self::openpgp::packet::{Header, BodyLength, Signature};
use self::openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
@@ -250,6 +251,139 @@ impl PacketDumper {
})?;
}
+ fn dump_key<P, R>(pd: &PacketDumper,
+ output: &mut dyn io::Write, i: &str, p: &Packet,
+ k: &Key<P, R>)
+ -> Result<()>
+ where P: key::KeyParts,
+ R: key::KeyRole,
+ {
+ writeln!(output, "{}", p.tag())?;
+ writeln!(output, "{} Version: {}", i, k.version())?;
+ writeln!(output, "{} Creation time: {}", i,
+ time::strftime(TIMEFMT, k.creation_time()).unwrap())?;
+ writeln!(output, "{} Pk algo: {}", i, k.pk_algo())?;
+ if let Some(bits) = k.mpis().bits() {
+ writeln!(output, "{} Pk size: {} bits", i, bits)?;
+ }
+ if pd.mpis {
+ writeln!(output, "{}", i)?;
+ writeln!(output, "{} Public Key:", i)?;
+
+ let ii = format!("{} ", i);
+ match k.mpis() {
+ mpis::PublicKey::RSA { e, n } =>
+ pd.dump_mpis(output, &ii,
+ &[e.value(), n.value()],
+ &["e", "n"])?,
+ mpis::PublicKey::DSA { p, q, g, y } =>
+ pd.dump_mpis(output, &ii,
+ &[p.value(), q.value(), g.value(),
+ y.value()],
+ &["p", "q", "g", "y"])?,
+ mpis::PublicKey::Elgamal { p, g, y } =>
+ pd.dump_mpis(output, &ii,
+ &[p.value(), g.value(), y.value()],
+ &["p", "g", "y"])?,
+ mpis::PublicKey::EdDSA { curve, q } => {
+ writeln!(output, "{} Curve: {}", ii, curve)?;
+ pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
+ },
+ mpis::PublicKey::ECDSA { curve, q } => {
+ writeln!(output, "{} Curve: {}", ii, curve)?;
+ pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
+ },
+ mpis::PublicKey::ECDH { curve, q, hash, sym } => {
+ writeln!(output, "{} Curve: {}", ii, curve)?;
+ writeln!(output, "{} Hash algo: {}", ii, hash)?;
+ writeln!(output, "{} Symmetric algo: {}", ii,
+ sym)?;
+ pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
+ },
+ mpis::PublicKey::Unknown { mpis, rest } => {
+ let keys: Vec<String> =
+ (0..mpis.len()).map(
+ |i| format!("mpi{}", i)).collect();
+ pd.dump_mpis(
+ output, &ii,
+ &mpis.iter().map(|m| {
+ m.value().iter().as_slice()
+ }).collect::<Vec<_>>()[..],
+ &keys.iter().map(|k| k.as_str())
+ .collect::<Vec<_>>()[..],
+ )?;
+
+ pd.dump_mpis(output, &ii, &[&rest[..]], &["rest"])?;
+ },
+ }
+
+ if let Some(secrets) = k.secret() {
+ use self::openpgp::packet::key::SecretKeyMaterial;
+ writeln!(output, "{}", i)?;
+ writeln!(output, "{} Secret Key:", i)?;
+
+ let ii = format!("{} ", i);
+ match secrets {
+ SecretKeyMaterial::Unencrypted(ref u) => u.map(
+ |mpis| -> Result<()> {
+ match mpis
+ {
+ mpis::SecretKeyMaterial::RSA { d, p, q, u } =>
+ pd.dump_mpis(output, &ii,
+ &[d.value(), p.value(),
+ q.value(), u.value()],
+ &["d", "p", "q", "u"])?,
+ mpis::SecretKeyMaterial::DSA { x } =>
+ pd.dump_mpis(output, &ii, &[x.value()],
+ &["x"])?,
+ mpis::SecretKeyMaterial::Elgamal { x } =>
+ pd.dump_mpis(output, &ii, &[x.value()],
+ &["x"])?,
+ mpis::SecretKeyMaterial::EdDSA { scalar } =>
+ pd.dump_mpis(output, &ii,
+ &[scalar.value()],
+ &["scalar"])?,
+ mpis::SecretKeyMaterial::ECDSA { scalar } =>
+ pd.dump_mpis(output, &ii,
+ &[scalar.value()],
+ &["scalar"])?,
+ mpis::SecretKeyMaterial::ECDH { scalar } =>
+ pd.dump_mpis(output, &ii,
+ &[scalar.value()],
+ &["scalar"])?,
+ mpis::SecretKeyMaterial::Unknown { mpis, rest } => {
+ let keys: Vec<String> =
+ (0..mpis.len()).map(
+ |i| format!("mpi{}", i)).collect();
+ pd.dump_mpis(
+ output, &ii,
+ &mpis.iter().map(|m| {
+ m.value().iter().as_slice()
+ }).collect::<Vec<_>>()[..],
+ &keys.iter().map(|k| k.as_str())
+ .collect::<Vec<_>>()[..],
+ )?;
+
+ pd.dump_mpis(output, &ii, &[rest],
+ &["rest"])?;
+ },
+ } Ok(()) })?,
+ SecretKeyMaterial::Encrypted(ref e) => {
+ writeln!(output, "{}", i)?;
+ write!(output, "{} S2K: ", ii)?;
+ pd.dump_s2k(output, &ii, e.s2k())?;
+ writeln!(output, "{} Sym. algo: {}", ii,
+ e.algo())?;
+ pd.dump_mpis(output, &ii, &[e.ciphertext()],
+ &["ciphertext"])?;
+ },
+ }
+ }
+ }
+
+ Ok(())
+ }
+
match p {
Unknown(ref u) => {
writeln!(output, "Unknown Packet")?;
@@ -257,6 +391,11 @@ impl PacketDumper {
writeln!(output, "{} Error: {}", i, u.error())?;
},
+ PublicKey(ref k) => dump_key(self, output, i, p, k)?,
+ PublicSubkey(ref k) => dump_key(self, output, i, p, k)?,
+ SecretKey(ref k) => dump_key(self, output, i, p, k)?,
+ SecretSubkey(ref k) => dump_key(self, output, i, p, k)?,
+
Signature(ref s) => {
writeln!(output, "Signature Packet")?;
writeln!(output, "{} Version: {}", i, s.version())?;
@@ -340,133 +479,6 @@ impl PacketDumper {
writeln!(output, "{} Last: {}", i, o.last())?;
},
- PublicKey(ref k) | PublicSubkey(ref k)
- | SecretKey(ref k) | SecretSubkey(ref k) =>
- {
- writeln!(output, "{}", p.tag())?;
- writeln!(output, "{} Version: {}", i, k.version())?;
- writeln!(output, "{} Creation time: {}", i,
- time::strftime(TIMEFMT, k.creation_time()).unwrap())?;
- writeln!(output, "{} Pk algo: {}", i, k.pk_algo())?;
- if let Some(bits) = k.mpis().bits() {
- writeln!(output, "{} Pk size: {} bits", i, bits)?;
- }
- if self.mpis {
- writeln!(output, "{}", i)?;
- writeln!(output, "{} Public Key:", i)?;
-
- let ii = format!("{} ", i);
- match k.mpis() {
- mpis::PublicKey::RSA { e, n } =>
- self.dump_mpis(output, &ii,
- &[e.value(), n.value()],
- &["e", "n"])?,
- mpis::PublicKey::DSA { p, q, g, y } =>
- self.dump_mpis(output, &ii,
- &[p.value(), q.value(), g.value(),
- y.value()],
- &["p", "q", "g", "y"])?,
- mpis::PublicKey::Elgamal { p, g, y } =>
- self.dump_mpis(output, &ii,
- &[p.value(), g.value(), y.value()],
- &["p", "g", "y"])?,
- mpis::PublicKey::EdDSA { curve, q } => {
- writeln!(output, "{} Curve: {}", ii, curve)?;
- self.dump_mpis(output, &ii, &[q.value()], &["q"])?;
- },
- mpis::PublicKey::ECDSA { curve, q } => {
- writeln!(output, "{} Curve: {}", ii, curve)?;
- self.dump_mpis(output, &ii, &[q.value()], &["q"])?;
- },
- mpis::PublicKey::ECDH { curve, q, hash, sym } => {
- writeln!(output, "{} Curve: {}", ii, curve)?;
- writeln!(output, "{} Hash algo: {}", ii, hash)?;
- writeln!(output, "{} Symmetric algo: {}", ii,
- sym)?;
- self.dump_mpis(output, &ii, &[q.value()], &["q"])?;
- },
- mpis::PublicKey::Unknown { mpis, rest } => {
- let keys: Vec<String> =
- (0..mpis.len()).map(
- |i| format!("mpi{}", i)).collect();
- self.dump_mpis(
- output, &ii,
- &mpis.iter().map(|m| {
- m.value().iter().as_slice()
- }).collect::<Vec<_>>()[..],
- &keys.iter().map(|k| k.as_str())
- .collect::<Vec<_>>()[..],
- )?;
-
- self.dump_mpis(output, &ii, &[&rest[..]], &["rest"])?;
- },
- }
-
- if let Some(secrets) = k.secret() {
- use self::openpgp::packet::key::SecretKeyMaterial;
- writeln!(output, "{}", i)?;
- writeln!(output, "{} Secret Key:", i)?;
-
- let ii = format!("{} ", i);
- match secrets {
- SecretKeyMaterial::Unencrypted(ref u) => u.map(
- |mpis| -> Result<()> {
- match mpis
- {
- mpis::SecretKeyMaterial::RSA { d, p, q, u } =>
- self.dump_mpis(output, &ii,
- &[d.value(), p.value(),
- q.value(), u.value()],
- &["d", "p", "q", "u"])?,
- mpis::SecretKeyMaterial::DSA { x } =>
- self.dump_mpis(output, &ii, &[x.value()],
- &["x"])?,
- mpis::SecretKeyMaterial::Elgamal { x } =>
- self.dump_mpis(output, &ii, &[x.value()],
- &["x"])?,
- mpis::SecretKeyMaterial::EdDSA { scalar } =>
- self.dump_mpis(output, &ii,
- &[scalar.value()],
- &["scalar"])?,
- mpis::SecretKeyMaterial::ECDSA { scalar } =>
- self.dump_mpis(output, &ii,
- &[scalar.value()],
- &["scalar"])?,
- mpis::SecretKeyMaterial::ECDH { scalar } =>
- self.dump_mpis(output, &ii,
- &[scalar.value()],
- &["scalar"])?,
- mpis::SecretKeyMaterial::Unknown { mpis, rest } => {
- let keys: Vec<String> =
- (0..mpis.len()).map(
- |i| format!("mpi{}", i)).collect();
- self.dump_mpis(
- output, &ii,
- &mpis.iter().map(|m| {
- m.value().iter().as_slice()
- }).collect::<Vec<_>>()[..],
- &keys.iter().map(|k| k.as_str())
- .collect::<Vec<_>>()[..],
- )?;
-
- self.dump_mpis(output, &ii, &[rest],
- &["rest"])?;
- },
- } Ok(()) })?,
- SecretKeyMaterial::Encrypted(ref e) => {
- writeln!(output, "{}", i)?;
- write!(output, "{} S2K: ", ii)?;
- self.dump_s2k(output, &ii, e.s2k())?;
- writeln!(output, "{} Sym. algo: {}", ii,
- e.algo())?;
- self.dump_mpis(output, &ii, &[e.ciphertext()],
- &["ciphertext"])?;
- },
- }
- }
- }
- },
-
Trust(ref p) => {
writeln!(output, "Trust Packet")?;
writeln!(output, "{} Value: {}", i, hex::encode(p.value()))?;
diff --git a/tool/src/commands/inspect.rs b/tool/src/commands/inspect.rs
index e9d42083..e1a73bc5 100644
--- a/tool/src/commands/inspect.rs
+++ b/tool/src/commands/inspect.rs
@@ -164,14 +164,17 @@ fn inspect_tpk(output: &mut io::Write, tpk: &openpgp::TPK,
Ok(())
}
-fn inspect_key(output: &mut io::Write,
- indent: &str,
- key: &openpgp::packet::Key,
- binding_signature: Option<&openpgp::packet::Signature>,
- certs: &[openpgp::packet::Signature],
- print_keygrips: bool,
- print_certifications: bool)
- -> Result<()> {
+fn inspect_key<P, R>(output: &mut io::Write,
+ indent: &str,
+ key: &openpgp::packet::Key<P, R>,
+ binding_signature: Option<&openpgp::packet::Signature>,
+ certs: &[openpgp::packet::Signature],
+ print_keygrips: bool,
+ print_certifications: bool)
+ -> Result<()>
+ where P: openpgp::packet::key::KeyParts,
+ R: openpgp::packet::key::KeyRole
+{
if let Some(sig) = binding_signature {
if sig.key_expired(key) {
writeln!(output, "{} Expired", indent)?;
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs
index c4175cd9..4593d95d 100644
--- a/tool/src/commands/mod.rs
+++ b/tool/src/commands/mod.rs
@@ -11,7 +11,7 @@ use sequoia_core::Context;
use crate::openpgp::constants::DataFormat;
use crate::openpgp::crypto;
use crate::openpgp::{TPK, KeyID, Result};
-use crate::openpgp::packet::key::SecretKeyMaterial;
+use crate::openpgp::packet::prelude::*;
use crate::openpgp::parse::{
Parse,
PacketParserResult,
@@ -42,7 +42,10 @@ fn tm2str(t: &time::Tm) -> String {
}
/// Returns suitable signing keys from a given list of TPKs.
-fn get_signing_keys(tpks: &[openpgp::TPK]) -> Result<Vec<crypto::KeyPair>> {
+fn get_signing_keys(tpks: &[openpgp::TPK])
+ -> Result<Vec<crypto::KeyPair<
+ openpgp::packet::key::UnspecifiedRole>>>
+{
let mut keys = Vec::new();
'next_tpk: for tsk in tpks {
for key in tsk.keys_valid()
@@ -115,7 +118,7 @@ pub fn encrypt(store: &mut store::Store,
if ! signers.is_empty() {
sink = Signer::with_intended_recipients(
sink,
- signers.iter_mut().map(|s| -> &mut dyn crypto::Signer { s })
+ signers.iter_mut().map(|s| -> &mut dyn crypto::Signer<_> { s })
.collect(),
&recipients,
None)?;
diff --git a/tool/src/commands/sign.rs b/tool/src/commands/sign.rs
index 749781dc..164b5710 100644
--- a/tool/src/commands/sign.rs
+++ b/tool/src/commands/sign.rs
@@ -84,7 +84,7 @@ fn sign_data(input: &mut io::Read, output_path: Option<&str>,
let mut keypairs = super::get_signing_keys(&secrets)?;
let signers = keypairs.iter_mut()
- .map(|s| -> &mut dyn crypto::Signer { s })
+ .map(|s| -> &mut dyn crypto::Signer<_> { s })
.collect();
// When extending a detached signature, prepend any existing
@@ -146,8 +146,8 @@ fn sign_message(input: &mut io::Read, output_path: Option<&str>,
// the loop, because the borrow checker does not understand that
// it happens only once.
let mut signers = Some(keypairs.iter_mut()
- .map(|s| -> &mut dyn crypto::Signer { s })
- .collect::<Vec<&mut dyn crypto::Signer>>());
+ .map(|s| -> &mut dyn crypto::Signer<_> { s })
+ .collect::<Vec<&mut dyn crypto::Signer<_>>>());
let mut sink = Message::new(output);