summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-03-01 16:25:59 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-03-01 18:08:57 +0100
commit913904754ddd585d93522bc45e8d9e830d278f9a (patch)
tree14e20277ddcdde82806e55586ef8748a5af27d90
parentea5606fd9cd2096301e7e4b690f9998d6a36bff9 (diff)
openpgp: Add support for brainpoolP384r1.
- One of the brainpool curves was not included in our enum Curve, because at the time we implemented ECC support, it wasn't part of the RFC4880bis document. - Unfortunately, we failed to mark enum Curve as non-exhaustive, so we cannot add a variant without breaking the API. - We can, however, support the curve by matching on its OID.
-rw-r--r--openpgp/NEWS3
-rw-r--r--openpgp/examples/supported-algorithms.rs1
-rw-r--r--openpgp/src/crypto/backend/openssl/asymmetric.rs6
-rw-r--r--openpgp/src/crypto/mpi.rs7
-rw-r--r--openpgp/src/policy.rs11
-rw-r--r--openpgp/src/types/mod.rs27
6 files changed, 44 insertions, 11 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS
index 744d47c4..f0c89281 100644
--- a/openpgp/NEWS
+++ b/openpgp/NEWS
@@ -3,6 +3,9 @@
#+TITLE: sequoia-openpgp NEWS – history of user-visible changes
#+STARTUP: content hidestars
+* Changes in 1.14.0
+** New functionality
+ - policy::AsymmetricAlgorithm::BrainpoolP384
* Changes in 1.13.0
** New cryptographic backends
- We added a backend that uses OpenSSL.
diff --git a/openpgp/examples/supported-algorithms.rs b/openpgp/examples/supported-algorithms.rs
index 570cdc96..760da1f4 100644
--- a/openpgp/examples/supported-algorithms.rs
+++ b/openpgp/examples/supported-algorithms.rs
@@ -39,6 +39,7 @@ fn main() {
Curve::NistP384,
Curve::NistP521,
Curve::BrainpoolP256,
+ Curve::Unknown([0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B].into()), // XXX
Curve::BrainpoolP512,
Curve::Ed25519,
Curve::Cv25519,
diff --git a/openpgp/src/crypto/backend/openssl/asymmetric.rs b/openpgp/src/crypto/backend/openssl/asymmetric.rs
index aef777bf..5a1dc295 100644
--- a/openpgp/src/crypto/backend/openssl/asymmetric.rs
+++ b/openpgp/src/crypto/backend/openssl/asymmetric.rs
@@ -70,8 +70,12 @@ impl TryFrom<&Curve> for Nid {
Curve::NistP384 => Nid::SECP384R1,
Curve::NistP521 => Nid::SECP521R1,
Curve::BrainpoolP256 => Nid::BRAINPOOL_P256R1,
+ Curve::Unknown(_) if curve.is_brainpoolp384() => Nid::BRAINPOOL_P384R1,
Curve::BrainpoolP512 => Nid::BRAINPOOL_P512R1,
- _ => return Err(crate::Error::UnsupportedEllipticCurve(curve.clone()).into()),
+ Curve::Ed25519 | // Handled differently.
+ Curve::Cv25519 | // Handled differently.
+ Curve::Unknown(_) =>
+ return Err(crate::Error::UnsupportedEllipticCurve(curve.clone()).into()),
})
}
}
diff --git a/openpgp/src/crypto/mpi.rs b/openpgp/src/crypto/mpi.rs
index e2a93992..7cc94206 100644
--- a/openpgp/src/crypto/mpi.rs
+++ b/openpgp/src/crypto/mpi.rs
@@ -201,10 +201,14 @@ impl MPI {
Ok((&value[1..], &[]))
},
+ Unknown(_) if ! curve.is_brainpoolp384() =>
+ Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
+
NistP256
| NistP384
| NistP521
| BrainpoolP256
+ | Unknown(_)
| BrainpoolP512
=>
{
@@ -232,9 +236,6 @@ impl MPI {
Ok((&value[1..1 + coordinate_length],
&value[1 + coordinate_length..]))
},
-
- Unknown(_) =>
- Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
}
}
diff --git a/openpgp/src/policy.rs b/openpgp/src/policy.rs
index 542fa64f..92b08a47 100644
--- a/openpgp/src/policy.rs
+++ b/openpgp/src/policy.rs
@@ -700,7 +700,7 @@ a_cutoff_list!(SubpacketTagCutoffList, SubpacketTag, 38,
ACCEPT, // 37. AttestedCertifications.
]);
-a_cutoff_list!(AsymmetricAlgorithmCutoffList, AsymmetricAlgorithm, 18,
+a_cutoff_list!(AsymmetricAlgorithmCutoffList, AsymmetricAlgorithm, 19,
[
Some(Timestamp::Y2014M2), // 0. RSA1024.
ACCEPT, // 1. RSA2048.
@@ -720,6 +720,7 @@ a_cutoff_list!(AsymmetricAlgorithmCutoffList, AsymmetricAlgorithm, 18,
ACCEPT, // 15. BrainpoolP256.
ACCEPT, // 16. BrainpoolP512.
ACCEPT, // 17. Cv25519.
+ ACCEPT, // 16. BrainpoolP384.
]);
a_cutoff_list!(SymmetricAlgorithmCutoffList, SymmetricAlgorithm, 14,
@@ -1560,6 +1561,8 @@ impl<'a> Policy for StandardPolicy<'a> {
Curve::NistP384 => NistP384,
Curve::NistP521 => NistP521,
Curve::BrainpoolP256 => BrainpoolP256,
+ Curve::Unknown(_) if curve.is_brainpoolp384()
+ => BrainpoolP384,
Curve::BrainpoolP512 => BrainpoolP512,
Curve::Ed25519 => Cv25519,
Curve::Cv25519 => Cv25519,
@@ -1688,6 +1691,8 @@ pub enum AsymmetricAlgorithm {
NistP521,
/// brainpoolP256r1.
BrainpoolP256,
+ /// brainpoolP384r1.
+ BrainpoolP384,
/// brainpoolP512r1.
BrainpoolP512,
/// D.J. Bernstein's Curve25519.
@@ -1697,7 +1702,7 @@ pub enum AsymmetricAlgorithm {
}
assert_send_and_sync!(AsymmetricAlgorithm);
-const ASYMMETRIC_ALGORITHM_VARIANTS: [AsymmetricAlgorithm; 18] = [
+const ASYMMETRIC_ALGORITHM_VARIANTS: [AsymmetricAlgorithm; 19] = [
AsymmetricAlgorithm::RSA1024,
AsymmetricAlgorithm::RSA2048,
AsymmetricAlgorithm::RSA3072,
@@ -1714,6 +1719,7 @@ const ASYMMETRIC_ALGORITHM_VARIANTS: [AsymmetricAlgorithm; 18] = [
AsymmetricAlgorithm::NistP384,
AsymmetricAlgorithm::NistP521,
AsymmetricAlgorithm::BrainpoolP256,
+ AsymmetricAlgorithm::BrainpoolP384,
AsymmetricAlgorithm::BrainpoolP512,
AsymmetricAlgorithm::Cv25519,
];
@@ -1754,6 +1760,7 @@ impl From<AsymmetricAlgorithm> for u8 {
NistP384 => 13,
NistP521 => 14,
BrainpoolP256 => 15,
+ BrainpoolP384 => 18,
BrainpoolP512 => 16,
Cv25519 => 17,
Unknown => 255,
diff --git a/openpgp/src/types/mod.rs b/openpgp/src/types/mod.rs
index 863880e5..698b65d1 100644
--- a/openpgp/src/types/mod.rs
+++ b/openpgp/src/types/mod.rs
@@ -365,6 +365,13 @@ pub enum Curve {
/// Unknown curve.
Unknown(Box<[u8]>),
}
+impl Curve {
+ /// Hack! Curve is not non-exhaustive, so we cannot easily add
+ /// a variant.
+ pub(crate) fn is_brainpoolp384(&self) -> bool {
+ self.oid() == BRAINPOOL_P384_OID
+ }
+}
assert_send_and_sync!(Curve);
impl Curve {
@@ -398,6 +405,7 @@ impl Curve {
NistP384 => Some(384),
NistP521 => Some(521),
BrainpoolP256 => Some(256),
+ Unknown(_) if self.is_brainpoolp384() => Some(384),
BrainpoolP512 => Some(512),
Ed25519 => Some(256),
Cv25519 => Some(256),
@@ -455,6 +463,8 @@ impl fmt::Display for Curve {
NistP384 => f.write_str("NIST curve P-384"),
NistP521 => f.write_str("NIST curve P-521"),
BrainpoolP256 => f.write_str("brainpoolP256r1"),
+ Unknown(_) if self.is_brainpoolp384() =>
+ f.write_str("brainpoolP384r1"),
BrainpoolP512 => f.write_str("brainpoolP512r1"),
Ed25519
=> f.write_str("D.J. Bernstein's \"Twisted\" Edwards curve Ed25519"),
@@ -469,6 +479,8 @@ impl fmt::Display for Curve {
NistP384 => f.write_str("NIST P-384"),
NistP521 => f.write_str("NIST P-521"),
BrainpoolP256 => f.write_str("brainpoolP256r1"),
+ Unknown(_) if self.is_brainpoolp384() =>
+ f.write_str("brainpoolP384r1"),
BrainpoolP512 => f.write_str("brainpoolP512r1"),
Ed25519
=> f.write_str("Ed25519"),
@@ -486,6 +498,8 @@ const NIST_P384_OID: &[u8] = &[0x2B, 0x81, 0x04, 0x00, 0x22];
const NIST_P521_OID: &[u8] = &[0x2B, 0x81, 0x04, 0x00, 0x23];
const BRAINPOOL_P256_OID: &[u8] =
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07];
+const BRAINPOOL_P384_OID: &[u8] =
+ &[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B];
const BRAINPOOL_P512_OID: &[u8] =
&[0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D];
const ED25519_OID: &[u8] =
@@ -513,6 +527,7 @@ impl Curve {
NIST_P384_OID => Curve::NistP384,
NIST_P521_OID => Curve::NistP521,
BRAINPOOL_P256_OID => Curve::BrainpoolP256,
+ BRAINPOOL_P384_OID => Curve::Unknown(BRAINPOOL_P384_OID.into()),
BRAINPOOL_P512_OID => Curve::BrainpoolP512,
ED25519_OID => Curve::Ed25519,
CV25519_OID => Curve::Cv25519,
@@ -568,6 +583,7 @@ impl Curve {
Curve::NistP384 => Ok(384),
Curve::NistP521 => Ok(521),
Curve::BrainpoolP256 => Ok(256),
+ Curve::Unknown(_) if self.is_brainpoolp384() => Ok(384),
Curve::BrainpoolP512 => Ok(512),
Curve::Ed25519 => Ok(256),
Curve::Cv25519 => Ok(256),
@@ -596,15 +612,16 @@ impl Curve {
#[cfg(test)]
impl Arbitrary for Curve {
fn arbitrary(g: &mut Gen) -> Self {
- match u8::arbitrary(g) % 8 {
+ match u8::arbitrary(g) % 9 {
0 => Curve::NistP256,
1 => Curve::NistP384,
2 => Curve::NistP521,
3 => Curve::BrainpoolP256,
- 4 => Curve::BrainpoolP512,
- 5 => Curve::Ed25519,
- 6 => Curve::Cv25519,
- 7 => Curve::Unknown({
+ 4 => Curve::Unknown(BRAINPOOL_P384_OID.into()),
+ 5 => Curve::BrainpoolP512,
+ 6 => Curve::Ed25519,
+ 7 => Curve::Cv25519,
+ 8 => Curve::Unknown({
let mut k = <Vec<u8>>::arbitrary(g);
k.truncate(255);
k.into_boxed_slice()