New test: I'm My Own Grandpa.

  - Fixes #27.
parent 17a37c32
......@@ -33,6 +33,7 @@ mod perturbed_certs;
mod expiration;
mod detached_primary;
mod binding_signature_subpackets;
mod im_my_own_grandpa;
fn make_test<I, P>(test: &str, packets: I,
expectation: Option<Expectation>)
......@@ -557,6 +558,7 @@ pub fn schedule(report: &mut Report) -> Result<()> {
report.add(Box::new(detached_primary::DetachedPrimary::new()?));
report.add(Box::new(
binding_signature_subpackets::BindingSignatureSubpackets::new()?));
report.add(Box::new(im_my_own_grandpa::ImMyOwnGrandpa::new()?));
revoked_key::schedule(report)?;
Ok(())
......
use sequoia_openpgp as openpgp;
use openpgp::{
Packet,
packet::signature::SignatureBuilder,
parse::Parse,
types::{KeyFlags, SignatureType},
};
use crate::{
Data,
OpenPGP,
Result,
data,
tests::{
ConsumerTest,
Expectation,
Test,
TestMatrix,
},
};
/// Explores a certificate corner case where a certificate includes
/// its primary key as subkey.
pub struct ImMyOwnGrandpa {
}
impl ImMyOwnGrandpa {
pub fn new() -> Result<ImMyOwnGrandpa> {
Ok(ImMyOwnGrandpa {
})
}
fn message(&self) -> &'static [u8] {
"Hello World :)".as_bytes()
}
}
impl Test for ImMyOwnGrandpa {
fn title(&self) -> String {
"I'm My Own Grandpa".into()
}
fn description(&self) -> String {
"<p>Explores a certificate corner case where a certificate \
includes its primary key as subkey. This is an oddball, \
supporting it is not necessary.</p>\
\
<p>A certificate is constructed by taking Bob's subkey and \
using it as primary key as well as subkey. The test encrypts \
a short message, and tries to decrypt is using Bob's key.</p>"
.into()
}
fn run(&self, implementations: &[Box<dyn OpenPGP + Sync>])
-> Result<TestMatrix> {
ConsumerTest::run(self, implementations)
}
}
impl ConsumerTest for ImMyOwnGrandpa {
fn produce(&self) -> Result<Vec<(String, Data, Option<Expectation>)>> {
let bob =
openpgp::Cert::from_bytes(data::certificate("bob-secret.pgp"))?;
let uid =
bob.userids().nth(0).unwrap().userid().clone();
let uidb =
bob.userids().nth(0).unwrap().self_signatures()
.nth(0).unwrap().clone();
let key = bob.keys().subkeys().nth(0).unwrap().key().clone();
let mut signer =
key.clone().parts_into_secret()?.into_keypair()?;
let sub_key = key.clone().take_secret().0;
let primary_key = sub_key.clone().role_into_primary();
let cert = openpgp::Cert::from_packets(
vec![primary_key.clone().into()].into_iter())?;
use super::make_test as make;
Ok(vec![
make("I'm My Own Grandpa",
vec![Packet::from(primary_key.clone()),
uid.clone().into(),
uid.bind(
&mut signer,
&cert,
uidb.into())?.into(),
sub_key.clone().into(),
sub_key.bind(
&mut signer,
&cert,
SignatureBuilder::new(SignatureType::SubkeyBinding)
.set_signature_creation_time(
sub_key.creation_time())?
.set_key_flags(KeyFlags::empty()
.set_storage_encryption()
.set_transport_encryption())?
)?.into(),
],
None)?,
])
}
fn consume(&self, _i: usize, pgp: &mut dyn OpenPGP, artifact: &[u8])
-> Result<Data> {
let ciphertext = pgp.encrypt(artifact, self.message())?;
pgp.new_context()?
.decrypt(data::certificate("bob-secret.pgp"), &ciphertext)
}
fn check_consumer(&self, _i: usize, artifact: &[u8])
-> Result<()> {
if artifact == self.message() {
Ok(())
} else {
Err(anyhow::anyhow!("Expected {:?}, got {:?}",
self.message(), artifact))
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment