diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-07-17 18:47:25 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-07-17 20:27:59 +0200 |
commit | 13d56eddcaa3925fb3bfa8ef42264bf906df3677 (patch) | |
tree | 9a8c49de219478d1afc20e3a4c58956524a290ec | |
parent | a997fb414b5fabf8c4c8869a403c54eb4250149b (diff) |
openpgp: Implement DSA using the RustCrypto backend.
-rw-r--r-- | Cargo.lock | 107 | ||||
-rw-r--r-- | openpgp/Cargo.toml | 3 | ||||
-rw-r--r-- | openpgp/NEWS | 1 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/asymmetric.rs | 55 |
4 files changed, 139 insertions, 27 deletions
@@ -576,6 +576,17 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" @@ -659,6 +670,16 @@ dependencies = [ [[package]] name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" @@ -752,6 +773,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] +name = "dsa" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664d19f8b4e0481c55d76fa6ed402a7a9a8821857ba37f2ec1fdb43af6f19cf7" +dependencies = [ + "digest 0.10.6", + "num-bigint-dig", + "num-traits", + "pkcs8 0.9.0", + "rfc6979 0.3.1", + "sha2 0.10.6", + "signature 2.0.0", + "zeroize", +] + +[[package]] name = "dyn-clone" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -785,12 +822,12 @@ version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ - "der", + "der 0.7.5", "digest 0.10.6", "elliptic-curve", - "rfc6979", - "signature 2.1.0", - "spki", + "rfc6979 0.4.0", + "signature 2.0.0", + "spki 0.7.2", ] [[package]] @@ -828,14 +865,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ "base16ct", - "crypto-bigint", + "crypto-bigint 0.5.2", "digest 0.10.6", "ff", "generic-array", "group", "hkdf", "pem-rfc7468", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", "sec1", "subtle", @@ -1889,9 +1926,19 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der", - "pkcs8", - "spki", + "der 0.7.5", + "pkcs8 0.10.2", + "spki 0.7.2", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", ] [[package]] @@ -1900,8 +1947,8 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.5", + "spki 0.7.2", ] [[package]] @@ -2171,6 +2218,17 @@ dependencies = [ [[package]] name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" @@ -2214,10 +2272,10 @@ dependencies = [ "num-iter", "num-traits", "pkcs1", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", - "signature 2.1.0", - "spki", + "signature 2.0.0", + "spki 0.7.2", "subtle", "zeroize", ] @@ -2285,9 +2343,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" dependencies = [ "base16ct", - "der", + "der 0.7.5", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -2405,6 +2463,7 @@ dependencies = [ "criterion", "des", "digest 0.10.6", + "dsa", "dyn-clone", "eax", "ecb", @@ -2539,9 +2598,9 @@ checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "signature" -version = "2.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" dependencies = [ "digest 0.10.6", "rand_core 0.6.4", @@ -2586,12 +2645,22 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", - "der", + "der 0.7.5", ] [[package]] diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index aed5d290..fef5737e 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -67,6 +67,7 @@ cipher = { version = "0.4", optional = true, features = ["std"] } cfb-mode = { version = "0.8", optional = true } des = { version = "0.8", optional = true } digest = { version = "0.10", optional = true } +dsa = { version = "0.5", optional = true } eax = { version = "0.5", optional = true } ecb = { version = "0.1", optional = true } ecdsa = { version = "0.16", optional = true, features = ["hazmat", "arithmetic"] } # XXX @@ -131,7 +132,7 @@ crypto-rust = [ "digest", "eax", "ecb", "ed25519", "ed25519-dalek", "generic-array", "idea", "md-5", "num-bigint-dig", "rand", "rand07", "ripemd", "rsa", "sha-1", "sha2", "twofish", "typenum", "x25519-dalek-ng", "p256", - "rand_core", "rand_core/getrandom", "ecdsa", "aes-gcm" + "rand_core", "rand_core/getrandom", "ecdsa", "aes-gcm", "dsa" ] crypto-cng = [ "cipher", "eax", "winapi", "win-crypto-ng", "ed25519", "ed25519-dalek", diff --git a/openpgp/NEWS b/openpgp/NEWS index 42a9f469..01764f37 100644 --- a/openpgp/NEWS +++ b/openpgp/NEWS @@ -28,6 +28,7 @@ the active direct key signature, we infer the key flags from the key's role and public key algorithm. ** New functionality + - The RustCrypto backend now supports DSA. - crypto::SessionKey::as_protected - parse::PacketParser::start_hashing - parse::PacketParserBuilder::automatic_hashing diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs index 54d776f0..e3642aa2 100644 --- a/openpgp/src/crypto/backend/rust/asymmetric.rs +++ b/openpgp/src/crypto/backend/rust/asymmetric.rs @@ -35,7 +35,7 @@ impl Asymmetric for super::Backend { RSAEncryptSign | RSAEncrypt | RSASign | ECDH | EdDSA | ECDSA => true, DSA - => false, + => true, ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_) => false, } @@ -143,6 +143,30 @@ impl Asymmetric for super::Backend { } } +impl From<&BigUint> for ProtectedMPI { + fn from(v: &BigUint) -> Self { + v.to_bytes_be().into() + } +} + +impl From<&ProtectedMPI> for BigUint { + fn from(v: &ProtectedMPI) -> Self { + BigUint::from_bytes_be(v.value()).into() + } +} + +impl From<&BigUint> for MPI { + fn from(v: &BigUint) -> Self { + v.to_bytes_be().into() + } +} + +impl From<&MPI> for BigUint { + fn from(v: &MPI) -> Self { + BigUint::from_bytes_be(v.value()).into() + } +} + fn pkcs1_padding(hash_algo: HashAlgorithm) -> Result<Pkcs1v15Sign> { let hash = match hash_algo { HashAlgorithm::MD5 => Pkcs1v15Sign::new::<md5::Md5>(), @@ -201,9 +225,20 @@ impl KeyPair { }, (PublicKeyAlgorithm::DSA, - mpi:: PublicKey::DSA { .. }, - mpi::SecretKeyMaterial::DSA { .. }) => { - Err(Error::UnsupportedPublicKeyAlgorithm(PublicKeyAlgorithm::DSA).into()) + mpi::PublicKey::DSA { p, q, g, y }, + mpi::SecretKeyMaterial::DSA { x }) => { + use dsa::signature::hazmat::PrehashSigner; + let c = dsa::Components::from_components( + p.into(), q.into(), g.into())?; + let public = + dsa::VerifyingKey::from_components(c, y.into())?; + let secret = + dsa::SigningKey::from_components(public, x.into())?; + let sig = secret.sign_prehash(digest)?; + Ok(mpi::Signature::DSA { + r: sig.r().into(), + s: sig.s().into(), + }) }, (PublicKeyAlgorithm::ECDSA, @@ -362,9 +397,15 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> { key.verify(padding, digest, &s.value_padded(key.size())?)?; Ok(()) } - (mpi::PublicKey::DSA { .. }, - mpi::Signature::DSA { .. }) => { - Err(Error::UnsupportedPublicKeyAlgorithm(PublicKeyAlgorithm::DSA).into()) + (mpi::PublicKey::DSA { p, q, g, y }, + mpi::Signature::DSA { r, s }) => { + use dsa::signature::hazmat::PrehashVerifier; + let c = dsa::Components::from_components( + p.into(), q.into(), g.into())?; + let public = dsa::VerifyingKey::from_components(c, y.into())?; + let sig = dsa::Signature::from_components(r.into(), s.into())?; + public.verify_prehash(digest, &sig)?; + Ok(()) }, (mpi::PublicKey::ECDSA { curve, q }, mpi::Signature::ECDSA { r, s }) => match curve |