rkyv issue

This commit is contained in:
John Smith 2022-11-12 12:10:38 -05:00
parent baf1353fd2
commit 1c93b6e8cb
17 changed files with 86 additions and 196 deletions

View File

@ -1,10 +1,10 @@
#![allow(dead_code)]
#![allow(clippy::absurd_extreme_comparisons)]
use super::*;
use crate::routing_table::VersionRange;
use crate::xx::*;
use crate::*;
use core::convert::TryInto;
use crate::routing_table::VersionRange;
// #[repr(C, packed)]
// struct EnvelopeHeader {
@ -59,9 +59,6 @@ impl Envelope {
sender_id: DHTKey,
recipient_id: DHTKey,
) -> Self {
assert!(sender_id.valid);
assert!(recipient_id.valid);
assert!(version >= MIN_CRYPTO_VERSION);
assert!(version <= MAX_CRYPTO_VERSION);
Self {
@ -206,15 +203,6 @@ impl Envelope {
body: &[u8],
node_id_secret: &DHTKeySecret,
) -> Result<Vec<u8>, VeilidAPIError> {
// Ensure sender node id is valid
if !self.sender_id.valid {
return Err(VeilidAPIError::generic("sender id is invalid"));
}
// Ensure recipient node id is valid
if !self.recipient_id.valid {
return Err(VeilidAPIError::generic("recipient id is invalid"));
}
// Ensure body isn't too long
let envelope_size: usize = body.len() + MIN_ENVELOPE_SIZE;
if envelope_size > MAX_ENVELOPE_SIZE {

View File

@ -2,10 +2,10 @@ use crate::veilid_rng::*;
use crate::xx::*;
use crate::*;
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
use core::convert::{TryFrom, TryInto};
use core::fmt;
use core::hash::{Hash, Hasher};
use core::hash::Hash;
use data_encoding::BASE64URL_NOPAD;
use digest::generic_array::typenum::U64;
@ -39,11 +39,29 @@ pub const DHT_SIGNATURE_LENGTH_ENCODED: usize = 86;
macro_rules! byte_array_type {
($name:ident, $size:expr) => {
#[derive(Clone, Copy, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[derive(
Clone,
Copy,
Hash,
Eq,
PartialEq,
PartialOrd,
Ord,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes, Hash, Eq, PartialEq, PartialOrd, Ord))]
pub struct $name {
pub bytes: [u8; $size],
pub valid: bool,
}
impl Default for $name {
fn default() -> Self {
Self {
bytes: [0u8; $size],
}
}
}
impl serde::Serialize for $name {
@ -51,12 +69,7 @@ macro_rules! byte_array_type {
where
S: serde::Serializer,
{
let s: String;
if self.valid {
s = self.encode();
} else {
s = "".to_owned();
}
let s = self.encode();
serde::Serialize::serialize(&s, serializer)
}
}
@ -76,28 +89,19 @@ macro_rules! byte_array_type {
impl $name {
pub fn new(bytes: [u8; $size]) -> Self {
Self { bytes, valid: true }
Self { bytes }
}
pub fn try_from_vec(v: Vec<u8>) -> Result<Self, VeilidAPIError> {
let mut this = Self {
bytes: [0u8; $size],
valid: true,
};
if v.len() != $size {
apibail_generic!(format!(
"Expected a Vec of length {} but it was {}",
$size,
v.len()
));
}
for n in 0..v.len() {
this.bytes[n] = v[n];
}
Ok(this)
let vl = v.len();
Ok(Self {
bytes: v.try_into().map_err(|_| {
VeilidAPIError::generic(format!(
"Expected a Vec of length {} but it was {}",
$size, vl
))
})?,
})
}
pub fn bit(&self, index: usize) -> bool {
@ -143,7 +147,6 @@ macro_rules! byte_array_type {
}
pub fn encode(&self) -> String {
assert!(self.valid);
BASE64URL_NOPAD.encode(&self.bytes)
}
@ -169,63 +172,7 @@ macro_rules! byte_array_type {
}
}
}
impl PartialOrd for $name {
fn partial_cmp(&self, other: &$name) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for $name {
fn cmp(&self, other: &$name) -> Ordering {
if !self.valid && !other.valid {
return Ordering::Equal;
}
if !self.valid && other.valid {
return Ordering::Less;
}
if self.valid && !other.valid {
return Ordering::Greater;
}
for n in 0..$size {
if self.bytes[n] < other.bytes[n] {
return Ordering::Less;
}
if self.bytes[n] > other.bytes[n] {
return Ordering::Greater;
}
}
Ordering::Equal
}
}
impl PartialEq<$name> for $name {
fn eq(&self, other: &$name) -> bool {
if self.valid != other.valid {
return false;
}
for n in 0..$size {
if self.bytes[n] != other.bytes[n] {
return false;
}
}
true
}
}
impl Eq for $name {}
impl Hash for $name {
fn hash<H: Hasher>(&self, state: &mut H) {
self.valid.hash(state);
if self.valid {
self.bytes.hash(state);
}
}
}
impl Default for $name {
fn default() -> Self {
let mut this = $name::new([0u8; $size]);
this.valid = false;
this
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", String::from(self))
@ -235,24 +182,13 @@ macro_rules! byte_array_type {
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, concat!(stringify!($name), "("))?;
write!(
f,
"{}",
if self.valid {
self.encode()
} else {
"".to_owned()
}
)?;
write!(f, "{}", self.encode())?;
write!(f, ")")
}
}
impl From<&$name> for String {
fn from(value: &$name) -> Self {
if !value.valid {
return "".to_owned();
}
let mut s = String::new();
for n in 0..($size / 8) {
let b: [u8; 8] = value.bytes[n * 8..(n + 1) * 8].try_into().unwrap();
@ -280,10 +216,7 @@ macro_rules! byte_array_type {
apibail_generic!(concat!(stringify!($name), " is incorrect length"));
}
match hex::decode_to_slice(value, &mut out.bytes) {
Ok(_) => {
out.valid = true;
Ok(out)
}
Ok(_) => Ok(out),
Err(err) => Err(VeilidAPIError::generic(err)),
}
}
@ -381,9 +314,6 @@ pub fn sign(
dht_key_secret: &DHTKeySecret,
data: &[u8],
) -> Result<DHTSignature, VeilidAPIError> {
assert!(dht_key.valid);
assert!(dht_key_secret.valid);
let mut kpb: [u8; DHT_KEY_SECRET_LENGTH + DHT_KEY_LENGTH] =
[0u8; DHT_KEY_SECRET_LENGTH + DHT_KEY_LENGTH];
@ -408,8 +338,6 @@ pub fn verify(
data: &[u8],
signature: &DHTSignature,
) -> Result<(), VeilidAPIError> {
assert!(dht_key.valid);
assert!(signature.valid);
let pk = PublicKey::from_bytes(&dht_key.bytes)
.map_err(|e| VeilidAPIError::parse_error("Public key is invalid", e))?;
let sig = Signature::from_bytes(&signature.bytes)
@ -428,7 +356,6 @@ pub fn generate_hash(data: &[u8]) -> DHTKey {
}
pub fn validate_hash(data: &[u8], dht_key: &DHTKey) -> bool {
assert!(dht_key.valid);
let bytes = *blake3::hash(data).as_bytes();
bytes == dht_key.bytes
@ -446,8 +373,6 @@ pub fn validate_key(dht_key: &DHTKey, dht_key_secret: &DHTKeySecret) -> bool {
}
pub fn distance(key1: &DHTKey, key2: &DHTKey) -> DHTKeyDistance {
assert!(key1.valid);
assert!(key2.valid);
let mut bytes = [0u8; DHT_KEY_LENGTH];
for (n, byte) in bytes.iter_mut().enumerate() {

View File

@ -112,15 +112,15 @@ impl Crypto {
let (table_store, node_id) = {
let mut inner = self.inner.lock();
let c = self.config.get();
inner.node_id = c.network.node_id;
inner.node_id_secret = c.network.node_id_secret;
inner.node_id = c.network.node_id.unwrap();
inner.node_id_secret = c.network.node_id_secret.unwrap();
(inner.table_store.clone(), c.network.node_id)
};
// load caches if they are valid for this node id
let mut db = table_store.open("crypto_caches", 1).await?;
let caches_valid = match db.load(0, b"node_id")? {
Some(v) => v.as_slice() == node_id.bytes,
Some(v) => v.as_slice() == node_id.unwrap().bytes,
None => false,
};
if caches_valid {
@ -132,7 +132,7 @@ impl Crypto {
drop(db);
table_store.delete("crypto_caches").await?;
db = table_store.open("crypto_caches", 1).await?;
db.store(0, b"node_id", &node_id.bytes)?;
db.store(0, b"node_id", &node_id.unwrap().bytes)?;
}
// Schedule flushing
@ -220,8 +220,6 @@ impl Crypto {
// These are safe to use regardless of initialization status
pub fn compute_dh(key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, VeilidAPIError> {
assert!(key.valid);
assert!(secret.valid);
let pk_ed = ed::PublicKey::from_bytes(&key.bytes).map_err(VeilidAPIError::internal)?;
let pk_xd = Self::ed25519_to_x25519_pk(&pk_ed)?;
let sk_ed = ed::SecretKey::from_bytes(&secret.bytes).map_err(VeilidAPIError::internal)?;

View File

@ -58,7 +58,6 @@ impl Receipt {
sender_id: DHTKey,
extra_data: D,
) -> Result<Self, VeilidAPIError> {
assert!(sender_id.valid);
if extra_data.as_ref().len() > MAX_EXTRA_DATA_SIZE {
return Err(VeilidAPIError::parse_error(
"extra data too large for receipt",
@ -151,11 +150,6 @@ impl Receipt {
}
pub fn to_signed_data(&self, secret: &DHTKeySecret) -> Result<Vec<u8>, VeilidAPIError> {
// Ensure sender node id is valid
if !self.sender_id.valid {
return Err(VeilidAPIError::internal("sender id is invalid"));
}
// Ensure extra data isn't too long
let receipt_size: usize = self.extra_data.len() + MIN_RECEIPT_SIZE;
if receipt_size > MAX_RECEIPT_SIZE {

View File

@ -88,9 +88,7 @@ pub async fn test_key_conversions() {
// Test default key
let (dht_key, dht_key_secret) = (key::DHTKey::default(), key::DHTKeySecret::default());
assert_eq!(dht_key.bytes, EMPTY_KEY);
assert!(!dht_key.valid);
assert_eq!(dht_key_secret.bytes, EMPTY_KEY_SECRET);
assert!(!dht_key_secret.valid);
let dht_key_string = String::from(&dht_key);
trace!("dht_key_string: {:?}", dht_key_string);
let dht_key_string2 = String::from(&dht_key);

View File

@ -81,8 +81,8 @@ impl RoutingTable {
RoutingTableUnlockedInner {
config: config.clone(),
network_manager,
node_id: c.network.node_id,
node_id_secret: c.network.node_id_secret,
node_id: c.network.node_id.unwrap(),
node_id_secret: c.network.node_id_secret.unwrap(),
kick_queue: Mutex::new(BTreeSet::default()),
rolling_transfers_task: TickTask::new(ROLLING_TRANSFERS_INTERVAL_SECS),
kick_buckets_task: TickTask::new(1),

View File

@ -22,9 +22,6 @@ pub fn encode_block_id(
key: &DHTKey,
builder: &mut veilid_capnp::b_l_a_k_e3_hash::Builder,
) -> Result<(), RPCError> {
if !key.valid {
return Err(RPCError::protocol("invalid key"));
}
builder.set_u0(u64::from_be_bytes(
key.bytes[0..8].try_into().map_err(RPCError::internal)?,
));

View File

@ -22,9 +22,6 @@ pub fn encode_public_key(
key: &DHTKey,
builder: &mut veilid_capnp::curve25519_public_key::Builder,
) -> Result<(), RPCError> {
if !key.valid {
return Err(RPCError::protocol("invalid key"));
}
builder.set_u0(u64::from_be_bytes(
key.bytes[0..8]
.try_into()

View File

@ -5,10 +5,6 @@ pub fn encode_signature(
sig: &DHTSignature,
builder: &mut veilid_capnp::ed25519_signature::Builder,
) {
if !sig.valid {
panic!("don't encode invalid signatures");
}
let sig = &sig.bytes;
builder.set_u0(u64::from_be_bytes(

View File

@ -14,7 +14,10 @@ pub fn encode_signed_direct_node_info(
.set_timestamp(signed_direct_node_info.timestamp);
let mut sig_builder = builder.reborrow().init_signature();
encode_signature(&signed_direct_node_info.signature, &mut sig_builder);
let Some(signature) = &signed_direct_node_info.signature else {
return Err(RPCError::internal("Should not encode SignedDirectNodeInfo without signature!"));
};
encode_signature(signature, &mut sig_builder);
Ok(())
}

View File

@ -193,8 +193,8 @@ fn config_callback(key: String) -> ConfigCallbackReturn {
"network.client_whitelist_timeout_ms" => Ok(Box::new(300_000u32)),
"network.reverse_connection_receipt_time_ms" => Ok(Box::new(5_000u32)),
"network.hole_punch_receipt_time_ms" => Ok(Box::new(5_000u32)),
"network.node_id" => Ok(Box::new(DHTKey::default())),
"network.node_id_secret" => Ok(Box::new(DHTKeySecret::default())),
"network.node_id" => Ok(Box::new(Option::<DHTKey>::None)),
"network.node_id_secret" => Ok(Box::new(Option::<DHTKeySecret>::None)),
"network.bootstrap" => Ok(Box::new(Vec::<String>::new())),
"network.bootstrap_nodes" => Ok(Box::new(Vec::<String>::new())),
"network.routing_table.limit_over_attached" => Ok(Box::new(64u32)),
@ -318,8 +318,8 @@ pub async fn test_config() {
assert_eq!(inner.network.client_whitelist_timeout_ms, 300_000u32);
assert_eq!(inner.network.reverse_connection_receipt_time_ms, 5_000u32);
assert_eq!(inner.network.hole_punch_receipt_time_ms, 5_000u32);
assert!(!inner.network.node_id.valid);
assert!(!inner.network.node_id_secret.valid);
assert!(inner.network.node_id.is_none());
assert!(inner.network.node_id_secret.is_none());
assert_eq!(inner.network.bootstrap, Vec::<String>::new());
assert_eq!(inner.network.bootstrap_nodes, Vec::<String>::new());
assert_eq!(inner.network.rpc.concurrency, 2u32);

View File

@ -73,7 +73,7 @@ pub async fn test_signed_node_info() {
NodeId::new(pkey),
node_info.clone(),
sni.timestamp,
sni.signature,
sni.signature.unwrap(),
)
.unwrap();

View File

@ -360,7 +360,6 @@ pub struct NodeId {
}
impl NodeId {
pub fn new(key: DHTKey) -> Self {
assert!(key.valid);
Self { key }
}
}
@ -1967,7 +1966,7 @@ impl MatchesDialInfoFilter for DialInfo {
pub struct SignedDirectNodeInfo {
pub node_info: NodeInfo,
pub timestamp: u64,
pub signature: DHTSignature,
pub signature: Option<DHTSignature>,
}
impl SignedDirectNodeInfo {
@ -1982,7 +1981,7 @@ impl SignedDirectNodeInfo {
Ok(Self {
node_info,
timestamp,
signature,
signature: Some(signature),
})
}
@ -1997,7 +1996,7 @@ impl SignedDirectNodeInfo {
Ok(Self {
node_info,
timestamp,
signature,
signature: Some(signature),
})
}
@ -2022,13 +2021,13 @@ impl SignedDirectNodeInfo {
pub fn with_no_signature(node_info: NodeInfo) -> Self {
Self {
node_info,
signature: DHTSignature::default(),
signature: None,
timestamp: intf::get_timestamp(),
}
}
pub fn has_valid_signature(&self) -> bool {
self.signature.valid
self.signature.is_some()
}
}

View File

@ -217,8 +217,8 @@ pub struct VeilidConfigNetwork {
pub client_whitelist_timeout_ms: u32,
pub reverse_connection_receipt_time_ms: u32,
pub hole_punch_receipt_time_ms: u32,
pub node_id: DHTKey,
pub node_id_secret: DHTKeySecret,
pub node_id: Option<DHTKey>,
pub node_id_secret: Option<DHTKeySecret>,
pub bootstrap: Vec<String>,
pub bootstrap_nodes: Vec<String>,
pub routing_table: VeilidConfigRoutingTable,
@ -675,7 +675,7 @@ impl VeilidConfig {
let mut node_id = self.inner.read().network.node_id;
let mut node_id_secret = self.inner.read().network.node_id_secret;
// See if node id was previously stored in the protected store
if !node_id.valid {
if node_id.is_none() {
debug!("pulling node id from storage");
if let Some(s) = protected_store
.load_user_secret_string("node_id")
@ -683,14 +683,14 @@ impl VeilidConfig {
.map_err(VeilidAPIError::internal)?
{
debug!("node id found in storage");
node_id = DHTKey::try_decode(s.as_str()).map_err(VeilidAPIError::internal)?
node_id = Some(DHTKey::try_decode(s.as_str()).map_err(VeilidAPIError::internal)?);
} else {
debug!("node id not found in storage");
}
}
// See if node id secret was previously stored in the protected store
if !node_id_secret.valid {
if node_id_secret.is_none() {
debug!("pulling node id secret from storage");
if let Some(s) = protected_store
.load_user_secret_string("node_id_secret")
@ -699,27 +699,25 @@ impl VeilidConfig {
{
debug!("node id secret found in storage");
node_id_secret =
DHTKeySecret::try_decode(s.as_str()).map_err(VeilidAPIError::internal)?
Some(DHTKeySecret::try_decode(s.as_str()).map_err(VeilidAPIError::internal)?);
} else {
debug!("node id secret not found in storage");
}
}
// If we have a node id from storage, check it
if node_id.valid && node_id_secret.valid {
// Validate node id
if !crypto::validate_key(&node_id, &node_id_secret) {
apibail_generic!("node id secret and node id key don't match");
}
}
// If we still don't have a valid node id, generate one
if !node_id.valid || !node_id_secret.valid {
debug!("generating new node id");
let (i, s) = generate_secret();
node_id = i;
node_id_secret = s;
}
let (node_id, node_id_secret) =
if let (Some(node_id), Some(node_id_secret)) = (node_id, node_id_secret) {
// Validate node id
if !crypto::validate_key(&node_id, &node_id_secret) {
apibail_generic!("node id secret and node id key don't match");
}
(node_id, node_id_secret)
} else {
// If we still don't have a valid node id, generate one
debug!("generating new node id");
generate_secret()
};
info!("Node Id is {}", node_id.encode());
// info!("Node Id Secret is {}", node_id_secret.encode());
@ -733,8 +731,8 @@ impl VeilidConfig {
.await
.map_err(VeilidAPIError::internal)?;
self.inner.write().network.node_id = node_id;
self.inner.write().network.node_id_secret = node_id_secret;
self.inner.write().network.node_id = Some(node_id);
self.inner.write().network.node_id_secret = Some(node_id_secret);
trace!("init_node_id complete");

View File

@ -737,8 +737,8 @@ class VeilidConfigNetwork {
int clientWhitelistTimeoutMs;
int reverseConnectionReceiptTimeMs;
int holePunchReceiptTimeMs;
String nodeId;
String nodeIdSecret;
String? nodeId;
String? nodeIdSecret;
List<String> bootstrap;
List<String> bootstrapNodes;
VeilidConfigRoutingTable routingTable;

View File

@ -256,8 +256,8 @@ pub fn process_command_line() -> EyreResult<(Settings, ArgMatches)> {
let s = DHTKeySecret::try_decode(&buffer)?;
(k, s)
};
settingsrw.core.network.node_id = k;
settingsrw.core.network.node_id_secret = s;
settingsrw.core.network.node_id = Some(k);
settingsrw.core.network.node_id_secret = Some(s);
}
if matches.occurrences_of("bootstrap") != 0 {

View File

@ -67,8 +67,8 @@ core:
client_whitelist_timeout_ms: 300000
reverse_connection_receipt_time_ms: 5000
hole_punch_receipt_time_ms: 5000
node_id: ''
node_id_secret: ''
node_id: null
node_id_secret: null
bootstrap: ['bootstrap.dev.veilid.net']
bootstrap_nodes: []
routing_table:
@ -588,8 +588,8 @@ pub struct Network {
pub client_whitelist_timeout_ms: u32,
pub reverse_connection_receipt_time_ms: u32,
pub hole_punch_receipt_time_ms: u32,
pub node_id: veilid_core::DHTKey,
pub node_id_secret: veilid_core::DHTKeySecret,
pub node_id: Option<veilid_core::DHTKey>,
pub node_id_secret: Option<veilid_core::DHTKeySecret>,
pub bootstrap: Vec<String>,
pub bootstrap_nodes: Vec<ParsedNodeDialInfo>,
pub routing_table: RoutingTable,
@ -1484,11 +1484,8 @@ mod tests {
assert_eq!(s.core.network.client_whitelist_timeout_ms, 300_000u32);
assert_eq!(s.core.network.reverse_connection_receipt_time_ms, 5_000u32);
assert_eq!(s.core.network.hole_punch_receipt_time_ms, 5_000u32);
assert_eq!(s.core.network.node_id, veilid_core::DHTKey::default());
assert_eq!(
s.core.network.node_id_secret,
veilid_core::DHTKeySecret::default()
);
assert_eq!(s.core.network.node_id, None);
assert_eq!(s.core.network.node_id_secret, None);
//
assert_eq!(
s.core.network.bootstrap,