diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-09-29 15:54:46 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-09-29 16:14:56 +0200 |
commit | bdd166fb66765dcc37b43e660fb03b511239b06a (patch) | |
tree | c22a0fd9c8596e12e0a7d9202c84e53df6bcc221 /openpgp/src/crypto/backend | |
parent | 6a11491ee26871944144482fa41c8725cdcfffa6 (diff) |
openpgp: Pad the DSA public key to the size of the modulus.
- Works around a crash in the CNG bindings.
- See https://github.com/emgre/win-crypto-ng/issues/39.
Diffstat (limited to 'openpgp/src/crypto/backend')
-rw-r--r-- | openpgp/src/crypto/backend/cng/asymmetric.rs | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs index b43324c3..d101ccc5 100644 --- a/openpgp/src/crypto/backend/cng/asymmetric.rs +++ b/openpgp/src/crypto/backend/cng/asymmetric.rs @@ -178,7 +178,10 @@ impl Signer for KeyPair { use win_crypto_ng::asymmetric::{Dsa, DsaPrivateBlob}; use win_crypto_ng::helpers::Blob; - if y.value().len() > 3072 / 8 { + let y = y.value_padded(p.value().len()) + .map_err(|e| Error::InvalidKey(e.to_string()))?; + + if y.len() > 3072 / 8 { return Err(Error::InvalidOperation( "DSA keys are supported up to 3072-bits".to_string()).into() ); @@ -186,7 +189,7 @@ impl Signer for KeyPair { enum Version { V1, V2 } // 1024-bit DSA keys are handled differently - let version = if y.value().len() <= 128 { Version::V1 } else { Version::V2 }; + let version = if y.len() <= 128 { Version::V1 } else { Version::V2 }; let blob: DsaPrivateBlob = match version { Version::V1 => { @@ -197,7 +200,7 @@ impl Signer for KeyPair { DsaPrivateBlob::V1(Blob::<DsaKeyPrivateBlob>::clone_from_parts( &winapi::shared::bcrypt::BCRYPT_DSA_KEY_BLOB { dwMagic: winapi::shared::bcrypt::BCRYPT_DSA_PUBLIC_MAGIC, - cbKey: y.value().len() as u32, + cbKey: y.len() as u32, Count: [0; 4], // unused Seed: [0; 20], // unused q: group, @@ -205,7 +208,7 @@ impl Signer for KeyPair { &DsaKeyPrivatePayload { modulus: p.value(), generator: g.value(), - public: y.value(), + public: &y, priv_exp: x.value(), }, )) @@ -235,7 +238,7 @@ impl Signer for KeyPair { // bits, q is 20 bytes long. // If the key exceeds 256 bits, q is 32 bytes long. cbGroupSize: std::cmp::min(q.value().len(), 32) as u32, - cbKey: y.value().len() as u32, + cbKey: y.len() as u32, cbSeedLength: seed.len() as u32, hashAlgorithm: hash, standardVersion: 1, // FIPS 186-3 @@ -246,7 +249,7 @@ impl Signer for KeyPair { group: q.value(), modulus: p.value(), generator: g.value(), - public: y.value(), + public: &y, priv_exp: x.value(), }, )) @@ -455,7 +458,10 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { use win_crypto_ng::asymmetric::{Dsa, DsaPublicBlob}; use win_crypto_ng::helpers::Blob; - if y.value().len() > 3072 / 8 { + let y = y.value_padded(p.value().len()) + .map_err(|e| Error::InvalidKey(e.to_string()))?; + + if y.len() > 3072 / 8 { return Err(Error::InvalidOperation( "DSA keys are supported up to 3072-bits".to_string()).into() ); @@ -474,7 +480,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { enum Version { V1, V2 } // 1024-bit DSA keys are handled differently - let version = if y.value().len() <= 128 { Version::V1 } else { Version::V2 }; + let version = if y.len() <= 128 { Version::V1 } else { Version::V2 }; let blob: DsaPublicBlob = match version { Version::V1 => { @@ -485,7 +491,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { DsaPublicBlob::V1(Blob::<DsaKeyPublicBlob>::clone_from_parts( &winapi::shared::bcrypt::BCRYPT_DSA_KEY_BLOB { dwMagic: winapi::shared::bcrypt::BCRYPT_DSA_PUBLIC_MAGIC, - cbKey: y.value().len() as u32, + cbKey: y.len() as u32, Count: [0; 4], // unused Seed: [0; 20], // unused q: group, @@ -493,7 +499,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { &DsaKeyPublicPayload { modulus: p.value(), generator: g.value(), - public: y.value(), + public: &y, }, )) }, @@ -522,7 +528,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { // bits, q is 20 bytes long. // If the key exceeds 256 bits, q is 32 bytes long. cbGroupSize: q.value().len() as u32, - cbKey: y.value().len() as u32, + cbKey: y.len() as u32, // https://csrc.nist.gov/csrc/media/publications/fips/186/3/archive/2009-06-25/documents/fips_186-3.pdf // Length of the seed used to generate the // prime number q. @@ -536,7 +542,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { group: q.value(), modulus: p.value(), generator: g.value(), - public: y.value(), + public: &y, }, )) }, |