identity_storage/key_id_storage/
keytool.rs1use async_trait::async_trait;
5use identity_verification::jwu::encode_b64;
6use iota_interaction::types::base_types::IotaAddress;
7use iota_interaction::KeytoolStorage;
8
9use crate::KeyId;
10
11use super::KeyIdStorage;
12use super::KeyIdStorageError;
13use super::KeyIdStorageErrorKind;
14use super::KeyIdStorageResult;
15use super::MethodDigest;
16
17const IDENTITY_VERIFICATION_METHOD_PREFIX: &str = "identity__";
18
19#[cfg_attr(feature = "send-sync-storage", async_trait)]
20#[cfg_attr(not(feature = "send-sync-storage"), async_trait(?Send))]
21impl KeyIdStorage for KeytoolStorage {
22 async fn insert_key_id(&self, method_digest: MethodDigest, key_id: KeyId) -> KeyIdStorageResult<()> {
23 let current_alias = key_id_to_alias(self, &key_id)?;
24 let new_alias = encode_method_digest(&method_digest);
25
26 self
27 .update_alias(¤t_alias, Some(&new_alias))
28 .map_err(|e| KeyIdStorageError::new(KeyIdStorageErrorKind::RetryableIOFailure).with_source(e))
29 }
30
31 async fn get_key_id(&self, method_digest: &MethodDigest) -> KeyIdStorageResult<KeyId> {
32 let alias = encode_method_digest(method_digest);
33 let pk = self
34 .get_key_by_alias(&alias)
35 .map_err(|e| KeyIdStorageError::new(KeyIdStorageErrorKind::RetryableIOFailure).with_source(e))?
36 .ok_or(KeyIdStorageErrorKind::KeyIdNotFound)?;
37 let address = IotaAddress::from(&pk);
38
39 Ok(KeyId::new(address.to_string()))
40 }
41
42 async fn delete_key_id(&self, method_digest: &MethodDigest) -> KeyIdStorageResult<()> {
43 let alias = encode_method_digest(method_digest);
44 self
45 .update_alias(&alias, None)
46 .map_err(|e| KeyIdStorageError::new(KeyIdStorageErrorKind::Unspecified).with_source(e))
47 }
48}
49
50fn key_id_to_alias(keytool: &KeytoolStorage, key_id: &KeyId) -> KeyIdStorageResult<String> {
51 let address = key_id.as_str().parse().map_err(|e| {
52 KeyIdStorageError::new(KeyIdStorageErrorKind::Unspecified)
53 .with_source(e)
54 .with_custom_message("invalid key id. Key id must be an IOTA address")
55 })?;
56 let (_, alias) = keytool
57 .get_key(address)
58 .map_err(|e| KeyIdStorageError::new(KeyIdStorageErrorKind::RetryableIOFailure).with_source(e))?
59 .ok_or(KeyIdStorageErrorKind::KeyIdNotFound)?;
60
61 Ok(alias)
62}
63
64fn encode_method_digest(method_digest: &MethodDigest) -> String {
65 let b64_method_digest = encode_b64(method_digest.pack());
66 format!("{IDENTITY_VERIFICATION_METHOD_PREFIX}{b64_method_digest}")
67}