Skip to content

Commit

Permalink
fix: non regression tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tbrezot committed Feb 16, 2023
1 parent d9fffee commit 1a37392
Show file tree
Hide file tree
Showing 14 changed files with 327 additions and 312 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ tiny-keccak = { version = "2.0.2", features = ["shake"] }
[dev-dependencies]
criterion = { version = "0.4", features = ["html_reports"], default_features = false }
hex = "0.4"
base64 = "0.21.0"
7 changes: 4 additions & 3 deletions examples/decrypt.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use cosmian_cover_crypt::statics::CoverCryptX25519Aes256;

fn main() {
#[cfg(feature = "serialization")]
{
use cosmian_cover_crypt::{core::api::EncryptedHeader, statics::UserSecretKey};
use cosmian_cover_crypt::{
core::api::EncryptedHeader,
statics::{CoverCryptX25519Aes256, UserSecretKey},
};
use cosmian_crypto_core::bytes_ser_de::Serializable;

const USK: &str = "3792e73f675863e3e80eb7df44ba6e1649b805969764682a6c3d42d0a5d6e70bb299e3833f5182c64bb80d9d911e25c9d4d403b90c9d7b7a79bf024cd287c009030138503cdc107fad8b43ca780927926c5cd7928cb95ae0facdff78b432dcc8142918c51233edc149c8e22959a39562136b8cf6785f87bb89ec7680bca086a78fcb99978f253ed9e50737fca6a5168dcbf26e6f460525e09fa3b424b8a88472756793e5170cf901b8b027e1ec96e81241f2183a2284b18fe42fe2f9538cdb4e35674fe7f08af7e4938d02279b701f5755020a0c625b6c4641c2873f253cc024a1d0503f2eb413990749c5ea50d23b1d0649c592e5701360862ac605a818cb648cab653cb9e258473510310cfa4612871c777c29b1851eef3034228a31029672a07813d0eba77084b582297c3b6a6fca3a174619259a729031ec96c70b2f829b3635bc06f0c5b7ef33797551c0a49798facca38eb2b17854416ec81ed488590e478b2e994693468e66349f63956ec239827a3709bfb8822e794a1405653ab16ecf40802fca78f8b7a9d308c8aa98031df05824d94b4edb1867a878bea25663d3b75ab13f62d3b50ba401081284ae8aad26a45129291fa47914afb33378214aed316b0a950218b30c37c0cb6a431abe57acc1408ebe8bcffbd444da87567a70baf1353aef001d9677b1cd4b9a8b779c23e71004aca6e7804812142c062c1a131969b0b4a609b60591001a2269c1a174c8f0b8a882027d15cb4f05e82b33195076e500768c2096189d6217af70f6776fd8b9a756c029d74dd7f40cfc6a134c13c5e138840eaabb8c5b805d38c2d30c62651a43c8e1b2996b0adf2a5e6fc5cd0bb8aadb293a84d01fd136406915384624185fbb10b43159d112b080b52e1717320ae0cdc23c4b6eab4fa7e4227f334ed9183279291f6cd6aae05781f9f968215a45c45cb77a51a328c8a4257a3944fa3a4001661ce74bad745fc49b57d5a01fb9b12212150196662f28eab28eacc5de4327efb47687239e0ad731c3e12ee8789a1a64cc4d335ea3d58aee988aa34b3e87f8ae14fc4b8733a556629e21d759f71657d4f1298ed6b8a3775178e925c6f65d4d029008a032660c7f0721c9d4aaaf1f3775226b39572a329be05f4978602a79ce080154699c7cef58148fec6db1663c580421b8106e2ef9067d415883b897b01902c4c716cc625117d8064bcbad9e518c0fd668b62716aa31a1a55072908b6f6c183aaca5aec3bb40bd951b33d17a6bf5b865916bcddc27a1c173d53465414787a1a07894550230a116dc678f5a80cf79e668f68a25b405bb544938a9f659567222f9661c781b33d4451e2b9a8ec90b1835043ed7693fb8988f13e41b6ff09dc7926593cba05912153722064a9125e2cc68da2ba788e02c4c050126e09d9c66084e393c665639db6c537bd58ee637310e38c09f77b72eba12fb673a69b1c50e05b5db79148aba4554d7112e64b48b60a627697be305b0d89416e38a2e8e89aa018845a9109b79f6808db1ad850180e3e28b90d90d85d77c3ab29c3615b2a3a6a814abceda482b4887c0600acd2a1a10ddc70a8285b84ba524cc1b5a01a59ac1c9cbc17c52b93823eb756a740b9a1adb751a5805f266bd213719eeb2568fc93edd732c99992a4825901c733a08d05ae4b190e603b9c1f20d18d172b566643039bac2826b9745cdbae2ba45b286292cb4fd846dafeb11b973a2d4bb0a31b5997b6694508af26f371ce1e87c439d165e0e291d000084af44e362566480b0f65e9435f190002e1dc713cd957b3e821562b3126ce90d00c267283dee0ea1584cd34732e3bad6c9c428c763b41d1abe7b9340680598a20e";
Expand Down
16 changes: 8 additions & 8 deletions src/abe_policy/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ fn generate_current_attribute_partitions(
#[cfg(test)]
mod tests {
use super::*;
use crate::statics::tests::policy;
use crate::tests::policy;

fn axes_attributes_from_policy(
axes: &[String],
Expand Down Expand Up @@ -575,7 +575,7 @@ mod tests {
// create access policy
let access_policy = AccessPolicy::new("Department", "HR")
| (AccessPolicy::new("Department", "FIN")
& AccessPolicy::new("Security Level", "Confidential"));
& AccessPolicy::new("Security Level", "High Secret"));

//
// create partitions from access policy
Expand All @@ -596,16 +596,16 @@ mod tests {
partitions_.insert(Partition::from_attribute_values(partition)?);
}

// add the other attribute combination: FIN && Confidential
// add the other attribute combination: FIN && High Secret
let fin_value = policy.attribute_current_value(&Attribute::new("Department", "FIN"))?;
let conf_value =
policy.attribute_current_value(&Attribute::new("Security Level", "Confidential"))?;
policy.attribute_current_value(&Attribute::new("Security Level", "High Secret"))?;
let mut partition = vec![fin_value, conf_value];
partition.sort_unstable();
partitions_.insert(Partition::from_attribute_values(partition)?);
// since this is a hierarchical axis, add the lower values: here only protected
// since this is a hierarchical axis, add the lower values: here only low secret
let prot_value =
policy.attribute_current_value(&Attribute::new("Security Level", "Protected"))?;
policy.attribute_current_value(&Attribute::new("Security Level", "Low Secret"))?;
let mut partition = vec![fin_value, prot_value];
partition.sort_unstable();
partitions_.insert(Partition::from_attribute_values(partition)?);
Expand All @@ -617,7 +617,7 @@ mod tests {
//
let policy_attributes_4 = AccessPolicy::from_boolean_expression(
"(Department::FIN && Security Level::Top Secret) || (Department::MKG && Security \
Level::Protected)",
Level::Low Secret)",
)
.unwrap();
let partition_4 = policy
Expand All @@ -626,7 +626,7 @@ mod tests {

let policy_attributes_5 = AccessPolicy::from_boolean_expression(
"(Department::FIN && Security Level::Top Secret) || (Department::MKG && Security \
Level::Confidential)",
Level::High Secret)",
)
.unwrap();
let partition_5 = policy
Expand Down
5 changes: 3 additions & 2 deletions src/core/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ mod tests {
use super::*;
use crate::{
abe_policy::{AccessPolicy, EncryptionHint},
statics::{tests::policy, CoverCryptX25519Aes256},
statics::CoverCryptX25519Aes256,
tests::policy,
};

const TAG_LENGTH: usize = 32;
Expand Down Expand Up @@ -414,7 +415,7 @@ mod tests {
let user_policy =
AccessPolicy::from_boolean_expression("Department::MKG && Security Level::Top Secret")?;
let encryption_policy = AccessPolicy::from_boolean_expression(
"Department::MKG && Security Level::Confidential",
"Department::MKG && Security Level::High Secret",
)?;
let (msk, mpk) = cc.generate_master_keys(&policy)?;
let usk = cc.generate_user_secret_key(&msk, &user_policy, &policy)?;
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub mod abe_policy;
pub mod core;
pub mod statics;

#[cfg(test)]
pub mod tests;

pub use error::Error;

pub use self::core::api::{CleartextHeader, CoverCrypt, EncryptedHeader};
216 changes: 0 additions & 216 deletions src/statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,219 +251,3 @@ pub type Encapsulation = <CoverCryptX25519Aes256 as CoverCrypt<
X25519KeyPair,
Aes256GcmCrypto,
>>::Encapsulation;

#[cfg(test)]
pub mod tests {
use super::*;
use crate::{
abe_policy::{AccessPolicy, Attribute, EncryptionHint, Partition, Policy, PolicyAxis},
CoverCrypt, Error,
};

pub fn policy() -> Result<Policy, Error> {
let sec_level = PolicyAxis::new(
"Security Level",
vec![
("Protected", EncryptionHint::Classic),
("Confidential", EncryptionHint::Classic),
("Top Secret", EncryptionHint::Hybridized),
],
true,
);
let department = PolicyAxis::new(
"Department",
vec![
("R&D", EncryptionHint::Classic),
("HR", EncryptionHint::Classic),
("MKG", EncryptionHint::Classic),
("FIN", EncryptionHint::Classic),
],
false,
);
let mut policy = Policy::new(100);
policy.add_axis(sec_level)?;
policy.add_axis(department)?;
Ok(policy)
}

#[test]
fn test_update_master_keys() -> Result<(), Error> {
let mut policy = policy()?;
let cover_crypt = CoverCryptX25519Aes256::default();
let (mut msk, mut mpk) = cover_crypt.generate_master_keys(&policy)?;
let partitions_msk: Vec<Partition> = msk.x.clone().into_keys().collect();
let partitions_mpk: Vec<Partition> = mpk.H.clone().into_keys().collect();
assert_eq!(partitions_msk.len(), partitions_mpk.len());
for p in &partitions_msk {
assert!(partitions_mpk.contains(p));
}
// rotate he FIN department
policy.rotate(&Attribute::new("Department", "FIN"))?;
// update the master keys
cover_crypt.update_master_keys(&policy, &mut msk, &mut mpk)?;
let new_partitions_msk: Vec<Partition> = msk.x.clone().into_keys().collect();
let new_partitions_mpk: Vec<Partition> = mpk.H.clone().into_keys().collect();
assert_eq!(new_partitions_msk.len(), new_partitions_mpk.len());
for p in &new_partitions_msk {
assert!(new_partitions_mpk.contains(p));
}
// 3 is the size of the security level axis
assert_eq!(new_partitions_msk.len(), partitions_msk.len() + 3);
Ok(())
}

#[test]
fn test_refresh_user_key() -> Result<(), Error> {
let mut policy = policy()?;
let cover_crypt = CoverCryptX25519Aes256::default();
let (mut msk, mut mpk) = cover_crypt.generate_master_keys(&policy)?;
let decryption_policy = AccessPolicy::from_boolean_expression(
"Department::MKG && Security Level::Confidential",
)?;
let mut usk = cover_crypt.generate_user_secret_key(&msk, &decryption_policy, &policy)?;
let original_usk = usk.clone();
// rotate he FIN department
policy.rotate(&Attribute::new("Department", "MKG"))?;
// update the master keys
cover_crypt.update_master_keys(&policy, &mut msk, &mut mpk)?;
// refresh the user key and preserve access to old partitions
cover_crypt.refresh_user_secret_key(&mut usk, &decryption_policy, &msk, &policy, true)?;
// 2 partitions accessed by the user were rotated (MKG Protected and
// Confidential)
assert_eq!(usk.x.len(), original_usk.x.len() + 2);
for x_i in &original_usk.x {
assert!(usk.x.contains(x_i));
}
// refresh the user key but do NOT preserve access to old partitions
cover_crypt.refresh_user_secret_key(&mut usk, &decryption_policy, &msk, &policy, false)?;
// the user should still have access to the same number of partitions
assert_eq!(usk.x.len(), original_usk.x.len());
for x_i in &original_usk.x {
assert!(!usk.x.contains(x_i));
}
Ok(())
}

#[test]
fn encrypt_decrypt_sym_key() -> Result<(), Error> {
let mut policy = policy()?;
policy.rotate(&Attribute::new("Department", "FIN"))?;
let access_policy = (AccessPolicy::new("Department", "R&D")
| AccessPolicy::new("Department", "FIN"))
& AccessPolicy::new("Security Level", "Top Secret");
let cover_crypt = CoverCryptX25519Aes256::default();
let (msk, mpk) = cover_crypt.generate_master_keys(&policy)?;
let (sym_key, encrypted_key) = cover_crypt.encaps(
&policy,
&mpk,
&AccessPolicy::from_boolean_expression(
"Department::R&D && Security Level::Top Secret",
)?,
)?;
let usk = cover_crypt.generate_user_secret_key(&msk, &access_policy, &policy)?;
let recovered_key = cover_crypt.decaps(&usk, &encrypted_key)?;
assert_eq!(sym_key, recovered_key, "Wrong decryption of the key!");
Ok(())
}

#[test]
fn test_single_attribute_in_access_policy() -> Result<(), Error> {
//
// Declare policy
let policy = policy()?;

//
// Setup CoverCrypt
let cover_crypt = CoverCryptX25519Aes256::default();
let (msk, _master_public_key) = cover_crypt.generate_master_keys(&policy)?;

//
// New user secret key
let _user_key = cover_crypt.generate_user_secret_key(
&msk,
&AccessPolicy::from_boolean_expression("Security Level::Top Secret")?,
&policy,
)?;

Ok(())
}

#[test]
fn test_rotate_then_encrypt() -> Result<(), Error> {
//
// Declare policy
let mut policy = policy()?;
let top_secret_ap = AccessPolicy::from_boolean_expression("Security Level::Top Secret")?;

//
// Setup CoverCrypt
let cover_crypt = CoverCryptX25519Aes256::default();
let (mut msk, mut master_public_key) = cover_crypt.generate_master_keys(&policy)?;

//
// New user secret key
let mut top_secret_fin_usk = cover_crypt.generate_user_secret_key(
&msk,
&AccessPolicy::from_boolean_expression(
"Security Level::Top Secret && Department::FIN",
)?,
&policy,
)?;

//
// Encrypt
let (_, encrypted_header) = EncryptedHeader::generate(
&cover_crypt,
&policy,
&master_public_key,
&top_secret_ap,
None,
None,
)?;

let _plaintext_header =
encrypted_header.decrypt(&cover_crypt, &top_secret_fin_usk, None)?;

//
// Rotate argument (must update master keys)
policy.rotate(&Attribute::from(("Security Level", "Top Secret")))?;
cover_crypt.update_master_keys(&policy, &mut msk, &mut master_public_key)?;

//
// Encrypt with new attribute
let (_, encrypted_header) = EncryptedHeader::generate(
&cover_crypt,
&policy,
&master_public_key,
&top_secret_ap,
None,
None,
)?;

// Decryption fails without refreshing the user key
assert!(
encrypted_header
.decrypt(&cover_crypt, &top_secret_fin_usk, None)
.is_err()
);

cover_crypt.refresh_user_secret_key(
&mut top_secret_fin_usk,
&AccessPolicy::from_boolean_expression(
"Security Level::Top Secret && Department::FIN",
)?,
&msk,
&policy,
false,
)?;

// The refreshed key can decrypt the header
assert!(
encrypted_header
.decrypt(&cover_crypt, &top_secret_fin_usk, None)
.is_ok()
);

Ok(())
}
}
57 changes: 57 additions & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::{
abe_policy::{EncryptionHint, LegacyPolicy, Policy, PolicyAxis},
Error,
};

mod statics;

#[cfg(feature = "serialization")]
mod non_regression;

pub fn policy() -> Result<Policy, Error> {
let sec_level = PolicyAxis::new(
"Security Level",
vec![
("Low Secret", EncryptionHint::Classic),
("High Secret", EncryptionHint::Classic),
("Top Secret", EncryptionHint::Hybridized),
],
true,
);
let department = PolicyAxis::new(
"Department",
vec![
("R&D", EncryptionHint::Classic),
("HR", EncryptionHint::Classic),
("MKG", EncryptionHint::Classic),
("FIN", EncryptionHint::Classic),
],
false,
);
let mut policy = Policy::new(100);
policy.add_axis(sec_level)?;
policy.add_axis(department)?;
Ok(policy)
}

#[test]
fn write_policy() {
let _policy = policy().unwrap();
std::fs::write("target/policy.json", serde_json::to_vec(&_policy).unwrap()).unwrap();
}

/// Read policy from a file. Assert `LegacyPolicy` is convertible into a
/// `Policy`.
#[test]
fn read_policy() {
// Can read a `Policy`
let policy_str = include_bytes!("./tests_data/policy.json");
Policy::try_from(policy_str.as_slice()).unwrap();

// Can read a `LegacyPolicy`
let legacy_policy_str = include_bytes!("./tests_data/legacy_policy.json");
serde_json::from_slice::<LegacyPolicy>(legacy_policy_str).unwrap();

// Can read `LegacyPolicy` as `Policy`
Policy::try_from(legacy_policy_str.as_slice()).unwrap();
}
Loading

0 comments on commit 1a37392

Please sign in to comment.