summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-09-08 16:05:12 +0200
committerJustus Winter <justus@sequoia-pgp.org>2021-09-08 17:11:24 +0200
commit4ef309b940c79b14be3703b08e8f4dd73e2d1de1 (patch)
tree8b8b30a6121c3affcc5c585b5859d077131efe4d
parenta524620bdd72eebeeb2db5d9da690396445b0ad3 (diff)
openpgp: Don't assume that we only use Ed25519 for EdDSA.
-rw-r--r--openpgp/src/crypto/backend/cng/asymmetric.rs75
1 files changed, 44 insertions, 31 deletions
diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs
index 1ca6074c..8f54fa54 100644
--- a/openpgp/src/crypto/backend/cng/asymmetric.rs
+++ b/openpgp/src/crypto/backend/cng/asymmetric.rs
@@ -133,34 +133,41 @@ impl Signer for KeyPair {
PublicKeyAlgorithm::EdDSA,
mpi::PublicKey::EdDSA { curve, q },
mpi::SecretKeyMaterial::EdDSA { scalar },
- ) => {
- // CNG doesn't support EdDSA, use ed25519-dalek instead
- use ed25519_dalek::{Keypair, Signer};
- use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH};
-
- let (public, ..) = q.decode_point(&Curve::Ed25519)?;
-
- // It's expected for the private key to be exactly
- // SECRET_KEY_LENGTH bytes long but OpenPGP allows leading
- // zeros to be stripped.
- // Padding has to be unconditional; otherwise we have a
- // secret-dependent branch.
- let missing = SECRET_KEY_LENGTH.saturating_sub(scalar.value().len());
- let mut keypair = Protected::from(
- vec![0u8; SECRET_KEY_LENGTH + PUBLIC_KEY_LENGTH]
- );
- keypair.as_mut()[missing..SECRET_KEY_LENGTH].copy_from_slice(scalar.value());
- keypair.as_mut()[SECRET_KEY_LENGTH..].copy_from_slice(&public);
- let pair = Keypair::from_bytes(&keypair).unwrap();
-
- let sig = pair.sign(digest).to_bytes();
-
- // https://tools.ietf.org/html/rfc8032#section-5.1.6
- let (r, s) = sig.split_at(sig.len() / 2);
- mpi::Signature::EdDSA {
- r: mpi::MPI::new(r),
- s: mpi::MPI::new(s),
- }
+ ) => match curve {
+ Curve::Ed25519 => {
+ // CNG doesn't support EdDSA, use ed25519-dalek instead
+ use ed25519_dalek::{Keypair, Signer};
+ use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH};
+
+ let (public, ..) = q.decode_point(&Curve::Ed25519)?;
+
+ // It's expected for the private key to be exactly
+ // SECRET_KEY_LENGTH bytes long but OpenPGP allows leading
+ // zeros to be stripped.
+ // Padding has to be unconditional; otherwise we have a
+ // secret-dependent branch.
+ let missing =
+ SECRET_KEY_LENGTH.saturating_sub(scalar.value().len());
+ let mut keypair = Protected::from(
+ vec![0u8; SECRET_KEY_LENGTH + PUBLIC_KEY_LENGTH]
+ );
+ keypair.as_mut()[missing..SECRET_KEY_LENGTH]
+ .copy_from_slice(scalar.value());
+ keypair.as_mut()[SECRET_KEY_LENGTH..]
+ .copy_from_slice(&public);
+ let pair = Keypair::from_bytes(&keypair).unwrap();
+
+ let sig = pair.sign(digest).to_bytes();
+
+ // https://tools.ietf.org/html/rfc8032#section-5.1.6
+ let (r, s) = sig.split_at(sig.len() / 2);
+ mpi::Signature::EdDSA {
+ r: mpi::MPI::new(r),
+ s: mpi::MPI::new(s),
+ }
+ },
+ _ => return Err(
+ Error::UnsupportedEllipticCurve(curve.clone()).into()),
},
(PublicKeyAlgorithm::DSA,
mpi:: PublicKey::DSA { y, p, q, g },
@@ -627,7 +634,10 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
Error::UnsupportedEllipticCurve(curve.clone()).into()),
}
},
- (mpi::PublicKey::EdDSA { curve, q }, mpi::Signature::EdDSA { r, s }) => {
+ (mpi::PublicKey::EdDSA { curve, q }, mpi::Signature::EdDSA { r, s })
+ => match curve
+ {
+ Curve::Ed25519 => {
// CNG doesn't support EdDSA, use ed25519-dalek instead
use ed25519_dalek::{PublicKey, Signature, SIGNATURE_LENGTH};
use ed25519_dalek::{Verifier};
@@ -653,8 +663,11 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
let signature = Signature::from(sig_bytes);
key.verify(digest, &signature)
- .map(|_| true)
- .map_err(|e| Error::BadSignature(e.to_string()))?
+ .map(|_| true)
+ .map_err(|e| Error::BadSignature(e.to_string()))?
+ },
+ _ => return Err(
+ Error::UnsupportedEllipticCurve(curve.clone()).into()),
},
_ => return Err(Error::MalformedPacket(format!(
"unsupported combination of key {} and signature {:?}.",