1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use anyhow::Result;
use super::Key;
use crate::crypto::{self, prelude::*, util};
#[derive(Clone, PartialEq)]
pub struct Recipients {
keys: Vec<Key>,
}
impl Recipients {
pub fn from(keys: Vec<Key>) -> Self {
assert!(keys_same_proto(&keys), "recipient keys must use same proto");
Self { keys }
}
pub fn keys(&self) -> &[Key] {
&self.keys
}
pub fn add(&mut self, key: Key) {
self.keys.push(key);
assert!(
keys_same_proto(&self.keys),
"added recipient key uses different proto"
);
}
pub fn remove(&mut self, key: &Key) {
self.keys.retain(|k| k != key);
}
pub fn remove_all(&mut self, keys: &[Key]) {
self.keys.retain(|k| !keys.contains(k));
}
pub fn has_fingerprint(&self, fingerprint: &str) -> bool {
self.keys
.iter()
.any(|k| util::fingerprints_equal(k.fingerprint(false), fingerprint))
}
}
pub fn contains_own_secret_key(recipients: &Recipients) -> Result<bool> {
let secrets = Recipients::from(crypto::context(crypto::PROTO)?.keys_private()?);
Ok(recipients
.keys()
.iter()
.any(|k| secrets.has_fingerprint(&k.fingerprint(false))))
}
fn keys_same_proto(keys: &[Key]) -> bool {
if keys.len() < 2 {
true
} else {
let proto = keys[0].proto();
keys[1..].iter().all(|k| k.proto() == proto)
}
}