From 3dacda4a93b1d3b1ef44484ac2691eec0aa759c9 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Fri, 4 Dec 2020 14:32:07 +0100 Subject: openpgp: Make Key::verify more low-level. - Key::encrypt returns mpi::Ciphertext, not a PKESK packet. Similarly, change Key::verify to take a mpi::Signature instead of a Signature packet. --- openpgp/src/crypto/backend/cng/asymmetric.rs | 26 +++++++++++-------------- openpgp/src/crypto/backend/nettle/asymmetric.rs | 25 +++++++++++------------- openpgp/src/packet/signature.rs | 2 +- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs index c2fd0647..1ca6074c 100644 --- a/openpgp/src/crypto/backend/cng/asymmetric.rs +++ b/openpgp/src/crypto/backend/cng/asymmetric.rs @@ -11,7 +11,7 @@ use crate::crypto::mem::Protected; use crate::crypto::mpi; use crate::crypto::SessionKey; use crate::packet::key::{Key4, SecretParts}; -use crate::packet::{self, key, Key}; +use crate::packet::{key, Key}; use crate::types::{PublicKeyAlgorithm, SymmetricAlgorithm}; use crate::types::{Curve, HashAlgorithm}; @@ -413,19 +413,16 @@ impl Key { } /// Verifies the given signature. - pub fn verify(&self, sig: &packet::Signature, digest: &[u8]) -> Result<()> { + pub fn verify(&self, sig: &mpi::Signature, hash_algo: HashAlgorithm, + digest: &[u8]) -> Result<()> { use cng::asymmetric::{AsymmetricAlgorithm, AsymmetricAlgorithmId}; use cng::asymmetric::{AsymmetricKey, Public, Rsa}; use cng::asymmetric::ecc::NamedCurve; use cng::asymmetric::signature::{Verifier, SignaturePadding}; use cng::key_blob::RsaKeyPublicPayload; - use PublicKeyAlgorithm::*; - - #[allow(deprecated)] - let ok = match (sig.pk_algo(), self.mpis(), sig.mpis()) { - (RSASign, mpi::PublicKey::RSA { e, n }, mpi::Signature::RSA { s }) | - (RSAEncryptSign, mpi::PublicKey::RSA { e, n }, mpi::Signature::RSA { s }) => { + let ok = match (self.mpis(), sig) { + (mpi::PublicKey::RSA { e, n }, mpi::Signature::RSA { s }) => { // CNG accepts only full-size signatures. Since for RSA it's a // big-endian number, just left-pad with zeroes as necessary. let sig_diff = n.value().len().saturating_sub(s.value().len()); @@ -464,12 +461,12 @@ impl Key { // // [Section 5.2.2 and 5.2.3 of RFC 4880]: // https://tools.ietf.org/html/rfc4880#section-5.2.2 - let hash = sig.hash_algo().try_into()?; + let hash = hash_algo.try_into()?; let padding = SignaturePadding::pkcs1(hash); key.verify(digest, s, Some(padding)).map(|_| true)? }, - (DSA, mpi:: PublicKey::DSA { y, p, q, g }, mpi::Signature::DSA { r, s }) => { + (mpi::PublicKey::DSA { y, p, q, g }, mpi::Signature::DSA { r, s }) => { use win_crypto_ng::key_blob::{DsaKeyPublicPayload, DsaKeyPublicBlob}; use win_crypto_ng::key_blob::{DsaKeyPublicV2Payload, DsaKeyPublicV2Blob}; use win_crypto_ng::asymmetric::{Dsa, DsaPublicBlob}; @@ -582,7 +579,7 @@ impl Key { key.verify(digest, &signature, None).map(|_| true)? }, - (ECDSA, mpi::PublicKey::ECDSA { curve, q }, mpi::Signature::ECDSA { s, r }) => + (mpi::PublicKey::ECDSA { curve, q }, mpi::Signature::ECDSA { s, r }) => { let (x, y) = q.decode_point(curve)?; // CNG expects full-sized signatures @@ -630,7 +627,7 @@ impl Key { Error::UnsupportedEllipticCurve(curve.clone()).into()), } }, - (EdDSA, mpi::PublicKey::EdDSA { curve, q }, mpi::Signature::EdDSA { r, s }) => { + (mpi::PublicKey::EdDSA { curve, q }, mpi::Signature::EdDSA { r, s }) => { // CNG doesn't support EdDSA, use ed25519-dalek instead use ed25519_dalek::{PublicKey, Signature, SIGNATURE_LENGTH}; use ed25519_dalek::{Verifier}; @@ -660,9 +657,8 @@ impl Key { .map_err(|e| Error::BadSignature(e.to_string()))? }, _ => return Err(Error::MalformedPacket(format!( - "unsupported combination of algorithm {}, key {} and \ - signature {:?}.", - sig.pk_algo(), self.pk_algo(), sig.mpis())).into()), + "unsupported combination of key {} and signature {:?}.", + self.pk_algo(), sig)).into()), }; if ok { diff --git a/openpgp/src/crypto/backend/nettle/asymmetric.rs b/openpgp/src/crypto/backend/nettle/asymmetric.rs index cc7cb2e4..d7ec16cf 100644 --- a/openpgp/src/crypto/backend/nettle/asymmetric.rs +++ b/openpgp/src/crypto/backend/nettle/asymmetric.rs @@ -8,7 +8,7 @@ use nettle::{curve25519, ecc, ecdh, ecdsa, ed25519, dsa, rsa, random::Yarrow}; use crate::{Error, Result}; -use crate::packet::{self, key, Key}; +use crate::packet::{key, Key}; use crate::crypto::asymmetric::{KeyPair, Decryptor, Signer}; use crate::crypto::mpi::{self, MPI, PublicKey}; use crate::crypto::SessionKey; @@ -256,15 +256,13 @@ impl Key { } /// Verifies the given signature. - pub fn verify(&self, sig: &packet::Signature, digest: &[u8]) -> Result<()> + pub fn verify(&self, sig: &mpi::Signature, hash_algo: HashAlgorithm, + digest: &[u8]) -> Result<()> { - use crate::PublicKeyAlgorithm::*; use crate::crypto::mpi::Signature; - #[allow(deprecated)] - let ok = match (sig.pk_algo(), self.mpis(), sig.mpis()) { - (RSASign, PublicKey::RSA { e, n }, Signature::RSA { s }) | - (RSAEncryptSign, PublicKey::RSA { e, n }, Signature::RSA { s }) => { + let ok = match (self.mpis(), sig) { + (PublicKey::RSA { e, n }, Signature::RSA { s }) => { let key = rsa::PublicKey::new(n.value(), e.value())?; // As described in [Section 5.2.2 and 5.2.3 of RFC 4880], @@ -273,17 +271,17 @@ impl Key { // // [Section 5.2.2 and 5.2.3 of RFC 4880]: // https://tools.ietf.org/html/rfc4880#section-5.2.2 - rsa::verify_digest_pkcs1(&key, digest, sig.hash_algo().oid()?, + rsa::verify_digest_pkcs1(&key, digest, hash_algo.oid()?, s.value())? }, - (DSA, PublicKey::DSA{ y, p, q, g }, Signature::DSA { s, r }) => { + (PublicKey::DSA { y, p, q, g }, Signature::DSA { s, r }) => { let key = dsa::PublicKey::new(y.value()); let params = dsa::Params::new(p.value(), q.value(), g.value()); let signature = dsa::Signature::new(r.value(), s.value()); dsa::verify(¶ms, &key, digest, &signature) }, - (EdDSA, PublicKey::EdDSA{ curve, q }, Signature::EdDSA { r, s }) => + (PublicKey::EdDSA { curve, q }, Signature::EdDSA { r, s }) => match curve { Curve::Ed25519 => { if q.value().get(0).map(|&b| b != 0x40).unwrap_or(true) { @@ -326,7 +324,7 @@ impl Key { _ => return Err(Error::UnsupportedEllipticCurve(curve.clone()).into()), }, - (ECDSA, PublicKey::ECDSA{ curve, q }, Signature::ECDSA { s, r }) => + (PublicKey::ECDSA { curve, q }, Signature::ECDSA { s, r }) => { let (x, y) = q.decode_point(curve)?; let key = match curve { @@ -341,9 +339,8 @@ impl Key { ecdsa::verify(&key, digest, &signature) }, _ => return Err(Error::MalformedPacket(format!( - "unsupported combination of algorithm {}, key {} and \ - signature {:?}.", - sig.pk_algo(), self.pk_algo(), sig.mpis())).into()), + "unsupported combination of key {} and signature {:?}.", + self.pk_algo(), sig)).into()), }; if ok { diff --git a/openpgp/src/packet/signature.rs b/openpgp/src/packet/signature.rs index 3819bb18..ff952c7b 100644 --- a/openpgp/src/packet/signature.rs +++ b/openpgp/src/packet/signature.rs @@ -2353,7 +2353,7 @@ impl Signature { "Signature has no creation time subpacket".into()).into()); } - let result = key.verify(self, digest.as_ref()); + let result = key.verify(self.mpis(), self.hash_algo(), digest.as_ref()); if result.is_ok() { // Mark information in this signature as authenticated. -- cgit v1.2.3