memory_testing/
lib.rs

1use std::path::Path;
2
3use bitwarden_crypto::Kdf;
4use zeroize::{Zeroize, Zeroizing};
5
6pub const TEST_STRING: &str = "THIS IS USED TO CHECK THAT THE MEMORY IS DUMPED CORRECTLY";
7
8pub fn load_cases(base_dir: &Path) -> Cases {
9    let mut json_str = std::fs::read_to_string(base_dir.join("cases.json")).unwrap();
10    let cases: Cases = serde_json::from_str(&json_str).unwrap();
11
12    // Make sure that we don't leave extra copies of the string data in memory
13    json_str.zeroize();
14    cases
15}
16
17#[derive(serde::Deserialize)]
18pub struct Cases {
19    pub cases: Vec<Case>,
20}
21
22#[derive(serde::Deserialize)]
23pub struct Case {
24    pub name: String,
25    #[serde(flatten)]
26    pub command: CaseCommand,
27    pub memory_lookups: Vec<MemoryLookup>,
28}
29
30// We don't actively zeroize this struct because we want the code in bitwarden_crypto
31// to handle it for us
32#[derive(serde::Deserialize)]
33#[serde(rename_all = "snake_case")]
34pub enum CaseCommand {
35    SymmetricKey {
36        key: String,
37    },
38    AsymmetricKey {
39        private_key: String,
40    },
41    MasterKey {
42        password: String,
43        email: String,
44        kdf: Kdf,
45    },
46    String {
47        parts: Vec<String>,
48    },
49}
50
51#[derive(serde::Deserialize)]
52pub struct MemoryLookup {
53    pub name: String,
54
55    #[serde(flatten)]
56    pub value: MemoryLookupValue,
57
58    #[serde(default)]
59    pub allowed_count: Option<usize>,
60}
61
62// We don't actually want these values to be caught by the memory testing,
63// so this enum should be always zeroized
64#[derive(serde::Deserialize)]
65#[serde(untagged)]
66pub enum MemoryLookupValue {
67    String { string: Zeroizing<String> },
68    Binary { hex: Zeroizing<String> },
69}