diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-04-01 15:46:02 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-04-01 16:15:00 +0200 |
commit | 3501ddd9bc4dcd58b2aa02c006d2f0cf0199a503 (patch) | |
tree | 7f17a019e5058e33031cc9a18f137b08d27b0a75 | |
parent | 6b18fb9388a5e9f19ae3637ea65cfc9b257056cc (diff) |
openpgp: Implement Arbitrary for some Key<_, _>.
-rw-r--r-- | openpgp/src/packet/key.rs | 74 | ||||
-rw-r--r-- | openpgp/src/packet/mod.rs | 26 |
2 files changed, 91 insertions, 9 deletions
diff --git a/openpgp/src/packet/key.rs b/openpgp/src/packet/key.rs index 722bead4..56545859 100644 --- a/openpgp/src/packet/key.rs +++ b/openpgp/src/packet/key.rs @@ -54,6 +54,7 @@ use std::fmt; use std::cmp::Ordering; use std::convert::{TryFrom, TryInto}; use std::time; +use quickcheck::{Arbitrary, Gen}; use crate::Error; use crate::cert::prelude::*; @@ -1650,6 +1651,79 @@ impl Encrypted { } } +impl<P, R> Arbitrary for super::Key<P, R> + where P: KeyParts, P: Clone, + R: KeyRole, R: Clone, + Key4<P, R>: Arbitrary, +{ + fn arbitrary<G: Gen>(g: &mut G) -> Self { + Key4::arbitrary(g).into() + } +} + +impl Arbitrary for Key4<PublicParts, UnspecifiedRole> { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + let mpis = mpis::PublicKey::arbitrary(g); + Key4 { + common: Arbitrary::arbitrary(g), + creation_time: Arbitrary::arbitrary(g), + pk_algo: mpis.algo() + .expect("mpis::PublicKey::arbitrary only uses known algos"), + mpis, + secret: None, + p: std::marker::PhantomData, + r: std::marker::PhantomData, + } + } +} + +impl Arbitrary for Key4<SecretParts, UnspecifiedRole> { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + use rand::Rng; + use PublicKeyAlgorithm::*; + use mpis::MPI; + + let key = Key4::arbitrary(g); + let mut secret: SecretKeyMaterial = match key.pk_algo() { + RSAEncryptSign => mpis::SecretKeyMaterial::RSA { + d: MPI::arbitrary(g).into(), + p: MPI::arbitrary(g).into(), + q: MPI::arbitrary(g).into(), + u: MPI::arbitrary(g).into(), + }, + + DSA => mpis::SecretKeyMaterial::DSA { + x: MPI::arbitrary(g).into(), + }, + + ElGamalEncrypt => mpis::SecretKeyMaterial::ElGamal { + x: MPI::arbitrary(g).into(), + }, + + EdDSA => mpis::SecretKeyMaterial::EdDSA { + scalar: MPI::arbitrary(g).into(), + }, + + ECDSA => mpis::SecretKeyMaterial::ECDSA { + scalar: MPI::arbitrary(g).into(), + }, + + ECDH => mpis::SecretKeyMaterial::ECDH { + scalar: MPI::arbitrary(g).into(), + }, + + _ => unreachable!("only valid algos, normalizes to these values"), + }.into(); + + if g.gen() { + secret.encrypt_in_place(&Password::from(Vec::arbitrary(g))) + .unwrap(); + } + + Key4::<PublicParts, UnspecifiedRole>::add_secret(key, secret).0 + } +} + #[cfg(test)] mod tests { use crate::packet::Key; diff --git a/openpgp/src/packet/mod.rs b/openpgp/src/packet/mod.rs index f4713ec3..087814e3 100644 --- a/openpgp/src/packet/mod.rs +++ b/openpgp/src/packet/mod.rs @@ -234,17 +234,25 @@ impl<'a> DerefMut for Packet { impl Arbitrary for Packet { fn arbitrary<G: Gen>(g: &mut G) -> Self { use rand::Rng; - match g.gen_range(0, 10) { + match g.gen_range(0, 14) { 0 => Signature::arbitrary(g).into(), 1 => OnePassSig::arbitrary(g).into(), - 2 => Marker::arbitrary(g).into(), - 3 => Trust::arbitrary(g).into(), - 4 => UserID::arbitrary(g).into(), - 5 => UserAttribute::arbitrary(g).into(), - 6 => Literal::arbitrary(g).into(), - 7 => CompressedData::arbitrary(g).into(), - 8 => PKESK::arbitrary(g).into(), - 9 => SKESK::arbitrary(g).into(), + 2 => Key::<key::PublicParts, key::UnspecifiedRole>::arbitrary(g) + .mark_role_primary().into(), + 3 => Key::<key::PublicParts, key::UnspecifiedRole>::arbitrary(g) + .mark_role_subordinate().into(), + 4 => Key::<key::SecretParts, key::UnspecifiedRole>::arbitrary(g) + .mark_role_primary().into(), + 5 => Key::<key::SecretParts, key::UnspecifiedRole>::arbitrary(g) + .mark_role_subordinate().into(), + 6 => Marker::arbitrary(g).into(), + 7 => Trust::arbitrary(g).into(), + 8 => UserID::arbitrary(g).into(), + 9 => UserAttribute::arbitrary(g).into(), + 10 => Literal::arbitrary(g).into(), + 11 => CompressedData::arbitrary(g).into(), + 12 => PKESK::arbitrary(g).into(), + 13 => SKESK::arbitrary(g).into(), _ => unreachable!(), } } |