summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-01-26 14:57:18 +0100
committerJustus Winter <justus@sequoia-pgp.org>2021-01-26 16:27:01 +0100
commit3d8bad0e9d9a6c640159ff666b1d99cc0e9c0c36 (patch)
tree491e9c0c047191e97cac6addc7c64703584a1566
parent88b835631a60fade67907e394fce8d3476b9ae36 (diff)
autocrypt: Include at least one user id in cleaned certs.
-rw-r--r--autocrypt/src/lib.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/autocrypt/src/lib.rs b/autocrypt/src/lib.rs
index e14511f9..36af44c3 100644
--- a/autocrypt/src/lib.rs
+++ b/autocrypt/src/lib.rs
@@ -133,12 +133,14 @@ impl AutocryptHeader {
}
// The UserIDs matching ADDR.
+ let mut found_one = false;
for uidb in cert.userids().with_policy(policy, None) {
// XXX: Fix match once we have the rfc2822-name-addr.
if let Ok(Some(a)) = uidb.userid().email() {
if &a == addr {
acc.push(uidb.userid().clone().into());
acc.push(uidb.binding_signature().clone().into());
+ found_one = true;
} else {
// Address is not matching.
continue;
@@ -149,6 +151,16 @@ impl AutocryptHeader {
}
}
+ // User ids are only decorative in Autocrypt. By convention,
+ // the cert should include a user id matching the sender's
+ // address, but we should include at least one user id.
+ if ! found_one {
+ if let Ok(uidb) = cert.with_policy(policy, None)?.primary_userid() {
+ acc.push(uidb.userid().clone().into());
+ acc.push(uidb.binding_signature().clone().into());
+ }
+ }
+
let cleaned_cert = Cert::try_from(acc)?;
Ok(AutocryptHeader {
@@ -1062,4 +1074,39 @@ mod test {
assert_eq!(cert.userids().next().unwrap().userid().value(),
&b"Testy McTestface <testy@example.org>"[..]);
}
+
+ #[test]
+ fn autocrypt_header_new_address_mismatch() -> Result<()> {
+ let p = &P::new();
+
+ let cert =
+ Cert::from_bytes(&include_bytes!("../tests/data/testy.pgp")[..])?;
+ let header = AutocryptHeader::new_sender(p, &cert,
+ "anna-lena@example.org",
+ "mutual")?;
+ let mut buf = Vec::new();
+ write!(&mut buf, "Autocrypt: ")?;
+ header.serialize(&mut buf)?;
+
+ let ac = AutocryptHeaders::from_bytes(&buf)?;
+
+ // We expect exactly one Autocrypt header.
+ assert_eq!(ac.headers.len(), 1);
+
+ assert_eq!(ac.headers[0].get("addr").unwrap().value,
+ "anna-lena@example.org");
+
+ assert_eq!(ac.headers[0].get("prefer-encrypt").unwrap().value,
+ "mutual");
+
+ let cert = ac.headers[0].key.as_ref()
+ .expect("Failed to parse key material.");
+ assert_eq!(&cert.fingerprint().to_string(),
+ "3E88 77C8 7727 4692 9751 89F5 D03F 6F86 5226 FE8B");
+ assert_eq!(cert.userids().len(), 1);
+ assert_eq!(cert.keys().subkeys().count(), 1);
+ assert_eq!(cert.userids().next().unwrap().userid().value(),
+ &b"Testy McTestface <testy@example.org>"[..]);
+ Ok(())
+ }
}