diff options
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/Cargo.toml | 3 | ||||
-rw-r--r-- | openpgp/NEWS | 1 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/asymmetric.rs | 55 |
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 |