bitwarden_crypto_cipher_suite/
cipher_suite_client.rs1use bitwarden_core::{Client, FromClient, key_management::KeySlotIds};
2use bitwarden_crypto::{Kdf, KeyStore};
3
4#[bitwarden_ffi::wasm_object]
10#[derive(FromClient)]
11pub struct CryptoCipherSuiteClient {
12 pub(crate) key_store: KeyStore<KeySlotIds>,
13}
14
15#[bitwarden_ffi::wasm_export]
16impl CryptoCipherSuiteClient {
17 pub fn default_kdf_for_new_account(&self) -> Kdf {
22 self.key_store
23 .context()
24 .cipher_suite()
25 .default_kdf_for_new_account()
26 }
27
28 pub fn is_kdf_compliant(&self, kdf: Kdf) -> bool {
34 self.key_store
35 .context()
36 .cipher_suite()
37 .is_kdf_compliant(&kdf)
38 }
39}
40
41pub trait CryptoCipherSuiteClientExt {
43 fn crypto_cipher_suite(&self) -> CryptoCipherSuiteClient;
45}
46
47impl CryptoCipherSuiteClientExt for Client {
48 fn crypto_cipher_suite(&self) -> CryptoCipherSuiteClient {
49 CryptoCipherSuiteClient::from_client(self)
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use bitwarden_core::{Client, ClientSettings};
56 use bitwarden_crypto::CipherSuite;
57
58 use super::*;
59
60 fn client_with_suite(cipher_suite: CipherSuite) -> Client {
61 let client = Client::new(Some(ClientSettings::default()));
62 client
63 .internal
64 .get_key_store()
65 .set_cipher_suite(cipher_suite);
66 client
67 }
68
69 #[test]
70 fn default_kdf_for_new_account_is_argon2_under_standard() {
71 let kdf = client_with_suite(CipherSuite::Standard)
72 .crypto_cipher_suite()
73 .default_kdf_for_new_account();
74 assert!(matches!(kdf, Kdf::Argon2id { .. }));
75 }
76
77 #[test]
78 fn default_kdf_for_new_account_is_pbkdf2_under_fips() {
79 let kdf = client_with_suite(CipherSuite::Fips)
80 .crypto_cipher_suite()
81 .default_kdf_for_new_account();
82 assert!(matches!(kdf, Kdf::PBKDF2 { .. }));
83 }
84
85 #[test]
86 fn every_kdf_is_compliant_under_standard() {
87 let client = client_with_suite(CipherSuite::Standard).crypto_cipher_suite();
88 assert!(client.is_kdf_compliant(Kdf::default_argon2()));
89 assert!(client.is_kdf_compliant(Kdf::default_pbkdf2()));
90 }
91
92 #[test]
93 fn only_pbkdf2_is_compliant_under_fips() {
94 let client = client_with_suite(CipherSuite::Fips).crypto_cipher_suite();
95 assert!(client.is_kdf_compliant(Kdf::default_pbkdf2()));
96 assert!(!client.is_kdf_compliant(Kdf::default_argon2()));
97 }
98}