use ockam_core::compat::sync::Arc;
use crate::purpose_keys::storage::PurposeKeysRepository;
use crate::{
ChangeHistoryRepository, IdentitiesKeys, PurposeKeyCreation, PurposeKeyVerification, Vault,
};
#[derive(Clone)]
pub struct PurposeKeys {
vault: Vault,
change_history_repository: Arc<dyn ChangeHistoryRepository>,
identity_keys: Arc<IdentitiesKeys>,
repository: Arc<dyn PurposeKeysRepository>,
}
impl PurposeKeys {
pub fn new(
vault: Vault,
change_history_repository: Arc<dyn ChangeHistoryRepository>,
identity_keys: Arc<IdentitiesKeys>,
repository: Arc<dyn PurposeKeysRepository>,
) -> Self {
Self {
vault,
change_history_repository,
identity_keys,
repository,
}
}
pub fn repository(&self) -> Arc<dyn PurposeKeysRepository> {
self.repository.clone()
}
pub fn purpose_keys_creation(&self) -> Arc<PurposeKeyCreation> {
Arc::new(PurposeKeyCreation::new(
self.vault.clone(),
self.change_history_repository.clone(),
self.identity_keys.clone(),
self.repository.clone(),
))
}
pub fn purpose_keys_verification(&self) -> Arc<PurposeKeyVerification> {
Arc::new(PurposeKeyVerification::new(
self.vault.verifying_vault.clone(),
self.change_history_repository.clone(),
))
}
}
#[cfg(test)]
mod tests {
use ockam_core::Result;
use crate::{identities, Purpose};
#[tokio::test]
async fn create_purpose_keys() -> Result<()> {
let identities = identities().await?;
let identities_creation = identities.identities_creation();
let purpose_keys = identities.purpose_keys();
let identifier = identities_creation.create_identity().await?;
let credentials_key = purpose_keys
.purpose_keys_creation()
.create_credential_purpose_key(&identifier)
.await?;
let secure_channel_key = purpose_keys
.purpose_keys_creation()
.create_secure_channel_purpose_key(&identifier)
.await?;
let credentials_key = purpose_keys
.purpose_keys_verification()
.verify_purpose_key_attestation(Some(&identifier), credentials_key.attestation())
.await?;
let secure_channel_key = purpose_keys
.purpose_keys_verification()
.verify_purpose_key_attestation(Some(&identifier), secure_channel_key.attestation())
.await?;
assert_eq!(identifier, credentials_key.subject);
assert_eq!(identifier, secure_channel_key.subject);
Ok(())
}
#[tokio::test]
async fn test_purpose_keys_are_persisted() -> Result<()> {
let identities = identities().await?;
let identities_creation = identities.identities_creation();
let purpose_keys = identities.purpose_keys();
let identifier = identities_creation.create_identity().await?;
let credentials_key = purpose_keys
.purpose_keys_creation()
.create_credential_purpose_key(&identifier)
.await?;
assert!(purpose_keys
.repository()
.get_purpose_key(&identifier, Purpose::Credentials)
.await?
.is_some());
assert!(purpose_keys
.repository()
.get_purpose_key(&identifier, Purpose::SecureChannel)
.await?
.is_none());
let secure_channel_key = purpose_keys
.purpose_keys_creation()
.create_secure_channel_purpose_key(&identifier)
.await?;
let key = purpose_keys
.repository()
.get_purpose_key(&identifier, Purpose::Credentials)
.await?
.unwrap();
purpose_keys
.purpose_keys_verification()
.verify_purpose_key_attestation(Some(&identifier), &key)
.await
.unwrap();
assert_eq!(&key, credentials_key.attestation());
let key = purpose_keys
.repository()
.get_purpose_key(&identifier, Purpose::SecureChannel)
.await?
.unwrap();
purpose_keys
.purpose_keys_verification()
.verify_purpose_key_attestation(Some(&identifier), &key)
.await
.unwrap();
assert_eq!(&key, secure_channel_key.attestation());
let credentials_key2 = purpose_keys
.purpose_keys_creation()
.create_credential_purpose_key(&identifier)
.await?;
let key = purpose_keys
.repository()
.get_purpose_key(&identifier, Purpose::Credentials)
.await?
.unwrap();
purpose_keys
.purpose_keys_verification()
.verify_purpose_key_attestation(Some(&identifier), &key)
.await
.unwrap();
assert_eq!(&key, credentials_key2.attestation());
Ok(())
}
}