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

View File

@ -186,7 +186,8 @@ pub enum ResponseOp {
result: ApiResult<u32>,
},
BestCryptoSystem {
value: u32,
#[serde(flatten)]
result: ApiResult<u32>,
},
CryptoSystem(CryptoSystemResponse),
VerifySignatures {
@ -197,7 +198,7 @@ pub enum ResponseOp {
GenerateSignatures {
#[serde(flatten)]
#[schemars(with = "ApiResult<Vec<String>>")]
result: ApiResultWithVecString<TypedSignatureSet>,
result: ApiResultWithVecString<Vec<TypedSignature>>,
},
GenerateKeyPair {
#[serde(flatten)]
@ -210,7 +211,8 @@ pub enum ResponseOp {
value: Timestamp,
},
Debug {
value: String,
#[serde(flatten)]
result: ApiResult<String>,
},
VeilidVersionString {
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 {
match r {
Err(e) => json_api::ApiResultWithVecU8::Err { error: e },
@ -42,6 +51,7 @@ pub struct JsonRequestProcessor {
routing_contexts: Mutex<BTreeMap<u32, RoutingContext>>,
table_dbs: Mutex<BTreeMap<u32, TableDB>>,
table_db_transactions: Mutex<BTreeMap<u32, TableDBTransaction>>,
crypto_systems: Mutex<BTreeMap<u32, CryptoSystemVersion>>,
}
impl JsonRequestProcessor {
@ -51,6 +61,7 @@ impl JsonRequestProcessor {
routing_contexts: Default::default(),
table_dbs: Default::default(),
table_db_transactions: Default::default(),
crypto_systems: Default::default(),
}
}
@ -151,6 +162,37 @@ impl JsonRequestProcessor {
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
// 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 {
let id = request.id;
@ -482,20 +640,121 @@ impl JsonRequestProcessor {
.await,
)
}
RequestOp::GetCryptoSystem { kind } => todo!(),
RequestOp::BestCryptoSystem => todo!(),
RequestOp::CryptoSystem(_) => todo!(),
RequestOp::GetCryptoSystem { kind } => {
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::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 {
node_ids,
data,
signatures,
} => todo!(),
RequestOp::GenerateSignatures { data, key_pairs } => todo!(),
RequestOp::GenerateKeyPair { kind } => todo!(),
RequestOp::Now => todo!(),
RequestOp::Debug { command } => todo!(),
RequestOp::VeilidVersionString => todo!(),
RequestOp::VeilidVersion => todo!(),
} => {
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::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 }