summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-07-17 18:47:25 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-07-17 20:27:59 +0200
commit13d56eddcaa3925fb3bfa8ef42264bf906df3677 (patch)
tree9a8c49de219478d1afc20e3a4c58956524a290ec
parenta997fb414b5fabf8c4c8869a403c54eb4250149b (diff)
openpgp: Implement DSA using the RustCrypto backend.
-rw-r--r--Cargo.lock107
-rw-r--r--openpgp/Cargo.toml3
-rw-r--r--openpgp/NEWS1
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs55
4 files changed, 139 insertions, 27 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1fc0a3c3..9be6aca7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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