summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/Cargo.toml3
-rw-r--r--openpgp/NEWS1
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs55
3 files changed, 51 insertions, 8 deletions
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