sequoia_openpgp/types/
key_flags.rs

1use std::fmt;
2use std::ops::{BitAnd, BitOr};
3
4#[cfg(test)]
5use quickcheck::{Arbitrary, Gen};
6
7use crate::types::Bitfield;
8
9/// Describes how a key may be used, and stores additional information.
10///
11/// Key flags are described in [Section 5.2.3.29 of RFC 9580].
12///
13/// [Section 5.2.3.29 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
14///
15/// # A note on equality
16///
17/// `PartialEq` compares the serialized form of the key flag sets.  If
18/// you prefer to compare two key flag sets for semantic equality, you
19/// should use [`KeyFlags::normalized_eq`].  The difference between
20/// semantic equality and serialized equality is that semantic
21/// equality ignores differences in the amount of padding.
22///
23///   [`KeyFlags::normalized_eq`]: KeyFlags::normalized_eq()
24///
25/// # Examples
26///
27/// ```
28/// use sequoia_openpgp as openpgp;
29/// # use openpgp::Result;
30/// use openpgp::cert::prelude::*;
31/// use openpgp::policy::StandardPolicy;
32///
33/// # fn main() -> Result<()> {
34/// let p = &StandardPolicy::new();
35///
36/// let (cert, _) =
37///     CertBuilder::new()
38///         .add_userid("Alice <alice@example.com>")
39///         .add_transport_encryption_subkey()
40///         .generate()?;
41///
42/// for subkey in cert.with_policy(p, None)?.keys().subkeys() {
43///     // Key contains one Encryption subkey:
44///     assert!(subkey.key_flags().unwrap().for_transport_encryption());
45/// }
46/// # Ok(()) }
47/// ```
48#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub struct KeyFlags(Bitfield);
50assert_send_and_sync!(KeyFlags);
51
52impl fmt::Debug for KeyFlags {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        if self.for_certification() {
55            f.write_str("C")?;
56        }
57        if self.for_signing() {
58            f.write_str("S")?;
59        }
60        if self.for_transport_encryption() {
61            f.write_str("Et")?;
62        }
63        if self.for_storage_encryption() {
64            f.write_str("Er")?;
65        }
66        if self.for_authentication() {
67            f.write_str("A")?;
68        }
69        if self.is_split_key() {
70            f.write_str("D")?;
71        }
72        if self.is_group_key() {
73            f.write_str("G")?;
74        }
75
76        let mut need_comma = false;
77        for i in self.0.iter_set() {
78            match i {
79                KEY_FLAG_CERTIFY
80                    | KEY_FLAG_SIGN
81                    | KEY_FLAG_ENCRYPT_FOR_TRANSPORT
82                    | KEY_FLAG_ENCRYPT_AT_REST
83                    | KEY_FLAG_SPLIT_KEY
84                    | KEY_FLAG_AUTHENTICATE
85                    | KEY_FLAG_GROUP_KEY
86                    => (),
87                i => {
88                    if need_comma { f.write_str(", ")?; }
89                    write!(f, "#{}", i)?;
90                    need_comma = true;
91                },
92            }
93        }
94
95        // Mention any padding, as equality is sensitive to this.
96        if let Some(padding) = self.0.padding_bytes() {
97            if need_comma { f.write_str(", ")?; }
98            write!(f, "+padding({} bytes)", padding)?;
99        }
100
101        Ok(())
102    }
103}
104
105impl BitAnd for &KeyFlags {
106    type Output = KeyFlags;
107
108    fn bitand(self, rhs: Self) -> KeyFlags {
109        let l = self.as_bitfield().as_bytes();
110        let r = rhs.as_bitfield().as_bytes();
111
112        let mut c = Vec::with_capacity(std::cmp::min(l.len(), r.len()));
113        for (l, r) in l.iter().zip(r.iter()) {
114            c.push(l & r);
115        }
116
117        KeyFlags(c.into())
118    }
119}
120
121impl BitOr for &KeyFlags {
122    type Output = KeyFlags;
123
124    fn bitor(self, rhs: Self) -> KeyFlags {
125        let l = self.as_bitfield().as_bytes();
126        let r = rhs.as_bitfield().as_bytes();
127
128        // Make l the longer one.
129        let (l, r) = if l.len() > r.len() {
130            (l, r)
131        } else {
132            (r, l)
133        };
134
135        let mut l = l.to_vec();
136        for (i, r) in r.iter().enumerate() {
137            l[i] |= r;
138        }
139
140        KeyFlags(l.into())
141    }
142}
143
144impl AsRef<KeyFlags> for KeyFlags {
145    fn as_ref(&self) -> &KeyFlags {
146        self
147    }
148}
149
150impl KeyFlags {
151    /// Creates a new instance from `bits`.
152    pub fn new<B: AsRef<[u8]>>(bits: B) -> Self {
153        Self(bits.as_ref().to_vec().into())
154    }
155
156    /// Returns a new `KeyFlags` with all capabilities disabled.
157    pub fn empty() -> Self {
158        KeyFlags::new(&[])
159    }
160
161    /// Returns a reference to the underlying [`Bitfield`].
162    pub fn as_bitfield(&self) -> &Bitfield {
163        &self.0
164    }
165
166    /// Returns a mutable reference to the underlying [`Bitfield`].
167    pub fn as_bitfield_mut(&mut self) -> &mut Bitfield {
168        &mut self.0
169    }
170
171    /// Compares two key flag sets for semantic equality.
172    ///
173    /// `KeyFlags` implementation of `PartialEq` compares two key
174    /// flag sets for serialized equality.  That is, the `PartialEq`
175    /// implementation considers two key flag sets to *not* be equal
176    /// if they have different amounts of padding.  This comparison
177    /// function ignores padding.
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// use sequoia_openpgp as openpgp;
183    /// use openpgp::types::KeyFlags;
184    ///
185    /// # fn main() -> openpgp::Result<()> {
186    /// let a = KeyFlags::new(&[0x1]);
187    /// let b = KeyFlags::new(&[0x1, 0x0]);
188    ///
189    /// assert!(a != b);
190    /// assert!(a.normalized_eq(&b));
191    /// # Ok(()) }
192    /// ```
193    pub fn normalized_eq(&self, other: &Self) -> bool {
194        self.0.normalized_eq(&other.0)
195    }
196
197    /// Returns whether the specified key flag is set.
198    ///
199    /// # Examples
200    ///
201    /// ```
202    /// use sequoia_openpgp as openpgp;
203    /// use openpgp::types::KeyFlags;
204    ///
205    /// # fn main() -> openpgp::Result<()> {
206    /// // Key flags 0 and 2.
207    /// let kf = KeyFlags::new(&[0x5]);
208    ///
209    /// assert!(kf.get(0));
210    /// assert!(! kf.get(1));
211    /// assert!(kf.get(2));
212    /// assert!(! kf.get(3));
213    /// assert!(! kf.get(8));
214    /// assert!(! kf.get(80));
215    /// # assert!(kf.for_certification());
216    /// # Ok(()) }
217    /// ```
218    pub fn get(&self, bit: usize) -> bool {
219        self.0.get(bit)
220    }
221
222    /// Sets the specified key flag.
223    ///
224    /// This also clears any padding (trailing NUL bytes).
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use sequoia_openpgp as openpgp;
230    /// use openpgp::types::KeyFlags;
231    ///
232    /// # fn main() -> openpgp::Result<()> {
233    /// let kf = KeyFlags::empty().set(0).set(2);
234    ///
235    /// assert!(kf.get(0));
236    /// assert!(! kf.get(1));
237    /// assert!(kf.get(2));
238    /// assert!(! kf.get(3));
239    /// # assert!(kf.for_certification());
240    /// # Ok(()) }
241    /// ```
242    pub fn set(mut self, bit: usize) -> Self {
243        self.0.set(bit);
244        self.0.canonicalize();
245        self
246    }
247
248    /// Clears the specified key flag.
249    ///
250    /// This also clears any padding (trailing NUL bytes).
251    ///
252    /// # Examples
253    ///
254    /// ```
255    /// use sequoia_openpgp as openpgp;
256    /// use openpgp::types::KeyFlags;
257    ///
258    /// # fn main() -> openpgp::Result<()> {
259    /// let kf = KeyFlags::empty().set(0).set(2).clear(2);
260    ///
261    /// assert!(kf.get(0));
262    /// assert!(! kf.get(1));
263    /// assert!(! kf.get(2));
264    /// assert!(! kf.get(3));
265    /// # assert!(kf.for_certification());
266    /// # Ok(()) }
267    /// ```
268    pub fn clear(mut self, bit: usize) -> Self {
269        self.0.clear(bit);
270        self.0.canonicalize();
271        self
272    }
273
274    /// This key may be used to certify other keys.
275    pub fn for_certification(&self) -> bool {
276        self.get(KEY_FLAG_CERTIFY)
277    }
278
279    /// Returns a KeyFlags where the certificate flag is set.
280    pub fn certification() -> Self {
281        KeyFlags::empty().set_certification()
282    }
283
284    /// Declares that this key may be used to certify other keys.
285    pub fn set_certification(self) -> Self {
286        self.set(KEY_FLAG_CERTIFY)
287    }
288
289    /// Declares that this key may not be used to certify other keys.
290    pub fn clear_certification(self) -> Self {
291        self.clear(KEY_FLAG_CERTIFY)
292    }
293
294    /// Declares whether this key may be used to certify other keys.
295    pub fn set_certification_to(self, value: bool) -> Self {
296        if value {
297            self.set(KEY_FLAG_CERTIFY)
298        } else {
299            self.clear(KEY_FLAG_CERTIFY)
300        }
301    }
302
303    /// This key may be used to sign data.
304    pub fn for_signing(&self) -> bool {
305        self.get(KEY_FLAG_SIGN)
306    }
307
308    /// Returns a KeyFlags where the signing flag is set.
309    pub fn signing() -> Self {
310        KeyFlags::empty().set_signing()
311    }
312
313    /// Declares that this key may be used to sign data.
314    pub fn set_signing(self) -> Self {
315        self.set(KEY_FLAG_SIGN)
316    }
317
318    /// Declares that this key may not be used to sign data.
319    pub fn clear_signing(self) -> Self {
320        self.clear(KEY_FLAG_SIGN)
321    }
322
323    /// Declares whether this key may be used to sign data.
324    pub fn set_signing_to(self, value: bool) -> Self {
325        if value {
326            self.set(KEY_FLAG_SIGN)
327        } else {
328            self.clear(KEY_FLAG_SIGN)
329        }
330    }
331
332    /// This key may be used to encrypt communications.
333    pub fn for_transport_encryption(&self) -> bool {
334        self.get(KEY_FLAG_ENCRYPT_FOR_TRANSPORT)
335    }
336
337    /// Returns a KeyFlags where the transport encryption flag is set.
338    pub fn transport_encryption() -> Self {
339        KeyFlags::empty().set_transport_encryption()
340    }
341
342    /// Declares that this key may be used to encrypt communications.
343    pub fn set_transport_encryption(self) -> Self {
344        self.set(KEY_FLAG_ENCRYPT_FOR_TRANSPORT)
345    }
346
347    /// Declares that this key may not be used to encrypt communications.
348    pub fn clear_transport_encryption(self) -> Self {
349        self.clear(KEY_FLAG_ENCRYPT_FOR_TRANSPORT)
350    }
351
352    /// Declares whether this key may be used to encrypt communications.
353    pub fn set_transport_encryption_to(self, value: bool) -> Self {
354        if value {
355            self.set(KEY_FLAG_ENCRYPT_FOR_TRANSPORT)
356        } else {
357            self.clear(KEY_FLAG_ENCRYPT_FOR_TRANSPORT)
358        }
359    }
360
361    /// This key may be used to encrypt storage.
362    pub fn for_storage_encryption(&self) -> bool {
363        self.get(KEY_FLAG_ENCRYPT_AT_REST)
364    }
365
366    /// Returns a KeyFlags where the storage encryption flag is set.
367    pub fn storage_encryption() -> Self {
368        KeyFlags::empty().set_storage_encryption()
369    }
370
371    /// Declares that this key may be used to encrypt storage.
372    pub fn set_storage_encryption(self) -> Self {
373        self.set(KEY_FLAG_ENCRYPT_AT_REST)
374    }
375
376    /// Declares that this key may not be used to encrypt storage.
377    pub fn clear_storage_encryption(self) -> Self {
378        self.clear(KEY_FLAG_ENCRYPT_AT_REST)
379    }
380
381    /// Declares whether this key may be used to encrypt storage.
382    pub fn set_storage_encryption_to(self, value: bool) -> Self {
383        if value {
384            self.set(KEY_FLAG_ENCRYPT_AT_REST)
385        } else {
386            self.clear(KEY_FLAG_ENCRYPT_AT_REST)
387        }
388    }
389
390    /// This key may be used for authentication.
391    pub fn for_authentication(&self) -> bool {
392        self.get(KEY_FLAG_AUTHENTICATE)
393    }
394
395    /// Returns a KeyFlags where the authentication flag is set.
396    pub fn authentication() -> Self {
397        KeyFlags::empty().set_authentication()
398    }
399
400    /// Declares that this key may be used for authentication.
401    pub fn set_authentication(self) -> Self {
402        self.set(KEY_FLAG_AUTHENTICATE)
403    }
404
405    /// Declares that this key may not be used for authentication.
406    pub fn clear_authentication(self) -> Self {
407        self.clear(KEY_FLAG_AUTHENTICATE)
408    }
409
410    /// Declares whether this key may be used for authentication.
411    pub fn set_authentication_to(self, value: bool) -> Self {
412        if value {
413            self.set(KEY_FLAG_AUTHENTICATE)
414        } else {
415            self.clear(KEY_FLAG_AUTHENTICATE)
416        }
417    }
418
419    /// The private component of this key may have been split
420    /// using a secret-sharing mechanism.
421    pub fn is_split_key(&self) -> bool {
422        self.get(KEY_FLAG_SPLIT_KEY)
423    }
424
425    /// Returns a KeyFlags where the split key flag is set.
426    pub fn split_key() -> Self {
427        KeyFlags::empty().set_split_key()
428    }
429
430    /// Declares that the private component of this key may have been
431    /// split using a secret-sharing mechanism.
432    pub fn set_split_key(self) -> Self {
433        self.set(KEY_FLAG_SPLIT_KEY)
434    }
435
436    /// Declares that the private component of this key has not been
437    /// split using a secret-sharing mechanism.
438    pub fn clear_split_key(self) -> Self {
439        self.clear(KEY_FLAG_SPLIT_KEY)
440    }
441
442    /// Declares whether the private component of this key may have been
443    /// split using a secret-sharing mechanism.
444    pub fn set_split_key_to(self, value: bool) -> Self {
445        if value {
446            self.set(KEY_FLAG_SPLIT_KEY)
447        } else {
448            self.clear(KEY_FLAG_SPLIT_KEY)
449        }
450    }
451
452    /// The private component of this key may be in possession of more
453    /// than one person.
454    pub fn is_group_key(&self) -> bool {
455        self.get(KEY_FLAG_GROUP_KEY)
456    }
457
458    /// Returns a KeyFlags where the group flag is set.
459    pub fn group_key() -> Self {
460        KeyFlags::empty().set_group_key()
461    }
462
463    /// Declares that the private component of this key is in
464    /// possession of more than one person.
465    pub fn set_group_key(self) -> Self {
466        self.set(KEY_FLAG_GROUP_KEY)
467    }
468
469    /// Declares that the private component of this key should not be
470    /// in possession of more than one person.
471    pub fn clear_group_key(self) -> Self {
472        self.clear(KEY_FLAG_GROUP_KEY)
473    }
474
475    /// Declares whether the private component of this key is in
476    /// possession of more than one person.
477    pub fn set_group_key_to(self, value: bool) -> Self {
478        if value {
479            self.set(KEY_FLAG_GROUP_KEY)
480        } else {
481            self.clear(KEY_FLAG_GROUP_KEY)
482        }
483    }
484
485    /// Returns whether no flags are set.
486    pub fn is_empty(&self) -> bool {
487        self.as_bitfield().as_bytes().iter().all(|b| *b == 0)
488    }
489}
490
491/// This key may be used to certify other keys.
492const KEY_FLAG_CERTIFY: usize = 0;
493
494/// This key may be used to sign data.
495const KEY_FLAG_SIGN: usize = 1;
496
497/// This key may be used to encrypt communications.
498const KEY_FLAG_ENCRYPT_FOR_TRANSPORT: usize = 2;
499
500/// This key may be used to encrypt storage.
501const KEY_FLAG_ENCRYPT_AT_REST: usize = 3;
502
503/// The private component of this key may have been split by a
504/// secret-sharing mechanism.
505const KEY_FLAG_SPLIT_KEY: usize = 4;
506
507/// This key may be used for authentication.
508const KEY_FLAG_AUTHENTICATE: usize = 5;
509
510/// The private component of this key may be in the possession of more
511/// than one person.
512const KEY_FLAG_GROUP_KEY: usize = 7;
513
514#[cfg(test)]
515impl Arbitrary for KeyFlags {
516    fn arbitrary(g: &mut Gen) -> Self {
517        Self::new(Vec::arbitrary(g))
518    }
519}
520
521#[cfg(test)]
522mod tests {
523    use super::*;
524
525    quickcheck! {
526        fn roundtrip(val: KeyFlags) -> bool {
527            let mut q_bytes = val.as_bitfield().as_bytes().to_vec();
528            let q = KeyFlags::new(&q_bytes);
529            assert_eq!(val, q);
530            assert!(val.normalized_eq(&q));
531
532            // Add some padding to q.  Make sure they are still equal.
533            q_bytes.push(0);
534            let q = KeyFlags::new(&q_bytes);
535            assert!(val != q);
536            assert!(val.normalized_eq(&q));
537
538            q_bytes.push(0);
539            let q = KeyFlags::new(&q_bytes);
540            assert!(val != q);
541            assert!(val.normalized_eq(&q));
542
543            true
544        }
545    }
546
547    #[test]
548    fn test_set_to() {
549        macro_rules! t {
550            ($set:ident, $set2:ident) => {
551                // Set using set2.
552                assert_eq!(KeyFlags::empty().$set(),
553                           KeyFlags::empty().$set2(true));
554
555                // Clear using set2.
556                assert_eq!(KeyFlags::empty().$set2(false),
557                           KeyFlags::empty());
558
559                // Set using set, then clear using set2.
560                assert_eq!(KeyFlags::empty().$set().$set2(false),
561                           KeyFlags::empty());
562            }
563        }
564
565        t!(set_certification, set_certification_to);
566        t!(set_signing, set_signing_to);
567        t!(set_transport_encryption, set_transport_encryption_to);
568        t!(set_storage_encryption, set_storage_encryption_to);
569        t!(set_split_key, set_split_key_to);
570        t!(set_group_key, set_group_key_to);
571    }
572}