Add a version number for exported IKML and encrypted data
This commit is contained in:
parent
aa56e5d032
commit
44cc9179ca
5 changed files with 70 additions and 55 deletions
|
@ -98,7 +98,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{DataContext, KeyContext};
|
use crate::{DataContext, KeyContext};
|
||||||
|
|
||||||
const TEST_CIPHERTEXT: &str = "AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA";
|
const TEST_CIPHERTEXT: &str = "enc-v1:AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA";
|
||||||
const TEST_DATA: &[u8] = b"Lorem ipsum dolor sit amet.";
|
const TEST_DATA: &[u8] = b"Lorem ipsum dolor sit amet.";
|
||||||
const TEST_KEY_CTX: &[&str] = &["db_name", "table_name", "column_name"];
|
const TEST_KEY_CTX: &[&str] = &["db_name", "table_name", "column_name"];
|
||||||
const TEST_DATA_CTX: &[&str] = &["018db876-3d9d-79af-9460-55d17da991d8"];
|
const TEST_DATA_CTX: &[&str] = &["018db876-3d9d-79af-9460-55d17da991d8"];
|
||||||
|
@ -118,7 +118,7 @@ mod tests {
|
||||||
#[cfg(feature = "chacha")]
|
#[cfg(feature = "chacha")]
|
||||||
fn get_ikm_lst_chacha20poly1305_blake3() -> InputKeyMaterialList {
|
fn get_ikm_lst_chacha20poly1305_blake3() -> InputKeyMaterialList {
|
||||||
InputKeyMaterialList::import(
|
InputKeyMaterialList::import(
|
||||||
"AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA",
|
"ikml-v1:AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA",
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ mod tests {
|
||||||
#[cfg(feature = "aes")]
|
#[cfg(feature = "aes")]
|
||||||
fn get_ikm_lst_aes128gcm_sha256() -> InputKeyMaterialList {
|
fn get_ikm_lst_aes128gcm_sha256() -> InputKeyMaterialList {
|
||||||
InputKeyMaterialList::import(
|
InputKeyMaterialList::import(
|
||||||
"AQAAAA:AQAAAAIAAAA2lXqTSduZ22J0LiwEhmENjB6pLo0GVKvAQYocJcAAp1f8_2UAAAAAuzDPeAAAAAAA",
|
"ikml-v1:AQAAAA:AQAAAAIAAAA2lXqTSduZ22J0LiwEhmENjB6pLo0GVKvAQYocJcAAp1f8_2UAAAAAuzDPeAAAAAAA",
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -143,8 +143,8 @@ mod tests {
|
||||||
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let ciphertext = res.unwrap();
|
let ciphertext = res.unwrap();
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("enc-v1:AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 98);
|
assert_eq!(ciphertext.len(), 105);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
||||||
|
@ -165,8 +165,8 @@ mod tests {
|
||||||
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let ciphertext = res.unwrap();
|
let ciphertext = res.unwrap();
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("enc-v1:AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 82);
|
assert_eq!(ciphertext.len(), 89);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
||||||
|
@ -187,8 +187,8 @@ mod tests {
|
||||||
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let ciphertext = res.unwrap();
|
let ciphertext = res.unwrap();
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("enc-v1:AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 98);
|
assert_eq!(ciphertext.len(), 105);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
||||||
|
@ -209,8 +209,8 @@ mod tests {
|
||||||
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let ciphertext = res.unwrap();
|
let ciphertext = res.unwrap();
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("enc-v1:AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 82);
|
assert_eq!(ciphertext.len(), 89);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
||||||
|
@ -231,8 +231,8 @@ mod tests {
|
||||||
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let ciphertext = res.unwrap();
|
let ciphertext = res.unwrap();
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("enc-v1:AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 110);
|
assert_eq!(ciphertext.len(), 117);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
||||||
|
@ -253,8 +253,8 @@ mod tests {
|
||||||
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
let res = cb.encrypt(&key_ctx, &data_ctx, TEST_DATA);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let ciphertext = res.unwrap();
|
let ciphertext = res.unwrap();
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("enc-v1:AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 94);
|
assert_eq!(ciphertext.len(), 101);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
let res = cb.decrypt(&key_ctx, &data_ctx, &ciphertext);
|
||||||
|
@ -267,13 +267,14 @@ mod tests {
|
||||||
#[cfg(feature = "chacha")]
|
#[cfg(feature = "chacha")]
|
||||||
fn decrypt_invalid_ciphertext() {
|
fn decrypt_invalid_ciphertext() {
|
||||||
let tests = &[
|
let tests = &[
|
||||||
("", "empty data"),
|
("", "empty data 1"),
|
||||||
("AQAATA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "unknown ikm id"),
|
("env-v1:", "empty data 2"),
|
||||||
("AQAAAA:8pVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "invalid nonce"),
|
("enc-v1:AQAATA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "unknown ikm id"),
|
||||||
("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:8TkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "invalid ciphertext"),
|
("enc-v1:AQAAAA:8pVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "invalid nonce"),
|
||||||
("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NaAAAAAAAAA", "invalid time period"),
|
("enc-v1:AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:8TkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "invalid ciphertext"),
|
||||||
("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:", "empty time period"),
|
("enc-v1:AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NaAAAAAAAAA", "invalid time period"),
|
||||||
("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg", "missing time period"),
|
("enc-v1:AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:", "empty time period"),
|
||||||
|
("enc-v1:AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg", "missing time period"),
|
||||||
];
|
];
|
||||||
|
|
||||||
let lst = get_ikm_lst_chacha20poly1305_blake3();
|
let lst = get_ikm_lst_chacha20poly1305_blake3();
|
||||||
|
|
|
@ -32,6 +32,8 @@ pub enum Error {
|
||||||
ParsingEncodedDataInvalidPartLen(usize, usize),
|
ParsingEncodedDataInvalidPartLen(usize, usize),
|
||||||
#[error("parsing error: encoded data: invalid timestamp: {0:?}")]
|
#[error("parsing error: encoded data: invalid timestamp: {0:?}")]
|
||||||
ParsingEncodedDataInvalidTimestamp(Vec<u8>),
|
ParsingEncodedDataInvalidTimestamp(Vec<u8>),
|
||||||
|
#[error("parsing error: encoded data: invalid version")]
|
||||||
|
ParsingEncodedDataInvalidVersion,
|
||||||
#[error("parsing error: scheme: {0}: unknown scheme")]
|
#[error("parsing error: scheme: {0}: unknown scheme")]
|
||||||
ParsingSchemeUnknownScheme(crate::scheme::SchemeSerializeType),
|
ParsingSchemeUnknownScheme(crate::scheme::SchemeSerializeType),
|
||||||
#[error("unable to generate random values: {0}")]
|
#[error("unable to generate random values: {0}")]
|
||||||
|
|
12
src/ikm.rs
12
src/ikm.rs
|
@ -325,7 +325,7 @@ impl InputKeyMaterialList {
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
```
|
```
|
||||||
let stored_ikml = "AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA";
|
let stored_ikml = "ikml-v1:AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA";
|
||||||
let mut ikml = coffio::InputKeyMaterialList::import(stored_ikml)?;
|
let mut ikml = coffio::InputKeyMaterialList::import(stored_ikml)?;
|
||||||
assert_eq!(ikml.len(), 1);
|
assert_eq!(ikml.len(), 1);
|
||||||
# Ok::<(), coffio::Error>(())
|
# Ok::<(), coffio::Error>(())
|
||||||
|
@ -384,7 +384,7 @@ mod tests {
|
||||||
#[cfg(feature = "chacha")]
|
#[cfg(feature = "chacha")]
|
||||||
fn import() {
|
fn import() {
|
||||||
let s =
|
let s =
|
||||||
"AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA";
|
"ikml-v1:AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA";
|
||||||
let res = InputKeyMaterialList::import(s);
|
let res = InputKeyMaterialList::import(s);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let lst = res.unwrap();
|
let lst = res.unwrap();
|
||||||
|
@ -407,7 +407,7 @@ mod tests {
|
||||||
#[cfg(feature = "chacha")]
|
#[cfg(feature = "chacha")]
|
||||||
fn from_str() {
|
fn from_str() {
|
||||||
let s =
|
let s =
|
||||||
"AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA";
|
"ikml-v1:AQAAAA:AQAAAAEAAAC_vYEw1ujVG5i-CtoPYSzik_6xaAq59odjPm5ij01-e6zz4mUAAAAALJGBiwAAAAAA";
|
||||||
let res = InputKeyMaterialList::from_str(s);
|
let res = InputKeyMaterialList::from_str(s);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let lst = res.unwrap();
|
let lst = res.unwrap();
|
||||||
|
@ -457,7 +457,7 @@ mod ikm_management {
|
||||||
// 6: * not_before: Tuesday 15 August 2180 10:21:42
|
// 6: * not_before: Tuesday 15 August 2180 10:21:42
|
||||||
// * not_after: Wednesday 15 August 2181 10:21:42
|
// * not_after: Wednesday 15 August 2181 10:21:42
|
||||||
// * is_revoked: false
|
// * is_revoked: false
|
||||||
const TEST_STR: &str = "BgAAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB:AgAAAAEAAADf7CR8vl_aWOUyfsO0ek0YQr_Yi7L_sJmF2nIt_XOaCzYNal4AAAAAtkBLYAAAAAAA:AwAAAAEAAAAMoNIW9gIGkzegUDEsU3N1Rf_Zz0OMuylUSiQjUzLXqzY0MmAAAAAANsk0iwEAAAAA:BAAAAAEAAABbwRrMz3x3DkfOEFg1BHfLLRHoNqg6d_xGWwdh48hH8rZm9mEAAAAANjy9YwAAAAAA:BQAAAAEAAAA2LwnTgDUF7qn7dy79VA24JSSgo6vllAtU5zmhrxNJu7YIz4sBAAAANoUMjgEAAAAB:BgAAAAEAAAAn0Vqe2f9YRXBt6xVYaeSLs0Gf0S0_5B-hk-a2b0rhlraCJbwAAAAAtlErjAEAAAAA";
|
const TEST_STR: &str = "ikml-v1:BgAAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB:AgAAAAEAAADf7CR8vl_aWOUyfsO0ek0YQr_Yi7L_sJmF2nIt_XOaCzYNal4AAAAAtkBLYAAAAAAA:AwAAAAEAAAAMoNIW9gIGkzegUDEsU3N1Rf_Zz0OMuylUSiQjUzLXqzY0MmAAAAAANsk0iwEAAAAA:BAAAAAEAAABbwRrMz3x3DkfOEFg1BHfLLRHoNqg6d_xGWwdh48hH8rZm9mEAAAAANjy9YwAAAAAA:BQAAAAEAAAA2LwnTgDUF7qn7dy79VA24JSSgo6vllAtU5zmhrxNJu7YIz4sBAAAANoUMjgEAAAAB:BgAAAAEAAAAn0Vqe2f9YRXBt6xVYaeSLs0Gf0S0_5B-hk-a2b0rhlraCJbwAAAAAtlErjAEAAAAA";
|
||||||
|
|
||||||
fn round_time(t: SystemTime) -> SystemTime {
|
fn round_time(t: SystemTime) -> SystemTime {
|
||||||
let secs = t.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
|
let secs = t.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
|
||||||
|
@ -504,7 +504,7 @@ mod ikm_management {
|
||||||
let res = lst.export();
|
let res = lst.export();
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let s = res.unwrap();
|
let s = res.unwrap();
|
||||||
assert_eq!(&s, "AAAAAA");
|
assert_eq!(&s, "ikml-v1:AAAAAA");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -515,7 +515,7 @@ mod ikm_management {
|
||||||
let res = lst.export();
|
let res = lst.export();
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let s = res.unwrap();
|
let s = res.unwrap();
|
||||||
assert_eq!(s.len(), 83);
|
assert_eq!(s.len(), 91);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -55,3 +55,5 @@ pub const DEFAULT_KEY_CTX_PERIODICITY: u64 = 31_556_925;
|
||||||
pub const DEFAULT_SCHEME: Scheme = Scheme::XChaCha20Poly1305WithBlake3;
|
pub const DEFAULT_SCHEME: Scheme = Scheme::XChaCha20Poly1305WithBlake3;
|
||||||
#[cfg(all(feature = "ikm-management", feature = "aes", not(feature = "chacha")))]
|
#[cfg(all(feature = "ikm-management", feature = "aes", not(feature = "chacha")))]
|
||||||
pub const DEFAULT_SCHEME: Scheme = Scheme::Aes128GcmWithSha256;
|
pub const DEFAULT_SCHEME: Scheme = Scheme::Aes128GcmWithSha256;
|
||||||
|
const STORAGE_ENC_VERSION: &str = "enc-v1:";
|
||||||
|
const STORAGE_IKML_VERSION: &str = "ikml-v1:";
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub(crate) fn encode_ikm_list(ikml: &InputKeyMaterialList) -> Result<String> {
|
||||||
acc + IKM_BASE_STRUCT_SIZE + ikm.scheme.get_ikm_size()
|
acc + IKM_BASE_STRUCT_SIZE + ikm.scheme.get_ikm_size()
|
||||||
})) + 4;
|
})) + 4;
|
||||||
let mut ret = String::with_capacity(data_size);
|
let mut ret = String::with_capacity(data_size);
|
||||||
|
ret += crate::STORAGE_IKML_VERSION;
|
||||||
ret += &encode_data(&ikml.id_counter.to_le_bytes());
|
ret += &encode_data(&ikml.id_counter.to_le_bytes());
|
||||||
for ikm in &ikml.ikm_lst {
|
for ikm in &ikml.ikm_lst {
|
||||||
ret += STORAGE_SEPARATOR;
|
ret += STORAGE_SEPARATOR;
|
||||||
|
@ -42,7 +43,7 @@ pub(crate) fn encode_cipher(
|
||||||
encrypted_data: &EncryptedData,
|
encrypted_data: &EncryptedData,
|
||||||
time_period: Option<u64>,
|
time_period: Option<u64>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut ret = String::new();
|
let mut ret = String::from(crate::STORAGE_ENC_VERSION);
|
||||||
ret += &encode_data(&ikm_id.to_le_bytes());
|
ret += &encode_data(&ikm_id.to_le_bytes());
|
||||||
ret += STORAGE_SEPARATOR;
|
ret += STORAGE_SEPARATOR;
|
||||||
ret += &encode_data(&encrypted_data.nonce);
|
ret += &encode_data(&encrypted_data.nonce);
|
||||||
|
@ -56,6 +57,9 @@ pub(crate) fn encode_cipher(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn decode_ikm_list(data: &str) -> Result<InputKeyMaterialList> {
|
pub(crate) fn decode_ikm_list(data: &str) -> Result<InputKeyMaterialList> {
|
||||||
|
let data = data
|
||||||
|
.strip_prefix(crate::STORAGE_IKML_VERSION)
|
||||||
|
.ok_or(Error::ParsingEncodedDataInvalidVersion)?;
|
||||||
let v: Vec<&str> = data.split(STORAGE_SEPARATOR).collect();
|
let v: Vec<&str> = data.split(STORAGE_SEPARATOR).collect();
|
||||||
if v.is_empty() {
|
if v.is_empty() {
|
||||||
return Err(Error::ParsingEncodedDataInvalidIkmListLen(v.len()));
|
return Err(Error::ParsingEncodedDataInvalidIkmListLen(v.len()));
|
||||||
|
@ -79,6 +83,9 @@ pub(crate) fn decode_ikm_list(data: &str) -> Result<InputKeyMaterialList> {
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
pub(crate) fn decode_cipher(data: &str) -> Result<(IkmId, EncryptedData, Option<u64>)> {
|
pub(crate) fn decode_cipher(data: &str) -> Result<(IkmId, EncryptedData, Option<u64>)> {
|
||||||
|
let data = data
|
||||||
|
.strip_prefix(crate::STORAGE_ENC_VERSION)
|
||||||
|
.ok_or(Error::ParsingEncodedDataInvalidVersion)?;
|
||||||
let mut v: Vec<&str> = data.split(STORAGE_SEPARATOR).collect();
|
let mut v: Vec<&str> = data.split(STORAGE_SEPARATOR).collect();
|
||||||
let time_period = if v.len() == NB_PARTS + 1 {
|
let time_period = if v.len() == NB_PARTS + 1 {
|
||||||
match v.pop() {
|
match v.pop() {
|
||||||
|
@ -119,7 +126,7 @@ pub(crate) fn decode_cipher(data: &str) -> Result<(IkmId, EncryptedData, Option<
|
||||||
|
|
||||||
#[cfg(all(test, feature = "ikm-management"))]
|
#[cfg(all(test, feature = "ikm-management"))]
|
||||||
mod ikm_lst {
|
mod ikm_lst {
|
||||||
const TEST_STR: &str = "BgAAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB:AgAAAAEAAADf7CR8vl_aWOUyfsO0ek0YQr_Yi7L_sJmF2nIt_XOaCzYNal4AAAAAtkBLYAAAAAAA:AwAAAAEAAAAMoNIW9gIGkzegUDEsU3N1Rf_Zz0OMuylUSiQjUzLXqzY0MmAAAAAANsk0iwEAAAAA:BAAAAAEAAABbwRrMz3x3DkfOEFg1BHfLLRHoNqg6d_xGWwdh48hH8rZm9mEAAAAANjy9YwAAAAAA:BQAAAAEAAAA2LwnTgDUF7qn7dy79VA24JSSgo6vllAtU5zmhrxNJu7YIz4sBAAAANoUMjgEAAAAB:BgAAAAEAAAAn0Vqe2f9YRXBt6xVYaeSLs0Gf0S0_5B-hk-a2b0rhlraCJbwAAAAAtlErjAEAAAAA";
|
const TEST_STR: &str = "ikml-v1:BgAAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB:AgAAAAEAAADf7CR8vl_aWOUyfsO0ek0YQr_Yi7L_sJmF2nIt_XOaCzYNal4AAAAAtkBLYAAAAAAA:AwAAAAEAAAAMoNIW9gIGkzegUDEsU3N1Rf_Zz0OMuylUSiQjUzLXqzY0MmAAAAAANsk0iwEAAAAA:BAAAAAEAAABbwRrMz3x3DkfOEFg1BHfLLRHoNqg6d_xGWwdh48hH8rZm9mEAAAAANjy9YwAAAAAA:BQAAAAEAAAA2LwnTgDUF7qn7dy79VA24JSSgo6vllAtU5zmhrxNJu7YIz4sBAAAANoUMjgEAAAAB:BgAAAAEAAAAn0Vqe2f9YRXBt6xVYaeSLs0Gf0S0_5B-hk-a2b0rhlraCJbwAAAAAtlErjAEAAAAA";
|
||||||
const TEST_CTN_0: &[u8] = &[
|
const TEST_CTN_0: &[u8] = &[
|
||||||
0x94, 0x00, 0xf7, 0x2a, 0x9e, 0x02, 0x78, 0xeb, 0xf1, 0xcc, 0xb4, 0x94, 0x9d, 0x23, 0x0f,
|
0x94, 0x00, 0xf7, 0x2a, 0x9e, 0x02, 0x78, 0xeb, 0xf1, 0xcc, 0xb4, 0x94, 0x9d, 0x23, 0x0f,
|
||||||
0x96, 0x79, 0x4b, 0x48, 0x99, 0xc0, 0x95, 0xc4, 0xe0, 0x38, 0xee, 0x7e, 0x94, 0x20, 0xde,
|
0x96, 0x79, 0x4b, 0x48, 0x99, 0xc0, 0x95, 0xc4, 0xe0, 0x38, 0xee, 0x7e, 0x94, 0x20, 0xde,
|
||||||
|
@ -251,8 +258,8 @@ mod ikm_lst {
|
||||||
let res = super::encode_ikm_list(&lst);
|
let res = super::encode_ikm_list(&lst);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
let s = res.unwrap();
|
let s = res.unwrap();
|
||||||
assert!(s.starts_with("AwAAAA:"));
|
assert!(s.starts_with("ikml-v1:AwAAAA:"));
|
||||||
assert_eq!(s.len(), 237);
|
assert_eq!(s.len(), 245);
|
||||||
|
|
||||||
let res = super::decode_ikm_list(&s);
|
let res = super::decode_ikm_list(&s);
|
||||||
assert!(res.is_ok(), "res: {res:?}");
|
assert!(res.is_ok(), "res: {res:?}");
|
||||||
|
@ -277,24 +284,25 @@ mod ikm_lst {
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_invalid() {
|
fn decode_invalid() {
|
||||||
let tests = &[
|
let tests = &[
|
||||||
("", "empty ikm"),
|
("", "empty string"),
|
||||||
|
("ikml-v1:", "empty ikm content"),
|
||||||
(
|
(
|
||||||
"AAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB",
|
"ikml-v1:AAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB",
|
||||||
"invalid id",
|
"invalid id",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
":AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB",
|
"ikml-v1::AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB",
|
||||||
"empty id",
|
"empty id",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB",
|
"ikml-v1:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47n6UIN5K2TbmoVwAAAAANmuEXgAAAAAB",
|
||||||
"no id",
|
"no id",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"BgAAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47",
|
"ikml-v1:BgAAAA:AQAAAAEAAACUAPcqngJ46_HMtJSdIw-WeUtImcCVxOA47",
|
||||||
"invalid ikm",
|
"invalid ikm",
|
||||||
),
|
),
|
||||||
("BgAAAA:", "empty ikm"),
|
("ikml-v1:BgAAAA:", "empty ikm"),
|
||||||
];
|
];
|
||||||
for (s, error_str) in tests {
|
for (s, error_str) in tests {
|
||||||
let res = super::decode_ikm_list(s);
|
let res = super::decode_ikm_list(s);
|
||||||
|
@ -308,8 +316,8 @@ mod ciphers {
|
||||||
use crate::ikm::IkmId;
|
use crate::ikm::IkmId;
|
||||||
use crate::storage::EncryptedData;
|
use crate::storage::EncryptedData;
|
||||||
|
|
||||||
const TEST_STR: &str = "KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN";
|
const TEST_STR: &str = "enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN";
|
||||||
const TEST_STR_T: &str = "KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN:NaAAAAAAAAA";
|
const TEST_STR_T: &str = "enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN:NaAAAAAAAAA";
|
||||||
const TEST_IKM_ID: IkmId = 42;
|
const TEST_IKM_ID: IkmId = 42;
|
||||||
const TEST_NONCE: &'static [u8] = &[
|
const TEST_NONCE: &'static [u8] = &[
|
||||||
0x6b, 0x94, 0xa9, 0x8c, 0x0a, 0x2a, 0x86, 0xfb, 0x88, 0xf6, 0x7d, 0xc6, 0x3e, 0x10, 0xca,
|
0x6b, 0x94, 0xa9, 0x8c, 0x0a, 0x2a, 0x86, 0xfb, 0x88, 0xf6, 0x7d, 0xc6, 0x3e, 0x10, 0xca,
|
||||||
|
@ -378,27 +386,29 @@ mod ciphers {
|
||||||
("", "empty data 1"),
|
("", "empty data 1"),
|
||||||
(":", "empty data 2"),
|
(":", "empty data 2"),
|
||||||
("::", "empty data 3"),
|
("::", "empty data 3"),
|
||||||
(":::", "empty data 4"),
|
("enc-v1::", "empty data 4"),
|
||||||
("a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "missing ikm id"),
|
("enc-v1:::", "empty data 5"),
|
||||||
("KgAAAA:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "missing nonce"),
|
("enc-v1::::", "empty data 6"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb", "missing ciphertext"),
|
("enc-v1:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "missing ikm id"),
|
||||||
|
("enc-v1:KgAAAA:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "missing nonce"),
|
||||||
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb", "missing ciphertext"),
|
||||||
|
|
||||||
// Empty parts
|
// Empty parts
|
||||||
(":a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "empty ikm id"),
|
("enc-v1::a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "empty ikm id"),
|
||||||
("KgAAAA::TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "empty nonce"),
|
("enc-v1:KgAAAA::TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "empty nonce"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:", "empty ciphertext"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:", "empty ciphertext"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN:", "empty time period"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN:", "empty time period"),
|
||||||
|
|
||||||
// Invalid base64 parts
|
// Invalid base64 parts
|
||||||
("KgAA.A:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid base64 ikm id"),
|
("enc-v1:KgAA.A:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid base64 ikm id"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKu@tqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid base64 nonce"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKu@tqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid base64 nonce"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHK/xfnY-zR_bN", "invalid base64 ciphertext"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHK/xfnY-zR_bN", "invalid base64 ciphertext"),
|
||||||
|
|
||||||
// Invalid data length
|
// Invalid data length
|
||||||
("KgAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid ikm id data length"),
|
("enc-v1:KgAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid ikm id data length"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid nonce data length"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN", "invalid nonce data length"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR", "invalid ciphertext data length"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR", "invalid ciphertext data length"),
|
||||||
("KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN:AQAAAA", "invalid time period length"),
|
("enc-v1:KgAAAA:a5SpjAoqhvuI9n3GPhDKuotqoLbf7_Fb:TI24Wr_g-ZV7_X1oHqVKak9iRlQSneYVOMWB-3Lp-hFHKfxfnY-zR_bN:AQAAAA", "invalid time period length"),
|
||||||
];
|
];
|
||||||
for (ciphertext, error_str) in invalid_tests {
|
for (ciphertext, error_str) in invalid_tests {
|
||||||
let res = super::decode_cipher(ciphertext);
|
let res = super::decode_cipher(ciphertext);
|
||||||
|
|
Loading…
Reference in a new issue