use super::*;
impl StorageManager {
pub fn generate_member_id(&self, writer_key: &PublicKey) -> VeilidAPIResult<MemberId> {
if writer_key.ref_value().len() == MEMBER_ID_LENGTH {
return Ok(MemberId::new(
writer_key.kind(),
BareMemberId::new(writer_key.ref_value()),
));
}
let crypto = self.crypto();
let Some(vcrypto) = crypto.get(writer_key.kind()) else {
apibail_generic!("unsupported cryptosystem");
};
let idhash = vcrypto.generate_hash(writer_key.ref_value());
if idhash.ref_value().len() < MEMBER_ID_LENGTH {
apibail_internal!(format!(
"generate_hash needs to produce at least {} bytes",
MEMBER_ID_LENGTH
));
}
Ok(MemberId::new(
writer_key.kind(),
BareMemberId::new(&idhash.ref_value()[0..MEMBER_ID_LENGTH]),
))
}
pub fn check_subkey_value_data(
&self,
schema: &DHTSchema,
owner: &PublicKey,
subkey: ValueSubkey,
value_data: &EncryptedValueData,
) -> VeilidAPIResult<()> {
match schema {
DHTSchema::DFLT(d) => self.check_subkey_value_data_dflt(d, owner, subkey, value_data),
DHTSchema::SMPL(s) => self.check_subkey_value_data_smpl(s, owner, subkey, value_data),
}
}
pub(crate) fn check_subkey_value_data_dflt(
&self,
schema_dflt: &DHTSchemaDFLT,
owner: &PublicKey,
subkey: ValueSubkey,
value_data: &EncryptedValueData,
) -> VeilidAPIResult<()> {
let subkey = subkey as usize;
if subkey < (schema_dflt.o_cnt() as usize) {
if &value_data.writer() == owner {
let max_value_len = usize::min(
MAX_SUBKEY_SIZE,
MAX_RECORD_DATA_SIZE / schema_dflt.o_cnt() as usize,
);
if value_data.data_size() <= max_value_len {
return Ok(());
}
apibail_invalid_argument!(
"value too big",
"data",
human_byte_data(value_data.data(), Some(64))
);
}
apibail_invalid_argument!(
"wrong writer",
"writer",
format!("{:?} != {:?}", value_data.writer(), owner)
);
}
apibail_invalid_argument!("subkey out of range", "subkey", subkey);
}
pub(crate) fn check_subkey_value_data_smpl(
&self,
schema_smpl: &DHTSchemaSMPL,
owner: &PublicKey,
subkey: ValueSubkey,
value_data: &EncryptedValueData,
) -> VeilidAPIResult<()> {
let mut cur_subkey = subkey as usize;
let max_value_len = usize::min(
MAX_SUBKEY_SIZE,
MAX_RECORD_DATA_SIZE / schema_smpl.subkey_count(),
);
if cur_subkey < (schema_smpl.o_cnt() as usize) {
if &value_data.writer() == owner {
if value_data.data_size() <= max_value_len {
return Ok(());
}
apibail_invalid_argument!(
"value too big",
"data",
human_byte_data(value_data.data(), Some(64))
);
}
apibail_invalid_argument!(
"wrong writer",
"writer",
format!("{:?}", value_data.writer())
);
}
cur_subkey -= schema_smpl.o_cnt() as usize;
let writer_hash = self.generate_member_id(&value_data.writer())?;
for m in schema_smpl.members() {
if cur_subkey < (m.m_cnt as usize) {
if writer_hash.ref_value() == &m.m_key {
if value_data.data_size() <= max_value_len {
return Ok(());
}
apibail_invalid_argument!(
"value too big",
"data",
human_byte_data(value_data.data(), Some(64))
);
}
apibail_invalid_argument!(
"wrong writer",
"writer",
format!("{:?}", value_data.writer())
);
}
cur_subkey -= m.m_cnt as usize;
}
apibail_invalid_argument!("subkey out of range", "subkey", subkey);
}
}