This commit is contained in:
John Smith 2023-06-06 18:48:37 -04:00
parent 89f5770fd1
commit 771a7c9e7e
3 changed files with 284 additions and 23 deletions

View File

@ -74,9 +74,8 @@ pub enum CryptoSystemRequestOp {
#[serde(with = "json_as_base64")] #[serde(with = "json_as_base64")]
#[schemars(with = "String")] #[schemars(with = "String")]
data: Vec<u8>, data: Vec<u8>,
#[serde(with = "json_as_base64")]
#[schemars(with = "String")] #[schemars(with = "String")]
hash_digest: Vec<u8>, hash_digest: HashDigest,
}, },
Distance { Distance {
#[schemars(with = "String")] #[schemars(with = "String")]
@ -153,9 +152,9 @@ pub enum CryptoSystemResponseOp {
result: ApiResultWithString<SharedSecret>, result: ApiResultWithString<SharedSecret>,
}, },
RandomBytes { RandomBytes {
#[serde(flatten)] #[serde(with = "json_as_base64")]
#[schemars(with = "ApiResult<String>")] #[schemars(with = "String")]
result: ApiResultWithVecU8, value: Vec<u8>,
}, },
DefaultSaltLength { DefaultSaltLength {
value: u32, value: u32,
@ -200,8 +199,9 @@ pub enum CryptoSystemResponseOp {
value: CryptoKeyDistance, value: CryptoKeyDistance,
}, },
Sign { Sign {
#[schemars(with = "String")] #[serde(flatten)]
value: Signature, #[schemars(with = "ApiResult<String>")]
result: ApiResultWithString<Signature>,
}, },
Verify { Verify {
#[serde(flatten)] #[serde(flatten)]
@ -221,8 +221,8 @@ pub enum CryptoSystemResponseOp {
result: ApiResultWithVecU8, result: ApiResultWithVecU8,
}, },
CryptNoAuth { CryptNoAuth {
#[serde(flatten)] #[serde(with = "json_as_base64")]
#[schemars(with = "ApiResult<String>")] #[schemars(with = "String")]
result: ApiResultWithVecU8, value: Vec<u8>,
}, },
} }

View File

@ -186,7 +186,8 @@ pub enum ResponseOp {
result: ApiResult<u32>, result: ApiResult<u32>,
}, },
BestCryptoSystem { BestCryptoSystem {
value: u32, #[serde(flatten)]
result: ApiResult<u32>,
}, },
CryptoSystem(CryptoSystemResponse), CryptoSystem(CryptoSystemResponse),
VerifySignatures { VerifySignatures {
@ -197,7 +198,7 @@ pub enum ResponseOp {
GenerateSignatures { GenerateSignatures {
#[serde(flatten)] #[serde(flatten)]
#[schemars(with = "ApiResult<Vec<String>>")] #[schemars(with = "ApiResult<Vec<String>>")]
result: ApiResultWithVecString<TypedSignatureSet>, result: ApiResultWithVecString<Vec<TypedSignature>>,
}, },
GenerateKeyPair { GenerateKeyPair {
#[serde(flatten)] #[serde(flatten)]
@ -210,7 +211,8 @@ pub enum ResponseOp {
value: Timestamp, value: Timestamp,
}, },
Debug { Debug {
value: String, #[serde(flatten)]
result: ApiResult<String>,
}, },
VeilidVersionString { VeilidVersionString {
value: String, value: String,

View File

@ -19,6 +19,15 @@ fn to_json_api_result_with_string<T: Clone + fmt::Debug>(
} }
} }
fn to_json_api_result_with_vec_string<T: Clone + fmt::Debug>(
r: VeilidAPIResult<T>,
) -> json_api::ApiResultWithVecString<T> {
match r {
Err(e) => json_api::ApiResultWithVecString::Err { error: e },
Ok(v) => json_api::ApiResultWithVecString::Ok { value: v },
}
}
fn to_json_api_result_with_vec_u8(r: VeilidAPIResult<Vec<u8>>) -> json_api::ApiResultWithVecU8 { fn to_json_api_result_with_vec_u8(r: VeilidAPIResult<Vec<u8>>) -> json_api::ApiResultWithVecU8 {
match r { match r {
Err(e) => json_api::ApiResultWithVecU8::Err { error: e }, Err(e) => json_api::ApiResultWithVecU8::Err { error: e },
@ -42,6 +51,7 @@ pub struct JsonRequestProcessor {
routing_contexts: Mutex<BTreeMap<u32, RoutingContext>>, routing_contexts: Mutex<BTreeMap<u32, RoutingContext>>,
table_dbs: Mutex<BTreeMap<u32, TableDB>>, table_dbs: Mutex<BTreeMap<u32, TableDB>>,
table_db_transactions: Mutex<BTreeMap<u32, TableDBTransaction>>, table_db_transactions: Mutex<BTreeMap<u32, TableDBTransaction>>,
crypto_systems: Mutex<BTreeMap<u32, CryptoSystemVersion>>,
} }
impl JsonRequestProcessor { impl JsonRequestProcessor {
@ -51,6 +61,7 @@ impl JsonRequestProcessor {
routing_contexts: Default::default(), routing_contexts: Default::default(),
table_dbs: Default::default(), table_dbs: Default::default(),
table_db_transactions: Default::default(), table_db_transactions: Default::default(),
crypto_systems: Default::default(),
} }
} }
@ -151,6 +162,37 @@ impl JsonRequestProcessor {
return 1; return 1;
} }
// CryptoSystem
fn add_crypto_system(&self, csv: CryptoSystemVersion) -> u32 {
let mut next_id: u32 = 1;
let mut crypto_systems = self.crypto_systems.lock();
while crypto_systems.contains_key(&next_id) {
next_id += 1;
}
crypto_systems.insert(next_id, csv);
next_id
}
fn lookup_crypto_system(&self, id: u32, cs_id: u32) -> Result<CryptoSystemVersion, Response> {
let crypto_systems = self.crypto_systems.lock();
let Some(crypto_system) = crypto_systems.get(&cs_id).cloned() else {
return Err(Response {
id,
op: ResponseOp::CryptoSystem(CryptoSystemResponse {
cs_id,
cs_op: CryptoSystemResponseOp::InvalidId
})
});
};
Ok(crypto_system)
}
fn release_crypto_system(&self, id: u32) -> i32 {
let mut crypto_systems = self.crypto_systems.lock();
if crypto_systems.remove(&id).is_none() {
return 0;
}
return 1;
}
// Target // Target
// Parse target // Parse target
@ -370,6 +412,122 @@ impl JsonRequestProcessor {
} }
} }
pub async fn process_crypto_system_request(
&self,
csv: CryptoSystemVersion,
csr: CryptoSystemRequest,
) -> CryptoSystemResponse {
let cs_op = match csr.cs_op {
CryptoSystemRequestOp::Release => {
self.release_crypto_system(csr.cs_id);
CryptoSystemResponseOp::Release {}
}
CryptoSystemRequestOp::CachedDh { key, secret } => CryptoSystemResponseOp::CachedDh {
result: to_json_api_result_with_string(csv.cached_dh(&key, &secret)),
},
CryptoSystemRequestOp::ComputeDh { key, secret } => CryptoSystemResponseOp::ComputeDh {
result: to_json_api_result_with_string(csv.compute_dh(&key, &secret)),
},
CryptoSystemRequestOp::RandomBytes { len } => CryptoSystemResponseOp::RandomBytes {
value: csv.random_bytes(len),
},
CryptoSystemRequestOp::DefaultSaltLength => CryptoSystemResponseOp::DefaultSaltLength {
value: csv.default_salt_length(),
},
CryptoSystemRequestOp::HashPassword { password, salt } => {
CryptoSystemResponseOp::HashPassword {
result: to_json_api_result(csv.hash_password(&password, &salt)),
}
}
CryptoSystemRequestOp::VerifyPassword {
password,
password_hash,
} => CryptoSystemResponseOp::VerifyPassword {
result: to_json_api_result(csv.verify_password(&password, &password_hash)),
},
CryptoSystemRequestOp::DeriveSharedSecret { password, salt } => {
CryptoSystemResponseOp::DeriveSharedSecret {
result: to_json_api_result_with_string(
csv.derive_shared_secret(&password, &salt),
),
}
}
CryptoSystemRequestOp::RandomNonce => CryptoSystemResponseOp::RandomNonce {
value: csv.random_nonce(),
},
CryptoSystemRequestOp::RandomSharedSecret => {
CryptoSystemResponseOp::RandomSharedSecret {
value: csv.random_shared_secret(),
}
}
CryptoSystemRequestOp::GenerateKeyPair => CryptoSystemResponseOp::GenerateKeyPair {
value: csv.generate_keypair(),
},
CryptoSystemRequestOp::GenerateHash { data } => CryptoSystemResponseOp::GenerateHash {
value: csv.generate_hash(&data),
},
CryptoSystemRequestOp::ValidateKeyPair { key, secret } => {
CryptoSystemResponseOp::ValidateKeyPair {
value: csv.validate_keypair(&key, &secret),
}
}
CryptoSystemRequestOp::ValidateHash { data, hash_digest } => {
CryptoSystemResponseOp::ValidateHash {
value: csv.validate_hash(&data, &hash_digest),
}
}
CryptoSystemRequestOp::Distance { key1, key2 } => CryptoSystemResponseOp::Distance {
value: csv.distance(&key1, &key2),
},
CryptoSystemRequestOp::Sign { key, secret, data } => CryptoSystemResponseOp::Sign {
result: to_json_api_result_with_string(csv.sign(&key, &secret, &data)),
},
CryptoSystemRequestOp::Verify { key, data, secret } => CryptoSystemResponseOp::Verify {
result: to_json_api_result(csv.verify(&key, &data, &secret)),
},
CryptoSystemRequestOp::AeadOverhead => CryptoSystemResponseOp::AeadOverhead {
value: csv.aead_overhead() as u32,
},
CryptoSystemRequestOp::DecryptAead {
body,
nonce,
shared_secret,
associated_data,
} => CryptoSystemResponseOp::DecryptAead {
result: to_json_api_result_with_vec_u8(csv.decrypt_aead(
&body,
&nonce,
&shared_secret,
associated_data.as_ref().map(|ad| ad.as_slice()),
)),
},
CryptoSystemRequestOp::EncryptAead {
body,
nonce,
shared_secret,
associated_data,
} => CryptoSystemResponseOp::EncryptAead {
result: to_json_api_result_with_vec_u8(csv.encrypt_aead(
&body,
&nonce,
&shared_secret,
associated_data.as_ref().map(|ad| ad.as_slice()),
)),
},
CryptoSystemRequestOp::CryptNoAuth {
body,
nonce,
shared_secret,
} => CryptoSystemResponseOp::CryptNoAuth {
value: csv.crypt_no_auth_unaligned(&body, &nonce, &shared_secret),
},
};
CryptoSystemResponse {
cs_id: csr.cs_id,
cs_op,
}
}
pub async fn process_request(&self, request: Request) -> Response { pub async fn process_request(&self, request: Request) -> Response {
let id = request.id; let id = request.id;
@ -482,20 +640,121 @@ impl JsonRequestProcessor {
.await, .await,
) )
} }
RequestOp::GetCryptoSystem { kind } => todo!(), RequestOp::GetCryptoSystem { kind } => {
RequestOp::BestCryptoSystem => todo!(), let crypto = match self.api.crypto() {
RequestOp::CryptoSystem(_) => todo!(), Ok(v) => v,
Err(e) => {
return Response {
id,
op: ResponseOp::GetCryptoSystem {
result: to_json_api_result(Err(e)),
},
}
}
};
ResponseOp::GetCryptoSystem {
result: to_json_api_result(
crypto
.get(kind)
.ok_or_else(|| {
VeilidAPIError::invalid_argument(
"unsupported cryptosystem",
"kind",
kind,
)
})
.map(|csv| self.add_crypto_system(csv)),
),
}
}
RequestOp::BestCryptoSystem => {
let crypto = match self.api.crypto() {
Ok(v) => v,
Err(e) => {
return Response {
id,
op: ResponseOp::GetCryptoSystem {
result: to_json_api_result(Err(e)),
},
}
}
};
ResponseOp::BestCryptoSystem {
result: to_json_api_result(Ok(self.add_crypto_system(crypto.best()))),
}
}
RequestOp::CryptoSystem(csr) => {
let csv = match self.lookup_crypto_system(id, csr.cs_id) {
Ok(v) => v,
Err(e) => return e,
};
ResponseOp::CryptoSystem(self.process_crypto_system_request(csv, csr).await)
}
RequestOp::VerifySignatures { RequestOp::VerifySignatures {
node_ids, node_ids,
data, data,
signatures, signatures,
} => todo!(), } => {
RequestOp::GenerateSignatures { data, key_pairs } => todo!(), let crypto = match self.api.crypto() {
RequestOp::GenerateKeyPair { kind } => todo!(), Ok(v) => v,
RequestOp::Now => todo!(), Err(e) => {
RequestOp::Debug { command } => todo!(), return Response {
RequestOp::VeilidVersionString => todo!(), id,
RequestOp::VeilidVersion => todo!(), op: ResponseOp::GetCryptoSystem {
result: to_json_api_result(Err(e)),
},
}
}
};
ResponseOp::VerifySignatures {
result: to_json_api_result_with_vec_string(crypto.verify_signatures(
&node_ids,
&data,
&signatures,
)),
}
}
RequestOp::GenerateSignatures { data, key_pairs } => {
let crypto = match self.api.crypto() {
Ok(v) => v,
Err(e) => {
return Response {
id,
op: ResponseOp::GetCryptoSystem {
result: to_json_api_result(Err(e)),
},
}
}
};
ResponseOp::GenerateSignatures {
result: to_json_api_result_with_vec_string(crypto.generate_signatures(
&data,
&key_pairs,
|k, s| TypedSignature::new(k.kind, s),
)),
}
}
RequestOp::GenerateKeyPair { kind } => ResponseOp::GenerateKeyPair {
result: to_json_api_result_with_string(Crypto::generate_keypair(kind)),
},
RequestOp::Now => ResponseOp::Now {
value: get_aligned_timestamp(),
},
RequestOp::Debug { command } => ResponseOp::Debug {
result: to_json_api_result(self.api.debug(command).await),
},
RequestOp::VeilidVersionString => ResponseOp::VeilidVersionString {
value: veilid_version_string(),
},
RequestOp::VeilidVersion => {
let (major, minor, patch) = veilid_version();
ResponseOp::VeilidVersion {
major,
minor,
patch,
}
}
}; };
Response { id, op } Response { id, op }