From 41fd3f08adff856ec558f8b06214e0f392893a26 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 5 Dec 2019 16:13:54 +0100 Subject: openpgp: Make crypto::{Signer,Decryptor} non-polymorphic. - These are low-level cryptographic traits that are not concerned with the role of a key. - Fixes #382. --- openpgp/examples/decrypt-with.rs | 3 +-- openpgp/src/cert/bindings.rs | 47 ++++++++++++++++-------------------- openpgp/src/cert/mod.rs | 17 ++++++------- openpgp/src/cert/revoke.rs | 32 +++++++++++-------------- openpgp/src/crypto/asymmetric.rs | 48 +++++++++++++------------------------ openpgp/src/packet/mod.rs | 9 +++---- openpgp/src/packet/pkesk.rs | 3 +-- openpgp/src/packet/signature/mod.rs | 47 +++++++++++++++--------------------- openpgp/src/serialize/stream.rs | 12 +++++----- 9 files changed, 91 insertions(+), 127 deletions(-) (limited to 'openpgp') diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index 537e8f8b..224a8726 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -10,7 +10,6 @@ extern crate sequoia_openpgp as openpgp; use crate::openpgp::crypto::{KeyPair, SessionKey}; use crate::openpgp::types::SymmetricAlgorithm; -use crate::openpgp::packet::key; use crate::openpgp::parse::{ Parse, stream::{ @@ -50,7 +49,7 @@ pub fn main() { /// keys for the signature verification and implements the /// verification policy. struct Helper { - keys: HashMap>, + keys: HashMap, } impl Helper { diff --git a/openpgp/src/cert/bindings.rs b/openpgp/src/cert/bindings.rs index 70ade707..c6d9e6c6 100644 --- a/openpgp/src/cert/bindings.rs +++ b/openpgp/src/cert/bindings.rs @@ -52,12 +52,11 @@ impl Key { /// // Check that we have an encryption subkey. /// assert_eq!(cert.keys_valid().key_flags(flags).count(), 1); /// # Ok(()) } - pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, - signature: signature::Builder, - creation_time: T) + pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, + signature: signature::Builder, + creation_time: T) -> Result - where T: Into>, - R: key::KeyRole + where T: Into> { signature .set_signature_creation_time( @@ -110,12 +109,11 @@ impl UserID { /// // Check that we have a userid. /// assert_eq!(cert.userids().len(), 1); /// # Ok(()) } - pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, - signature: signature::Builder, - creation_time: T) - -> Result - where T: Into>, - R: key::KeyRole + pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, + signature: signature::Builder, + creation_time: T) + -> Result + where T: Into> { signature .set_signature_creation_time( @@ -180,14 +178,13 @@ impl UserID { /// // Check that we have a certification on the userid. /// assert_eq!(bob.userids().nth(0).unwrap().certifications().len(), 1); /// # Ok(()) } - pub fn certify(&self, signer: &mut dyn Signer, cert: &Cert, - signature_type: S, - hash_algo: H, creation_time: T) + pub fn certify(&self, signer: &mut dyn Signer, cert: &Cert, + signature_type: S, + hash_algo: H, creation_time: T) -> Result where S: Into>, H: Into>, - T: Into>, - R: key::KeyRole + T: Into> { let typ = signature_type.into(); let typ = match typ { @@ -257,12 +254,11 @@ impl UserAttribute { /// // Check that we have a user attribute. /// assert_eq!(cert.user_attributes().len(), 1); /// # Ok(()) } - pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, - signature: signature::Builder, - creation_time: T) + pub fn bind(&self, signer: &mut dyn Signer, cert: &Cert, + signature: signature::Builder, + creation_time: T) -> Result - where T: Into>, - R: key::KeyRole + where T: Into> { signature .set_signature_creation_time( @@ -331,14 +327,13 @@ impl UserAttribute { /// assert_eq!(bob.user_attributes().nth(0).unwrap().certifications().len(), /// 1); /// # Ok(()) } - pub fn certify(&self, signer: &mut dyn Signer, cert: &Cert, - signature_type: S, - hash_algo: H, creation_time: T) + pub fn certify(&self, signer: &mut dyn Signer, cert: &Cert, + signature_type: S, + hash_algo: H, creation_time: T) -> Result where S: Into>, H: Into>, - T: Into>, - R: key::KeyRole + T: Into> { let typ = signature_type.into(); let typ = match typ { diff --git a/openpgp/src/cert/mod.rs b/openpgp/src/cert/mod.rs index 23db1bc8..d0999a95 100644 --- a/openpgp/src/cert/mod.rs +++ b/openpgp/src/cert/mod.rs @@ -1095,10 +1095,9 @@ impl Cert { /// # Ok(()) /// # } /// ``` - pub fn revoke_in_place(self, primary_signer: &mut dyn Signer, - code: ReasonForRevocation, reason: &[u8]) + pub fn revoke_in_place(self, primary_signer: &mut dyn Signer, + code: ReasonForRevocation, reason: &[u8]) -> Result - where R: key::KeyRole { let sig = CertRevocationBuilder::new() .set_reason_for_revocation(code, reason)? @@ -1137,11 +1136,10 @@ impl Cert { /// /// This function exists to facilitate testing, which is why it is /// not exported. - fn set_expiry_as_of(self, primary_signer: &mut dyn Signer, - expiration: Option, - now: time::SystemTime) + fn set_expiry_as_of(self, primary_signer: &mut dyn Signer, + expiration: Option, + now: time::SystemTime) -> Result - where R: key::KeyRole { let sig = { let (template, userid) = self @@ -1173,10 +1171,9 @@ impl Cert { /// /// Note: the time is relative to the key's creation time, not the /// current time! - pub fn set_expiry(self, primary_signer: &mut dyn Signer, - expiration: Option) + pub fn set_expiry(self, primary_signer: &mut dyn Signer, + expiration: Option) -> Result - where R: key::KeyRole { self.set_expiry_as_of(primary_signer, expiration, time::SystemTime::now()) diff --git a/openpgp/src/cert/revoke.rs b/openpgp/src/cert/revoke.rs index f4f6e31c..a4876e0f 100644 --- a/openpgp/src/cert/revoke.rs +++ b/openpgp/src/cert/revoke.rs @@ -100,10 +100,9 @@ impl CertRevocationBuilder { /// Returns a revocation certificate for the cert `Cert` signed by /// `signer`. - pub fn build(self, signer: &mut dyn Signer, cert: &Cert, hash_algo: H) + pub fn build(self, signer: &mut dyn Signer, cert: &Cert, hash_algo: H) -> Result - where H: Into>, - R: key::KeyRole + where H: Into> { let hash_algo = hash_algo.into().unwrap_or(HashAlgorithm::SHA512); let mut hash = hash_algo.context()?; @@ -221,12 +220,11 @@ impl SubkeyRevocationBuilder { /// Returns a revocation certificate for the cert `Cert` signed by /// `signer`. - pub fn build(mut self, signer: &mut dyn Signer, - cert: &Cert, key: &key::PublicSubkey, - hash_algo: H) + pub fn build(mut self, signer: &mut dyn Signer, + cert: &Cert, key: &key::PublicSubkey, + hash_algo: H) -> Result - where H: Into>, - R: key::KeyRole + where H: Into> { let hash_algo = hash_algo.into().unwrap_or(HashAlgorithm::SHA512); let creation_time @@ -337,12 +335,11 @@ impl UserIDRevocationBuilder { /// Returns a revocation certificate for the cert `Cert` signed by /// `signer`. - pub fn build(mut self, signer: &mut dyn Signer, - cert: &Cert, userid: &UserID, - hash_algo: H) + pub fn build(mut self, signer: &mut dyn Signer, + cert: &Cert, userid: &UserID, + hash_algo: H) -> Result - where H: Into>, - R: key::KeyRole + where H: Into> { let hash_algo = hash_algo.into().unwrap_or(HashAlgorithm::SHA512); let creation_time @@ -456,12 +453,11 @@ impl UserAttributeRevocationBuilder { /// Returns a revocation certificate for the cert `Cert` signed by /// `signer`. - pub fn build(mut self, signer: &mut dyn Signer, - cert: &Cert, ua: &UserAttribute, - hash_algo: H) + pub fn build(mut self, signer: &mut dyn Signer, + cert: &Cert, ua: &UserAttribute, + hash_algo: H) -> Result - where H: Into>, - R: key::KeyRole + where H: Into> { let hash_algo = hash_algo.into().unwrap_or(HashAlgorithm::SHA512); let creation_time diff --git a/openpgp/src/crypto/asymmetric.rs b/openpgp/src/crypto/asymmetric.rs index e67461ce..7185a471 100644 --- a/openpgp/src/crypto/asymmetric.rs +++ b/openpgp/src/crypto/asymmetric.rs @@ -16,19 +16,17 @@ use crate::Result; /// signature. Using this trait allows Sequoia to perform all /// operations involving signing to use a variety of secret key /// storage mechanisms (e.g. smart cards). -pub trait Signer - where R: key::KeyRole -{ +pub trait Signer { /// Returns a reference to the public key. - fn public(&self) -> &Key; + fn public(&self) -> &Key; /// Creates a signature over the `digest` produced by `hash_algo`. fn sign(&mut self, hash_algo: HashAlgorithm, digest: &[u8]) -> Result; } -impl Signer for Box> { - fn public(&self) -> &Key { +impl Signer for Box { + fn public(&self) -> &Key { self.as_ref().public() } @@ -44,11 +42,9 @@ impl Signer for Box> { /// ciphertext. Using this trait allows Sequoia to perform all /// operations involving decryption to use a variety of secret key /// storage mechanisms (e.g. smart cards). -pub trait Decryptor - where R: key::KeyRole -{ +pub trait Decryptor { /// Returns a reference to the public key. - fn public(&self) -> &Key; + fn public(&self) -> &Key; /// Decrypts `ciphertext`, returning the plain session key. fn decrypt(&mut self, ciphertext: &mpis::Ciphertext) @@ -64,18 +60,14 @@ pub trait Decryptor /// [`Signer`]: trait.Signer.html /// [`Decryptor`]: trait.Decryptor.html #[derive(Clone)] -pub struct KeyPair - where R: key::KeyRole -{ - public: Key, +pub struct KeyPair { + public: Key, secret: packet::key::Unencrypted, } -impl KeyPair - where R: key::KeyRole -{ +impl KeyPair { /// Creates a new key pair. - pub fn new(public: Key, + pub fn new(public: Key, secret: packet::key::Unencrypted) -> Result { @@ -86,7 +78,7 @@ impl KeyPair } /// Returns a reference to the public key. - pub fn public(&self) -> &Key { + pub fn public(&self) -> &Key { &self.public } @@ -96,10 +88,8 @@ impl KeyPair } } -impl Signer for KeyPair - where R: key::KeyRole -{ - fn public(&self) -> &Key { +impl Signer for KeyPair { + fn public(&self) -> &Key { &self.public } @@ -226,10 +216,8 @@ impl Signer for KeyPair } } -impl Decryptor for KeyPair - where R: key::KeyRole -{ - fn public(&self) -> &Key { +impl Decryptor for KeyPair { + fn public(&self) -> &Key { &self.public } @@ -274,10 +262,8 @@ impl Decryptor for KeyPair } } -impl From> for Key - where R: key::KeyRole -{ - fn from(p: KeyPair) -> Self { +impl From for Key { + fn from(p: KeyPair) -> Self { let (mut key, secret) = (p.public, p.secret); key.set_secret(Some(secret.into())); key.mark_parts_secret().expect("XXX") diff --git a/openpgp/src/packet/mod.rs b/openpgp/src/packet/mod.rs index fe756298..ca9a39de 100644 --- a/openpgp/src/packet/mod.rs +++ b/openpgp/src/packet/mod.rs @@ -744,7 +744,7 @@ impl Key { /// # Errors /// /// Fails if the secret key is missing, or encrypted. - pub fn into_keypair(mut self) -> Result> { + pub fn into_keypair(mut self) -> Result { use crate::packet::key::SecretKeyMaterial; let secret = match self.set_secret(None) { Some(SecretKeyMaterial::Unencrypted(secret)) => secret, @@ -756,7 +756,7 @@ impl Key { "no secret key".into()).into()), }; - KeyPair::new(self.into(), secret) + KeyPair::new(self.mark_role_unspecified().into(), secret) } } @@ -767,7 +767,7 @@ impl key::Key4 { /// # Errors /// /// Fails if the secret key is missing, or encrypted. - pub fn into_keypair(mut self) -> Result> { + pub fn into_keypair(mut self) -> Result { use crate::packet::key::SecretKeyMaterial; let secret = match self.set_secret(None) { Some(SecretKeyMaterial::Unencrypted(secret)) => secret, @@ -779,7 +779,8 @@ impl key::Key4 { "no secret key".into()).into()), }; - KeyPair::new(self.mark_parts_public().into(), secret) + KeyPair::new(self.mark_role_unspecified().mark_parts_public().into(), + secret) } } diff --git a/openpgp/src/packet/pkesk.rs b/openpgp/src/packet/pkesk.rs index f307dd9c..db88c215 100644 --- a/openpgp/src/packet/pkesk.rs +++ b/openpgp/src/packet/pkesk.rs @@ -149,9 +149,8 @@ impl PKESK3 { /// Decrypts the ESK and returns the session key and symmetric algorithm /// used to encrypt the following payload. - pub fn decrypt(&self, decryptor: &mut dyn Decryptor) + pub fn decrypt(&self, decryptor: &mut dyn Decryptor) -> Result<(SymmetricAlgorithm, SessionKey)> - where R: key::KeyRole { let plain = decryptor.decrypt(&self.esk)?; let key_rgn = 1..(plain.len() - 2); diff --git a/openpgp/src/packet/signature/mod.rs b/openpgp/src/packet/signature/mod.rs index 199f7a88..1740e727 100644 --- a/openpgp/src/packet/signature/mod.rs +++ b/openpgp/src/packet/signature/mod.rs @@ -138,9 +138,8 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_standalone(mut self, signer: &mut dyn Signer) - -> Result - where R: key::KeyRole + pub fn sign_standalone(mut self, signer: &mut dyn Signer) + -> Result { self.pk_algo = signer.public().pk_algo(); let digest = Signature::standalone_hash(&self)?; @@ -151,9 +150,8 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_timestamp(mut self, signer: &mut dyn Signer) - -> Result - where R: key::KeyRole + pub fn sign_timestamp(mut self, signer: &mut dyn Signer) + -> Result { self.pk_algo = signer.public().pk_algo(); let digest = Signature::timestamp_hash(&self)?; @@ -164,9 +162,8 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_primary_key_binding(mut self, signer: &mut dyn Signer) + pub fn sign_primary_key_binding(mut self, signer: &mut dyn Signer) -> Result - where R: key::KeyRole { self.pk_algo = signer.public().pk_algo(); let digest = @@ -181,11 +178,10 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_userid_binding(mut self, signer: &mut dyn Signer, - key: &key::PublicKey, - userid: &UserID) + pub fn sign_userid_binding(mut self, signer: &mut dyn Signer, + key: &key::PublicKey, + userid: &UserID) -> Result - where R: key::KeyRole { self.pk_algo = signer.public().pk_algo(); let digest = Signature::userid_binding_hash(&self, key, userid)?; @@ -197,12 +193,11 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_subkey_binding(mut self, signer: &mut dyn Signer, - primary: &key::PublicKey, - subkey: &Key) + pub fn sign_subkey_binding

(mut self, signer: &mut dyn Signer, + primary: &key::PublicKey, + subkey: &Key) -> Result - where P: key:: KeyParts, - R: key::KeyRole + where P: key:: KeyParts { self.pk_algo = signer.public().pk_algo(); let digest = Signature::subkey_binding_hash(&self, primary, subkey)?; @@ -214,11 +209,10 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_user_attribute_binding(mut self, signer: &mut dyn Signer, - key: &key::PublicKey, - ua: &UserAttribute) + pub fn sign_user_attribute_binding(mut self, signer: &mut dyn Signer, + key: &key::PublicKey, + ua: &UserAttribute) -> Result - where R: key::KeyRole { self.pk_algo = signer.public().pk_algo(); let digest = @@ -231,10 +225,9 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_hash(mut self, signer: &mut dyn Signer, - mut hash: hash::Context) + pub fn sign_hash(mut self, signer: &mut dyn Signer, + mut hash: hash::Context) -> Result - where R: key::KeyRole { // Fill out some fields, then hash the packet. self.pk_algo = signer.public().pk_algo(); @@ -252,9 +245,8 @@ impl Builder { /// /// The Signature's public-key algorithm field is set to the /// algorithm used by `signer`. - pub fn sign_message(mut self, signer: &mut dyn Signer, msg: &[u8]) + pub fn sign_message(mut self, signer: &mut dyn Signer, msg: &[u8]) -> Result - where R: key::KeyRole { // Hash the message let mut hash = self.hash_algo.context()?; @@ -271,9 +263,8 @@ impl Builder { self.sign(signer, digest) } - fn sign(self, signer: &mut dyn Signer, digest: Vec) + fn sign(self, signer: &mut dyn Signer, digest: Vec) -> Result - where R: key::KeyRole { let algo = self.hash_algo; let mpis = signer.sign(algo, &digest)?; diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index 0ee18a18..35b08b1a 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -203,7 +203,7 @@ pub struct Signer<'a> { // take our inner reader. If that happens, we only update the // digests. inner: Option>, - signers: Vec + 'a>>, + signers: Vec>, intended_recipients: Vec, detached: bool, hash: crypto::hash::Context, @@ -231,7 +231,7 @@ impl<'a> Signer<'a> { /// # let keypair = tsk.keys_valid().for_signing().nth(0).unwrap().2 /// # .clone().mark_parts_secret().unwrap().into_keypair().unwrap(); /// # f(tsk, keypair).unwrap(); - /// # fn f(cert: Cert, mut signing_keypair: KeyPair) + /// # fn f(cert: Cert, mut signing_keypair: KeyPair) /// # -> Result<()> { /// /// let mut o = vec![]; @@ -272,7 +272,7 @@ impl<'a> Signer<'a> { /// # } /// ``` pub fn new(inner: writer::Stack<'a, Cookie>, signer: S) -> Self - where S: crypto::Signer + 'a + where S: crypto::Signer + 'a { let inner = writer::BoxStack::from(inner); let level = inner.cookie_ref().level + 1; @@ -298,7 +298,7 @@ impl<'a> Signer<'a> { /// Adds an additional signer. pub fn add_signer(mut self, signer: S) -> Self - where S: crypto::Signer + 'a + where S: crypto::Signer + 'a { self.signers.push(Box::new(signer)); self @@ -334,7 +334,7 @@ impl<'a> Signer<'a> { /// # let keypair = tsk.keys_valid().for_signing().nth(0).unwrap().2 /// # .clone().mark_parts_secret().unwrap().into_keypair().unwrap(); /// # f(tsk, keypair).unwrap(); - /// # fn f(cert: Cert, mut signing_keypair: KeyPair) + /// # fn f(cert: Cert, mut signing_keypair: KeyPair) /// # -> Result<()> { /// /// let mut o = vec![]; @@ -1479,7 +1479,7 @@ mod test { let mut signers = keys.iter().map(|(_, key)| { key.clone().mark_parts_secret().unwrap().into_keypair() .expect("expected unencrypted secret key") - }).collect::>>(); + }).collect::>(); let m = Message::new(&mut o); let mut signer = Signer::new(m, signers.pop().unwrap()); -- cgit v1.2.3