|
| 1 | +#[cfg(test)] |
| 2 | +mod tests { |
| 3 | + use crate::common::{clear, connect_with_tls, id, trace, PROXY}; |
| 4 | + use cipherstash_client::config::EnvSource; |
| 5 | + use cipherstash_client::credentials::auto_refresh::AutoRefresh; |
| 6 | + use cipherstash_client::ejsonpath::Selector; |
| 7 | + use cipherstash_client::encryption::{ |
| 8 | + Encrypted, EncryptedEntry, EncryptedSteVecTerm, JsonIndexer, JsonIndexerOptions, OreTerm, |
| 9 | + Plaintext, PlaintextTarget, QueryBuilder, ReferencedPendingPipeline, |
| 10 | + }; |
| 11 | + use cipherstash_client::{ |
| 12 | + encryption::{ScopedCipher, SteVec}, |
| 13 | + zerokms::{encrypted_record, EncryptedRecord}, |
| 14 | + }; |
| 15 | + use cipherstash_client::{ConsoleConfig, CtsConfig, ZeroKMSConfig}; |
| 16 | + use cipherstash_config::column::{Index, IndexType}; |
| 17 | + use cipherstash_config::{ColumnConfig, ColumnMode, ColumnType}; |
| 18 | + use cipherstash_proxy::Identifier; |
| 19 | + use rustls::unbuffered::EncodeError; |
| 20 | + use serde::{Deserialize, Serialize}; |
| 21 | + use std::sync::Arc; |
| 22 | + use tracing::info; |
| 23 | + use uuid::Uuid; |
| 24 | + |
| 25 | + pub mod option_mp_base85 { |
| 26 | + use cipherstash_client::zerokms::encrypted_record::formats::mp_base85; |
| 27 | + use cipherstash_client::zerokms::EncryptedRecord; |
| 28 | + use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
| 29 | + |
| 30 | + pub fn serialize<S>( |
| 31 | + value: &Option<EncryptedRecord>, |
| 32 | + serializer: S, |
| 33 | + ) -> Result<S::Ok, S::Error> |
| 34 | + where |
| 35 | + S: Serializer, |
| 36 | + { |
| 37 | + match value { |
| 38 | + Some(record) => mp_base85::serialize(record, serializer), |
| 39 | + None => serializer.serialize_none(), |
| 40 | + } |
| 41 | + } |
| 42 | + |
| 43 | + pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<EncryptedRecord>, D::Error> |
| 44 | + where |
| 45 | + D: Deserializer<'de>, |
| 46 | + { |
| 47 | + let result = Option::<EncryptedRecord>::deserialize(deserializer)?; |
| 48 | + Ok(result) |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + #[derive(Debug, Deserialize, Serialize)] |
| 53 | + |
| 54 | + pub struct EqlEncrypted { |
| 55 | + #[serde(rename = "c", with = "option_mp_base85")] |
| 56 | + ciphertext: Option<EncryptedRecord>, |
| 57 | + #[serde(rename = "i")] |
| 58 | + identifier: Identifier, |
| 59 | + #[serde(rename = "v")] |
| 60 | + version: u16, |
| 61 | + |
| 62 | + #[serde(rename = "o")] |
| 63 | + ore_index: Option<Vec<String>>, |
| 64 | + #[serde(rename = "m")] |
| 65 | + match_index: Option<Vec<u16>>, |
| 66 | + #[serde(rename = "u")] |
| 67 | + unique_index: Option<String>, |
| 68 | + |
| 69 | + #[serde(rename = "s")] |
| 70 | + selector: Option<String>, |
| 71 | + |
| 72 | + #[serde(rename = "b")] |
| 73 | + blake3_index: Option<String>, |
| 74 | + |
| 75 | + #[serde(rename = "ocf")] |
| 76 | + ore_cclw_fixed_index: Option<String>, |
| 77 | + #[serde(rename = "ocv")] |
| 78 | + ore_cclw_var_index: Option<String>, |
| 79 | + |
| 80 | + #[serde(rename = "sv")] |
| 81 | + ste_vec_index: Option<Vec<EqlSteVecEncrypted>>, |
| 82 | + } |
| 83 | + |
| 84 | + #[derive(Debug, Deserialize, Serialize)] |
| 85 | + pub struct EqlSteVecEncrypted { |
| 86 | + #[serde(rename = "c", with = "option_mp_base85")] |
| 87 | + ciphertext: Option<EncryptedRecord>, |
| 88 | + |
| 89 | + #[serde(rename = "s")] |
| 90 | + selector: Option<String>, |
| 91 | + #[serde(rename = "b")] |
| 92 | + blake3_index: Option<String>, |
| 93 | + #[serde(rename = "ocf")] |
| 94 | + ore_cclw_fixed_index: Option<String>, |
| 95 | + #[serde(rename = "ocv")] |
| 96 | + ore_cclw_var_index: Option<String>, |
| 97 | + } |
| 98 | + |
| 99 | + impl EqlEncrypted { |
| 100 | + pub fn ste_vec(ste_vec_index: Vec<EqlSteVecEncrypted>) -> Self { |
| 101 | + Self { |
| 102 | + ste_vec_index: Some(ste_vec_index), |
| 103 | + ciphertext: None, |
| 104 | + identifier: Identifier { |
| 105 | + table: "blah".to_string(), |
| 106 | + column: "vtha".to_string(), |
| 107 | + }, |
| 108 | + version: 1, |
| 109 | + ore_index: None, |
| 110 | + match_index: None, |
| 111 | + unique_index: None, |
| 112 | + selector: None, |
| 113 | + ore_cclw_fixed_index: None, |
| 114 | + ore_cclw_var_index: None, |
| 115 | + blake3_index: None, |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | + impl EqlSteVecEncrypted { |
| 120 | + pub fn ste_vec_element(selector: String, record: EncryptedRecord) -> Self { |
| 121 | + Self { |
| 122 | + ciphertext: Some(record), |
| 123 | + selector: Some(selector), |
| 124 | + ore_cclw_fixed_index: None, |
| 125 | + ore_cclw_var_index: None, |
| 126 | + blake3_index: None, |
| 127 | + } |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + #[tokio::test] |
| 132 | + async fn generate_ste_vec() { |
| 133 | + trace(); |
| 134 | + |
| 135 | + // clear().await; |
| 136 | + // let client = connect_with_tls(PROXY).await; |
| 137 | + |
| 138 | + let console_config = ConsoleConfig::builder().with_env().build().unwrap(); |
| 139 | + let cts_config = CtsConfig::builder().with_env().build().unwrap(); |
| 140 | + let zerokms_config = ZeroKMSConfig::builder() |
| 141 | + .add_source(EnvSource::default()) |
| 142 | + .console_config(&console_config) |
| 143 | + .cts_config(&cts_config) |
| 144 | + .build_with_client_key() |
| 145 | + .unwrap(); |
| 146 | + let zerokms_client = zerokms_config |
| 147 | + .create_client_with_credentials(AutoRefresh::new(zerokms_config.credentials())); |
| 148 | + |
| 149 | + let dataset_id = Uuid::parse_str("295504329cb045c398dc464c52a287a1").unwrap(); |
| 150 | + |
| 151 | + let cipher = Arc::new( |
| 152 | + ScopedCipher::init(Arc::new(zerokms_client), Some(dataset_id)) |
| 153 | + .await |
| 154 | + .unwrap(), |
| 155 | + ); |
| 156 | + |
| 157 | + let prefix = "prefix".to_string(); |
| 158 | + |
| 159 | + let column_config = ColumnConfig::build("column_name".to_string()) |
| 160 | + .casts_as(ColumnType::JsonB) |
| 161 | + .add_index(Index::new(IndexType::SteVec { |
| 162 | + prefix: prefix.to_owned(), |
| 163 | + })); |
| 164 | + |
| 165 | + // let mut value = |
| 166 | + // serde_json::from_str::<serde_json::Value>("{\"hello\": \"one\", \"n\": 10}").unwrap(); |
| 167 | + |
| 168 | + // let mut value = |
| 169 | + // serde_json::from_str::<serde_json::Value>("{\"hello\": \"two\", \"n\": 20}").unwrap(); |
| 170 | + |
| 171 | + let mut value = |
| 172 | + serde_json::from_str::<serde_json::Value>("{\"hello\": \"two\", \"n\": 30}").unwrap(); |
| 173 | + |
| 174 | + // let mut value = |
| 175 | + // serde_json::from_str::<serde_json::Value>("{\"hello\": \"world\", \"n\": 42}").unwrap(); |
| 176 | + |
| 177 | + // let mut value = |
| 178 | + // serde_json::from_str::<serde_json::Value>("{\"hello\": \"world\", \"n\": 42}").unwrap(); |
| 179 | + |
| 180 | + // let mut value = |
| 181 | + // serde_json::from_str::<serde_json::Value>("{\"blah\": { \"vtha\": 42 }}").unwrap(); |
| 182 | + |
| 183 | + let plaintext = Plaintext::JsonB(Some(value)); |
| 184 | + |
| 185 | + let idx = 0; |
| 186 | + |
| 187 | + let mut pipeline = ReferencedPendingPipeline::new(cipher.clone()); |
| 188 | + let encryptable = PlaintextTarget::new(plaintext, column_config); |
| 189 | + pipeline |
| 190 | + .add_with_ref::<PlaintextTarget>(encryptable, idx) |
| 191 | + .unwrap(); |
| 192 | + |
| 193 | + let mut encrypteds = vec![]; |
| 194 | + |
| 195 | + let mut result = pipeline.encrypt(None).await.unwrap(); |
| 196 | + if let Some(Encrypted::SteVec(ste_vec)) = result.remove(idx) { |
| 197 | + for entry in ste_vec { |
| 198 | + let selector = hex::encode(entry.0 .0); |
| 199 | + let term = entry.1; |
| 200 | + let record = entry.2; |
| 201 | + |
| 202 | + let mut e = EqlSteVecEncrypted::ste_vec_element(selector, record); |
| 203 | + |
| 204 | + match term { |
| 205 | + EncryptedSteVecTerm::Mac(items) => { |
| 206 | + e.blake3_index = Some(hex::encode(&items)); |
| 207 | + } |
| 208 | + EncryptedSteVecTerm::OreFixed(o) => { |
| 209 | + e.ore_cclw_fixed_index = Some(hex::encode(o.bytes)); |
| 210 | + } |
| 211 | + EncryptedSteVecTerm::OreVariable(o) => { |
| 212 | + e.ore_cclw_var_index = Some(hex::encode(o.bytes)); |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + encrypteds.push(e); |
| 217 | + } |
| 218 | + // info!("{:?}" = encrypteds); |
| 219 | + } |
| 220 | + |
| 221 | + info!("---------------------------------------------"); |
| 222 | + |
| 223 | + let e = EqlEncrypted::ste_vec(encrypteds); |
| 224 | + info!("{:?}" = ?e); |
| 225 | + |
| 226 | + let json = serde_json::to_value(e).unwrap(); |
| 227 | + info!("{}", json); |
| 228 | + |
| 229 | + let indexer = JsonIndexer::new(JsonIndexerOptions { prefix }); |
| 230 | + |
| 231 | + info!("---------------------------------------------"); |
| 232 | + |
| 233 | + // Path |
| 234 | + // let path: String = "$.blah.vtha".to_string(); |
| 235 | + // let selector = Selector::parse(&path).unwrap(); |
| 236 | + // let selector = indexer.generate_selector(selector, cipher.index_key()); |
| 237 | + // let selector = hex::encode(selector.0); |
| 238 | + // info!("{}", selector); |
| 239 | + |
| 240 | + // Comparison |
| 241 | + let n = 30; |
| 242 | + let term = OreTerm::Number(n); |
| 243 | + |
| 244 | + let term = indexer.generate_term(term, cipher.index_key()).unwrap(); |
| 245 | + |
| 246 | + match term { |
| 247 | + EncryptedSteVecTerm::Mac(items) => todo!(), |
| 248 | + EncryptedSteVecTerm::OreFixed(ore_cllw8_v1) => { |
| 249 | + let term = hex::encode(ore_cllw8_v1.bytes); |
| 250 | + info!("{n}: {term}"); |
| 251 | + } |
| 252 | + EncryptedSteVecTerm::OreVariable(ore_cllw8_variable_v1) => todo!(), |
| 253 | + } |
| 254 | + |
| 255 | + // if let Some(ste_vec_index) = e.ste_vec_index { |
| 256 | + // for e in ste_vec_index { |
| 257 | + // info!("{}", e); |
| 258 | + // if let Some(ct) = e.ciphertext { |
| 259 | + // let decrypted = cipher.decrypt(encrypted).await?; |
| 260 | + // info!("{}", decrypted); |
| 261 | + // } |
| 262 | + // } |
| 263 | + // } |
| 264 | + } |
| 265 | +} |
0 commit comments