diff --git a/src/data_types/credential.rs b/src/data_types/credential.rs index feac9846..f99b03a5 100644 --- a/src/data_types/credential.rs +++ b/src/data_types/credential.rs @@ -129,7 +129,7 @@ impl RawCredentialValues { CredentialValuesEncoding::Auto => { let mut cred_values = MakeCredentialValues::default(); for (attribute, raw_value) in self.0.iter() { - cred_values.add_raw(attribute, &raw_value.to_string())?; + cred_values.add_raw(attribute, raw_value)?; } Ok(cred_values.into()) } diff --git a/src/data_types/w3c/credential.rs b/src/data_types/w3c/credential.rs index fa0acd93..28912c89 100644 --- a/src/data_types/w3c/credential.rs +++ b/src/data_types/w3c/credential.rs @@ -5,10 +5,9 @@ use std::collections::{HashMap, HashSet}; use std::string::ToString; use zeroize::Zeroize; -use crate::data_types::pres_request::{PredicateInfo, PredicateTypes}; use crate::data_types::w3c::constants::{ANONCREDS_CONTEXTS, ANONCREDS_CREDENTIAL_TYPES}; use crate::data_types::w3c::credential_proof::{CredentialProof, CredentialSignatureProof}; -use crate::data_types::w3c::presentation_proof::CredentialPresentationProof; +use crate::data_types::w3c::presentation_proof::{CredentialPresentationProof, PredicateAttribute}; use crate::data_types::{ cred_def::CredentialDefinitionId, credential::CredentialValuesEncoding, @@ -105,7 +104,7 @@ impl Validatable for CredentialAttributes { "CredentialAttributes validation failed: {} value format is not supported", attribute ) - .into()) + .into()); } } } @@ -129,29 +128,21 @@ impl From<&CredentialValues> for CredentialAttributes { } impl CredentialAttributes { - pub fn add_attribute(&mut self, attribute: String, value: Value) { + pub(crate) fn add_attribute(&mut self, attribute: String, value: Value) { self.0.insert(attribute, value); } - pub fn add_predicate(&mut self, attribute: String, value: PredicateAttribute) { + pub(crate) fn add_predicate(&mut self, attribute: String, value: PredicateAttribute) { self.0.insert(attribute, json!(value)); } - pub fn get_attribute(&self, attribute: &str) -> Result<&Value> { - self.0 - .get(attribute) - .ok_or_else(|| err_msg!("Credential attribute {} not found", attribute)) - } - - pub fn encode(&self, encoding: &CredentialValuesEncoding) -> Result { + pub(crate) fn encode(&self, encoding: &CredentialValuesEncoding) -> Result { match encoding { CredentialValuesEncoding::Auto => { let mut cred_values = MakeCredentialValues::default(); for (attribute, raw_value) in self.0.iter() { match raw_value { - Value::String(raw_value) => { - cred_values.add_raw(attribute, &raw_value.to_string())? - } + Value::String(raw_value) => cred_values.add_raw(attribute, raw_value)?, value => { return Err(err_msg!( "Encoding is not supported for credential value {:?}", @@ -170,36 +161,6 @@ impl CredentialAttributes { } } -#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] -pub struct PredicateAttribute { - #[serde(rename = "type")] - pub type_: PredicateAttributeType, - pub p_type: PredicateTypes, - pub p_value: i32, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum PredicateAttributeType { - #[serde(rename = "AnonCredsPredicate")] - AnonCredsPredicate, -} - -impl Default for PredicateAttributeType { - fn default() -> Self { - PredicateAttributeType::AnonCredsPredicate - } -} - -impl From for PredicateAttribute { - fn from(info: PredicateInfo) -> Self { - PredicateAttribute { - type_: PredicateAttributeType::AnonCredsPredicate, - p_type: info.p_type, - p_value: info.p_value, - } - } -} - #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct CredentialStatus { pub id: URI, @@ -298,35 +259,21 @@ impl W3CCredential { } pub fn get_credential_signature_proof(&self) -> Result<&CredentialSignatureProof> { - match &self.proof { - OneOrMany::One(ref proof) => proof.get_credential_signature_proof(), - OneOrMany::Many(ref proofs) => proofs - .iter() - .find_map(|proof| proof.get_credential_signature_proof().ok()) - .ok_or_else(|| err_msg!("credential does not contain AnonCredsSignatureProof")), - } + self.proof + .get_value(&|proof: &CredentialProof| proof.get_credential_signature_proof()) } pub(crate) fn get_mut_credential_signature_proof( &mut self, ) -> Result<&mut CredentialSignatureProof> { - match self.proof { - OneOrMany::One(ref mut proof) => proof.get_mut_credential_signature_proof(), - OneOrMany::Many(ref mut proofs) => proofs - .iter_mut() - .find_map(|proof| proof.get_mut_credential_signature_proof().ok()) - .ok_or_else(|| err_msg!("credential does not contain AnonCredsSignatureProof")), - } + self.proof.get_mut_value(&|proof: &mut CredentialProof| { + proof.get_mut_credential_signature_proof() + }) } pub fn get_presentation_proof(&self) -> Result<&CredentialPresentationProof> { - match &self.proof { - OneOrMany::One(ref proof) => proof.get_presentation_proof(), - OneOrMany::Many(ref proofs) => proofs - .iter() - .find_map(|proof| proof.get_presentation_proof().ok()) - .ok_or_else(|| err_msg!("credential does not contain PresentationProof")), - } + self.proof + .get_value(&|proof: &CredentialProof| proof.get_presentation_proof()) } pub fn validate(&self) -> Result<()> { diff --git a/src/data_types/w3c/one_or_many.rs b/src/data_types/w3c/one_or_many.rs index 106554cc..d72efb52 100644 --- a/src/data_types/w3c/one_or_many.rs +++ b/src/data_types/w3c/one_or_many.rs @@ -1,3 +1,5 @@ +use crate::error::Result; + /// Helper structure to handle the case when value is either single object or list of objects #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -11,3 +13,28 @@ impl Default for OneOrMany { OneOrMany::Many(Vec::new()) } } + +impl OneOrMany { + pub fn get_value(&self, closure: &dyn Fn(&T) -> Result<&F>) -> Result<&F> { + match &self { + OneOrMany::One(value) => closure(value), + OneOrMany::Many(values) => values + .iter() + .find_map(|value| closure(value).ok()) + .ok_or_else(|| err_msg!("Object does not contain required value")), + } + } + + pub(crate) fn get_mut_value( + &mut self, + closure: &dyn Fn(&mut T) -> Result<&mut F>, + ) -> Result<&mut F> { + match self { + OneOrMany::One(value) => closure(value), + OneOrMany::Many(values) => values + .iter_mut() + .find_map(|value| closure(value).ok()) + .ok_or_else(|| err_msg!("Object does not contain required value")), + } + } +} diff --git a/src/data_types/w3c/presentation_proof.rs b/src/data_types/w3c/presentation_proof.rs index 25c36ac2..4d6db809 100644 --- a/src/data_types/w3c/presentation_proof.rs +++ b/src/data_types/w3c/presentation_proof.rs @@ -1,3 +1,4 @@ +use crate::data_types::pres_request::{PredicateInfo, PredicateTypes}; use crate::utils::base64; use anoncreds_clsignatures::{AggregatedProof, SubProof}; use std::collections::HashSet; @@ -131,3 +132,33 @@ pub struct CredentialAttributesMapping { #[serde(default)] pub predicates: HashSet, } + +#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] +pub struct PredicateAttribute { + #[serde(rename = "type")] + pub type_: PredicateAttributeType, + pub p_type: PredicateTypes, + pub p_value: i32, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum PredicateAttributeType { + #[serde(rename = "AnonCredsPredicate")] + AnonCredsPredicate, +} + +impl Default for PredicateAttributeType { + fn default() -> Self { + PredicateAttributeType::AnonCredsPredicate + } +} + +impl From for PredicateAttribute { + fn from(info: PredicateInfo) -> Self { + PredicateAttribute { + type_: PredicateAttributeType::AnonCredsPredicate, + p_type: info.p_type, + p_value: info.p_value, + } + } +} diff --git a/src/data_types/w3c/uri.rs b/src/data_types/w3c/uri.rs index d6a7dd75..1f770158 100644 --- a/src/data_types/w3c/uri.rs +++ b/src/data_types/w3c/uri.rs @@ -21,9 +21,9 @@ impl<'de> Deserialize<'de> for URI { let id: String = Deserialize::deserialize(v).map_err(de::Error::custom)?; - URI_IDENTIFIER.captures(&id).ok_or_else(|| { - de::Error::custom("CredentialWC3 `id` validation failed: not URI id is passed") - })?; + URI_IDENTIFIER + .captures(&id) + .ok_or_else(|| de::Error::custom("Invalid URI passed"))?; Ok(URI(id)) } diff --git a/src/ffi/credential.rs b/src/ffi/credential.rs index ff2c7081..820bb96d 100644 --- a/src/ffi/credential.rs +++ b/src/ffi/credential.rs @@ -6,7 +6,7 @@ use ffi_support::{rust_string_to_c, FfiStr}; use super::error::{catch_error, ErrorCode}; use super::object::{AnoncredsObject, ObjectHandle}; use super::util::FfiStrList; -use crate::conversion::{credential_from_w3c, credential_to_w3c}; +use crate::credential_conversion::{credential_from_w3c, credential_to_w3c}; use crate::data_types::credential::CredentialValuesEncoding; use crate::data_types::w3c::credential::CredentialAttributes; use crate::data_types::w3c::credential_proof::{CredentialProof, NonAnonCredsDataIntegrityProof}; @@ -299,6 +299,7 @@ pub extern "C" fn anoncreds_process_w3c_credential( /// /// # Params /// cred: object handle pointing to credential in legacy form to convert +/// cred_def: object handle pointing to the credential definition /// cred_p: reference that will contain converted credential (in W3C form) instance pointer /// /// # Returns @@ -353,8 +354,8 @@ pub extern "C" fn anoncreds_credential_from_w3c( /// Add Non-Anoncreds Data Integrity proof signature to W3C AnonCreds credential /// /// # Params -/// cred - object handle pointing to W3C AnonCreds credential -/// proof - data integrity proof as JSON string +/// cred: object handle pointing to W3C AnonCreds credential +/// proof: data integrity proof as JSON string /// cred_p: reference that will contain update credential /// /// # Returns @@ -388,8 +389,8 @@ pub extern "C" fn anoncreds_w3c_credential_add_non_anoncreds_integrity_proof( /// Set id to W3C AnonCreds credential /// /// # Params -/// cred - object handle pointing to W3C AnonCreds credential -/// id - id to add into credential +/// cred: object handle pointing to W3C AnonCreds credential +/// id: id to add into credential /// cred_p: reference that will contain update credential /// /// # Returns @@ -419,8 +420,8 @@ pub extern "C" fn anoncreds_w3c_set_credential_id( /// Set subject id to W3C AnonCreds credential /// /// # Params -/// cred - object handle pointing to W3C AnonCreds credential -/// id - subject id to add into credential +/// cred: object handle pointing to W3C AnonCreds credential +/// id: subject id to add into credential /// cred_p: reference that will contain update credential /// /// # Returns @@ -450,8 +451,8 @@ pub extern "C" fn anoncreds_credential_w3c_subject_id( /// Add context to W3C AnonCreds credential /// /// # Params -/// cred - object handle pointing to W3C AnonCreds credential -/// context - context to add into credential +/// cred: object handle pointing to W3C AnonCreds credential +/// context: context to add into credential /// cred_p: reference that will contain update credential /// /// # Returns @@ -483,8 +484,8 @@ pub extern "C" fn anoncreds_w3c_credential_add_context( /// Add type to W3C AnonCreds credential /// /// # Params -/// cred - object handle pointing to W3C AnonCreds credential -/// type - type to add into credential +/// cred: object handle pointing to W3C AnonCreds credential +/// type: type to add into credential /// cred_p: reference that will contain update credential /// /// # Returns @@ -511,6 +512,15 @@ pub extern "C" fn anoncreds_w3c_credential_add_type( }) } +/// Get value of requested credential attribute as string +/// +/// # Params +/// handle: object handle pointing to the credential (in W3 form) +/// name: name of attribute to retrieve +/// result_p: reference that will contain value of request credential attribute +/// +/// # Returns +/// Error code #[no_mangle] pub extern "C" fn anoncreds_w3c_credential_get_attribute( handle: ObjectHandle, diff --git a/src/macros.rs b/src/macros.rs index 04d9d9cb..4b460bb0 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,13 +1,3 @@ -#[cfg(test)] -macro_rules! assert_kind { - ($kind:ident, $var:expr) => { - match $var { - Err(e) => assert_eq!($crate::error::ErrorKind::$kind, e.kind()), - _ => assert!(false, "Result expected to be error"), - } - }; -} - #[cfg(debug_assertions)] macro_rules! secret { ($val:expr) => {{ diff --git a/src/services/conversion.rs b/src/services/credential_conversion.rs similarity index 96% rename from src/services/conversion.rs rename to src/services/credential_conversion.rs index e03e8048..80107e3c 100644 --- a/src/services/conversion.rs +++ b/src/services/credential_conversion.rs @@ -13,7 +13,7 @@ use crate::Error; /// # Example /// /// ```rust -/// use anoncreds::conversion; +/// use anoncreds::credential_conversion; /// use anoncreds::issuer; /// use anoncreds::prover; /// use anoncreds::types::MakeCredentialValues; @@ -82,7 +82,7 @@ use crate::Error; /// None, /// ).expect("Unable to process the credential"); /// -/// let _w3c_credential = conversion::credential_to_w3c(&credential, &cred_def) +/// let _w3c_credential = credential_conversion::credential_to_w3c(&credential, &cred_def) /// .expect("Unable to convert credential to w3c form"); /// /// ``` @@ -90,6 +90,12 @@ pub fn credential_to_w3c( credential: &Credential, cred_def: &CredentialDefinition, ) -> Result { + trace!( + "credential_to_w3c >>> credential: {:?}, cred_def: {:?}", + credential, + cred_def + ); + credential.validate()?; let credential = credential.try_clone()?; @@ -114,6 +120,11 @@ pub fn credential_to_w3c( w3c_credential.set_attributes(attributes); w3c_credential.add_proof(CredentialProof::AnonCredsSignatureProof(proof)); + trace!( + "w3c_process_credential <<< w3c_credential {:?}", + w3c_credential + ); + Ok(w3c_credential) } @@ -122,7 +133,7 @@ pub fn credential_to_w3c( /// # Example /// /// ```rust -/// use anoncreds::conversion; +/// use anoncreds::credential_conversion; /// use anoncreds::issuer; /// use anoncreds::prover; /// use anoncreds::types::{MakeCredentialAttributes, MakeCredentialValues}; @@ -192,11 +203,16 @@ pub fn credential_to_w3c( /// None, /// ).expect("Unable to process the credential"); /// -/// let _w3c_credential = conversion::credential_from_w3c(&credential) +/// let _w3c_credential = credential_conversion::credential_from_w3c(&credential) /// .expect("Unable to convert credential to w3c form"); /// /// ``` pub fn credential_from_w3c(w3c_credential: &W3CCredential) -> Result { + trace!( + "credential_from_w3c >>> w3c_credential: {:?}", + w3c_credential + ); + w3c_credential.validate()?; let schema_id = w3c_credential.credential_schema.schema.clone(); @@ -220,6 +236,8 @@ pub fn credential_from_w3c(w3c_credential: &W3CCredential) -> Result, encoding: Option, ) -> Result { - trace!("w3c_create_credential >>> cred_def: {:?}, cred_def_private: {:?}, cred_offer.nonce: {:?}, cred_request: {:?},\ + trace!("create_w3c_credential >>> cred_def: {:?}, cred_def_private: {:?}, cred_offer.nonce: {:?}, cred_request: {:?},\ cred_values: {:?}, revocation_config: {:?}", cred_def, secret!(&cred_def_private), &cred_offer.nonce, &cred_request, secret!(&raw_credential_values), revocation_config, ); @@ -865,7 +865,7 @@ pub fn create_w3c_credential( credential.add_proof(CredentialProof::AnonCredsSignatureProof(proof)); trace!( - "w3c_create_credential <<< credential {:?}", + "create_w3c_credential <<< credential {:?}", secret!(&credential), ); diff --git a/src/services/mod.rs b/src/services/mod.rs index 160bd609..4bcf5f3a 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,4 +1,4 @@ -pub mod conversion; +pub mod credential_conversion; pub(crate) mod helpers; pub mod issuer; pub mod prover; diff --git a/src/services/prover.rs b/src/services/prover.rs index 3c9a0a57..a5e07cf8 100644 --- a/src/services/prover.rs +++ b/src/services/prover.rs @@ -17,7 +17,7 @@ use crate::data_types::presentation::RevealedAttributeInfo; use crate::data_types::presentation::SubProofReferent; use crate::data_types::rev_status_list::RevocationStatusList; use crate::data_types::schema::{Schema, SchemaId}; -use crate::data_types::w3c::credential::{CredentialSubject, PredicateAttribute, W3CCredential}; +use crate::data_types::w3c::credential::{CredentialSubject, W3CCredential}; use crate::data_types::w3c::one_or_many::OneOrMany; use crate::data_types::w3c::presentation::W3CPresentation; use crate::error::{Error, Result}; @@ -34,7 +34,7 @@ use crate::data_types::rev_reg_def::RevocationRegistryDefinitionId; use crate::data_types::w3c::credential_proof::{CredentialProof, CredentialSignature}; use crate::data_types::w3c::presentation_proof::{ CredentialAttributesMapping, CredentialPresentationProof, CredentialPresentationProofValue, - PresentationProof, PresentationProofValue, + PredicateAttribute, PresentationProof, PresentationProofValue, }; use anoncreds_clsignatures::{ CredentialSignature as CLCredentialSignature, NonCredentialSchema, Proof, ProofBuilder, @@ -358,7 +358,7 @@ pub fn process_w3c_credential( cred_def: &CredentialDefinition, rev_reg_def: Option<&RevocationRegistryDefinition>, ) -> Result<()> { - trace!("w3c_process_credential >>> credential: {:?}, cred_request_metadata: {:?}, link_secret: {:?}, cred_def: {:?}, rev_reg_def: {:?}", + trace!("process_w3c_credential >>> credential: {:?}, cred_request_metadata: {:?}, link_secret: {:?}, cred_def: {:?}, rev_reg_def: {:?}", w3c_credential, cred_request_metadata, secret!(&link_secret), cred_def, rev_reg_def); let cred_values = w3c_credential @@ -388,7 +388,7 @@ pub fn process_w3c_credential( ) .encode(); - trace!("w3c_process_credential <<< "); + trace!("process_w3c_credential <<< "); Ok(()) } @@ -558,7 +558,7 @@ pub fn create_presentation( schemas: &HashMap, cred_defs: &HashMap, ) -> Result { - trace!("create_proof >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, self_attested: {:?}, link_secret: {:?}, schemas: {:?}, cred_defs: {:?}", + trace!("create_presentation >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, self_attested: {:?}, link_secret: {:?}, schemas: {:?}, cred_defs: {:?}", credentials, pres_req, credentials, &self_attested, secret!(&link_secret), schemas, cred_defs); if credentials.is_empty() && self_attested.as_ref().map_or(true, HashMap::is_empty) { @@ -628,7 +628,10 @@ pub fn create_presentation( identifiers, }; - trace!("create_proof <<< full_proof: {:?}", secret!(&full_proof)); + trace!( + "create_presentation <<< full_proof: {:?}", + secret!(&full_proof) + ); Ok(full_proof) } @@ -641,7 +644,7 @@ pub fn create_w3c_presentation( schemas: &HashMap, cred_defs: &HashMap, ) -> Result { - trace!("create_proof >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, link_secret: {:?}, schemas: {:?}, cred_defs: {:?}", + trace!("create_w3c_presentation >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, link_secret: {:?}, schemas: {:?}, cred_defs: {:?}", credentials, pres_req, credentials, secret!(&link_secret), schemas, cred_defs); if credentials.is_empty() { @@ -704,7 +707,7 @@ pub fn create_w3c_presentation( } trace!( - "create_proof <<< presentation: {:?}", + "create_w3c_presentation <<< presentation: {:?}", secret!(&presentation) ); @@ -1074,7 +1077,7 @@ fn build_credential_subject<'p>( let predicate_info = pres_req_val .requested_predicates .get(referent) - .unwrap() + .ok_or_else(|| err_msg!("predicate {} not found request", referent))? .clone(); let (attribute, _) = credentials.cred.get_attribute(&predicate_info.name)?; let predicate = PredicateAttribute::from(predicate_info); @@ -1210,7 +1213,7 @@ impl<'a> CLProofBuilder<'a> { mod tests { use super::*; - use crate::data_types::pres_request::PredicateTypes; + // use crate::data_types::pres_request::PredicateTypes; macro_rules! hashmap { ($( $key: expr => $val: expr ),*) => { @@ -1224,18 +1227,6 @@ mod tests { } } - macro_rules! hashset { - ($( $val: expr ),*) => { - { - let mut set = ::std::collections::HashSet::new(); - $( - set.insert($val); - )* - set - } - } - } - mod get_credential_values_for_attribute { use super::*; diff --git a/src/services/verifier.rs b/src/services/verifier.rs index 659bed6a..e9052bde 100644 --- a/src/services/verifier.rs +++ b/src/services/verifier.rs @@ -141,7 +141,7 @@ pub fn verify_w3c_presentation( &HashMap>, >, ) -> Result { - trace!("verify >>> presentation: {:?}, pres_req: {:?}, schemas: {:?}, cred_defs: {:?}, rev_reg_defs: {:?} rev_status_lists: {:?}", + trace!("verify_w3c_presentation >>> presentation: {:?}, pres_req: {:?}, schemas: {:?}, cred_defs: {:?}, rev_reg_defs: {:?} rev_status_lists: {:?}", presentation, pres_req, schemas, cred_defs, rev_reg_defs, rev_status_lists); // These values are from the prover and cannot be trusted @@ -216,7 +216,7 @@ pub fn verify_w3c_presentation( let valid = proof_verifier.verify(&proof)?; - trace!("verify <<< valid: {:?}", valid); + trace!("verify_w3c_presentation <<< valid: {:?}", valid); Ok(valid) } diff --git a/tests/anoncreds_demos.rs b/tests/anoncreds_demos.rs index 4ac6599a..1cdae503 100644 --- a/tests/anoncreds_demos.rs +++ b/tests/anoncreds_demos.rs @@ -1,4 +1,4 @@ -use anoncreds::conversion::{credential_from_w3c, credential_to_w3c}; +use anoncreds::credential_conversion::{credential_from_w3c, credential_to_w3c}; use anoncreds::data_types::cred_def::CredentialDefinitionId; use anoncreds::data_types::rev_reg_def::RevocationRegistryDefinitionId; use anoncreds::data_types::schema::SchemaId; diff --git a/tests/utils/mock.rs b/tests/utils/mock.rs index 1cdba746..2cfa799b 100644 --- a/tests/utils/mock.rs +++ b/tests/utils/mock.rs @@ -5,7 +5,7 @@ use std::{ fs::create_dir, }; -use anoncreds::conversion::{credential_from_w3c, credential_to_w3c}; +use anoncreds::credential_conversion::{credential_from_w3c, credential_to_w3c}; use anoncreds::data_types::w3c::credential::W3CCredential; use anoncreds::data_types::w3c::presentation::W3CPresentation; use anoncreds::types::{