use std::fs::File;
use std::time::Duration;
use assert_cli;
use assert_cli::Assert;
use tempfile;
use tempfile::TempDir;
use sequoia_openpgp as openpgp;
use openpgp::Result;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::subpacket::NotationData;
use openpgp::packet::signature::subpacket::NotationDataFlags;
use openpgp::parse::Parse;
use openpgp::policy::StandardPolicy;
use openpgp::serialize::Serialize;
#[test]
fn sq_certify() -> Result<()> {
let tmp_dir = TempDir::new().unwrap();
let alice_pgp = tmp_dir.path().join("alice.pgp");
let bob_pgp = tmp_dir.path().join("bob.pgp");
let (alice, _) =
CertBuilder::general_purpose(None, Some("alice@example.org"))
.generate()?;
let mut file = File::create(&alice_pgp)?;
alice.as_tsk().serialize(&mut file)?;
let (bob, _) =
CertBuilder::general_purpose(None, Some("bob@example.org"))
.generate()?;
let mut file = File::create(&bob_pgp)?;
bob.serialize(&mut file)?;
Assert::cargo_binary("sq")
.with_args(
&["certify",
alice_pgp.to_str().unwrap(),
bob_pgp.to_str().unwrap(),
"bob@example.org",
])
.stdout().satisfies(|output| {
let p = &StandardPolicy::new();
let cert = Cert::from_bytes(output).unwrap();
let vc = cert.with_policy(p, None).unwrap();
for ua in vc.userids() {
if ua.userid().value() == b"bob@example.org" {
let certifications: Vec<_>
= ua.certifications().collect();
assert_eq!(certifications.len(), 1);
let c = certifications[0];
assert_eq!(c.trust_signature(), None);
assert_eq!(c.regular_expressions().count(), 0);
assert_eq!(c.revocable().unwrap_or(true), true);
assert_eq!(c.exportable_certification().unwrap_or(true), true);
assert!(c.signature_validity_period().is_some());
return true;
}
}
false
},
"Bad certification")
.unwrap();
Assert::cargo_binary("sq")
.with_args(
&["certify",
alice_pgp.to_str().unwrap(),
bob_pgp.to_str().unwrap(),
"bob@example.org",
"--expires", "never"
])
.stdout().satisfies(|output| {
let p = &StandardPolicy::new();
let cert = Cert::from_bytes(output).unwrap();
let vc = cert.with_policy(p, None).unwrap();
for ua in vc.userids() {
if ua.userid().value() == b"bob@example.org" {
let certifications: Vec<_>
= ua.certifications().collect();
assert_eq!(certifications.len(), 1);
let c = certifications[0];
assert_eq!(c.trust_signature(), None);
assert_eq!(c.regular_expressions().count(), 0);
assert_eq!(c.revocable().unwrap_or(true), true);
assert_eq!(c.exportable_certification().unwrap_or(true), true);
assert!(c.signature_validity_period().is_none());
return true;
}
}
false
},
"Bad certification")
.unwrap();
Assert::cargo_binary("sq")
.with_args(
&["certify",
alice_pgp.to_str().unwrap(),
bob_pgp.to_str().unwrap(),
"bob@example.org",
"--depth", "10",
"--amount", "5",
"--regex", "a",
"--regex", "b",
"--local",
"--non-revocable",
"--expires-in", "1d",
])
.stdout().satisfies(|output| {
let p = &mut StandardPolicy::new();
use openpgp::packet::signature::subpacket::SubpacketTag;
p.accept_critical_subpacket(SubpacketTag::TrustSignature);
p.accept_critical_subpacket(SubpacketTag::RegularExpression);
let cert = Cert::from_bytes(output).unwrap();
let vc = cert.with_policy(p, None).unwrap();
for ua in vc.userids() {
if ua.userid().value() == b"bob@example.org" {
let certifications: Vec<_>
= ua.certifications().collect();
assert_eq!(certifications.len(), 1);
let c = certifications[0];
assert_eq!(c.trust_signature(), Some((10, 5)));
assert_eq!(&c.regular_expressions().collect::<Vec<_>>()[..],
&[ b"a", b"b" ]);
assert_eq!(c.revocable(), Some(false));
assert_eq!(c.exportable_certification(), Some(false));
assert_eq!(c.signature_validity_period(),
Some(Duration::new(24 * 60 * 60, 0)));
return true;
}
}
false
},
"Bad certification")
.unwrap();
Assert::cargo_binary("sq")
.with_args(
&["certify",
alice_pgp.to_str().unwrap(),
bob_pgp.to_str().unwrap(),
"bob",
])
.fails()
.unwrap();
Assert::cargo_binary("sq")
.with_args(
&["certify",
"--notation", "foo", "bar",
"--notation", "!foo", "xyzzy",
"--notation", "hello@example.org", "1234567890",
alice_pgp.to_str().unwrap(),
bob_pgp.to_str().unwrap(),
"bob@example.org",
])
.stdout().satisfies(|output| {
let p = &mut StandardPolicy::new();
let cert = Cert::from_bytes(output).unwrap();
let vc = cert.with_policy(p, None).unwrap();
for ua in vc.userids() {
if ua.userid().value() == b"bob@example.org" {
let certifications: Vec<_>
= ua.certifications().collect();
assert_eq!(certifications.len(), 0);
}
}
p.good_critical_notations(&["foo"]);
let vc = cert.with_policy(p, None).unwrap();
for ua in vc.userids() {
if ua.userid().value() == b"bob@example.org" {
let certifications: Vec<_>
= ua.certifications().collect();
assert_eq!(certifications.len(), 1);
let c = certifications[0];
assert_eq!(c.trust_signature(), None);
assert_eq!(c.regular_expressions().count(), 0);
assert_eq!(c.revocable().unwrap_or(true), true);
assert_eq!(c.exportable_certification().unwrap_or(true), true);
assert!(c.signature_validity_period().is_some());
let hr = NotationDataFlags::empty().set_human_readable();
let notations = &mut [
(NotationData::new("foo", "bar", hr.clone()), false),
(NotationData::new("foo", "xyzzy", hr.clone()), false),
(NotationData::new("hello@example.org", "1234567890", hr), false)
];
for n in c.notation_data() {
if n.name() == "salt@notations.sequoia-pgp.org" {
continue;
}
for (m, found) in notations.iter_mut() {
if n == m {
assert!(!*found);
*found = true;
}
}
}
for (n, found) in notations.iter() {
assert!(found, "Missing: {:?}", n);
}
return true;
}
}
false
},
"Bad certification")
.unwrap();
Ok(())
}