kms_secp256k1_api/services/mocks/
mock_kms_client_service.rs1#[cfg(test)]
2use crate::constants::{
3 CASPER_PUBLIC_KEY_BASE64, CASPER_PUBLIC_KEY_PREFIXED, COSMOS_ADDRESS, COSMOS_PUBLIC_KEY,
4 COSMOS_PUBLIC_KEY_BASE64, COSMOS_SIGNATURE_BASE64, COSMOS_TRANSACTION_HASH, ETH_ADDRESS,
5 ETH_PUBLIC_KEY_BASE64, ETH_SIGNATURE_BASE64, ETH_TRANSACTION_HASH, RANDOM_PUBLIC_KEY_BASE64,
6 SIGNATURE_BASE64, TRANSACTION_HASH,
7};
8#[cfg(test)]
9use crate::services::keys_service::KeyEntry;
10#[cfg(test)]
11use crate::services::kms_client_service::KmsClientService;
12#[cfg(test)]
13use base64::Engine;
14#[cfg(test)]
15use base64::engine::general_purpose::STANDARD;
16#[cfg(test)]
17use k256::{
18 EncodedPoint, Secp256k1,
19 ecdsa::SigningKey,
20 elliptic_curve::{PublicKey, pkcs8::EncodePublicKey, rand_core::OsRng, sec1::FromEncodedPoint},
21};
22
23#[cfg(test)]
24pub struct MockKmsClientService;
25
26#[cfg(test)]
27#[async_trait::async_trait]
28impl KmsClientService for MockKmsClientService {
29 async fn create_key(&self) -> Result<(String, String), String> {
30 let signing_key = SigningKey::random(&mut OsRng);
31 let verifying_key = signing_key.verifying_key();
32 let encoded_point: EncodedPoint = verifying_key.to_encoded_point(false);
33
34 let public_key: PublicKey<Secp256k1> = PublicKey::from_encoded_point(&encoded_point)
35 .into_option()
36 .ok_or_else(|| "Failed to create PublicKey from encoded point".to_string())?;
37
38 let der = public_key
39 .to_public_key_der()
40 .map_err(|e| format!("DER encode error: {e}"))?;
41
42 let der_base64 = STANDARD.encode(der.as_bytes());
43
44 Ok(("mock-key_id".to_string(), der_base64))
45 }
46
47 async fn create_alias(&self, _key_id: &str, _alias: &str) -> Result<(), String> {
48 Ok(())
49 }
50
51 async fn sign(&self, _transaction_hash_hex: &str, address: &str) -> Result<String, String> {
52 if address.eq(CASPER_PUBLIC_KEY_PREFIXED) {
53 Ok(SIGNATURE_BASE64.to_string())
54 } else if address.eq(ETH_ADDRESS) {
55 Ok(ETH_SIGNATURE_BASE64.to_string())
56 } else if address.eq(COSMOS_ADDRESS) {
57 Ok(COSMOS_SIGNATURE_BASE64.to_string())
58 } else {
59 unimplemented!("Mock KMS Client signature type unimplemented for sign")
60 }
61 }
62
63 async fn verify(
64 &self,
65 transaction_hash_hex: &str,
66 signature_base64: &str,
67 key: &str,
68 ) -> Result<bool, String> {
69 let expected_cases = [
70 ExpectedMatch {
71 tx_hash: TRANSACTION_HASH,
72 signature: SIGNATURE_BASE64,
73 key: CASPER_PUBLIC_KEY_PREFIXED,
74 },
75 ExpectedMatch {
76 tx_hash: ETH_TRANSACTION_HASH,
77 signature: ETH_SIGNATURE_BASE64,
78 key: ETH_ADDRESS,
79 },
80 ExpectedMatch {
81 tx_hash: COSMOS_TRANSACTION_HASH,
82 signature: COSMOS_SIGNATURE_BASE64,
83 key: COSMOS_PUBLIC_KEY,
84 },
85 ];
86
87 let matches = expected_cases.iter().any(|case| {
88 transaction_hash_hex.contains(case.tx_hash)
89 && signature_base64 == case.signature
90 && key.contains(case.key)
91 || key == case.key
92 });
93
94 Ok(matches)
95 }
96
97 async fn delete_key(&self, key: &str) -> Result<bool, String> {
98 if key.contains("known_public_key") {
99 Ok(true)
100 } else {
101 Ok(false)
102 }
103 }
104
105 async fn list_keys(&self) -> Result<Vec<KeyEntry>, String> {
106 Ok(vec![
107 KeyEntry {
108 address: "address_1".to_string().into(),
109 public_key_base64: STANDARD.encode("public_key_1_base64").into(),
110 public_key: Some("public_key_1".to_string()).into(),
111 key_id: "key_id_1".to_string().into(),
112 },
113 KeyEntry {
114 address: "address_2".to_string().into(),
115 public_key_base64: STANDARD.encode("public_key_2_base64").into(),
116 public_key: Some("public_key_2".to_string()).into(),
117 key_id: "key_id_2".to_string().into(),
118 },
119 ])
120 }
121
122 async fn get_public_key(&self, alias: &str) -> Result<String, String> {
123 if CASPER_PUBLIC_KEY_PREFIXED.contains(alias) {
124 Ok(CASPER_PUBLIC_KEY_BASE64.to_string())
125 } else if alias.eq(ETH_ADDRESS) {
126 Ok(ETH_PUBLIC_KEY_BASE64.to_string())
127 } else if alias.eq(COSMOS_ADDRESS) {
128 Ok(COSMOS_PUBLIC_KEY_BASE64.to_string())
129 } else if alias.eq("bad_key") {
130 Ok(
131 RANDOM_PUBLIC_KEY_BASE64.to_string(), )
133 } else {
134 unimplemented!("Mock KMS Client signature type unimplemented for get_public_key")
135 }
136 }
137}
138
139#[allow(dead_code)]
140struct ExpectedMatch<'a> {
141 tx_hash: &'a str,
142 signature: &'a str,
143 key: &'a str,
144}