encryption checkpoint

This commit is contained in:
John Smith 2023-05-24 09:58:45 +01:00
parent 5760096fcb
commit 01df18c081

View File

@ -1,3 +1,5 @@
use rustls::internal::msgs::handshake::EncryptedExtensions;
use crate::*; use crate::*;
cfg_if! { cfg_if! {
@ -59,7 +61,7 @@ impl TableDB {
decryption_key: Option<TypedSharedSecret>, decryption_key: Option<TypedSharedSecret>,
) -> Self { ) -> Self {
let encrypt_info = encryption_key.map(|ek| CryptInfo::new(crypto.clone(), ek)); let encrypt_info = encryption_key.map(|ek| CryptInfo::new(crypto.clone(), ek));
let decrypt_info = dcryption_key.map(|dk| CryptInfo::new(crypto.clone(), dk)); let decrypt_info = decryption_key.map(|dk| CryptInfo::new(crypto.clone(), dk));
Self { Self {
unlocked_inner: Arc::new(TableDBUnlockedInner { unlocked_inner: Arc::new(TableDBUnlockedInner {
@ -89,15 +91,17 @@ impl TableDB {
db.num_columns().map_err(VeilidAPIError::from) db.num_columns().map_err(VeilidAPIError::from)
} }
/// Encrypt buffer using encrypt key and prepend nonce to output
fn maybe_encrypt(&self, data: &[u8]) -> Vec<u8> { fn maybe_encrypt(&self, data: &[u8]) -> Vec<u8> {
if let Some(ei) = &self.unlocked_inner.encrypt_info { if let Some(ei) = &self.unlocked_inner.encrypt_info {
let mut out = unsafe { unaligned_u8_vec_uninit(NONCE_LENGTH + data.len()) }; let mut out = unsafe { unaligned_u8_vec_uninit(NONCE_LENGTH + data.len()) };
random_bytes(&mut out[0..NONCE_LENGTH]); random_bytes(&mut out[0..NONCE_LENGTH]);
let (nonce, encout) = out.split_at_mut(NONCE_LENGTH);
ei.vcrypto.crypt_b2b_no_auth( ei.vcrypto.crypt_b2b_no_auth(
data, data,
&mut out[NONCE_LENGTH..], encout,
&out[0..NONCE_LENGTH], (nonce as &[u8]).try_into().unwrap(),
&ei.key, &ei.key,
); );
out out
@ -106,33 +110,31 @@ impl TableDB {
} }
} }
fn maybe_decrypt(&self, data: &[u8]) -> VeilidAPIResult<Vec<u8>> { /// Decrypt buffer using decrypt key with nonce prepended to input
fn maybe_decrypt(&self, data: &[u8]) -> Vec<u8> {
if let Some(di) = &self.unlocked_inner.decrypt_info { if let Some(di) = &self.unlocked_inner.decrypt_info {
if data.len() <= NONCE_LENGTH { assert!(data.len() > NONCE_LENGTH);
return Err(VeilidAPIError::internal("data too short"));
}
xxxx make decrypt
let mut out = unsafe { unaligned_u8_vec_uninit(NONCE_LENGTH + data.len()) };
random_bytes(&mut out[0..NONCE_LENGTH]);
ei.vcrypto.crypt_b2b_no_auth( let mut out = unsafe { unaligned_u8_vec_uninit(data.len() - NONCE_LENGTH) };
data,
&mut out[NONCE_LENGTH..], di.vcrypto.crypt_b2b_no_auth(
&out[0..NONCE_LENGTH], &data[NONCE_LENGTH..],
&ei.key, &mut out,
(&data[0..NONCE_LENGTH]).try_into().unwrap(),
&di.key,
); );
out out
} else { } else {
Ok(data.to_vec()) data.to_vec()
} }
} }
/// Get the list of keys in a column of the TableDB /// Get the list of keys in a column of the TableDB
pub async fn get_keys(&self, col: u32) -> VeilidAPIResult<Vec<Vec<u8>>> { pub async fn get_keys(&self, col: u32) -> VeilidAPIResult<Vec<Vec<u8>>> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut out: Vec<Box<[u8]>> = Vec::new(); let mut out = Vec::new();
db.iter(col, None, |kv| { db.iter(col, None, |kv| {
out.push(kv.0.clone().into_boxed_slice()); out.push(self.maybe_decrypt(&kv.0));
Ok(Option::<()>::None) Ok(Option::<()>::None)
}) })
.await .await
@ -150,7 +152,7 @@ impl TableDB {
pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> VeilidAPIResult<()> { pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> VeilidAPIResult<()> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut dbt = db.transaction(); let mut dbt = db.transaction();
dbt.put(col, key, value); dbt.put(col, self.maybe_encrypt(key), self.maybe_encrypt(value));
db.write(dbt).await.map_err(VeilidAPIError::generic) db.write(dbt).await.map_err(VeilidAPIError::generic)
} }
@ -163,7 +165,11 @@ impl TableDB {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut dbt = db.transaction(); let mut dbt = db.transaction();
dbt.put(col, key, v.as_slice()); dbt.put(
col,
self.maybe_encrypt(key),
self.maybe_encrypt(v.as_slice()),
);
db.write(dbt).await.map_err(VeilidAPIError::generic) db.write(dbt).await.map_err(VeilidAPIError::generic)
} }
@ -176,14 +182,23 @@ impl TableDB {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let mut dbt = db.transaction(); let mut dbt = db.transaction();
dbt.put(col, key, v.as_slice()); dbt.put(
col,
self.maybe_encrypt(key),
self.maybe_encrypt(v.as_slice()),
);
db.write(dbt).await.map_err(VeilidAPIError::generic) db.write(dbt).await.map_err(VeilidAPIError::generic)
} }
/// Read a key from a column in the TableDB immediately. /// Read a key from a column in the TableDB immediately.
pub async fn load(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<Vec<u8>>> { pub async fn load(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<Vec<u8>>> {
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
db.get(col, key).await.map_err(VeilidAPIError::from) let ekey = self.maybe_encrypt(key);
Ok(db
.get(col, &ekey)
.await
.map_err(VeilidAPIError::from)?
.map(|v| self.maybe_decrypt(&v)))
} }
/// Read an rkyv key from a column in the TableDB immediately /// Read an rkyv key from a column in the TableDB immediately
@ -194,7 +209,9 @@ impl TableDB {
for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>, for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>,
<T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>, <T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>,
{ {
let out = match self.load(col, key).await? { let ekey = self.maybe_encrypt(key);
let out = match self.load(col, &ekey).await?.map(|v| self.maybe_decrypt(&v)) {
Some(v) => Some(from_rkyv(v)?), Some(v) => Some(from_rkyv(v)?),
None => None, None => None,
}; };
@ -206,7 +223,9 @@ impl TableDB {
where where
T: for<'de> serde::Deserialize<'de>, T: for<'de> serde::Deserialize<'de>,
{ {
let out = match self.load(col, key).await? { let ekey = self.maybe_encrypt(key);
let out = match self.load(col, &ekey).await?.map(|v| self.maybe_decrypt(&v)) {
Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?), Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?),
None => None, None => None,
}; };
@ -215,8 +234,14 @@ impl TableDB {
/// Delete key with from a column in the TableDB /// Delete key with from a column in the TableDB
pub async fn delete(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<Vec<u8>>> { pub async fn delete(&self, col: u32, key: &[u8]) -> VeilidAPIResult<Option<Vec<u8>>> {
let ekey = self.maybe_encrypt(key);
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let old_value = db.delete(col, key).await.map_err(VeilidAPIError::from)?; let old_value = db
.delete(col, &ekey)
.await
.map_err(VeilidAPIError::from)?
.map(|v| self.maybe_decrypt(&v));
Ok(old_value) Ok(old_value)
} }
@ -228,8 +253,15 @@ impl TableDB {
for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>, for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>,
<T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>, <T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>,
{ {
let ekey = self.maybe_encrypt(key);
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let old_value = match db.delete(col, key).await.map_err(VeilidAPIError::from)? { let old_value = match db
.delete(col, &ekey)
.await
.map_err(VeilidAPIError::from)?
.map(|v| self.maybe_decrypt(&v))
{
Some(v) => Some(from_rkyv(v)?), Some(v) => Some(from_rkyv(v)?),
None => None, None => None,
}; };
@ -241,13 +273,29 @@ impl TableDB {
where where
T: for<'de> serde::Deserialize<'de>, T: for<'de> serde::Deserialize<'de>,
{ {
let ekey = self.maybe_encrypt(key);
let db = self.unlocked_inner.database.clone(); let db = self.unlocked_inner.database.clone();
let old_value = match db.delete(col, key).await.map_err(VeilidAPIError::from)? { let old_value = match db
.delete(col, &ekey)
.await
.map_err(VeilidAPIError::from)?
.map(|v| self.maybe_decrypt(&v))
{
Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?), Some(v) => Some(serde_json::from_slice(&v).map_err(VeilidAPIError::internal)?),
None => None, None => None,
}; };
Ok(old_value) 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)))
}
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -294,10 +342,7 @@ impl TableDBTransaction {
.take() .take()
.ok_or_else(|| VeilidAPIError::generic("transaction already completed"))? .ok_or_else(|| VeilidAPIError::generic("transaction already completed"))?
}; };
let db = self.db.unlocked_inner.database.clone(); self.db.do_commit(dbt).await
db.write(dbt)
.await
.map_err(|e| VeilidAPIError::generic(format!("commit failed, transaction lost: {}", e)))
} }
/// Rollback the transaction. Does nothing to the TableDB. /// Rollback the transaction. Does nothing to the TableDB.