identity_jose/jwk/
key_set.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use core::iter::FromIterator;
5use core::ops::Index;
6use core::ops::IndexMut;
7use core::slice::Iter;
8use core::slice::SliceIndex;
9use zeroize::Zeroize;
10
11use crate::jwk::Jwk;
12
13/// JSON Web Key Set.
14///
15/// [More Info](https://tools.ietf.org/html/rfc7517#section-5)
16#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
17pub struct JwkSet {
18  /// An array of JWK values.
19  ///
20  /// [More Info](https://tools.ietf.org/html/rfc7517#section-5.1)
21  keys: Vec<Jwk>,
22}
23
24impl JwkSet {
25  /// Creates a new `JwkSet`.
26  pub const fn new() -> Self {
27    Self { keys: Vec::new() }
28  }
29
30  /// Returns the total number of keys in the set.
31  pub fn len(&self) -> usize {
32    self.keys.len()
33  }
34
35  /// Returns a boolean indicating if the set of keys is empty.
36  pub fn is_empty(&self) -> bool {
37    self.keys.is_empty()
38  }
39
40  /// Returns a slice containing the entire vector of keys.
41  pub fn as_slice(&self) -> &[Jwk] {
42    &self.keys
43  }
44
45  /// Returns an iterator over the contained [`Jwk`]s.
46  pub fn iter(&self) -> Iter<'_, Jwk> {
47    self.keys.iter()
48  }
49
50  /// Returns a list of keys matching the given `kid`.
51  pub fn get(&self, kid: &str) -> Vec<&Jwk> {
52    self
53      .keys
54      .iter()
55      .filter(|key| matches!(key.kid(), Some(value) if value == kid))
56      .collect()
57  }
58
59  /// Adds a new `key` to the set.
60  pub fn add(&mut self, key: impl Into<Jwk>) {
61    self.keys.push(key.into());
62  }
63
64  /// Removes the key at position `index`, returning `true` if the key was
65  /// removed.
66  pub fn del(&mut self, index: usize) -> bool {
67    if index < self.keys.len() {
68      self.keys.remove(index);
69      true
70    } else {
71      false
72    }
73  }
74
75  /// Removes and returns the last `key` in the set.
76  pub fn pop(&mut self) -> Option<Jwk> {
77    self.keys.pop()
78  }
79}
80
81impl FromIterator<Jwk> for JwkSet {
82  fn from_iter<I>(iter: I) -> Self
83  where
84    I: IntoIterator<Item = Jwk>,
85  {
86    Self {
87      keys: Vec::from_iter(iter),
88    }
89  }
90}
91
92impl<I> Index<I> for JwkSet
93where
94  I: SliceIndex<[Jwk]>,
95{
96  type Output = I::Output;
97
98  fn index(&self, index: I) -> &Self::Output {
99    Index::index(&*self.keys, index)
100  }
101}
102
103impl<I> IndexMut<I> for JwkSet
104where
105  I: SliceIndex<[Jwk]>,
106{
107  fn index_mut(&mut self, index: I) -> &mut Self::Output {
108    IndexMut::index_mut(&mut *self.keys, index)
109  }
110}
111
112impl Zeroize for JwkSet {
113  fn zeroize(&mut self) {
114    self.keys.zeroize();
115  }
116}
117
118impl Drop for JwkSet {
119  fn drop(&mut self) {
120    self.zeroize();
121  }
122}