diff --git a/aries_vcx/src/common/proofs/verifier/verifier.rs b/aries_vcx/src/common/proofs/verifier/verifier.rs index 5e57a1b99f..0e372e4f5a 100644 --- a/aries_vcx/src/common/proofs/verifier/verifier.rs +++ b/aries_vcx/src/common/proofs/verifier/verifier.rs @@ -65,9 +65,7 @@ pub mod unit_tests { #[tokio::test] async fn test_proof_self_attested_proof_validation() { - SetupProfile::run_indy(|setup| async move { - let holder_setup = init_holder_setup_in_indy_context(&setup).await; - + SetupProfile::run(|setup| async move { let requested_attrs = json!([ json!({ "name":"address1", @@ -83,7 +81,7 @@ pub mod unit_tests { let revocation_details = r#"{"support_revocation":false}"#.to_string(); let name = "Optional".to_owned(); - let proof_req_json = ProofRequestData::create(&holder_setup.profile, &name) + let proof_req_json = ProofRequestData::create(&setup.profile, &name) .await .unwrap() .set_requested_attributes_as_string(requested_attrs) @@ -95,7 +93,7 @@ pub mod unit_tests { let proof_req_json = serde_json::to_string(&proof_req_json).unwrap(); - let anoncreds = Arc::clone(&holder_setup.profile).inject_anoncreds(); + let anoncreds = Arc::clone(&setup.profile).inject_anoncreds(); let prover_proof_json = anoncreds .prover_create_proof( &proof_req_json, @@ -194,19 +192,18 @@ pub mod unit_tests { ) .await .unwrap(); - // TODO: should return a new AriesVcxErrorKind err instead of AriesVcxErrorKind::VdrToolsError assert_eq!( - validate_indy_proof(&setup.profile, &prover_proof_json, &proof_req_json) + validate_indy_proof(&holder_setup.profile, &prover_proof_json, &proof_req_json) .await .unwrap_err() .kind(), - AriesVcxErrorKind::VdrToolsError(405) - ); // AnoncredsProofRejected + AriesVcxErrorKind::ProofRejected + ); let mut proof_req_json: serde_json::Value = serde_json::from_str(&proof_req_json).unwrap(); proof_req_json["requested_attributes"]["attribute_0"]["restrictions"] = json!({}); assert_eq!( - validate_indy_proof(&setup.profile, &prover_proof_json, &proof_req_json.to_string()) + validate_indy_proof(&holder_setup.profile, &prover_proof_json, &proof_req_json.to_string()) .await .unwrap(), true @@ -285,7 +282,7 @@ pub mod unit_tests { .await .unwrap(); assert_eq!( - validate_indy_proof(&setup.profile, &prover_proof_json, &proof_req_json) + validate_indy_proof(&holder_setup.profile, &prover_proof_json, &proof_req_json) .await .unwrap(), true @@ -297,7 +294,7 @@ pub mod unit_tests { let prover_proof_json = serde_json::to_string(&proof_obj).unwrap(); assert_eq!( - validate_indy_proof(&setup.profile, &prover_proof_json, &proof_req_json) + validate_indy_proof(&holder_setup.profile, &prover_proof_json, &proof_req_json) .await .unwrap_err() .kind(), @@ -310,7 +307,7 @@ pub mod unit_tests { let prover_proof_json = serde_json::to_string(&proof_obj).unwrap(); assert_eq!( - validate_indy_proof(&setup.profile, &prover_proof_json, &proof_req_json) + validate_indy_proof(&holder_setup.profile, &prover_proof_json, &proof_req_json) .await .unwrap_err() .kind(), @@ -338,7 +335,7 @@ pub mod integration_tests { let (schemas, cred_defs, proof_req, proof) = create_indy_proof(&setup.profile, &holder_setup.profile, &setup.institution_did).await; - let anoncreds = Arc::clone(&setup.profile).inject_anoncreds(); + let anoncreds = Arc::clone(&holder_setup.profile).inject_anoncreds(); let proof_validation = anoncreds .verifier_verify_proof(&proof_req, &proof, &schemas, &cred_defs, "{}", "{}") .await @@ -357,7 +354,7 @@ pub mod integration_tests { let (schemas, cred_defs, proof_req, proof) = create_proof_with_predicate(&setup.profile, &holder_setup.profile, &setup.institution_did, true).await; - let anoncreds = Arc::clone(&setup.profile).inject_anoncreds(); + let anoncreds = Arc::clone(&holder_setup.profile).inject_anoncreds(); let proof_validation = anoncreds .verifier_verify_proof(&proof_req, &proof, &schemas, &cred_defs, "{}", "{}") .await @@ -376,7 +373,7 @@ pub mod integration_tests { let (schemas, cred_defs, proof_req, proof) = create_proof_with_predicate(&setup.profile, &holder_setup.profile, &setup.institution_did, false).await; - let anoncreds = Arc::clone(&setup.profile).inject_anoncreds(); + let anoncreds = Arc::clone(&holder_setup.profile).inject_anoncreds(); anoncreds .verifier_verify_proof(&proof_req, &proof, &schemas, &cred_defs, "{}", "{}") .await diff --git a/aries_vcx/src/errors/error.rs b/aries_vcx/src/errors/error.rs index 2a5238670b..b9f548e023 100644 --- a/aries_vcx/src/errors/error.rs +++ b/aries_vcx/src/errors/error.rs @@ -70,6 +70,8 @@ pub enum AriesVcxErrorKind { InvalidProofCredentialData, #[error("Proof Request Passed into Libindy Call Was Invalid")] InvalidProofRequest, + #[error("The proof was rejected")] + ProofRejected, // Schema #[error("No Schema for that schema sequence number")] diff --git a/aries_vcx/src/errors/mapping_credx.rs b/aries_vcx/src/errors/mapping_credx.rs index c11d2d5ca1..05e1130041 100644 --- a/aries_vcx/src/errors/mapping_credx.rs +++ b/aries_vcx/src/errors/mapping_credx.rs @@ -3,14 +3,23 @@ use indy_credx::Error as CredxError; impl From for AriesVcxError { fn from(err: CredxError) -> Self { - match err.kind() { + // Credx will occasionally wrap the real error within the `cause` of an ErrorKind::Input error type + // So we use this cause error if the cause exists and can be downcast to an credxerror + let cause = if err.kind() == indy_credx::ErrorKind::Input { + err.cause.as_ref().and_then(|x| x.downcast_ref::()) + } else { + None + }; + let e = cause.unwrap_or(&err); + + match e.kind() { indy_credx::ErrorKind::Input => AriesVcxError::from_msg(AriesVcxErrorKind::InvalidInput, err), indy_credx::ErrorKind::IOError => AriesVcxError::from_msg(AriesVcxErrorKind::IOError, err), indy_credx::ErrorKind::InvalidState => AriesVcxError::from_msg(AriesVcxErrorKind::InvalidState, err), indy_credx::ErrorKind::Unexpected => AriesVcxError::from_msg(AriesVcxErrorKind::UnknownError, err), indy_credx::ErrorKind::CredentialRevoked => AriesVcxError::from_msg(AriesVcxErrorKind::InvalidState, err), indy_credx::ErrorKind::InvalidUserRevocId => AriesVcxError::from_msg(AriesVcxErrorKind::InvalidInput, err), - indy_credx::ErrorKind::ProofRejected => AriesVcxError::from_msg(AriesVcxErrorKind::InvalidState, err), + indy_credx::ErrorKind::ProofRejected => AriesVcxError::from_msg(AriesVcxErrorKind::ProofRejected, err), indy_credx::ErrorKind::RevocationRegistryFull => { AriesVcxError::from_msg(AriesVcxErrorKind::InvalidState, err) } diff --git a/aries_vcx/src/errors/mapping_vdrtools.rs b/aries_vcx/src/errors/mapping_vdrtools.rs index 160eb5d733..2e0dbda036 100644 --- a/aries_vcx/src/errors/mapping_vdrtools.rs +++ b/aries_vcx/src/errors/mapping_vdrtools.rs @@ -31,6 +31,7 @@ impl From for AriesVcxErrorKind { UnknownWalletStorageType => AriesVcxErrorKind::InvalidConfiguration, WalletStorageTypeAlreadyRegistered => AriesVcxErrorKind::InvalidConfiguration, WalletAccessFailed => AriesVcxErrorKind::WalletAccessFailed, + ProofRejected => AriesVcxErrorKind::ProofRejected, _ => { let err_code = types::ErrorCode::from(indy) as u32; AriesVcxErrorKind::VdrToolsError(err_code) diff --git a/aries_vcx/src/plugins/anoncreds/credx_anoncreds.rs b/aries_vcx/src/plugins/anoncreds/credx_anoncreds.rs index 4d0846f1b6..5d4afec1aa 100644 --- a/aries_vcx/src/plugins/anoncreds/credx_anoncreds.rs +++ b/aries_vcx/src/plugins/anoncreds/credx_anoncreds.rs @@ -18,8 +18,8 @@ use async_trait::async_trait; use credx::{ types::{ Credential as CredxCredential, CredentialDefinitionId, CredentialRequestMetadata, CredentialRevocationState, - DidValue, MasterSecret, PresentCredentials, PresentationRequest, RevocationRegistryDefinition, - RevocationRegistryDelta, Schema, SchemaId, + DidValue, MasterSecret, PresentCredentials, Presentation, PresentationRequest, RevocationRegistry, + RevocationRegistryDefinition, RevocationRegistryDelta, RevocationRegistryId, Schema, SchemaId, }, ursa::bn::BigNumber, }; @@ -154,7 +154,36 @@ impl BaseAnonCreds for IndyCredxAnonCreds { rev_reg_defs_json, rev_regs_json, ); - Err(unimplemented_method_err("credx verifier_verify_proof")) + + let presentation: Presentation = serde_json::from_str(proof_json)?; + let pres_req: PresentationRequest = serde_json::from_str(proof_req_json)?; + + let schemas: HashMap = serde_json::from_str(schemas_json)?; + let cred_defs: HashMap = + serde_json::from_str(credential_defs_json)?; + + let rev_reg_defs: Option> = + serde_json::from_str(rev_reg_defs_json)?; + + let rev_regs: Option>> = + serde_json::from_str(rev_regs_json)?; + let rev_regs: Option>> = + rev_regs.as_ref().map(|regs| { + let mut new_regs: HashMap> = HashMap::new(); + for (k, v) in regs { + new_regs.insert(k.clone(), hashmap_as_ref(v)); + } + new_regs + }); + + Ok(credx::verifier::verify_presentation( + &presentation, + &pres_req, + &hashmap_as_ref(&schemas), + &hashmap_as_ref(&cred_defs), + rev_reg_defs.as_ref().map(|regs| hashmap_as_ref(regs)).as_ref(), + rev_regs.as_ref(), + )?) } async fn issuer_create_and_store_revoc_reg( @@ -234,8 +263,8 @@ impl BaseAnonCreds for IndyCredxAnonCreds { None }; - let _schemas: HashMap = serde_json::from_str(schemas_json)?; - let _cred_defs: HashMap = + let schemas: HashMap = serde_json::from_str(schemas_json)?; + let cred_defs: HashMap = serde_json::from_str(credential_defs_json)?; let mut present_credentials: PresentCredentials = PresentCredentials::new(); @@ -334,25 +363,13 @@ impl BaseAnonCreds for IndyCredxAnonCreds { let link_secret = self.get_link_secret(link_secret_id).await?; - let mut schemas: HashMap = HashMap::new(); - - for (k, v) in _schemas.iter() { - schemas.insert(k.clone(), v); - } - - let mut cred_defs: HashMap = HashMap::new(); - - for (k, v) in _cred_defs.iter() { - cred_defs.insert(k.clone(), v); - } - let presentation = credx::prover::create_presentation( &pres_req, present_credentials, self_attested, &link_secret, - &schemas, - &cred_defs, + &hashmap_as_ref(&schemas), + &hashmap_as_ref(&cred_defs), )?; Ok(serde_json::to_string(&presentation)?) @@ -748,6 +765,21 @@ fn unimplemented_method_err(method_name: &str) -> AriesVcxError { ) } +// common transformation requirement in credx +fn hashmap_as_ref<'a, T, U>(map: &'a HashMap) -> HashMap +where + T: std::hash::Hash, + T: std::cmp::Eq, + T: std::clone::Clone, +{ + let mut new_map: HashMap = HashMap::new(); + for (k, v) in map.iter() { + new_map.insert(k.clone(), v); + } + + new_map +} + #[cfg(test)] #[cfg(feature = "general_test")] mod unit_tests { @@ -767,7 +799,6 @@ mod unit_tests { let profile = mock_profile(); let anoncreds: Box = Box::new(IndyCredxAnonCreds::new(profile)); - assert_unimplemented(anoncreds.verifier_verify_proof("", "", "", "", "", "").await); assert_unimplemented(anoncreds.issuer_create_and_store_revoc_reg("", "", "", 0, "").await); assert_unimplemented( anoncreds diff --git a/aries_vcx/src/utils/devsetup.rs b/aries_vcx/src/utils/devsetup.rs index 4d85d0a1c9..27f1d7b8c6 100644 --- a/aries_vcx/src/utils/devsetup.rs +++ b/aries_vcx/src/utils/devsetup.rs @@ -360,6 +360,8 @@ impl SetupProfile { } pub async fn init() -> SetupProfile { + init_test_logging(); + set_test_configs(); if SetupProfile::should_run_modular() { info!("SetupProfile >> using modular profile"); SetupProfile::init_modular().await @@ -372,8 +374,6 @@ impl SetupProfile { // FUTURE - ideally no tests should be using this method, they should be using the generic init // after modular profile Anoncreds/Ledger methods have all been implemented, all tests should use init() async fn init_indy() -> SetupProfile { - init_test_logging(); - set_test_configs(); let (institution_did, wallet_handle) = setup_issuer_wallet().await; settings::set_config_value( @@ -399,8 +399,6 @@ impl SetupProfile { } async fn init_modular() -> SetupProfile { - init_test_logging(); - set_test_configs(); let (institution_did, wallet_handle) = setup_issuer_wallet().await; let genesis_file_path = create_tmp_genesis_txn_file(); diff --git a/libvcx/src/errors/error.rs b/libvcx/src/errors/error.rs index 98abd1b67b..12de7ef869 100644 --- a/libvcx/src/errors/error.rs +++ b/libvcx/src/errors/error.rs @@ -93,6 +93,8 @@ pub enum LibvcxErrorKind { InvalidProofCredentialData, #[error("Proof Request Passed into Libindy Call Was Invalid")] InvalidProofRequest, + #[error("The proof was rejected")] + ProofRejected, // Schema #[error("Could not create schema")] diff --git a/libvcx/src/errors/mapping_from_ariesvcx.rs b/libvcx/src/errors/mapping_from_ariesvcx.rs index c7b3114936..f597e08e16 100644 --- a/libvcx/src/errors/mapping_from_ariesvcx.rs +++ b/libvcx/src/errors/mapping_from_ariesvcx.rs @@ -80,6 +80,7 @@ impl From for LibvcxErrorKind { AriesVcxErrorKind::NoAgentInformation => LibvcxErrorKind::NoAgentInformation, AriesVcxErrorKind::InvalidMessageFormat => LibvcxErrorKind::InvalidMessageFormat, AriesVcxErrorKind::LedgerItemNotFound => LibvcxErrorKind::LedgerItemNotFound, + AriesVcxErrorKind::ProofRejected => LibvcxErrorKind::ProofRejected, } } }