diff --git a/Cargo.toml b/Cargo.toml index 96a9eea53..b071fd6a0 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,7 +90,8 @@ serde = { version = "1.0.210", default-features = false, features = ["std", "der serde_json = { version = "1.0.128", default-features = false, features = ["std"] } log = { version = "0.4.22", default-features = false, features = ["std"]} -vss-client = "0.3" +#vss-client = "0.3" +vss-client = { git = "https://github.com/tnull/vss-rust-client", rev = "03ca9d99f70387aabec225020e46434cda8d18ff" } prost = { version = "0.11.6", default-features = false} [target.'cfg(windows)'.dependencies] diff --git a/src/io/vss_store.rs b/src/io/vss_store.rs index e2cfc3c7b..e93aa9c8a 100644 --- a/src/io/vss_store.rs +++ b/src/io/vss_store.rs @@ -38,12 +38,14 @@ type CustomRetryPolicy = FilteredRetryPolicy< Box bool + 'static + Send + Sync>, >; +const KEY_LENGTH: usize = 32; + /// A [`KVStore`] implementation that writes to and reads from a [VSS](https://github.com/lightningdevkit/vss-server/blob/main/README.md) backend. pub struct VssStore { client: VssClient, store_id: String, runtime: Arc, - storable_builder: StorableBuilder, + data_encryption_key: [u8; KEY_LENGTH], key_obfuscator: KeyObfuscator, } @@ -55,7 +57,6 @@ impl VssStore { let (data_encryption_key, obfuscation_master_key) = derive_data_encryption_and_obfuscation_keys(&vss_seed); let key_obfuscator = KeyObfuscator::new(obfuscation_master_key); - let storable_builder = StorableBuilder::new(data_encryption_key, RandEntropySource); let retry_policy = ExponentialBackoffRetryPolicy::new(Duration::from_millis(10)) .with_max_attempts(10) .with_max_total_delay(Duration::from_secs(15)) @@ -70,7 +71,7 @@ impl VssStore { }) as _); let client = VssClient::new_with_headers(base_url, retry_policy, header_provider); - Self { client, store_id, runtime, storable_builder, key_obfuscator } + Self { client, store_id, runtime, data_encryption_key, key_obfuscator } } fn build_key( @@ -132,10 +133,9 @@ impl KVStore for VssStore { &self, primary_namespace: &str, secondary_namespace: &str, key: &str, ) -> io::Result> { check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "read")?; - let request = GetObjectRequest { - store_id: self.store_id.clone(), - key: self.build_key(primary_namespace, secondary_namespace, key)?, - }; + + let store_key = self.build_key(primary_namespace, secondary_namespace, key)?; + let request = GetObjectRequest { store_id: self.store_id.clone(), key: store_key.clone() }; let resp = self.runtime.block_on(self.client.get_object(&request)).map_err(|e| { let msg = format!( "Failed to read from key {}/{}/{}: {}", @@ -156,20 +156,31 @@ impl KVStore for VssStore { Error::new(ErrorKind::Other, msg) })?; - Ok(self.storable_builder.deconstruct(storable)?.0) + let storable_builder = StorableBuilder::new(RandEntropySource); + let decrypted = storable_builder + .deconstruct(storable, &self.data_encryption_key, store_key.as_bytes())? + .0; + Ok(decrypted) } fn write( &self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: &[u8], ) -> io::Result<()> { check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "write")?; + let store_key = self.build_key(primary_namespace, secondary_namespace, key)?; let version = -1; - let storable = self.storable_builder.build(buf.to_vec(), version); + let storable_builder = StorableBuilder::new(RandEntropySource); + let storable = storable_builder.build( + buf.to_vec(), + version, + &&self.data_encryption_key, + store_key.as_bytes(), + ); let request = PutObjectRequest { store_id: self.store_id.clone(), global_version: None, transaction_items: vec![KeyValue { - key: self.build_key(primary_namespace, secondary_namespace, key)?, + key: store_key, version, value: storable.encode_to_vec(), }], @@ -228,6 +239,12 @@ impl KVStore for VssStore { } } +impl Drop for VssStore { + fn drop(&mut self) { + self.data_encryption_key.copy_from_slice(&[0u8; KEY_LENGTH]); + } +} + fn derive_data_encryption_and_obfuscation_keys(vss_seed: &[u8; 32]) -> ([u8; 32], [u8; 32]) { let hkdf = |initial_key_material: &[u8], salt: &[u8]| -> [u8; 32] { let mut engine = HmacEngine::::new(salt);