Skip to content

Commit

Permalink
VCX: Strict Aries protocol
Browse files Browse the repository at this point in the history
Signed-off-by: artem.ivanov <[email protected]>
  • Loading branch information
Artemkaaas committed Jun 17, 2020
1 parent f5aca7b commit 43e3f20
Show file tree
Hide file tree
Showing 23 changed files with 349 additions and 122 deletions.
8 changes: 6 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,15 @@ Almost all of them are optional and depend on the way you use Vcx (with agency o
* `threadpool_size` - size of thread pool used for command execution (8 by default).
* `protocol_version` - message protocol to use for agent to agency and agent to agent communication.
* `protocol_type` - message protocol to use for agent to agency and agent to agent communication.
Can be one of:
* "1.0" - use bundled messages, auth/anon cryptography.
* "2.0" - use aries cross domain message format, pack/unpack functions.
* "3.0" - use aries cross domain message format, pack/unpack functions and aries communication protocols (is alternative to the combination of settings "protocol_version":"2.0" and "communication_method":"aries").
* "3.0" - use aries cross domain message format, pack/unpack functions and aries communication protocols
(is alternative to the combination of settings "protocol_version":"2.0" and "communication_method":"aries").
Functions return messages in the `proprietary` format.
* "4.0" - use aries cross domain message format, pack/unpack functions and aries communication protocols.
Functions return messages in the `aries` format.
* `author_agreement` - accept and use transaction author agreement data containing the following fields:
* `acceptanceMechanismType` - (string) mechanism how user has accepted the TAA
Expand Down
27 changes: 25 additions & 2 deletions vcx/libvcx/src/credential.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_json;
use ::{serde_json, settings};
use serde_json::Value;
use std::convert::TryInto;

Expand Down Expand Up @@ -439,7 +439,7 @@ fn create_credential_v3(source_id: &str, offer: &str) -> VcxResult<Option<Creden
serde_json::Value::Array(mut offer) => { // legacy offer format
offer.pop()
.ok_or(VcxError::from_msg(VcxErrorKind::InvalidJson, "Cannot get Credential Offer"))?
},
}
offer => offer //aries offer format
};

Expand All @@ -455,6 +455,16 @@ fn create_credential_v3(source_id: &str, offer: &str) -> VcxResult<Option<Creden
pub fn credential_create_with_offer(source_id: &str, offer: &str) -> VcxResult<u32> {
trace!("credential_create_with_offer >>> source_id: {}, offer: {}", source_id, secret!(&offer));

// strict aries protocol is set. Credential Offer must be in aries format
if settings::is_strict_aries_protocol_set() {
let cred_offer: CredentialOfferV3 = serde_json::from_str(offer)
.map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson,
format!("Strict `aries` protocol is enabled. Can not parse `aries` formatted Credential Offer: {}", err)))?;

let holder = Holder::create(cred_offer, source_id)?;
return HANDLE_MAP.add(Credentials::V3(holder));
}

let credential =
match create_credential_v3(source_id, &offer)? {
Some(credential) => credential,
Expand Down Expand Up @@ -519,6 +529,12 @@ pub fn get_credential(handle: u32) -> VcxResult<String> {
}
Credentials::V3(ref credential) => {
let (cred_id, credential) = credential.get_credential()?;

// strict aries protocol is set. Return aries formatted credential
if settings::is_strict_aries_protocol_set() {
return Ok(json!(credential).to_string());
}

let credential: CredentialMessage = credential.try_into()?;

let mut json = serde_json::Map::new();
Expand Down Expand Up @@ -676,6 +692,13 @@ pub fn get_credential_offer_messages(connection_handle: u32) -> VcxResult<String

if connection::is_v3_connection(connection_handle)? {
let credential_offers = Holder::get_credential_offer_messages(connection_handle)?;

// strict aries protocol is set. Return aries formatted Credential Offers
if settings::is_strict_aries_protocol_set() {
return Ok(json!(credential_offers).to_string());
}

// map credential offers into proprietary format
let msgs: Vec<Vec<::serde_json::Value>> = credential_offers
.into_iter()
.map(|credential_offer| credential_offer.try_into())
Expand Down
15 changes: 15 additions & 0 deletions vcx/libvcx/src/disclosed_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,16 @@ pub fn create_proof(source_id: &str, proof_req: &str) -> VcxResult<u32> {

debug!("creating disclosed proof with id: {}", source_id);

// strict aries protocol is set. Presentation Request must be in aries format
if settings::is_strict_aries_protocol_set() {
let presentation_request: PresentationRequest = serde_json::from_str(proof_req)
.map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson,
format!("Strict `aries` protocol is enabled. Can not parse `aries` formatted Presentation Request: {}", err)))?;

let proof = Prover::create(source_id, presentation_request)?;
return HANDLE_MAP.add(DisclosedProofs::V3(proof));
}

let proof =
match create_proof_v3(source_id, &proof_req)? {
Some(proof) => proof,
Expand Down Expand Up @@ -886,6 +896,11 @@ pub fn get_proof_request_messages(connection_handle: u32, match_name: Option<&st
if connection::is_v3_connection(connection_handle)? {
let presentation_requests = Prover::get_presentation_request_messages(connection_handle, match_name)?;

// strict aries protocol is set. return aries formatted Proof Request.
if settings::is_strict_aries_protocol_set() {
return Ok(json!(presentation_requests).to_string());
}

let msgs: Vec<ProofRequestMessage> = presentation_requests
.into_iter()
.map(|presentation_request| presentation_request.try_into())
Expand Down
10 changes: 5 additions & 5 deletions vcx/libvcx/src/issuer_credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,11 @@ pub fn issuer_credential_create(cred_def_handle: u32,
trace!("issuer_credential_create >>> cred_def_handle: {}, source_id: {}, issuer_did: {}, credential_name: {}, credential_data: {}, price: {}",
cred_def_handle, source_id, issuer_did, credential_name, secret!(&credential_data), price);

// // Initiate connection of new format -- redirect to v3 folder
// if settings::is_aries_protocol_set() {
// let issuer = v3::handlers::issuance::Issuer::create(cred_def_handle, &credential_data, &source_id)?;
// return ISSUER_CREDENTIAL_MAP.add(IssuerCredentials::V3(issuer));
// }
// Initiate connection of new format -- redirect to v3 folder
if settings::is_strict_aries_protocol_set() {
let issuer = Issuer::create(cred_def_handle, &credential_data, &source_id)?;
return ISSUER_CREDENTIAL_MAP.add(IssuerCredentials::V3(issuer));
}

let issuer_credential = IssuerCredential::create(cred_def_handle, source_id, issuer_did, credential_name, credential_data, price)?;

Expand Down
6 changes: 4 additions & 2 deletions vcx/libvcx/src/messages/agent_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ pub fn connect_register_provision(config: &str) -> VcxResult<String> {
let (agent_did, agent_vk) = match my_config.protocol_type {
settings::ProtocolTypes::V1 => onboarding_v1(&my_did, &my_vk, &my_config.agency_did)?,
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3=> onboarding_v2(&my_did, &my_vk, &my_config.agency_did)?,
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => onboarding_v2(&my_did, &my_vk, &my_config.agency_did)?,
};

let config = get_final_config(&my_did, &my_vk, &agent_did, &agent_vk, &wallet_name, &my_config)?;
Expand Down Expand Up @@ -408,7 +409,8 @@ pub fn update_agent_info(id: &str, value: &str) -> VcxResult<()> {
update_agent_info_v1(&to_did, com_method)
}
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => {
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => {
update_agent_info_v2(&to_did, com_method)
}
}
Expand Down
6 changes: 4 additions & 2 deletions vcx/libvcx/src/messages/create_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ impl CreateKeyBuilder {
match self.version {
settings::ProtocolTypes::V1 => AgencyMock::set_next_response(constants::CREATE_KEYS_RESPONSE.to_vec()),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => AgencyMock::set_next_response(constants::CREATE_KEYS_V2_RESPONSE.to_vec()),
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => AgencyMock::set_next_response(constants::CREATE_KEYS_V2_RESPONSE.to_vec()),
}
}

Expand All @@ -94,7 +95,8 @@ impl CreateKeyBuilder {
})
),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 =>
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 =>
A2AMessage::Version2(
A2AMessageV2::CreateKey(CreateKey {
msg_type: MessageTypes::MessageTypeV2(MessageTypes::build_v2(A2AMessageKinds::CreateKey)),
Expand Down
42 changes: 29 additions & 13 deletions vcx/libvcx/src/messages/get_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ impl GetMessagesBuilder {
self.pairwise_dids.clone()))
),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 =>
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 =>
A2AMessage::Version2(
A2AMessageV2::GetMessages(
GetMessages::build(A2AMessageKinds::GetMessagesByConnections,
Expand All @@ -194,7 +195,6 @@ impl GetMessagesBuilder {
self.status_codes.clone(),
self.pairwise_dids.clone()))
),

};

let agency_did = settings::get_config_value(settings::CONFIG_REMOTE_TO_SDK_DID)?;
Expand Down Expand Up @@ -247,7 +247,8 @@ impl GeneralMessage for GetMessagesBuilder {
self.pairwise_dids.clone()))
),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 =>
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 =>
A2AMessage::Version2(
A2AMessageV2::GetMessages(
GetMessages::build(A2AMessageKinds::GetMessages,
Expand Down Expand Up @@ -295,6 +296,18 @@ pub struct Message {
pub decrypted_payload: Option<String>,
}

#[macro_export]
macro_rules! convert_aries_message {
($message:ident, $target_type:ident, $kind:ident) => (
if settings::is_strict_aries_protocol_set() {
(PayloadKinds::$kind, json!(&$message).to_string())
} else {
let converted_message: $target_type = $message.try_into()?;
(PayloadKinds::$kind, json!(&converted_message).to_string())
}
)
}

impl Message {
pub fn payload<'a>(&'a self) -> VcxResult<Vec<u8>> {
match self.payload {
Expand Down Expand Up @@ -331,26 +344,29 @@ impl Message {
use v3::messages::a2a::A2AMessage;
use v3::utils::encryption_envelope::EncryptionEnvelope;
use ::issuer_credential::{CredentialOffer, CredentialMessage};
use ::messages::proofs::proof_message::ProofMessage;
use ::messages::payload::{PayloadTypes, PayloadV1, PayloadKinds};
use std::convert::TryInto;

let a2a_message = EncryptionEnvelope::open(self.payload()?)?;

let (kind, msg) = match a2a_message {
A2AMessage::PresentationRequest(presentation_request) => {
let proof_req: ProofRequestMessage = presentation_request.try_into()?;

(PayloadKinds::ProofRequest, json!(&proof_req).to_string())
convert_aries_message!(presentation_request, ProofRequestMessage, ProofRequest)
}
A2AMessage::CredentialOffer(offer) => {
let cred_offer: CredentialOffer = offer.try_into()?;

(PayloadKinds::CredOffer, json!(vec![cred_offer]).to_string())
if settings::is_strict_aries_protocol_set() {
(PayloadKinds::CredOffer, json!(&offer).to_string())
} else {
let cred_offer: CredentialOffer = offer.try_into()?;
(PayloadKinds::CredOffer, json!(vec![cred_offer]).to_string())
}
}
A2AMessage::Credential(credential) => {
let credential: CredentialMessage = credential.try_into()?;

(PayloadKinds::Cred, json!(&credential).to_string())
convert_aries_message!(credential, CredentialMessage, Cred)
}
A2AMessage::Presentation(presentation) => {
convert_aries_message!(presentation, ProofMessage, Proof)
}
msg => {
let msg = json!(&msg).to_string();
Expand Down Expand Up @@ -512,7 +528,7 @@ mod tests {
assert_eq!(all_messages.len(), 1);

let invalid_status_code = "abc".to_string();
let bad_req = download_agent_messages(Some(vec![invalid_status_code]), None);
let bad_req = download_agent_messages(Some(vec![invalid_status_code]), None);
assert!(bad_req.is_err());
}

Expand Down
21 changes: 14 additions & 7 deletions vcx/libvcx/src/messages/invite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ impl SendInviteBuilder {
match self.version {
settings::ProtocolTypes::V1 => AgencyMock::set_next_response(SEND_INVITE_RESPONSE.to_vec()),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => AgencyMock::set_next_response(SEND_INVITE_V2_RESPONSE.to_vec()),
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => AgencyMock::set_next_response(SEND_INVITE_V2_RESPONSE.to_vec()),
}
}

Expand All @@ -372,7 +373,8 @@ impl SendInviteBuilder {
// TODO: THINK better
settings::ProtocolTypes::V1 => 1,
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => 0
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => 0
};

match response.remove(index) {
Expand Down Expand Up @@ -473,7 +475,8 @@ impl AcceptInviteBuilder {
match self.version {
settings::ProtocolTypes::V1 => AgencyMock::set_next_response(ACCEPT_INVITE_RESPONSE.to_vec()),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => AgencyMock::set_next_response(ACCEPT_INVITE_V2_RESPONSE.to_vec()),
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => AgencyMock::set_next_response(ACCEPT_INVITE_V2_RESPONSE.to_vec()),
}
}

Expand Down Expand Up @@ -590,7 +593,8 @@ impl RedirectConnectionBuilder {
match self.version {
settings::ProtocolTypes::V1 => AgencyMock::set_next_response(ACCEPT_INVITE_RESPONSE.to_vec()),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => AgencyMock::set_next_response(ACCEPT_INVITE_V2_RESPONSE.to_vec()),
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => AgencyMock::set_next_response(ACCEPT_INVITE_V2_RESPONSE.to_vec()),
}
}

Expand Down Expand Up @@ -651,7 +655,8 @@ impl GeneralMessage for SendInviteBuilder {
A2AMessage::Version1(A2AMessageV1::MessageDetail(MessageDetail::ConnectionRequest(details)))]
}
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => {
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => {
let msg = ConnectionRequest {
msg_type: MessageTypes::build_v2(A2AMessageKinds::ConnectionRequest),
send_msg: true,
Expand Down Expand Up @@ -706,7 +711,8 @@ impl GeneralMessage for AcceptInviteBuilder {
A2AMessage::Version1(A2AMessageV1::MessageDetail(MessageDetail::ConnectionRequestAnswer(self.payload.clone())))]
}
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => {
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => {
let msg = ConnectionRequestAnswer {
msg_type: MessageTypes::build_v2(A2AMessageKinds::ConnectionRequestAnswer),
send_msg: true,
Expand Down Expand Up @@ -761,7 +767,8 @@ impl GeneralMessage for RedirectConnectionBuilder {
A2AMessage::Version1(A2AMessageV1::MessageDetail(MessageDetail::ConnectionRequestRedirect(self.payload.clone())))]
}
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => {
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => {
let msg = ConnectionRequestRedirect {
msg_type: MessageTypes::build_v2(A2AMessageKinds::ConnectionRequestRedirect),
send_msg: true,
Expand Down
3 changes: 2 additions & 1 deletion vcx/libvcx/src/messages/message_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ impl MessageTypes {
match settings::get_protocol_type() {
settings::ProtocolTypes::V1 => MessageTypes::MessageTypeV1(MessageTypes::build_v1(kind)),
settings::ProtocolTypes::V2 |
settings::ProtocolTypes::V3 => MessageTypes::MessageTypeV2(MessageTypes::build_v2(kind))
settings::ProtocolTypes::V3 |
settings::ProtocolTypes::V4 => MessageTypes::MessageTypeV2(MessageTypes::build_v2(kind))
}
}

Expand Down
Loading

0 comments on commit 43e3f20

Please sign in to comment.