diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-09-08 16:05:12 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-09-08 17:11:24 +0200 |
commit | 4ef309b940c79b14be3703b08e8f4dd73e2d1de1 (patch) | |
tree | 8b8b30a6121c3affcc5c585b5859d077131efe4d | |
parent | a524620bdd72eebeeb2db5d9da690396445b0ad3 (diff) |
openpgp: Don't assume that we only use Ed25519 for EdDSA.
-rw-r--r-- | openpgp/src/crypto/backend/cng/asymmetric.rs | 75 |
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 {:?}.", |