summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-05-12 18:53:49 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-05-22 12:00:11 +0200
commitd1fb7c0582058ccbe262b6650ca43f627ed8d628 (patch)
treeb9901e5542a8dc85adf389100ab31c07b5db5d8b
parent995a7cff7fa0cd3273d8dad8080f6b50de79eaa9 (diff)
openpgp: Formalize reporting of supported algorithms.
-rw-r--r--openpgp/src/crypto/backend/botan.rs29
-rw-r--r--openpgp/src/crypto/backend/botan/asymmetric.rs25
-rw-r--r--openpgp/src/crypto/backend/cng.rs25
-rw-r--r--openpgp/src/crypto/backend/cng/asymmetric.rs21
-rw-r--r--openpgp/src/crypto/backend/interface.rs17
-rw-r--r--openpgp/src/crypto/backend/nettle.rs25
-rw-r--r--openpgp/src/crypto/backend/nettle/asymmetric.rs21
-rw-r--r--openpgp/src/crypto/backend/openssl.rs33
-rw-r--r--openpgp/src/crypto/backend/openssl/asymmetric.rs28
-rw-r--r--openpgp/src/crypto/backend/rust.rs31
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs27
-rw-r--r--openpgp/src/types/mod.rs6
12 files changed, 143 insertions, 145 deletions
diff --git a/openpgp/src/crypto/backend/botan.rs b/openpgp/src/crypto/backend/botan.rs
index cf5e295e..3f1ab906 100644
--- a/openpgp/src/crypto/backend/botan.rs
+++ b/openpgp/src/crypto/backend/botan.rs
@@ -22,35 +22,6 @@ impl super::interface::Backend for Backend {
}
}
-impl PublicKeyAlgorithm {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use PublicKeyAlgorithm::*;
- #[allow(deprecated)]
- match &self {
- RSAEncryptSign | RSAEncrypt | RSASign | DSA | ECDH | ECDSA | EdDSA |
- ElGamalEncrypt | ElGamalEncryptSign
- => true,
- Private(_) | Unknown(_)
- => false,
- }
- }
-}
-
-impl Curve {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use self::Curve::*;
- match &self {
- NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519 |
- BrainpoolP256 | BrainpoolP512
- => true,
- Unknown(_) if self.is_brainpoolp384() // XXX
- => true,
- Unknown(_)
- => false,
- }
- }
-}
-
impl AEADAlgorithm {
/// Returns the best AEAD mode supported by the backend.
///
diff --git a/openpgp/src/crypto/backend/botan/asymmetric.rs b/openpgp/src/crypto/backend/botan/asymmetric.rs
index d9f989ad..c817aafd 100644
--- a/openpgp/src/crypto/backend/botan/asymmetric.rs
+++ b/openpgp/src/crypto/backend/botan/asymmetric.rs
@@ -34,6 +34,31 @@ use crate::{
};
impl Asymmetric for super::Backend {
+ fn supports_algo(algo: PublicKeyAlgorithm) -> bool {
+ use PublicKeyAlgorithm::*;
+ #[allow(deprecated)]
+ match algo {
+ RSAEncryptSign | RSAEncrypt | RSASign | DSA | ECDH | ECDSA | EdDSA |
+ ElGamalEncrypt | ElGamalEncryptSign
+ => true,
+ Private(_) | Unknown(_)
+ => false,
+ }
+ }
+
+ fn supports_curve(curve: &Curve) -> bool {
+ use Curve::*;
+ match curve {
+ NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519 |
+ BrainpoolP256 | BrainpoolP512
+ => true,
+ Unknown(_) if curve.is_brainpoolp384() // XXX
+ => true,
+ Unknown(_)
+ => false,
+ }
+ }
+
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
let mut rng = RandomNumberGenerator::new_userspace()?;
let secret = Privkey::create("Curve25519", "", &mut rng)?;
diff --git a/openpgp/src/crypto/backend/cng.rs b/openpgp/src/crypto/backend/cng.rs
index d40b904b..9f43958f 100644
--- a/openpgp/src/crypto/backend/cng.rs
+++ b/openpgp/src/crypto/backend/cng.rs
@@ -25,31 +25,6 @@ impl super::interface::Backend for Backend {
}
}
-impl PublicKeyAlgorithm {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use PublicKeyAlgorithm::*;
- #[allow(deprecated)]
- match &self {
- RSAEncryptSign | RSAEncrypt | RSASign | DSA | ECDH | ECDSA | EdDSA
- => true,
- ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_)
- => false,
- }
- }
-}
-
-impl Curve {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use self::Curve::*;
- match &self {
- NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519
- => true,
- BrainpoolP256 | BrainpoolP512 | Unknown(_)
- => false,
- }
- }
-}
-
impl AEADAlgorithm {
/// Returns the best AEAD mode supported by the backend.
///
diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs
index 91c7700c..38eb1905 100644
--- a/openpgp/src/crypto/backend/cng/asymmetric.rs
+++ b/openpgp/src/crypto/backend/cng/asymmetric.rs
@@ -23,6 +23,27 @@ use win_crypto_ng as cng;
const CURVE25519_SIZE: usize = 32;
impl Asymmetric for super::Backend {
+ fn supports_algo(algo: PublicKeyAlgorithm) -> bool {
+ use PublicKeyAlgorithm::*;
+ #[allow(deprecated)]
+ match algo {
+ RSAEncryptSign | RSAEncrypt | RSASign | DSA | ECDH | ECDSA | EdDSA
+ => true,
+ ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_)
+ => false,
+ }
+ }
+
+ fn supports_curve(curve: &Curve) -> bool {
+ use Curve::*;
+ match curve {
+ NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519
+ => true,
+ BrainpoolP256 | BrainpoolP512 | Unknown(_)
+ => false,
+ }
+ }
+
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
use cng::asymmetric::{Ecdh, AsymmetricKey, Export};
use cng::asymmetric::ecc::Curve25519;
diff --git a/openpgp/src/crypto/backend/interface.rs b/openpgp/src/crypto/backend/interface.rs
index 21034862..ad539b16 100644
--- a/openpgp/src/crypto/backend/interface.rs
+++ b/openpgp/src/crypto/backend/interface.rs
@@ -3,6 +3,7 @@
use crate::{
Result,
crypto::mem::Protected,
+ types::{Curve, PublicKeyAlgorithm},
};
/// Abstracts over the cryptographic backends.
@@ -25,6 +26,22 @@ pub trait Backend: Asymmetric {
/// Public-key cryptography interface.
pub trait Asymmetric {
+ /// Returns whether the given public key cryptography algorithm is
+ /// supported by this backend.
+ ///
+ /// Note: when implementing this function, match exhaustively on
+ /// `algo`, do not use a catch-all. This way, when new algorithms
+ /// are introduced, we will see where we may need to add support.
+ fn supports_algo(algo: PublicKeyAlgorithm) -> bool;
+
+ /// Returns whether the given elliptic curve is supported by this
+ /// backend.
+ ///
+ /// Note: when implementing this function, match exhaustively on
+ /// `curve`, do not use a catch-all. This way, when new algorithms
+ /// are introduced, we will see where we may need to add support.
+ fn supports_curve(curve: &Curve) -> bool;
+
/// Generates an X25519 key pair.
///
/// Returns a tuple containing the secret and public key.
diff --git a/openpgp/src/crypto/backend/nettle.rs b/openpgp/src/crypto/backend/nettle.rs
index cf144f26..a8624513 100644
--- a/openpgp/src/crypto/backend/nettle.rs
+++ b/openpgp/src/crypto/backend/nettle.rs
@@ -29,31 +29,6 @@ impl super::interface::Backend for Backend {
}
}
-impl PublicKeyAlgorithm {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use PublicKeyAlgorithm::*;
- #[allow(deprecated)]
- match &self {
- RSAEncryptSign | RSAEncrypt | RSASign | DSA | ECDH | ECDSA | EdDSA
- => true,
- ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_)
- => false,
- }
- }
-}
-
-impl Curve {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use self::Curve::*;
- match &self {
- NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519
- => true,
- BrainpoolP256 | BrainpoolP512 | Unknown(_)
- => false,
- }
- }
-}
-
impl AEADAlgorithm {
/// Returns the best AEAD mode supported by the backend.
///
diff --git a/openpgp/src/crypto/backend/nettle/asymmetric.rs b/openpgp/src/crypto/backend/nettle/asymmetric.rs
index 06dcf2aa..2e631edd 100644
--- a/openpgp/src/crypto/backend/nettle/asymmetric.rs
+++ b/openpgp/src/crypto/backend/nettle/asymmetric.rs
@@ -16,6 +16,27 @@ use crate::crypto::SessionKey;
use crate::types::{Curve, HashAlgorithm};
impl Asymmetric for super::Backend {
+ fn supports_algo(algo: PublicKeyAlgorithm) -> bool {
+ use PublicKeyAlgorithm::*;
+ #[allow(deprecated)]
+ match algo {
+ RSAEncryptSign | RSAEncrypt | RSASign | DSA | ECDH | ECDSA | EdDSA
+ => true,
+ ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_)
+ => false,
+ }
+ }
+
+ fn supports_curve(curve: &Curve) -> bool {
+ use Curve::*;
+ match curve {
+ NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519
+ => true,
+ BrainpoolP256 | BrainpoolP512 | Unknown(_)
+ => false,
+ }
+ }
+
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
debug_assert_eq!(curve25519::CURVE25519_SIZE, 32);
let mut rng = Yarrow::default();
diff --git a/openpgp/src/crypto/backend/openssl.rs b/openpgp/src/crypto/backend/openssl.rs
index 70d20de4..96679e2d 100644
--- a/openpgp/src/crypto/backend/openssl.rs
+++ b/openpgp/src/crypto/backend/openssl.rs
@@ -1,5 +1,4 @@
//! Implementation of Sequoia crypto API using the OpenSSL cryptographic library.
-use std::convert::TryFrom;
use crate::types::*;
@@ -22,38 +21,6 @@ impl super::interface::Backend for Backend {
}
}
-impl PublicKeyAlgorithm {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use PublicKeyAlgorithm::*;
- #[allow(deprecated)]
- match self {
- RSAEncryptSign | RSAEncrypt | RSASign => true,
- DSA => true,
- ECDH | ECDSA | EdDSA => true,
- ElGamalEncrypt | ElGamalEncryptSign |
- Private(_) | Unknown(_)
- => false,
- }
- }
-}
-
-impl Curve {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- if matches!(self, Curve::Ed25519 | Curve::Cv25519) {
- // 25519-based algorithms are special-cased and supported
- true
- } else {
- // the rest of EC algorithms are supported via the same
- // codepath
- if let Ok(nid) = openssl::nid::Nid::try_from(self) {
- openssl::ec::EcGroup::from_curve_name(nid).is_ok()
- } else {
- false
- }
- }
- }
-}
-
impl AEADAlgorithm {
/// Returns the best AEAD mode supported by the backend.
///
diff --git a/openpgp/src/crypto/backend/openssl/asymmetric.rs b/openpgp/src/crypto/backend/openssl/asymmetric.rs
index 396ab0f1..61a0b735 100644
--- a/openpgp/src/crypto/backend/openssl/asymmetric.rs
+++ b/openpgp/src/crypto/backend/openssl/asymmetric.rs
@@ -24,6 +24,34 @@ use openssl::sign::Signer as OpenSslSigner;
use openssl::sign::Verifier;
impl Asymmetric for super::Backend {
+ fn supports_algo(algo: PublicKeyAlgorithm) -> bool {
+ use PublicKeyAlgorithm::*;
+ #[allow(deprecated)]
+ match algo {
+ RSAEncryptSign | RSAEncrypt | RSASign => true,
+ DSA => true,
+ ECDH | ECDSA | EdDSA => true,
+ ElGamalEncrypt | ElGamalEncryptSign |
+ Private(_) | Unknown(_)
+ => false,
+ }
+ }
+
+ fn supports_curve(curve: &Curve) -> bool {
+ if matches!(curve, Curve::Ed25519 | Curve::Cv25519) {
+ // 25519-based algorithms are special-cased and supported
+ true
+ } else {
+ // the rest of EC algorithms are supported via the same
+ // codepath
+ if let Ok(nid) = openssl::nid::Nid::try_from(curve) {
+ openssl::ec::EcGroup::from_curve_name(nid).is_ok()
+ } else {
+ false
+ }
+ }
+ }
+
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
let pair = openssl::pkey::PKey::generate_x25519()?;
Ok((pair.raw_private_key()?.into(),
diff --git a/openpgp/src/crypto/backend/rust.rs b/openpgp/src/crypto/backend/rust.rs
index 3a4d098a..41e95492 100644
--- a/openpgp/src/crypto/backend/rust.rs
+++ b/openpgp/src/crypto/backend/rust.rs
@@ -60,37 +60,6 @@ impl<T, N: ArrayLength<T>> GenericArrayExt<T, N> for GenericArray<T, N> {
const LEN: usize = N::USIZE;
}
-impl PublicKeyAlgorithm {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use PublicKeyAlgorithm::*;
- #[allow(deprecated)]
- match &self {
- RSAEncryptSign | RSAEncrypt | RSASign | ECDH | EdDSA | ECDSA
- => true,
- DSA
- => false,
- ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_)
- => false,
- }
- }
-}
-
-impl Curve {
- pub(crate) fn is_supported_by_backend(&self) -> bool {
- use self::Curve::*;
- match &self {
- NistP256
- => true,
- NistP384 | NistP521
- => false,
- Ed25519 | Cv25519
- => true,
- BrainpoolP256 | BrainpoolP512 | Unknown(_)
- => false,
- }
- }
-}
-
impl AEADAlgorithm {
/// Returns the best AEAD mode supported by the backend.
///
diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs
index d6729e3d..44163e2d 100644
--- a/openpgp/src/crypto/backend/rust/asymmetric.rs
+++ b/openpgp/src/crypto/backend/rust/asymmetric.rs
@@ -28,6 +28,33 @@ use super::GenericArrayExt;
const CURVE25519_SIZE: usize = 32;
impl Asymmetric for super::Backend {
+ fn supports_algo(algo: PublicKeyAlgorithm) -> bool {
+ use PublicKeyAlgorithm::*;
+ #[allow(deprecated)]
+ match algo {
+ RSAEncryptSign | RSAEncrypt | RSASign | ECDH | EdDSA | ECDSA
+ => true,
+ DSA
+ => false,
+ ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_)
+ => false,
+ }
+ }
+
+ fn supports_curve(curve: &Curve) -> bool {
+ use self::Curve::*;
+ match curve {
+ NistP256
+ => true,
+ NistP384 | NistP521
+ => false,
+ Ed25519 | Cv25519
+ => true,
+ BrainpoolP256 | BrainpoolP512 | Unknown(_)
+ => false,
+ }
+ }
+
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
use x25519_dalek::{StaticSecret, PublicKey};
diff --git a/openpgp/src/types/mod.rs b/openpgp/src/types/mod.rs
index 64fd174e..88fe1505 100644
--- a/openpgp/src/types/mod.rs
+++ b/openpgp/src/types/mod.rs
@@ -207,7 +207,8 @@ impl PublicKeyAlgorithm {
/// assert!(!PublicKeyAlgorithm::Private(101).is_supported());
/// ```
pub fn is_supported(&self) -> bool {
- self.is_supported_by_backend()
+ use crate::crypto::backend::{Backend, interface::Asymmetric};
+ Backend::supports_algo(*self)
}
/// Returns an iterator over all valid variants.
@@ -605,7 +606,8 @@ impl Curve {
/// assert!(!Curve::Unknown(Box::new([0x2B, 0x11])).is_supported());
/// ```
pub fn is_supported(&self) -> bool {
- self.is_supported_by_backend()
+ use crate::crypto::backend::{Backend, interface::Asymmetric};
+ Backend::supports_curve(self)
}
}