sequoia_openpgp/types/revocation_key.rs
1#[cfg(test)]
2use quickcheck::{Arbitrary, Gen};
3
4use crate::{
5 cert::prelude::*,
6 Error,
7 Fingerprint,
8 Result,
9 types::{
10 PublicKeyAlgorithm,
11 },
12};
13
14/// Designates a key as a valid third-party revoker.
15///
16/// This is described in [Section 5.2.3.23 of RFC 9580].
17///
18/// [Section 5.2.3.23 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
19///
20/// Revocation keys can be retrieved using [`ValidAmalgamation::revocation_keys`]
21/// and set using [`CertBuilder::set_revocation_keys`].
22///
23/// [`ValidAmalgamation::revocation_keys`]: crate::cert::amalgamation::ValidAmalgamation::revocation_keys()
24/// [`CertBuilder::set_revocation_keys`]: crate::cert::CertBuilder::set_revocation_keys()
25///
26/// # Examples
27///
28/// ```
29/// use sequoia_openpgp as openpgp;
30/// # use openpgp::Result;
31/// use openpgp::cert::prelude::*;
32/// use openpgp::policy::StandardPolicy;
33/// use openpgp::types::RevocationKey;
34///
35/// # fn main() -> Result<()> {
36/// let p = &StandardPolicy::new();
37///
38/// let (alice, _) =
39/// CertBuilder::general_purpose(Some("alice@example.org"))
40/// .generate()?;
41///
42/// // Make Alice a designated revoker for Bob.
43/// let (bob, _) =
44/// CertBuilder::general_purpose(Some("bob@example.org"))
45/// .set_revocation_keys(vec![(&alice).into()])
46/// .generate()?;
47///
48/// // Make sure Alice is listed as a designated revoker for Bob.
49/// assert_eq!(bob.with_policy(p, None)?.revocation_keys()
50/// .collect::<Vec<&RevocationKey>>(),
51/// vec![&(&alice).into()]);
52/// # Ok(()) }
53/// ```
54#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
55pub struct RevocationKey {
56 /// The public key algorithm used by the authorized key.
57 pk_algo: PublicKeyAlgorithm,
58
59 /// Fingerprint of authorized key.
60 fp: Fingerprint,
61
62 /// Indicates that the relation between revoker and revokee is
63 /// of a sensitive nature.
64 sensitive: bool,
65
66 /// Other bits are for future expansion to other kinds of
67 /// authorizations.
68 unknown: u8,
69}
70assert_send_and_sync!(RevocationKey);
71
72impl From<&Cert> for RevocationKey {
73 fn from(cert: &Cert) -> Self {
74 RevocationKey::new(cert.primary_key().key().pk_algo(),
75 cert.fingerprint(),
76 false)
77 }
78}
79
80impl RevocationKey {
81 /// Creates a new instance.
82 pub fn new(pk_algo: PublicKeyAlgorithm, fp: Fingerprint, sensitive: bool)
83 -> Self
84 {
85 RevocationKey {
86 pk_algo, fp, sensitive, unknown: 0,
87 }
88 }
89
90 /// Creates a new instance from the raw `class` parameter.
91 pub fn from_bits(pk_algo: PublicKeyAlgorithm, fp: Fingerprint, class: u8)
92 -> Result<Self> {
93 if class & REVOCATION_KEY_FLAG_MUST_BE_SET == 0 {
94 return Err(Error::InvalidArgument(
95 "Most significant bit of class must be set".into()).into());
96 }
97 let sensitive = class & REVOCATION_KEY_FLAG_SENSITIVE > 0;
98 let unknown = class & REVOCATION_KEY_MASK_UNKNOWN;
99 Ok(RevocationKey {
100 pk_algo, fp, sensitive, unknown,
101 })
102 }
103
104 /// Returns the `class` octet, the sum of all flags.
105 pub fn class(&self) -> u8 {
106 REVOCATION_KEY_FLAG_MUST_BE_SET
107 | if self.sensitive() {
108 REVOCATION_KEY_FLAG_SENSITIVE
109 } else {
110 0
111 }
112 | self.unknown
113 }
114
115 /// Returns the revoker's identity.
116 pub fn revoker(&self) -> (PublicKeyAlgorithm, &Fingerprint) {
117 (self.pk_algo, &self.fp)
118 }
119
120 /// Sets the revoker's identity.
121 pub fn set_revoker(&mut self, pk_algo: PublicKeyAlgorithm, fp: Fingerprint)
122 -> (PublicKeyAlgorithm, Fingerprint) {
123 let pk_algo = std::mem::replace(&mut self.pk_algo, pk_algo);
124 let fp = std::mem::replace(&mut self.fp, fp);
125 (pk_algo, fp)
126 }
127
128 /// Returns whether the relation between revoker and
129 /// revokee is of a sensitive nature.
130 pub fn sensitive(&self) -> bool {
131 self.sensitive
132 }
133
134 /// Sets whether the relation between revoker and revokee
135 /// is of a sensitive nature.
136 pub fn set_sensitive(mut self, v: bool) -> Self {
137 self.sensitive = v;
138 self
139 }
140}
141
142/// This bit must be set.
143const REVOCATION_KEY_FLAG_MUST_BE_SET: u8 = 0x80;
144
145/// Relation is of a sensitive nature.
146const REVOCATION_KEY_FLAG_SENSITIVE: u8 = 0x40;
147
148/// Mask covering the unknown bits.
149const REVOCATION_KEY_MASK_UNKNOWN: u8 = ! (REVOCATION_KEY_FLAG_MUST_BE_SET
150 | REVOCATION_KEY_FLAG_SENSITIVE);
151
152#[cfg(test)]
153impl Arbitrary for RevocationKey {
154 fn arbitrary(g: &mut Gen) -> Self {
155 RevocationKey {
156 pk_algo: Arbitrary::arbitrary(g),
157 fp: Arbitrary::arbitrary(g),
158 sensitive: Arbitrary::arbitrary(g),
159 unknown: u8::arbitrary(g) & REVOCATION_KEY_MASK_UNKNOWN,
160 }
161 }
162}