json api
This commit is contained in:
		| @@ -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>, | ||||
|     }, | ||||
| } | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user