refactor rpc validation

This commit is contained in:
John Smith
2023-04-20 11:47:54 -04:00
parent b4a071170d
commit 7f909a06b9
52 changed files with 729 additions and 430 deletions

View File

@@ -3,9 +3,7 @@ mod record;
mod record_data;
mod record_store;
mod record_store_limits;
mod signed_value_data;
mod signed_value_descriptor;
mod value_detail;
mod types;
use keys::*;
use record::*;
@@ -13,9 +11,7 @@ use record_data::*;
use record_store::*;
use record_store_limits::*;
pub use signed_value_data::*;
pub use signed_value_descriptor::*;
pub use value_detail::*;
pub use types::*;
use super::*;
use crate::rpc_processor::*;
@@ -174,14 +170,15 @@ impl StorageManager {
&self,
vcrypto: CryptoSystemVersion,
record: Record,
) -> Result<(), VeilidAPIError> {
) -> Result<TypedKey, VeilidAPIError> {
// add value record to record store
let mut inner = self.inner.lock();
let Some(local_record_store) = inner.local_record_store.as_mut() else {
apibail_generic!("not initialized");
};
let key = self.get_key(vcrypto.clone(), &record);
local_record_store.new_record(key, record).await
local_record_store.new_record(key, record).await?;
Ok(key)
}
pub async fn create_record(
@@ -202,22 +199,27 @@ impl StorageManager {
let owner = vcrypto.generate_keypair();
// Make a signed value descriptor for this dht value
let signed_value_descriptor = SignedValueDescriptor::new(owner.key, )
let signed_value_descriptor = SignedValueDescriptor::make_signature(
owner.key,
schema_data,
vcrypto.clone(),
owner.secret,
)?;
// Add new local value record
let cur_ts = get_aligned_timestamp();
let record = Record::new(
cur_ts,
owner.key,
signed_value_descriptor,
Some(owner.secret),
schema,
safety_selection,
);
self.new_local_record(vcrypto.clone(), record)
)?;
let dht_key = self
.new_local_record(vcrypto, record)
.await
.map_err(VeilidAPIError::internal)?;
Ok(key)
Ok(dht_key)
}
pub async fn open_record(

View File

@@ -0,0 +1,9 @@
mod signed_value_data;
mod signed_value_descriptor;
mod value_detail;
use super::*;
pub use signed_value_data::*;
pub use signed_value_descriptor::*;
pub use value_detail::*;

View File

@@ -24,31 +24,32 @@ pub struct SignedValueData {
signature: Signature,
}
impl SignedValueData {
pub fn new(
value_data: ValueData,
owner: PublicKey,
subkey: ValueSubkey,
signature: Signature,
vcrypto: CryptoSystemVersion,
) -> Result<Self, VeilidAPIError> {
let node_info_bytes = Self::make_signature_bytes(&value_data, &owner, subkey)?;
// validate signature
vcrypto.verify(&value_data.writer(), &node_info_bytes, &signature)?;
Ok(Self {
pub fn new(value_data: ValueData, signature: Signature) -> Self {
Self {
value_data,
signature,
})
}
}
pub fn validate(
&self,
owner: &PublicKey,
subkey: ValueSubkey,
vcrypto: CryptoSystemVersion,
) -> Result<(), VeilidAPIError> {
let node_info_bytes = Self::make_signature_bytes(&self.value_data, owner, subkey)?;
// validate signature
vcrypto.verify(&self.value_data.writer(), &node_info_bytes, &self.signature)
}
pub fn make_signature(
value_data: ValueData,
owner: PublicKey,
owner: &PublicKey,
subkey: ValueSubkey,
vcrypto: CryptoSystemVersion,
writer_secret: SecretKey,
) -> Result<Self, VeilidAPIError> {
let node_info_bytes = Self::make_signature_bytes(&value_data, &owner, subkey)?;
let node_info_bytes = Self::make_signature_bytes(&value_data, owner, subkey)?;
// create signature
let signature = vcrypto.sign(&value_data.writer(), &writer_secret, &node_info_bytes)?;

View File

@@ -25,20 +25,17 @@ pub struct SignedValueDescriptor {
signature: Signature,
}
impl SignedValueDescriptor {
pub fn new(
owner: PublicKey,
schema_data: Vec<u8>,
signature: Signature,
vcrypto: CryptoSystemVersion,
) -> Result<Self, VeilidAPIError> {
// validate signature
vcrypto.verify(&owner, &schema_data, &signature)?;
Ok(Self {
pub fn new(owner: PublicKey, schema_data: Vec<u8>, signature: Signature) -> Self {
Self {
owner,
schema_data,
signature,
})
}
}
pub fn validate(&self, vcrypto: CryptoSystemVersion) -> Result<(), VeilidAPIError> {
// validate signature
vcrypto.verify(&self.owner, &self.schema_data, &self.signature)
}
pub fn owner(&self) -> &PublicKey {
@@ -75,4 +72,12 @@ impl SignedValueDescriptor {
pub fn total_size(&self) -> usize {
mem::size_of::<Self>() + self.schema_data.len()
}
pub fn cmp_no_sig(&self, other: &Self) -> cmp::Ordering {
let o = self.owner.cmp(&other.owner);
if o != cmp::Ordering::Equal {
return o;
}
self.schema_data.cmp(&other.schema_data)
}
}

View File

@@ -0,0 +1,77 @@
use super::*;
use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
use serde::*;
/////////////////////////////////////////////////////////////////////////////////////////////////////
///
#[derive(
Clone,
Debug,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct ValueDetail {
signed_value_data: SignedValueData,
descriptor: Option<SignedValueDescriptor>,
}
impl ValueDetail {
pub fn new(
signed_value_data: SignedValueData,
descriptor: Option<SignedValueDescriptor>,
) -> Self {
Self {
signed_value_data,
descriptor,
}
}
pub fn validate(
&self,
last_descriptor: Option<&SignedValueDescriptor>,
subkey: ValueSubkey,
vcrypto: CryptoSystemVersion,
) -> Result<(), VeilidAPIError> {
// Get descriptor to validate with
let descriptor = if let Some(descriptor) = &self.descriptor {
if let Some(last_descriptor) = last_descriptor {
if descriptor.cmp_no_sig(&last_descriptor) != cmp::Ordering::Equal {
return Err(VeilidAPIError::generic(
"value detail descriptor does not match last descriptor",
));
}
}
descriptor
} else {
let Some(descriptor) = last_descriptor else {
return Err(VeilidAPIError::generic(
"no last descriptor, requires a descriptor",
));
};
descriptor
};
// Ensure the descriptor itself validates
descriptor.validate(vcrypto.clone())?;
// And the signed value data
self.signed_value_data
.validate(descriptor.owner(), subkey, vcrypto)
}
pub fn signed_value_data(&self) -> &SignedValueData {
&self.signed_value_data
}
pub fn descriptor(&self) -> Option<&SignedValueDescriptor> {
self.descriptor.as_ref()
}
}

View File

@@ -1,43 +0,0 @@
use super::*;
use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
use serde::*;
/////////////////////////////////////////////////////////////////////////////////////////////////////
///
#[derive(
Clone,
Debug,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct ValueDetail {
signed_value_data: SignedValueData,
descriptor: Option<SignedValueDescriptor>,
}
impl ValueDetail {
pub fn new(
signed_value_data: SignedValueData,
descriptor: Option<SignedValueDescriptor>,
) -> Self {
Self {
signed_value_data,
descriptor,
}
}
pub fn signed_value_data(&self) -> &SignedValueData {
&self.signed_value_data
}
pub fn descriptor(&self) -> Option<&SignedValueDescriptor> {
self.descriptor.as_ref()
}
}