bitwarden_crypto/enc_string/
mod.rs1mod asymmetric;
10mod symmetric;
11
12pub use asymmetric::UnsignedSharedKey;
13use base64::{engine::general_purpose::STANDARD, Engine};
14pub use symmetric::EncString;
15
16use crate::error::{EncStringParseError, Result};
17
18fn check_length(buf: &[u8], expected: usize) -> Result<()> {
19 if buf.len() < expected {
20 return Err(EncStringParseError::InvalidLength {
21 expected,
22 got: buf.len(),
23 }
24 .into());
25 }
26 Ok(())
27}
28
29fn from_b64_vec(s: &str) -> Result<Vec<u8>> {
30 Ok(STANDARD
31 .decode(s)
32 .map_err(EncStringParseError::InvalidBase64)?)
33}
34
35fn from_b64<const N: usize>(s: &str) -> Result<[u8; N]> {
36 Ok(from_b64_vec(s)?
37 .try_into()
38 .map_err(|e: Vec<_>| EncStringParseError::InvalidLength {
39 expected: N,
40 got: e.len(),
41 })?)
42}
43
44fn split_enc_string(s: &str) -> (&str, Vec<&str>) {
45 let header_parts: Vec<_> = s.split('.').collect();
46
47 if header_parts.len() == 2 {
48 (header_parts[0], header_parts[1].split('|').collect())
49 } else {
50 let parts: Vec<_> = s.split('|').collect();
52 if parts.len() == 3 {
53 ("1", parts) } else {
55 ("0", parts) }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_check_length_less_than_expected() {
66 let buf = [1, 2, 3];
67 let expected = 5;
68 let result = check_length(&buf, expected);
69 assert!(result.is_err());
70 }
71
72 #[test]
73 fn test_check_length_equal_to_expected() {
74 let buf = [1, 2, 3, 4, 5];
75 let expected = 5;
76 let result = check_length(&buf, expected);
77 assert!(result.is_ok());
78 }
79
80 #[test]
81 fn test_check_length_greater_than_expected() {
82 let buf = [1, 2, 3, 4, 5, 6];
83 let expected = 5;
84 let result = check_length(&buf, expected);
85 assert!(result.is_ok());
86 }
87
88 #[test]
89 fn test_split_enc_string_new_format() {
90 let s = "2.abc|def|ghi";
91 let (header, parts) = split_enc_string(s);
92 assert_eq!(header, "2");
93 assert_eq!(parts, vec!["abc", "def", "ghi"]);
94 }
95
96 #[test]
97 fn test_split_enc_string_old_format_three_parts() {
98 let s = "abc|def|ghi";
99 let (header, parts) = split_enc_string(s);
100 assert_eq!(header, "1");
101 assert_eq!(parts, vec!["abc", "def", "ghi"]);
102 }
103
104 #[test]
105 fn test_split_enc_string_old_format_fewer_parts() {
106 let s = "abc|def";
107 let (header, parts) = split_enc_string(s);
108 assert_eq!(header, "0");
109 assert_eq!(parts, vec!["abc", "def"]);
110 }
111}