Skip to content

Commit

Permalink
feat: implement Subject responsible for singing and verifying data (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
nanderstabel authored May 8, 2024
1 parent 9f39488 commit fcd11b0
Show file tree
Hide file tree
Showing 14 changed files with 176 additions and 64 deletions.
44 changes: 26 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ edition = "2021"
rust-version = "1.76.0"

[workspace.dependencies]
did_manager = { git = "https://git@github.com/impierce/did-manager.git", rev = "11ce737" }
did_manager = { git = "https://git@github.com/impierce/did-manager.git", rev = "c70c0f1" }
siopv2 = { git = "https://git@github.com/impierce/openid4vc.git", rev = "a932af7" }
oid4vci = { git = "https://git@github.com/impierce/openid4vc.git", rev = "a932af7" }
oid4vc-core = { git = "https://git@github.com/impierce/openid4vc.git", rev = "a932af7" }
Expand Down
6 changes: 4 additions & 2 deletions agent_api_rest/src/verification/relying_party/redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub mod tests {
verification::{authorization_requests::tests::authorization_requests, relying_party::request::tests::request},
};
use agent_event_publisher_http::{EventPublisherHttp, TEST_EVENT_PUBLISHER_HTTP_CONFIG};
use agent_secret_manager::secret_manager;
use agent_secret_manager::{secret_manager, subject::Subject};
use agent_shared::config;
use agent_store::{in_memory, EventPublisher};
use agent_verification::services::test_utils::test_verification_services;
Expand Down Expand Up @@ -108,7 +108,9 @@ pub mod tests {
.unwrap();

let provider_manager = ProviderManager::new(
Arc::new(futures::executor::block_on(async { secret_manager().await })),
Arc::new(Subject {
secret_manager: secret_manager().await,
}),
"did:key",
)
.unwrap();
Expand Down
6 changes: 4 additions & 2 deletions agent_application/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{str::FromStr, sync::Arc};
use agent_api_rest::app;
use agent_event_publisher_http::EventPublisherHttp;
use agent_issuance::{startup_commands::startup_commands, state::initialize};
use agent_secret_manager::secret_manager;
use agent_secret_manager::{secret_manager, subject::Subject};
use agent_shared::config;
use agent_store::{in_memory, postgres, EventPublisher};
use agent_verification::services::VerificationServices;
Expand All @@ -27,7 +27,9 @@ async fn main() {

let default_did_method = config!("default_did_method").unwrap_or("did:key".to_string());
let verification_services = Arc::new(VerificationServices::new(
Arc::new(secret_manager().await),
Arc::new(Subject {
secret_manager: secret_manager().await,
}),
// TODO: Temporary solution. Remove this once `ClientMetadata` is part of `RelyingPartyManager`.
ClientMetadataResource::ClientMetadata {
client_name: None,
Expand Down
11 changes: 4 additions & 7 deletions agent_issuance/src/credential/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use async_trait::async_trait;
use cqrs_es::Aggregate;
use derivative::Derivative;
use jsonwebtoken::{Algorithm, Header};
use oid4vc_core::{jwt, Subject};
use oid4vc_core::{jwt, Subject as _};
use oid4vci::VerifiableCredentialJwt;
use serde::{Deserialize, Serialize};
use serde_json::json;
Expand Down Expand Up @@ -74,14 +74,11 @@ impl Aggregate for Credential {
if self.signed.is_some() && !overwrite {
return Ok(vec![]);
}
let (issuer, default_did_method) = futures::executor::block_on(async {
let (issuer, default_did_method) = {
let mut services = SecretManagerServices::new(None);
services.init().await.unwrap();
(
Arc::new(services.secret_manager.unwrap()),
services.default_did_method.clone(),
)
});
(Arc::new(services.subject.unwrap()), services.default_did_method.clone())
};
let issuer_did = issuer.identifier(&default_did_method).unwrap();
let signed_credential = {
// TODO: Add error message here.
Expand Down
38 changes: 19 additions & 19 deletions agent_issuance/src/offer/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ impl Aggregate for Offer {
authorization_server_metadata,
credential_request,
} => {
let issuer = futures::executor::block_on(async {
let issuer = {
let mut services = SecretManagerServices::new(None);
services.init().await.unwrap();
Arc::new(services.secret_manager.unwrap())
});
Arc::new(services.subject.unwrap())
};

let credential_issuer = CredentialIssuer {
subject: issuer.clone(),
Expand Down Expand Up @@ -200,10 +200,10 @@ impl Aggregate for Offer {
pub mod tests {
use super::*;

use agent_secret_manager::subject::Subject;
use cqrs_es::test::TestFramework;
use did_manager::SecretManager;
use lazy_static::lazy_static;
use oid4vc_core::Subject;
use oid4vc_core::Subject as _;
use oid4vci::{
credential_format_profiles::{
w3c_verifiable_credentials::jwt_vc_json::CredentialDefinition, CredentialFormats, Parameters,
Expand All @@ -228,7 +228,7 @@ pub mod tests {
*ACCESS_TOKENS.lock().unwrap() = vec![generate_random_string()].into();
*C_NONCES.lock().unwrap() = vec![generate_random_string()].into();

let subject = subject();
let subject = test_subject();
OfferTestFramework::with(OfferServices)
.given_no_previous_events()
.when(OfferCommand::CreateCredentialOffer)
Expand All @@ -245,7 +245,7 @@ pub mod tests {
*ACCESS_TOKENS.lock().unwrap() = vec![generate_random_string()].into();
*C_NONCES.lock().unwrap() = vec![generate_random_string()].into();

let subject = subject();
let subject = test_subject();
OfferTestFramework::with(OfferServices)
.given(vec![OfferEvent::CredentialOfferCreated {
pre_authorized_code: subject.pre_authorized_code.clone(),
Expand All @@ -266,7 +266,7 @@ pub mod tests {
*ACCESS_TOKENS.lock().unwrap() = vec![generate_random_string()].into();
*C_NONCES.lock().unwrap() = vec![generate_random_string()].into();

let subject = subject();
let subject = test_subject();
OfferTestFramework::with(OfferServices)
.given(vec![
OfferEvent::CredentialOfferCreated {
Expand All @@ -292,7 +292,7 @@ pub mod tests {
*ACCESS_TOKENS.lock().unwrap() = vec![generate_random_string()].into();
*C_NONCES.lock().unwrap() = vec![generate_random_string()].into();

let subject = subject();
let subject = test_subject();
OfferTestFramework::with(OfferServices)
.given(vec![
OfferEvent::CredentialOfferCreated {
Expand Down Expand Up @@ -321,7 +321,7 @@ pub mod tests {
*ACCESS_TOKENS.lock().unwrap() = vec![generate_random_string()].into();
*C_NONCES.lock().unwrap() = vec![generate_random_string()].into();

let subject = subject();
let subject = test_subject();
OfferTestFramework::with(OfferServices)
.given(vec![
OfferEvent::CredentialOfferCreated {
Expand Down Expand Up @@ -357,7 +357,7 @@ pub mod tests {
*ACCESS_TOKENS.lock().unwrap() = vec![generate_random_string()].into();
*C_NONCES.lock().unwrap() = vec![generate_random_string()].into();

let subject = subject();
let subject = test_subject();
OfferTestFramework::with(OfferServices)
.given(vec![
OfferEvent::CredentialOfferCreated {
Expand Down Expand Up @@ -388,7 +388,7 @@ pub mod tests {

#[derive(Clone)]
struct TestSubject {
secret_manager: Arc<SecretManager>,
subject: Arc<Subject>,
credential: String,
access_token: String,
pre_authorized_code: String,
Expand All @@ -400,15 +400,15 @@ pub mod tests {
pub static ref PRE_AUTHORIZED_CODES: Mutex<VecDeque<String>> = Mutex::new(vec![].into());
pub static ref ACCESS_TOKENS: Mutex<VecDeque<String>> = Mutex::new(vec![].into());
pub static ref C_NONCES: Mutex<VecDeque<String>> = Mutex::new(vec![].into());
static ref SUBJECT_KEY_DID: Arc<SecretManager> = Arc::new(secret_manager());
pub static ref SUBJECT_KEY_DID: Arc<Subject> = Arc::new(subject());
pub static ref SUBJECT_IDENTIFIER_KEY_ID: String = SUBJECT_KEY_DID.identifier("did:key").unwrap();
}

fn subject() -> TestSubject {
fn test_subject() -> TestSubject {
let pre_authorized_code = PRE_AUTHORIZED_CODES.lock().unwrap()[0].clone();

TestSubject {
secret_manager: SUBJECT_KEY_DID.clone(),
subject: SUBJECT_KEY_DID.clone(),
credential: VERIFIABLE_CREDENTIAL_JWT.clone(),
pre_authorized_code: pre_authorized_code.clone(),
access_token: ACCESS_TOKENS.lock().unwrap()[0].clone(),
Expand Down Expand Up @@ -451,8 +451,8 @@ pub mod tests {
proof: Some(
KeyProofType::builder()
.proof_type(ProofType::Jwt)
.signer(subject.secret_manager.clone())
.iss(subject.secret_manager.identifier("did:key").unwrap())
.signer(subject.subject.clone())
.iss(subject.subject.identifier("did:key").unwrap())
.aud(CREDENTIAL_ISSUER_METADATA.credential_issuer.clone())
.iat(1571324800)
.exp(9999999999i64)
Expand All @@ -475,11 +475,11 @@ pub mod tests {
}
}

fn secret_manager() -> SecretManager {
fn subject() -> Subject {
futures::executor::block_on(async {
let mut services = SecretManagerServices::new(None);
services.init().await.unwrap();
services.secret_manager.unwrap()
services.subject.unwrap()
})
}
}
2 changes: 2 additions & 0 deletions agent_secret_manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ agent_shared = { path = "../agent_shared" }

anyhow = "1.0"
async-trait = "0.1"
base64 = { version = "0.22.0" }
cqrs-es = "0.4.2"
did_manager.workspace = true
futures.workspace = true
identity_iota = { version = "1.2" }
log = "0.4"
oid4vc-core.workspace = true
serde.workspace = true
Expand Down
9 changes: 5 additions & 4 deletions agent_secret_manager/src/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,20 @@ impl Aggregate for AgentSecretManager {
match command {
SecretManagerCommand::Initialize => {
let mut guard = services.lock().await;
assert!(guard.secret_manager.is_none());
assert!(guard.subject.is_none());
guard.init().await.unwrap();
assert!(guard.secret_manager.is_some());
assert!(guard.subject.is_some());

Ok(vec![SecretManagerEvent::Initialized {}])
}
SecretManagerCommand::EnableDidMethod { method } => {
let guard = services.lock().await;
assert!(guard.secret_manager.is_some());
assert!(guard.subject.is_some());
let result = guard
.secret_manager
.subject
.as_ref()
.unwrap()
.secret_manager
.produce_document(method.clone())
.await;

Expand Down
3 changes: 2 additions & 1 deletion agent_secret_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod aggregate;
pub mod commands;
pub mod events;
pub mod services;
pub mod subject;

// TODO: find better solution for this
pub async fn secret_manager() -> SecretManager {
Expand All @@ -14,7 +15,7 @@ pub async fn secret_manager() -> SecretManager {

match (snapshot_path, password, key_id) {
(Ok(snapshot_path), Ok(password), Ok(key_id)) => {
SecretManager::load(snapshot_path, password, key_id).await.unwrap()
SecretManager::load(snapshot_path, password, key_id, None, None).await.unwrap()
}
(Ok(snapshot_path), Ok(password), _) => SecretManager::generate(snapshot_path, password).await.unwrap(),
_ => panic!("Unable to load or generate `SecretManager`. Please make sure to set both `AGENT_SECRET_MANAGER_STRONGHOLD_PATH` and `AGENT_SECRET_MANAGER_STRONGHOLD_PASSWORD` environment variables."),
Expand Down
Loading

0 comments on commit fcd11b0

Please sign in to comment.