Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DID Exchange Protocol #928

Merged
merged 2 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/mediator.pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

test-integration-mediator:
runs-on: ubuntu-22.04
services:
services:
mysql:
image: mysql:latest
env:
Expand All @@ -53,4 +53,9 @@ jobs:
- name: Setup database
run: DATABASE_URL=${MYSQL_URL} sqlx migrate run --source aries/agents/rust/mediator/mediation/migrations
- name: "Run mediator integration tests"
run: cargo run --bin mediator & sleep 5 && cargo test --verbose --package mediator -- --nocapture;
run: cargo run --bin mediator & sleep 5 && cargo test --verbose --package mediator -- --nocapture;
- name: "Collect docker logs on failure"
if: failure()
uses: ./.github/actions/upload-docker-logs
with:
name: "docker-services-${{ github.job }}"
15 changes: 15 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions aries/agents/rust/aries-vcx-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ aries_vcx_core = { path = "../../../../aries_vcx_core", features = [
"vdrtools_wallet",
] }
shared = { path = "../../../shared" }
did_resolver_registry = { path = "../../../../did_resolver_registry" }
did_resolver_sov = { path = "../../../../did_resolver_sov" }
did_peer = { path = "../../../../did_peer" }
did_key = { path = "../../../../did_key" }
public_key = { path = "../../../../public_key" }
async-trait = "0.1.64"
derive_builder = "0.12.0"
serde_json = "1.0.85"
Expand Down
17 changes: 16 additions & 1 deletion aries/agents/rust/aries-vcx-agent/src/agent/agent_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use crate::{
agent::agent_config::AgentConfig,
services::{
connection::ServiceConnections, credential_definition::ServiceCredentialDefinitions,
holder::ServiceCredentialsHolder, issuer::ServiceCredentialsIssuer, prover::ServiceProver,
did_exchange::ServiceDidExchange, holder::ServiceCredentialsHolder,
issuer::ServiceCredentialsIssuer, out_of_band::ServiceOutOfBand, prover::ServiceProver,
revocation_registry::ServiceRevocationRegistries, schema::ServiceSchemas,
verifier::ServiceVerifier,
},
Expand All @@ -31,6 +32,8 @@ pub struct Agent {
pub(super) issuer: Arc<ServiceCredentialsIssuer>,
pub(super) verifier: Arc<ServiceVerifier>,
pub(super) prover: Arc<ServiceProver>,
pub(super) out_of_band: Arc<ServiceOutOfBand>,
pub(super) did_exchange: Arc<ServiceDidExchange>,
}

impl Agent {
Expand Down Expand Up @@ -62,6 +65,14 @@ impl Agent {
self.connections.clone()
}

pub fn out_of_band(&self) -> Arc<ServiceOutOfBand> {
self.out_of_band.clone()
}

pub fn did_exchange(&self) -> Arc<ServiceDidExchange> {
self.did_exchange.clone()
}

pub fn schemas(&self) -> Arc<ServiceSchemas> {
self.schemas.clone()
}
Expand Down Expand Up @@ -89,4 +100,8 @@ impl Agent {
pub fn prover(&self) -> Arc<ServiceProver> {
self.prover.clone()
}

pub fn public_did(&self) -> &str {
self.did_exchange.public_did()
}
}
58 changes: 56 additions & 2 deletions aries/agents/rust/aries-vcx-agent/src/agent/init.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
use std::sync::Arc;

use aries_vcx::global::settings::DEFAULT_LINK_SECRET_ALIAS;
use aries_vcx::{
common::ledger::{
service_didsov::{DidSovServiceType, EndpointDidSov},
transactions::{add_new_did, write_endpoint},
},
global::settings::DEFAULT_LINK_SECRET_ALIAS,
};
use aries_vcx_core::{
self,
anoncreds::{base_anoncreds::BaseAnonCreds, credx_anoncreds::IndyCredxAnonCreds},
ledger::indy_vdr_ledger::DefaultIndyLedgerRead,
wallet::indy::{
wallet::{create_and_open_wallet, wallet_configure_issuer},
IndySdkWallet, WalletConfig,
},
};
use did_peer::resolver::PeerDidResolver;
use did_resolver_registry::ResolverRegistry;
use did_resolver_sov::resolution::DidSovResolver;

use crate::{
agent::{agent_config::AgentConfig, agent_struct::Agent},
error::AgentResult,
services::{
connection::{ServiceConnections, ServiceEndpoint},
credential_definition::ServiceCredentialDefinitions,
did_exchange::ServiceDidExchange,
holder::ServiceCredentialsHolder,
issuer::ServiceCredentialsIssuer,
out_of_band::ServiceOutOfBand,
prover::ServiceProver,
revocation_registry::ServiceRevocationRegistries,
schema::ServiceSchemas,
Expand Down Expand Up @@ -73,7 +85,7 @@ impl Agent {
};

let anoncreds = IndyCredxAnonCreds;
let (ledger_read, ledger_write) = build_ledger_components(vcx_pool_config).unwrap();
let (ledger_read, ledger_write) = build_ledger_components(vcx_pool_config.clone()).unwrap();

let ledger_read = Arc::new(ledger_read);
let ledger_write = Arc::new(ledger_write);
Expand All @@ -83,8 +95,48 @@ impl Agent {
.await
.unwrap();

// TODO: This setup should be easier
// The default issuer did can't be used - its verkey is not in base58 - TODO: double-check
let (public_did, _verkey) = add_new_did(
wallet.as_ref(),
ledger_write.as_ref(),
&config_issuer.institution_did,
None,
)
.await?;
let endpoint = EndpointDidSov::create()
.set_service_endpoint(init_config.service_endpoint.clone())
.set_types(Some(vec![DidSovServiceType::DidCommunication]));
write_endpoint(
wallet.as_ref(),
ledger_write.as_ref(),
&public_did,
&endpoint,
)
.await?;

let did_peer_resolver = PeerDidResolver::new();
let did_sov_resolver: DidSovResolver<Arc<DefaultIndyLedgerRead>, DefaultIndyLedgerRead> =
DidSovResolver::new(ledger_read.clone());
let did_resolver_registry = Arc::new(
ResolverRegistry::new()
.register_resolver("peer".into(), did_peer_resolver)
.register_resolver("sov".into(), did_sov_resolver),
);

let connections = Arc::new(ServiceConnections::new(
ledger_read.clone(),
wallet.clone(),
init_config.service_endpoint.clone(),
));
let did_exchange = Arc::new(ServiceDidExchange::new(
ledger_read.clone(),
wallet.clone(),
did_resolver_registry,
init_config.service_endpoint.clone(),
public_did,
));
let out_of_band = Arc::new(ServiceOutOfBand::new(
wallet.clone(),
init_config.service_endpoint,
));
Expand Down Expand Up @@ -137,6 +189,8 @@ impl Agent {
anoncreds,
wallet,
connections,
did_exchange,
out_of_band,
schemas,
cred_defs,
rev_regs,
Expand Down
55 changes: 54 additions & 1 deletion aries/agents/rust/aries-vcx-agent/src/error/convertors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use std::convert::From;

use aries_vcx::errors::error::{AriesVcxError, AriesVcxErrorKind};
use aries_vcx::{
did_doc::error::DidDocumentBuilderError,
did_doc_sov::error::DidDocumentSovError,
errors::error::{AriesVcxError, AriesVcxErrorKind},
protocols::did_exchange::state_machine::generic::GenericDidExchange,
};
use aries_vcx_core::errors::error::AriesVcxCoreError;

use crate::error::*;
Expand Down Expand Up @@ -33,3 +38,51 @@ impl From<AriesVcxCoreError> for AgentError {
AgentError { message, kind }
}
}

impl From<DidDocumentSovError> for AgentError {
fn from(err: DidDocumentSovError) -> Self {
let kind = AgentErrorKind::GenericAriesVcxError;
let message = format!("DidDocumentSovError; err: {:?}", err.to_string());
AgentError { message, kind }
}
}

impl From<DidDocumentBuilderError> for AgentError {
fn from(err: DidDocumentBuilderError) -> Self {
let kind = AgentErrorKind::GenericAriesVcxError;
let message = format!("DidDocumentBuilderError; err: {:?}", err.to_string());
AgentError { message, kind }
}
}

impl From<aries_vcx::did_parser::ParseError> for AgentError {
fn from(err: aries_vcx::did_parser::ParseError) -> Self {
let kind = AgentErrorKind::GenericAriesVcxError;
let message = format!("DidParseError; err: {:?}", err.to_string());
AgentError { message, kind }
}
}

impl From<public_key::PublicKeyError> for AgentError {
fn from(err: public_key::PublicKeyError) -> Self {
let kind = AgentErrorKind::GenericAriesVcxError;
let message = format!("PublicKeyError; err: {:?}", err.to_string());
AgentError { message, kind }
}
}

impl From<did_key::error::DidKeyError> for AgentError {
fn from(err: did_key::error::DidKeyError) -> Self {
let kind = AgentErrorKind::GenericAriesVcxError;
let message = format!("DidKeyError; err: {:?}", err.to_string());
AgentError { message, kind }
}
}

impl From<(GenericDidExchange, AriesVcxError)> for AgentError {
fn from(err: (GenericDidExchange, AriesVcxError)) -> Self {
let kind = AgentErrorKind::GenericAriesVcxError;
let message = format!("GenericDidExchange; err: {:?}", err.1.to_string());
AgentError { message, kind }
}
}
2 changes: 2 additions & 0 deletions aries/agents/rust/aries-vcx-agent/src/error/error_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ pub enum AgentErrorKind {
MediatedConnectionServiceUnavailable,
#[error("Failed to submit http request")]
PostMessageFailed,
#[error("Invalid state")]
InvalidState,
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub struct AgentError {

impl std::fmt::Display for AgentError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
f.write_str(&self.kind.to_string())
f.write_str(&format!("{}: {}", self.kind, self.message))
}
}

Expand Down
57 changes: 57 additions & 0 deletions aries/agents/rust/aries-vcx-agent/src/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use aries_vcx::{
did_doc_sov::{service::ServiceSov, DidDocumentSov},
messages::AriesMessage,
utils::{encryption_envelope::EncryptionEnvelope, from_did_doc_sov_to_legacy},
};
use aries_vcx_core::wallet::base_wallet::BaseWallet;
use serde_json::json;
use url::Url;

use crate::{AgentError, AgentErrorKind, AgentResult};

pub fn get_their_endpoint(did_document: &DidDocumentSov) -> AgentResult<Url> {
let service = did_document.service().first().ok_or(AgentError::from_msg(
AgentErrorKind::InvalidState,
"No service found",
))?;
// todo: will get cleaned up after service is de-generified
let url: String = match service {
ServiceSov::Legacy(d) => d.service_endpoint().to_string(),
ServiceSov::AIP1(d) => d.service_endpoint().to_string(),
ServiceSov::DIDCommV1(d) => d.service_endpoint().to_string(),
ServiceSov::DIDCommV2(d) => d.service_endpoint().to_string(),
};
Url::parse(&url).map_err(|err| {
AgentError::from_msg(
AgentErrorKind::InvalidState,
&format!("Failed to parse url found in did document due: {:?}", err),
)
})
}

pub async fn pairwise_encrypt(
our_did_doc: &DidDocumentSov,
their_did_doc: &DidDocumentSov,
wallet: &impl BaseWallet,
message: &AriesMessage,
) -> AgentResult<EncryptionEnvelope> {
let sender_verkey = our_did_doc
.resolved_key_agreement()
.next()
.ok_or_else(|| {
AgentError::from_msg(
AgentErrorKind::InvalidState,
"No key agreement method found in our did document",
)
})?
.public_key()?
.base58();
EncryptionEnvelope::create(
wallet,
json!(message).to_string().as_bytes(),
Some(&sender_verkey),
&from_did_doc_sov_to_legacy(their_did_doc.clone())?,
)
.await
.map_err(|err| err.into())
}
2 changes: 1 addition & 1 deletion aries/agents/rust/aries-vcx-agent/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
extern crate derive_builder;
extern crate serde;

extern crate serde_json;
#[macro_use]
extern crate log;
Expand All @@ -10,6 +9,7 @@ extern crate uuid;

mod agent;
mod error;
pub mod helper;
mod http;
mod services;
mod storage;
Expand Down
Loading
Loading