diff --git a/veilid-core/src/crypto/types/keypair.rs b/veilid-core/src/crypto/types/keypair.rs index 253f84ea..0ea30b23 100644 --- a/veilid-core/src/crypto/types/keypair.rs +++ b/veilid-core/src/crypto/types/keypair.rs @@ -56,9 +56,7 @@ impl fmt::Display for KeyPair { impl fmt::Debug for KeyPair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, concat!(stringify!($name), "("))?; - write!(f, "{}", self.encode())?; - write!(f, ")") + write!(f, "KeyPair({})", self.encode()) } } diff --git a/veilid-core/src/table_store/table_db.rs b/veilid-core/src/table_store/table_db.rs index e28f716e..7b90509e 100644 --- a/veilid-core/src/table_store/table_db.rs +++ b/veilid-core/src/table_store/table_db.rs @@ -1,5 +1,3 @@ -use rustls::internal::msgs::handshake::EncryptedExtensions; - use crate::*; cfg_if! { @@ -27,7 +25,6 @@ impl CryptInfo { pub struct TableDBUnlockedInner { table: String, table_store: TableStore, - crypto: Crypto, database: Database, // Encryption and decryption key will be the same unless configured for an in-place migration encrypt_info: Option, @@ -67,7 +64,6 @@ impl TableDB { unlocked_inner: Arc::new(TableDBUnlockedInner { table, table_store, - crypto, database, encrypt_info, decrypt_info, @@ -92,10 +88,26 @@ impl TableDB { } /// Encrypt buffer using encrypt key and prepend nonce to output - fn maybe_encrypt(&self, data: &[u8]) -> Vec { + /// Keyed nonces are unique because keys must be unique + /// Normally they must be sequential or random, but the critical + /// requirement is that they are different for each encryption + /// but if the contents are guaranteed to be unique, then a nonce + /// can be generated from the hash of the contents and the encryption key itself + fn maybe_encrypt(&self, data: &[u8], keyed_nonce: bool) -> Vec { if let Some(ei) = &self.unlocked_inner.encrypt_info { let mut out = unsafe { unaligned_u8_vec_uninit(NONCE_LENGTH + data.len()) }; - random_bytes(&mut out[0..NONCE_LENGTH]); + + if keyed_nonce { + // Key content nonce + let mut noncedata = Vec::with_capacity(data.len() + PUBLIC_KEY_LENGTH); + noncedata.extend_from_slice(data); + noncedata.extend_from_slice(&ei.key.bytes); + let noncehash = ei.vcrypto.generate_hash(&noncedata); + out[0..NONCE_LENGTH].copy_from_slice(&noncehash[0..NONCE_LENGTH]) + } else { + // Random nonce + random_bytes(&mut out[0..NONCE_LENGTH]); + } let (nonce, encout) = out.split_at_mut(NONCE_LENGTH); ei.vcrypto.crypt_b2b_no_auth( @@ -133,8 +145,8 @@ impl TableDB { pub async fn get_keys(&self, col: u32) -> VeilidAPIResult>> { let db = self.unlocked_inner.database.clone(); let mut out = Vec::new(); - db.iter(col, None, |kv| { - out.push(self.maybe_decrypt(&kv.0)); + db.iter_keys(col, None, |k| { + out.push(self.maybe_decrypt(k)); Ok(Option::<()>::None) }) .await @@ -152,7 +164,11 @@ impl TableDB { pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> VeilidAPIResult<()> { let db = self.unlocked_inner.database.clone(); let mut dbt = db.transaction(); - dbt.put(col, self.maybe_encrypt(key), self.maybe_encrypt(value)); + dbt.put( + col, + self.maybe_encrypt(key, true), + self.maybe_encrypt(value, false), + ); db.write(dbt).await.map_err(VeilidAPIError::generic) } @@ -161,16 +177,8 @@ impl TableDB { where T: RkyvSerialize, { - let v = to_rkyv(value)?; - - let db = self.unlocked_inner.database.clone(); - let mut dbt = db.transaction(); - dbt.put( - col, - self.maybe_encrypt(key), - self.maybe_encrypt(v.as_slice()), - ); - db.write(dbt).await.map_err(VeilidAPIError::generic) + let value = to_rkyv(value)?; + self.store(col, key, &value).await } /// Store a key in json format with a value in a column in the TableDB. Performs a single transaction immediately. @@ -178,24 +186,16 @@ impl TableDB { where T: serde::Serialize, { - let v = serde_json::to_vec(value).map_err(VeilidAPIError::internal)?; - - let db = self.unlocked_inner.database.clone(); - let mut dbt = db.transaction(); - dbt.put( - col, - self.maybe_encrypt(key), - self.maybe_encrypt(v.as_slice()), - ); - db.write(dbt).await.map_err(VeilidAPIError::generic) + let value = serde_json::to_vec(value).map_err(VeilidAPIError::internal)?; + self.store(col, key, &value).await } /// Read a key from a column in the TableDB immediately. pub async fn load(&self, col: u32, key: &[u8]) -> VeilidAPIResult>> { let db = self.unlocked_inner.database.clone(); - let ekey = self.maybe_encrypt(key); + let key = self.maybe_encrypt(key, true); Ok(db - .get(col, &ekey) + .get(col, &key) .await .map_err(VeilidAPIError::from)? .map(|v| self.maybe_decrypt(&v))) @@ -209,9 +209,7 @@ impl TableDB { for<'t> CheckBytes>, ::Archived: RkyvDeserialize, { - let ekey = self.maybe_encrypt(key); - - let out = match self.load(col, &ekey).await?.map(|v| self.maybe_decrypt(&v)) { + let out = match self.load(col, key).await? { Some(v) => Some(from_rkyv(v)?), None => None, }; @@ -223,9 +221,7 @@ impl TableDB { where T: for<'de> serde::Deserialize<'de>, { - let ekey = self.maybe_encrypt(key); - - let out = match self.load(col, &ekey).await?.map(|v| self.maybe_decrypt(&v)) { + let out = match self.load(col, key).await? { Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?), None => None, }; @@ -234,11 +230,11 @@ impl TableDB { /// Delete key with from a column in the TableDB pub async fn delete(&self, col: u32, key: &[u8]) -> VeilidAPIResult>> { - let ekey = self.maybe_encrypt(key); + let key = self.maybe_encrypt(key, true); let db = self.unlocked_inner.database.clone(); let old_value = db - .delete(col, &ekey) + .delete(col, &key) .await .map_err(VeilidAPIError::from)? .map(|v| self.maybe_decrypt(&v)); @@ -253,15 +249,7 @@ impl TableDB { for<'t> CheckBytes>, ::Archived: RkyvDeserialize, { - let ekey = self.maybe_encrypt(key); - - let db = self.unlocked_inner.database.clone(); - let old_value = match db - .delete(col, &ekey) - .await - .map_err(VeilidAPIError::from)? - .map(|v| self.maybe_decrypt(&v)) - { + let old_value = match self.delete(col, key).await? { Some(v) => Some(from_rkyv(v)?), None => None, }; @@ -273,29 +261,12 @@ impl TableDB { where T: for<'de> serde::Deserialize<'de>, { - let ekey = self.maybe_encrypt(key); - - let db = self.unlocked_inner.database.clone(); - let old_value = match db - .delete(col, &ekey) - .await - .map_err(VeilidAPIError::from)? - .map(|v| self.maybe_decrypt(&v)) - { + let old_value = match self.delete(col, key).await? { Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?), None => None, }; Ok(old_value) } - - /// Perform commit - async fn do_commit(&self, dbt: TableDBTransaction) -> VeilidAPIResult<()> { - let db = self.unlocked_inner.database.clone(); - xxx translate transaction to encrypt - db.write(dbt) - .await - .map_err(|e| VeilidAPIError::generic(format!("commit failed, transaction lost: {}", e))) - } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -342,7 +313,11 @@ impl TableDBTransaction { .take() .ok_or_else(|| VeilidAPIError::generic("transaction already completed"))? }; - self.db.do_commit(dbt).await + + let db = self.db.unlocked_inner.database.clone(); + db.write(dbt) + .await + .map_err(|e| VeilidAPIError::generic(format!("commit failed, transaction lost: {}", e))) } /// Rollback the transaction. Does nothing to the TableDB. @@ -353,8 +328,10 @@ impl TableDBTransaction { /// Store a key with a value in a column in the TableDB pub fn store(&self, col: u32, key: &[u8], value: &[u8]) { + let key = self.db.maybe_encrypt(key, true); + let value = self.db.maybe_encrypt(value, false); let mut inner = self.inner.lock(); - inner.dbt.as_mut().unwrap().put(col, key, value); + inner.dbt.as_mut().unwrap().put_owned(col, key, value); } /// Store a key in rkyv format with a value in a column in the TableDB @@ -362,9 +339,12 @@ impl TableDBTransaction { where T: RkyvSerialize, { - let v = to_rkyv(value)?; + let value = to_rkyv(value)?; + let key = self.db.maybe_encrypt(key, true); + let value = self.db.maybe_encrypt(&value, false); + let mut inner = self.inner.lock(); - inner.dbt.as_mut().unwrap().put(col, key, v.as_slice()); + inner.dbt.as_mut().unwrap().put_owned(col, key, value); Ok(()) } @@ -373,16 +353,20 @@ impl TableDBTransaction { where T: serde::Serialize, { - let v = serde_json::to_vec(value).map_err(VeilidAPIError::internal)?; + let value = serde_json::to_vec(value).map_err(VeilidAPIError::internal)?; + let key = self.db.maybe_encrypt(key, true); + let value = self.db.maybe_encrypt(&value, false); + let mut inner = self.inner.lock(); - inner.dbt.as_mut().unwrap().put(col, key, v.as_slice()); + inner.dbt.as_mut().unwrap().put_owned(col, key, value); Ok(()) } /// Delete key with from a column in the TableDB pub fn delete(&self, col: u32, key: &[u8]) { + let key = self.db.maybe_encrypt(key, true); let mut inner = self.inner.lock(); - inner.dbt.as_mut().unwrap().delete(col, key); + inner.dbt.as_mut().unwrap().delete_owned(col, key); } }