carry over verified UIDs on key update
This commit is contained in:
parent
53719c2166
commit
563aaa8736
|
@ -429,4 +429,20 @@ mod tests {
|
|||
|
||||
test::test_uid_revocation(&mut db);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_reupload() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_reupload(&mut db);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uid_replacement() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_uid_replacement(&mut db);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,8 +172,9 @@ pub trait Database: Sync + Send {
|
|||
use sequoia_openpgp::RevocationStatus;
|
||||
|
||||
let fpr = Fingerprint::try_from(tpk.primary().fingerprint())?;
|
||||
let mut all_uids = Vec::default();
|
||||
let mut active_uids = Vec::default();
|
||||
let mut revoked_uids = Vec::default();
|
||||
let mut verified_uids = Vec::default();
|
||||
|
||||
// update verify tokens
|
||||
for uid in tpk.userids() {
|
||||
|
@ -181,19 +182,51 @@ pub trait Database: Sync + Send {
|
|||
|
||||
match uid.revoked(None) {
|
||||
RevocationStatus::CouldBe(_) | RevocationStatus::Revoked(_) => {
|
||||
revoked_uids.push(email);
|
||||
match self.by_email(&email) {
|
||||
None => {}
|
||||
Some(other_tpk) => {
|
||||
match TPK::from_bytes(&other_tpk) {
|
||||
Ok(other_tpk) => {
|
||||
all_uids
|
||||
.push((email, other_tpk.fingerprint()));
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
RevocationStatus::NotAsFarAsWeKnow
|
||||
if self.by_email(&email).is_none() =>
|
||||
{
|
||||
let payload = Verify::new(
|
||||
uid.userid(),
|
||||
&uid.selfsigs().collect::<Vec<_>>(),
|
||||
fpr.clone(),
|
||||
)?;
|
||||
active_uids.push((email, self.new_verify_token(payload)?));
|
||||
RevocationStatus::NotAsFarAsWeKnow => {
|
||||
let add_to_verified = match self.by_email(&email) {
|
||||
None => false,
|
||||
Some(other_tpk) => {
|
||||
match TPK::from_bytes(&other_tpk) {
|
||||
Ok(other_tpk) => {
|
||||
all_uids.push((
|
||||
email.clone(),
|
||||
other_tpk.fingerprint(),
|
||||
));
|
||||
other_tpk.fingerprint() == tpk.fingerprint()
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if add_to_verified {
|
||||
verified_uids.push(email.clone());
|
||||
} else {
|
||||
let payload = Verify::new(
|
||||
uid.userid(),
|
||||
&uid.selfsigs().collect::<Vec<_>>(),
|
||||
fpr.clone(),
|
||||
)?;
|
||||
|
||||
active_uids.push((
|
||||
email.clone(),
|
||||
self.new_verify_token(payload)?,
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,6 +235,10 @@ pub trait Database: Sync + Send {
|
|||
|
||||
tpk = Self::strip_userids(tpk)?;
|
||||
|
||||
for (email, fpr) in all_uids {
|
||||
self.unlink_email(&email, &Fingerprint::try_from(fpr).unwrap());
|
||||
}
|
||||
|
||||
for _ in 0..100
|
||||
/* while cas failed */
|
||||
{
|
||||
|
@ -214,7 +251,10 @@ pub trait Database: Sync + Send {
|
|||
|
||||
if self.compare_and_swap(&fpr, Some(&old), Some(&new))? {
|
||||
self.link_subkeys(&fpr, subkeys)?;
|
||||
self.unlink_userids(&fpr, revoked_uids);
|
||||
for email in verified_uids {
|
||||
self.link_email(&email, &fpr);
|
||||
}
|
||||
|
||||
return Ok(active_uids);
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +264,7 @@ pub trait Database: Sync + Send {
|
|||
|
||||
if self.compare_and_swap(&fpr, None, Some(&fresh))? {
|
||||
self.link_subkeys(&fpr, subkeys)?;
|
||||
self.unlink_userids(&fpr, revoked_uids);
|
||||
|
||||
return Ok(active_uids);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,6 +238,64 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn test_reupload<D: Database>(db: &mut D) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let str_uid2 = "Test B <test_b@example.com>";
|
||||
let tpk = TPKBuilder::default()
|
||||
.add_userid(str_uid1)
|
||||
.add_userid(str_uid2)
|
||||
.generate().unwrap().0;
|
||||
let mut uid1 = UserID::new();
|
||||
let mut uid2 = UserID::new();
|
||||
|
||||
uid1.set_userid_from_bytes(str_uid1.as_bytes());
|
||||
uid2.set_userid_from_bytes(str_uid2.as_bytes());
|
||||
|
||||
let email1 = Email::from_str(str_uid1).unwrap();
|
||||
let email2 = Email::from_str(str_uid2).unwrap();
|
||||
|
||||
// upload key
|
||||
let tokens = db.merge_or_publish(tpk.clone()).unwrap();
|
||||
|
||||
// verify 1st uid
|
||||
assert!(db.verify_token(&tokens[0].1).unwrap().is_some());
|
||||
assert!(db.by_email(&email2).is_none() ^ db.by_email(&email1).is_none());
|
||||
|
||||
// reupload
|
||||
let tokens = db.merge_or_publish(tpk.clone()).unwrap();
|
||||
|
||||
assert_eq!(tokens.len(), 1);
|
||||
assert!(db.by_email(&email2).is_none() ^ db.by_email(&email1).is_none());
|
||||
}
|
||||
|
||||
pub fn test_uid_replacement<D: Database>(db: &mut D) {
|
||||
let str_uid = "Test A <test_a@example.com>";
|
||||
let tpk1 = TPKBuilder::default()
|
||||
.add_userid(str_uid)
|
||||
.generate().unwrap().0;
|
||||
let tpk2 = TPKBuilder::default()
|
||||
.add_userid(str_uid)
|
||||
.generate().unwrap().0;
|
||||
|
||||
let email = Email::from_str(str_uid).unwrap();
|
||||
let fpr1 = tpk1.fingerprint();
|
||||
let fpr2 = tpk2.fingerprint();
|
||||
|
||||
// upload key
|
||||
let tokens = db.merge_or_publish(tpk1.clone()).unwrap();
|
||||
|
||||
// verify 1st uid
|
||||
assert!(db.verify_token(&tokens[0].1).unwrap().is_some());
|
||||
assert_eq!(TPK::from_bytes(&db.by_email(&email).unwrap()).unwrap().fingerprint(), fpr1);
|
||||
|
||||
// replace
|
||||
let tokens = db.merge_or_publish(tpk2.clone()).unwrap();
|
||||
|
||||
assert!(db.by_email(&email).is_none());
|
||||
assert!(db.verify_token(&tokens[0].1).unwrap().is_some());
|
||||
assert_eq!(TPK::from_bytes(&db.by_email(&email).unwrap()).unwrap().fingerprint(), fpr2);
|
||||
}
|
||||
|
||||
pub fn test_uid_deletion<D: Database>(db: &mut D) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let str_uid2 = "Test B <test_b@example.com>";
|
||||
|
|
Loading…
Reference in New Issue