From 6749058b7a2f196acff18d97eaae6c92a166fe8c Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Thu, 1 Feb 2024 16:47:59 +0100 Subject: [PATCH] Write more tests for Crypto crate (#570) Extend unit testing for the crypto crate. --- .../src/enc_string/asymmetric.rs | 33 ++++++++ crates/bitwarden-crypto/src/enc_string/mod.rs | 53 +++++++++++++ .../src/enc_string/symmetric.rs | 76 +++++++++++++++++++ 3 files changed, 162 insertions(+) diff --git a/crates/bitwarden-crypto/src/enc_string/asymmetric.rs b/crates/bitwarden-crypto/src/enc_string/asymmetric.rs index 04768db9e..f9bda838a 100644 --- a/crates/bitwarden-crypto/src/enc_string/asymmetric.rs +++ b/crates/bitwarden-crypto/src/enc_string/asymmetric.rs @@ -206,6 +206,8 @@ impl schemars::JsonSchema for AsymmetricEncString { #[cfg(test)] mod tests { + use schemars::schema_for; + use super::{AsymmetricCryptoKey, AsymmetricEncString, KeyDecryptable}; const RSA_PRIVATE_KEY: &str = "-----BEGIN PRIVATE KEY----- @@ -288,4 +290,35 @@ XKZBokBGnjFnTnKcs7nv/O8= assert_eq!(t.key.to_string(), cipher); assert_eq!(serde_json::to_string(&t).unwrap(), serialized); } + + #[test] + fn test_from_str_invalid() { + let enc_str = "7.ABC"; + let enc_string: Result = enc_str.parse(); + + let err = enc_string.unwrap_err(); + assert_eq!( + err.to_string(), + "EncString error, Invalid asymmetric type, got type 7 with 1 parts" + ); + } + + #[test] + fn test_debug_format() { + let enc_str: &str = "4.ZheRb3PCfAunyFdQYPfyrFqpuvmln9H9w5nDjt88i5A7ug1XE0LJdQHCIYJl0YOZ1gCOGkhFu/CRY2StiLmT3iRKrrVBbC1+qRMjNNyDvRcFi91LWsmRXhONVSPjywzrJJXglsztDqGkLO93dKXNhuKpcmtBLsvgkphk/aFvxbaOvJ/FHdK/iV0dMGNhc/9tbys8laTdwBlI5xIChpRcrfH+XpSFM88+Bu03uK67N9G6eU1UmET+pISJwJvMuIDMqH+qkT7OOzgL3t6I0H2LDj+CnsumnQmDsvQzDiNfTR0IgjpoE9YH2LvPXVP2wVUkiTwXD9cG/E7XeoiduHyHjw=="; + let enc_string: AsymmetricEncString = enc_str.parse().unwrap(); + + let debug_string = format!("{:?}", enc_string); + assert_eq!(debug_string, "AsymmetricEncString"); + } + + #[test] + fn test_json_schema() { + let schema = schema_for!(AsymmetricEncString); + + assert_eq!( + serde_json::to_string(&schema).unwrap(), + r#"{"$schema":"http://json-schema.org/draft-07/schema#","title":"AsymmetricEncString","type":"string"}"# + ); + } } diff --git a/crates/bitwarden-crypto/src/enc_string/mod.rs b/crates/bitwarden-crypto/src/enc_string/mod.rs index e1433821f..3250c1a58 100644 --- a/crates/bitwarden-crypto/src/enc_string/mod.rs +++ b/crates/bitwarden-crypto/src/enc_string/mod.rs @@ -75,3 +75,56 @@ where T::from_str(v).map_err(|e| E::custom(format!("{:?}", e))) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_check_length_less_than_expected() { + let buf = [1, 2, 3]; + let expected = 5; + let result = check_length(&buf, expected); + assert!(result.is_err()); + } + + #[test] + fn test_check_length_equal_to_expected() { + let buf = [1, 2, 3, 4, 5]; + let expected = 5; + let result = check_length(&buf, expected); + assert!(result.is_ok()); + } + + #[test] + fn test_check_length_greater_than_expected() { + let buf = [1, 2, 3, 4, 5, 6]; + let expected = 5; + let result = check_length(&buf, expected); + assert!(result.is_ok()); + } + + #[test] + fn test_split_enc_string_new_format() { + let s = "2.abc|def|ghi"; + let (header, parts) = split_enc_string(s); + assert_eq!(header, "2"); + assert_eq!(parts, vec!["abc", "def", "ghi"]); + } + + #[test] + fn test_split_enc_string_old_format_three_parts() { + let s = "abc|def|ghi"; + let (header, parts) = split_enc_string(s); + assert_eq!(header, "1"); + assert_eq!(parts, vec!["abc", "def", "ghi"]); + } + + #[test] + fn test_split_enc_string_old_format_fewer_parts() { + let s = "abc|def"; + let (header, parts) = split_enc_string(s); + assert_eq!(header, "0"); + assert_eq!(parts, vec!["abc", "def"]); + } +} diff --git a/crates/bitwarden-crypto/src/enc_string/symmetric.rs b/crates/bitwarden-crypto/src/enc_string/symmetric.rs index a76315e96..a7768de23 100644 --- a/crates/bitwarden-crypto/src/enc_string/symmetric.rs +++ b/crates/bitwarden-crypto/src/enc_string/symmetric.rs @@ -274,6 +274,8 @@ impl schemars::JsonSchema for EncString { #[cfg(test)] mod tests { + use schemars::schema_for; + use super::EncString; use crate::{derive_symmetric_key, KeyDecryptable, KeyEncryptable}; @@ -325,4 +327,78 @@ mod tests { assert_eq!(enc_string_new.to_string(), enc_str) } + + #[test] + fn test_from_str_cbc256() { + let enc_str = "0.pMS6/icTQABtulw52pq2lg==|XXbxKxDTh+mWiN1HjH2N1w=="; + let enc_string: EncString = enc_str.parse().unwrap(); + + assert_eq!(enc_string.enc_type(), 0); + if let EncString::AesCbc256_B64 { iv, data } = &enc_string { + assert_eq!( + iv, + &[164, 196, 186, 254, 39, 19, 64, 0, 109, 186, 92, 57, 218, 154, 182, 150] + ); + assert_eq!( + data, + &[93, 118, 241, 43, 16, 211, 135, 233, 150, 136, 221, 71, 140, 125, 141, 215] + ); + } + } + + #[test] + fn test_from_str_cbc128_hmac() { + let enc_str = "1.Hh8gISIjJCUmJygpKissLQ==|MjM0NTY3ODk6Ozw9Pj9AQUJDREU=|KCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkc="; + let enc_string: EncString = enc_str.parse().unwrap(); + + assert_eq!(enc_string.enc_type(), 1); + if let EncString::AesCbc128_HmacSha256_B64 { iv, mac, data } = &enc_string { + assert_eq!( + iv, + &[30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45] + ); + assert_eq!( + mac, + &[ + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 + ] + ); + assert_eq!( + data, + &[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69] + ); + } + } + + #[test] + fn test_from_str_invalid() { + let enc_str = "7.ABC"; + let enc_string: Result = enc_str.parse(); + + let err = enc_string.unwrap_err(); + assert_eq!( + err.to_string(), + "EncString error, Invalid symmetric type, got type 7 with 1 parts" + ); + } + + #[test] + fn test_debug_format() { + let enc_str = "2.pMS6/icTQABtulw52pq2lg==|XXbxKxDTh+mWiN1HjH2N1w==|Q6PkuT+KX/axrgN9ubD5Ajk2YNwxQkgs3WJM0S0wtG8="; + let enc_string: EncString = enc_str.parse().unwrap(); + + let debug_string = format!("{:?}", enc_string); + assert_eq!(debug_string, "EncString"); + } + + #[test] + fn test_json_schema() { + let schema = schema_for!(EncString); + + assert_eq!( + serde_json::to_string(&schema).unwrap(), + r#"{"$schema":"http://json-schema.org/draft-07/schema#","title":"EncString","type":"string"}"# + ); + } }