From 0b4688e4a06b3077a6b93d0722f2fbfc1e989420 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Wed, 26 Apr 2023 15:20:22 +0200 Subject: openpgp: Harmonize Key::encrypt, make pk_algo match exhaustive. - This changes and harmonizes the behavior of Key::encrypt, notably it also returns more specific errors when a signature algorithm is used for encryption. - It also makes the matches over the public key algorithms exhaustive, so that when we add more algorithms in the future, we will see where we need to implement them. --- openpgp/src/crypto/backend/botan/asymmetric.rs | 33 +++++++++++++++++------- openpgp/src/crypto/backend/cng/asymmetric.rs | 11 +++++++- openpgp/src/crypto/backend/nettle/asymmetric.rs | 11 +++++++- openpgp/src/crypto/backend/openssl/asymmetric.rs | 13 ++++++++-- openpgp/src/crypto/backend/rust/asymmetric.rs | 11 +++++++- 5 files changed, 64 insertions(+), 15 deletions(-) (limited to 'openpgp/src') diff --git a/openpgp/src/crypto/backend/botan/asymmetric.rs b/openpgp/src/crypto/backend/botan/asymmetric.rs index 51ed2edc..0a3afbd1 100644 --- a/openpgp/src/crypto/backend/botan/asymmetric.rs +++ b/openpgp/src/crypto/backend/botan/asymmetric.rs @@ -247,9 +247,11 @@ impl Key { use crate::PublicKeyAlgorithm::*; #[allow(deprecated)] - match (self.pk_algo(), self.mpis()) { - (RSAEncryptSign, mpi::PublicKey::RSA { e, n }) | - (RSAEncrypt, mpi::PublicKey::RSA { e, n }) => { + match self.pk_algo() { + RSAEncryptSign | + RSAEncrypt => if let mpi::PublicKey::RSA { e, n } = + self.mpis() + { // The ciphertext has the length of the modulus. let ciphertext_len = n.value().len(); if data.len() + 11 > ciphertext_len { @@ -264,10 +266,15 @@ impl Key { Ok(mpi::Ciphertext::RSA { c: MPI::new(&esk), }) + } else { + Err(Error::MalformedPacket(format!( + "Expected RSA public key, got {:?}", self.mpis())).into()) }, - (ElGamalEncryptSign, mpi::PublicKey::ElGamal { p, g, y }) | - (ElGamalEncrypt, mpi::PublicKey::ElGamal { p, g, y }) => { + ElGamalEncryptSign | + ElGamalEncrypt => if let mpi::PublicKey::ElGamal { p, g, y } = + self.mpis() + { // OpenPGP encodes E and C separately, but our // cryptographic library concatenates them. let size = p.value().len(); @@ -288,14 +295,20 @@ impl Key { e: MPI::new(&esk[..size]), c: MPI::new(&esk[size..]), }) + } else { + Err(Error::MalformedPacket(format!( + "Expected ElGamal public key, got {:?}", self.mpis())).into()) }, - (ECDH, mpi::PublicKey::ECDH { .. }) => - crate::crypto::ecdh::encrypt(self.parts_as_public(), data), + ECDH => crate::crypto::ecdh::encrypt(self.parts_as_public(), data), - _ => return Err(Error::MalformedPacket(format!( - "unsupported combination of key {} and mpis {:?}.", - self.pk_algo(), self.mpis())).into()), + RSASign | DSA | ECDSA | EdDSA => + Err(Error::InvalidOperation( + format!("{} is not an encryption algorithm", self.pk_algo()) + ).into()), + + Private(_) | Unknown(_) => + Err(Error::UnsupportedPublicKeyAlgorithm(self.pk_algo()).into()), } } diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs index 1eb110af..3b541e55 100644 --- a/openpgp/src/crypto/backend/cng/asymmetric.rs +++ b/openpgp/src/crypto/backend/cng/asymmetric.rs @@ -411,8 +411,17 @@ impl Key { }, } }, + ECDH => crate::crypto::ecdh::encrypt(self.parts_as_public(), data), - algo => Err(Error::UnsupportedPublicKeyAlgorithm(algo).into()), + + RSASign | DSA | ECDSA | EdDSA => + Err(Error::InvalidOperation( + format!("{} is not an encryption algorithm", self.pk_algo()) + ).into()), + + ElGamalEncrypt | ElGamalEncryptSign | + Private(_) | Unknown(_) => + Err(Error::UnsupportedPublicKeyAlgorithm(self.pk_algo()).into()), } } diff --git a/openpgp/src/crypto/backend/nettle/asymmetric.rs b/openpgp/src/crypto/backend/nettle/asymmetric.rs index 54fa31d2..c96ccaf0 100644 --- a/openpgp/src/crypto/backend/nettle/asymmetric.rs +++ b/openpgp/src/crypto/backend/nettle/asymmetric.rs @@ -222,9 +222,18 @@ impl Key { }, } }, + ECDH => crate::crypto::ecdh::encrypt(self.parts_as_public(), data), - algo => Err(Error::UnsupportedPublicKeyAlgorithm(algo).into()), + + RSASign | DSA | ECDSA | EdDSA => + Err(Error::InvalidOperation( + format!("{} is not an encryption algorithm", self.pk_algo()) + ).into()), + + ElGamalEncrypt | ElGamalEncryptSign | + Private(_) | Unknown(_) => + Err(Error::UnsupportedPublicKeyAlgorithm(self.pk_algo()).into()), } } diff --git a/openpgp/src/crypto/backend/openssl/asymmetric.rs b/openpgp/src/crypto/backend/openssl/asymmetric.rs index 1d586585..3ba3ca64 100644 --- a/openpgp/src/crypto/backend/openssl/asymmetric.rs +++ b/openpgp/src/crypto/backend/openssl/asymmetric.rs @@ -1,4 +1,4 @@ -use crate::Result; +use crate::{Error, Result}; use crate::crypto::asymmetric::{Decryptor, KeyPair, Signer}; use crate::crypto::mpi; @@ -289,8 +289,17 @@ impl Key { )) .into()), }, + ECDH => crate::crypto::ecdh::encrypt(self.parts_as_public(), data), - algo => Err(crate::Error::UnsupportedPublicKeyAlgorithm(algo).into()), + + RSASign | DSA | ECDSA | EdDSA => + Err(Error::InvalidOperation( + format!("{} is not an encryption algorithm", self.pk_algo()) + ).into()), + + ElGamalEncrypt | ElGamalEncryptSign | + Private(_) | Unknown(_) => + Err(Error::UnsupportedPublicKeyAlgorithm(self.pk_algo()).into()), } } diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs index 4090fdbb..c20363dd 100644 --- a/openpgp/src/crypto/backend/rust/asymmetric.rs +++ b/openpgp/src/crypto/backend/rust/asymmetric.rs @@ -243,8 +243,17 @@ impl Key { pk => Err(Error::MalformedPacket(format!( "Key: Expected RSA public key, got {:?}", pk)).into()) } + ECDH => crate::crypto::ecdh::encrypt(self.parts_as_public(), data), - algo => Err(Error::UnsupportedPublicKeyAlgorithm(algo).into()), + + RSASign | DSA | ECDSA | EdDSA => + Err(Error::InvalidOperation( + format!("{} is not an encryption algorithm", self.pk_algo()) + ).into()), + + ElGamalEncrypt | ElGamalEncryptSign | + Private(_) | Unknown(_) => + Err(Error::UnsupportedPublicKeyAlgorithm(self.pk_algo()).into()), } } -- cgit v1.2.3