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}