test(crypto): M-05 — verify schema equality between standard and hidden vault containers

This commit is contained in:
2026-09-19 09:15:56 +02:00
parent e496c418c5
commit a2c16eda72
+152
View File
@@ -774,3 +774,155 @@ async fn test_v01_carrier_fs_copy_delegation_and_functionality() {
let _ = std::fs::remove_file(&path);
}
#[test]
fn test_m05_deniability_schema_equality_standard_vs_hidden() {
let path_std = temp_db_path("schema_std");
let path_hidden = temp_db_path("schema_hidden");
let kdf_params = KdfParams {
memory_cost: MIN_MEMORY_COST_KIB,
time_cost: MIN_TIME_COST,
parallelism: 1,
};
let salt_std = generate_salt();
let kek_std = derive_kek("StandardPass123!", &salt_std, &kdf_params).unwrap();
let dek_std = generate_dek();
let (wrapped_std, nonce_std, tag_std) = wrap_slot0_payload(&kek_std, &dek_std, 0).unwrap();
let db_std = Database::open(&path_std).expect("Open std db");
db_std
.init_schema(
&salt_std,
&kdf_params,
&wrapped_std,
&nonce_std,
&tag_std,
)
.expect("Init std schema");
db_std.checkpoint().unwrap();
let salt_0 = generate_salt();
let kek_0 = derive_kek("DecoyPass123!", &salt_0, &kdf_params).unwrap();
let dek_0 = generate_dek();
let salt_1 = generate_salt();
let kek_1 = derive_kek("HiddenPass123!", &salt_1, &kdf_params).unwrap();
let dek_1 = generate_dek();
let carrier_node_id = 3i64;
let (wrapped_0, nonce_0, tag_0) = wrap_slot0_payload(&kek_0, &dek_0, carrier_node_id).unwrap();
let (wrapped_1, nonce_1, tag_1) =
wrap_slot1_payload(&kek_1, &dek_1, &dek_0, carrier_node_id).unwrap();
let db_hidden = Database::open(&path_hidden).expect("Open hidden db");
db_hidden
.init_schema_with_carrier(
&salt_0,
&kdf_params,
&wrapped_0,
&nonce_0,
&tag_0,
Some((
"carrier.dat",
1024 * 1024,
&salt_1,
&kdf_params,
&wrapped_1,
&nonce_1,
&tag_1,
&dek_0,
&dek_1,
)),
)
.expect("Init carrier schema");
db_hidden.checkpoint().unwrap();
// Vergleiche Schemas via rusqlite
let conn_std = rusqlite::Connection::open(&path_std).unwrap();
let conn_hidden = rusqlite::Connection::open(&path_hidden).unwrap();
let get_schema_elements = |conn: &rusqlite::Connection| -> Vec<(String, String, Option<String>)> {
let mut stmt = conn
.prepare(
"SELECT type, name, sql FROM sqlite_master
WHERE type IN ('table', 'index') AND name NOT LIKE 'sqlite_%'
ORDER BY type, name",
)
.unwrap();
let rows = stmt
.query_map([], |row| {
Ok((
row.get::<_, String>(0)?,
row.get::<_, String>(1)?,
row.get::<_, Option<String>>(2)?,
))
})
.unwrap();
rows.map(|r| r.unwrap()).collect()
};
let schema_std = get_schema_elements(&conn_std);
let schema_hidden = get_schema_elements(&conn_hidden);
assert_eq!(
schema_std, schema_hidden,
"M-05: SQLite-Schema (Tabellen, Indizes, DDL) muss zwischen Standard- und Hidden-Vault identisch sein"
);
// Spalten- und Typinformationen vergleichen
for table in &["meta", "nodes", "chunks"] {
let get_table_info = |conn: &rusqlite::Connection| -> Vec<(i64, String, String, i64, Option<String>, i64)> {
let mut stmt = conn.prepare(&format!("PRAGMA table_info({});", table)).unwrap();
let rows = stmt
.query_map([], |row| {
Ok((
row.get::<_, i64>(0)?,
row.get::<_, String>(1)?,
row.get::<_, String>(2)?,
row.get::<_, i64>(3)?,
row.get::<_, Option<String>>(4)?,
row.get::<_, i64>(5)?,
))
})
.unwrap();
rows.map(|r| r.unwrap()).collect()
};
let cols_std = get_table_info(&conn_std);
let cols_hidden = get_table_info(&conn_hidden);
assert_eq!(
cols_std, cols_hidden,
"M-05: Spalten und Typen für Tabelle '{}' müssen identisch sein",
table
);
}
// Pragmas vergleichen (page_size, auto_vacuum, secure_delete)
let get_pragma = |conn: &rusqlite::Connection, pragma: &str| -> i64 {
conn.query_row(&format!("PRAGMA {};", pragma), [], |r| r.get(0))
.unwrap()
};
assert_eq!(
get_pragma(&conn_std, "page_size"),
get_pragma(&conn_hidden, "page_size")
);
assert_eq!(
get_pragma(&conn_std, "auto_vacuum"),
get_pragma(&conn_hidden, "auto_vacuum")
);
assert_eq!(
get_pragma(&conn_std, "secure_delete"),
get_pragma(&conn_hidden, "secure_delete")
);
drop(conn_std);
drop(conn_hidden);
drop(db_std);
drop(db_hidden);
let _ = std::fs::remove_file(&path_std);
let _ = std::fs::remove_file(&path_hidden);
}