bitwarden_crypto/traits/
key_id.rs1use std::{fmt::Debug, hash::Hash};
2
3use zeroize::ZeroizeOnDrop;
4
5use crate::{AsymmetricCryptoKey, CryptoKey, SymmetricCryptoKey};
6
7pub trait KeyId:
19 Debug + Clone + Copy + Hash + Eq + PartialEq + Ord + PartialOrd + Send + Sync + 'static
20{
21 type KeyValue: CryptoKey + Send + Sync + ZeroizeOnDrop;
22
23 fn is_local(&self) -> bool;
26}
27
28pub trait KeyIds {
31 type Symmetric: KeyId<KeyValue = SymmetricCryptoKey>;
32 type Asymmetric: KeyId<KeyValue = AsymmetricCryptoKey>;
33}
34
35#[macro_export]
55macro_rules! key_ids {
56 ( $(
57 #[$meta_type:tt]
58 $vis:vis enum $name:ident {
59 $(
60 $( #[$variant_tag:tt] )?
61 $variant:ident $( ( $inner:ty ) )?
62 ),*
63 $(,)?
64 }
65 )+
66 $ids_vis:vis $ids_name:ident => $symm_name:ident, $asymm_name:ident;
67 ) => {
68 $(
69 #[derive(std::fmt::Debug, Clone, Copy, std::hash::Hash, Eq, PartialEq, Ord, PartialOrd)]
70 $vis enum $name { $(
71 $variant $( ($inner) )?,
72 )* }
73
74 impl $crate::KeyId for $name {
75 type KeyValue = key_ids!(@key_type $meta_type);
76
77 fn is_local(&self) -> bool {
78 use $name::*;
79 match self { $(
80 key_ids!(@variant_match $variant $( ( $inner ) )?) =>
81 key_ids!(@variant_value $( $variant_tag )? ),
82 )* }
83 }
84 }
85 )+
86
87 $ids_vis struct $ids_name;
88 impl $crate::KeyIds for $ids_name {
89 type Symmetric = $symm_name;
90 type Asymmetric = $asymm_name;
91 }
92 };
93
94 ( @key_type symmetric ) => { $crate::SymmetricCryptoKey };
95 ( @key_type asymmetric ) => { $crate::AsymmetricCryptoKey };
96
97 ( @variant_match $variant:ident ( $inner:ty ) ) => { $variant (_) };
98 ( @variant_match $variant:ident ) => { $variant };
99
100 ( @variant_value local ) => { true };
101 ( @variant_value ) => { false };
102}
103
104#[cfg(test)]
105pub(crate) mod tests {
106 use crate::{
107 traits::tests::{TestAsymmKey, TestSymmKey},
108 KeyId,
109 };
110
111 #[test]
112 fn test_local() {
113 assert!(!TestSymmKey::A(0).is_local());
114 assert!(!TestSymmKey::B((4, 10)).is_local());
115 assert!(TestSymmKey::C(8).is_local());
116
117 assert!(!TestAsymmKey::A(0).is_local());
118 assert!(!TestAsymmKey::B.is_local());
119 assert!(TestAsymmKey::C("test").is_local());
120 }
121}