ockam_entity/worker/
create_key.rs1use crate::change_history::ProfileChangeHistory;
2use crate::profile::Profile;
3use crate::EntityError::InvalidInternalState;
4use crate::{
5 ChangeBlock, EntityError, EventIdentifier, KeyAttributes, MetaKeyAttributes, ProfileChange,
6 ProfileChangeEvent, ProfileChangeType, ProfileEventAttributes, ProfileState, Signature,
7 SignatureType,
8};
9use ockam_core::vault::Signature as OckamVaultSignature;
10use ockam_core::vault::{Hasher, SecretVault, Signer};
11use ockam_core::vault::{PublicKey, Secret};
12use ockam_core::{Encodable, Result};
13use ockam_vault_sync_core::VaultSync;
14use serde::{Deserialize, Serialize};
15
16#[derive(Serialize, Deserialize, Debug, Clone)]
18pub struct CreateKeyChangeData {
19 key_attributes: KeyAttributes,
20 public_key: PublicKey,
21}
22
23impl CreateKeyChangeData {
24 pub fn key_attributes(&self) -> &KeyAttributes {
26 &self.key_attributes
27 }
28 pub fn public_key(&self) -> &PublicKey {
30 &self.public_key
31 }
32}
33
34impl CreateKeyChangeData {
35 pub fn new(key_attributes: KeyAttributes, public_key: PublicKey) -> Self {
37 CreateKeyChangeData {
38 key_attributes,
39 public_key,
40 }
41 }
42}
43
44#[derive(Serialize, Deserialize, Debug, Clone)]
46pub struct CreateKeyChange {
47 data: CreateKeyChangeData,
48 self_signature: OckamVaultSignature,
49}
50
51impl CreateKeyChange {
52 pub fn data(&self) -> &CreateKeyChangeData {
54 &self.data
55 }
56 pub fn self_signature(&self) -> &OckamVaultSignature {
58 &self.self_signature
59 }
60}
61
62impl CreateKeyChange {
63 pub fn new(data: CreateKeyChangeData, self_signature: OckamVaultSignature) -> Self {
65 CreateKeyChange {
66 data,
67 self_signature,
68 }
69 }
70}
71
72impl ProfileState {
73 async fn generate_key_if_needed(
74 secret: Option<&Secret>,
75 key_attributes: &KeyAttributes,
76 vault: &mut VaultSync,
77 ) -> Result<Secret> {
78 if let Some(s) = secret {
79 Ok(s.clone())
80 } else {
81 let MetaKeyAttributes::SecretAttributes(secret_attributes) = key_attributes.meta();
82
83 vault.secret_generate(*secret_attributes).await
84 }
85 }
86
87 pub(crate) async fn make_create_key_event_static(
89 secret: Option<&Secret>,
90 prev_id: EventIdentifier,
91 key_attributes: KeyAttributes,
92 attributes: ProfileEventAttributes,
93 root_key: Option<&Secret>,
94 vault: &mut VaultSync,
95 ) -> Result<ProfileChangeEvent> {
96 let secret_key = Self::generate_key_if_needed(secret, &key_attributes, vault).await?;
97
98 let public_key = vault.secret_public_key_get(&secret_key).await?;
99
100 let data = CreateKeyChangeData::new(key_attributes, public_key);
101 let data_binary = data.encode().map_err(|_| EntityError::BareError)?;
102 let data_hash = vault.sha256(data_binary.as_slice()).await?;
103 let self_signature = vault.sign(&secret_key, &data_hash).await?;
104 let change = CreateKeyChange::new(data, self_signature);
105
106 let profile_change = ProfileChange::new(
107 Profile::CURRENT_CHANGE_VERSION,
108 attributes,
109 ProfileChangeType::CreateKey(change),
110 );
111
112 let change_block = ChangeBlock::new(prev_id, profile_change);
113 let change_block_binary = change_block.encode().map_err(|_| EntityError::BareError)?;
114
115 let event_id = vault.sha256(&change_block_binary).await?;
116 let event_id = EventIdentifier::from_hash(event_id);
117
118 let self_signature = vault.sign(&secret_key, event_id.as_ref()).await?;
119 let self_signature = Signature::new(SignatureType::SelfSign, self_signature);
120
121 let mut signatures = vec![self_signature];
122
123 if let Some(root_key) = root_key {
126 let root_signature = vault.sign(root_key, event_id.as_ref()).await?;
127 let root_signature = Signature::new(SignatureType::RootSign, root_signature);
128
129 signatures.push(root_signature);
130 }
131
132 let signed_change_event = ProfileChangeEvent::new(event_id, change_block, signatures);
133
134 Ok(signed_change_event)
135 }
136
137 pub(crate) async fn make_create_key_event(
139 &mut self,
140 secret: Option<&Secret>,
141 key_attributes: KeyAttributes,
142 attributes: ProfileEventAttributes,
143 ) -> Result<ProfileChangeEvent> {
144 if ProfileChangeHistory::find_last_key_event(
146 self.change_history().as_ref(),
147 key_attributes.label(),
148 )
149 .is_ok()
150 {
151 return Err(InvalidInternalState.into());
152 }
153
154 let prev_id = match self.change_history().get_last_event_id() {
155 Ok(prev_id) => prev_id,
156 Err(_) => EventIdentifier::initial(&mut self.vault).await,
157 };
158
159 let root_secret = self.get_root_secret_key().await?;
160 let root_key = Some(&root_secret);
161
162 Self::make_create_key_event_static(
163 secret,
164 prev_id,
165 key_attributes,
166 attributes,
167 root_key,
168 &mut self.vault,
169 )
170 .await
171 }
172}