refactor rpc validation
This commit is contained in:
@@ -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(
|
||||
|
||||
9
veilid-core/src/storage_manager/types/mod.rs
Normal file
9
veilid-core/src/storage_manager/types/mod.rs
Normal 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::*;
|
||||
@@ -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)?;
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
77
veilid-core/src/storage_manager/types/value_detail.rs
Normal file
77
veilid-core/src/storage_manager/types/value_detail.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user