From 142af17d1aae7264a3b042df88adf0da34725f3b Mon Sep 17 00:00:00 2001 From: "artem.ivanov" Date: Tue, 21 Nov 2023 10:24:55 +0300 Subject: [PATCH] Use credential status property for exposing revocation registry id Signed-off-by: artem.ivanov --- src/data_types/w3c/credential.rs | 55 +++++++++++++++++++++--- src/data_types/w3c/credential_proof.rs | 23 ++++------ src/data_types/w3c/presentation_proof.rs | 30 ++++--------- src/ffi/credential.rs | 8 ++-- src/services/credential_conversion.rs | 26 +++++++---- src/services/issuer.rs | 8 +++- src/services/prover.rs | 7 +-- src/services/verifier.rs | 20 ++++----- src/utils/base64.rs | 2 +- src/utils/encoded_object.rs | 20 +++++++++ src/utils/mod.rs | 2 + tests/anoncreds_demos.rs | 16 +++---- tests/utils/mock.rs | 11 +++-- 13 files changed, 142 insertions(+), 86 deletions(-) create mode 100644 src/utils/encoded_object.rs diff --git a/src/data_types/w3c/credential.rs b/src/data_types/w3c/credential.rs index 24932765..40cac689 100644 --- a/src/data_types/w3c/credential.rs +++ b/src/data_types/w3c/credential.rs @@ -185,9 +185,31 @@ impl CredentialAttributes { #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct CredentialStatus { - pub id: URI, #[serde(rename = "type")] - pub type_: String, + pub type_: CredentialStatusType, + pub id: RevocationRegistryDefinitionId, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum CredentialStatusType { + #[serde(rename = "AnonCredsCredentialStatusList2023")] + AnonCredsCredentialStatusList2023, + Other(String), +} + +impl Default for CredentialStatusType { + fn default() -> Self { + CredentialStatusType::AnonCredsCredentialStatusList2023 + } +} + +impl CredentialStatus { + pub fn new(id: RevocationRegistryDefinitionId) -> CredentialStatus { + CredentialStatus { + type_: CredentialStatusType::AnonCredsCredentialStatusList2023, + id, + } + } } #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] @@ -197,8 +219,6 @@ pub struct CredentialSchema { pub type_: CredentialSchemaType, pub definition: CredentialDefinitionId, pub schema: SchemaId, - #[serde(skip_serializing_if = "Option::is_none")] - pub revocation_registry: Option, #[serde(default)] pub encoding: CredentialValuesEncoding, } @@ -207,14 +227,12 @@ impl CredentialSchema { pub fn new( schema: SchemaId, definition: CredentialDefinitionId, - revocation_registry: Option, encoding: CredentialValuesEncoding, ) -> CredentialSchema { CredentialSchema { type_: CredentialSchemaType::AnonCredsDefinition, definition, schema, - revocation_registry, encoding, } } @@ -255,6 +273,10 @@ impl W3CCredential { self.credential_schema = credential_schema } + pub fn set_credential_status(&mut self, credential_status: CredentialStatus) { + self.credential_status = Some(credential_status) + } + pub fn set_attributes(&mut self, attributes: CredentialAttributes) { self.credential_subject.attributes = attributes } @@ -321,4 +343,25 @@ impl W3CCredential { } Ok(()) } + + pub fn schema_id(&self) -> &SchemaId { + &self.credential_schema.schema + } + + pub fn cred_def_id(&self) -> &CredentialDefinitionId { + &self.credential_schema.definition + } + + pub fn get_rev_reg_id(&self) -> Option<&RevocationRegistryDefinitionId> { + if let Some(credential_status) = self.credential_status.as_ref() { + match credential_status.type_ { + CredentialStatusType::AnonCredsCredentialStatusList2023 => { + Some(&credential_status.id) + } + CredentialStatusType::Other(_) => None, + } + } else { + None + } + } } diff --git a/src/data_types/w3c/credential_proof.rs b/src/data_types/w3c/credential_proof.rs index 1d3bfbaa..67d07629 100644 --- a/src/data_types/w3c/credential_proof.rs +++ b/src/data_types/w3c/credential_proof.rs @@ -1,11 +1,12 @@ use crate::data_types::w3c::presentation_proof::CredentialPresentationProof; -use crate::utils::base64; +use crate::utils::encoded_object::EncodedObject; use anoncreds_clsignatures::{ CredentialSignature as CLCredentialSignature, RevocationRegistry, SignatureCorrectnessProof, Witness, }; use serde_json::Value; +#[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum CredentialProof { @@ -24,14 +25,14 @@ pub struct CredentialSignatureProof { impl CredentialSignatureProof { pub fn new(signature: CredentialSignature) -> Self { CredentialSignatureProof { - type_: CredentialSignatureType::CLSignature2023, + type_: CredentialSignatureType::AnonCredsProof2023, signature: signature.encode(), } } pub fn get_credential_signature(&self) -> crate::Result { match self.type_ { - CredentialSignatureType::CLSignature2023 => { + CredentialSignatureType::AnonCredsProof2023 => { CredentialSignature::decode(&self.signature) } } @@ -42,13 +43,13 @@ pub type NonAnonCredsDataIntegrityProof = Value; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum CredentialSignatureType { - #[serde(rename = "CLSignature2023")] - CLSignature2023, + #[serde(rename = "AnonCredsProof2023")] + AnonCredsProof2023, } impl Default for CredentialSignatureType { fn default() -> Self { - CredentialSignatureType::CLSignature2023 + CredentialSignatureType::AnonCredsProof2023 } } @@ -107,12 +108,6 @@ impl CredentialSignature { witness, } } - - pub fn encode(&self) -> String { - base64::encode_json(&self) - } - - pub fn decode(string: &str) -> crate::Result { - base64::decode_json(string) - } } + +impl EncodedObject for CredentialSignature {} diff --git a/src/data_types/w3c/presentation_proof.rs b/src/data_types/w3c/presentation_proof.rs index 4d6db809..6d4a8159 100644 --- a/src/data_types/w3c/presentation_proof.rs +++ b/src/data_types/w3c/presentation_proof.rs @@ -1,5 +1,5 @@ use crate::data_types::pres_request::{PredicateInfo, PredicateTypes}; -use crate::utils::base64; +use crate::utils::encoded_object::EncodedObject; use anoncreds_clsignatures::{AggregatedProof, SubProof}; use std::collections::HashSet; @@ -28,16 +28,10 @@ impl CredentialPresentationProofValue { pub fn new(sub_proof: SubProof) -> CredentialPresentationProofValue { CredentialPresentationProofValue { sub_proof } } - - pub fn encode(&self) -> String { - base64::encode_json(&self) - } - - pub fn decode(string: &str) -> crate::Result { - base64::decode_json(string) - } } +impl EncodedObject for CredentialPresentationProofValue {} + impl CredentialPresentationProof { pub fn new( proof_value: CredentialPresentationProofValue, @@ -99,16 +93,10 @@ impl PresentationProofValue { aggregated: aggregated_proof, } } - - pub fn encode(&self) -> String { - base64::encode_json(&self) - } - - pub fn decode(string: &str) -> crate::Result { - base64::decode_json(string) - } } +impl EncodedObject for PresentationProofValue {} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum PresentationProofType { #[serde(rename = "AnonCredsPresentationProof2023")] @@ -137,8 +125,8 @@ pub struct CredentialAttributesMapping { pub struct PredicateAttribute { #[serde(rename = "type")] pub type_: PredicateAttributeType, - pub p_type: PredicateTypes, - pub p_value: i32, + pub predicate: PredicateTypes, + pub value: i32, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -157,8 +145,8 @@ impl From for PredicateAttribute { fn from(info: PredicateInfo) -> Self { PredicateAttribute { type_: PredicateAttributeType::AnonCredsPredicate, - p_type: info.p_type, - p_value: info.p_value, + predicate: info.p_type, + value: info.p_value, } } } diff --git a/src/ffi/credential.rs b/src/ffi/credential.rs index 820bb96d..ab1d5919 100644 --- a/src/ffi/credential.rs +++ b/src/ffi/credential.rs @@ -532,12 +532,10 @@ pub extern "C" fn anoncreds_w3c_credential_get_attribute( let cred = handle.load()?; let cred = cred.cast_ref::()?; let val = match name.as_opt_str().unwrap_or_default() { - "schema_id" => rust_string_to_c(cred.credential_schema.schema.clone()), - "cred_def_id" => rust_string_to_c(cred.credential_schema.definition.to_string()), + "schema_id" => rust_string_to_c(cred.schema_id().clone()), + "cred_def_id" => rust_string_to_c(cred.cred_def_id().to_string()), "rev_reg_id" => cred - .credential_schema - .revocation_registry - .as_ref() + .get_rev_reg_id() .map_or(ptr::null_mut(), |s| rust_string_to_c(s.to_string())), "rev_reg_index" => cred .get_credential_signature_proof()? diff --git a/src/services/credential_conversion.rs b/src/services/credential_conversion.rs index 80107e3c..e8bc00d4 100644 --- a/src/services/credential_conversion.rs +++ b/src/services/credential_conversion.rs @@ -1,6 +1,8 @@ use crate::data_types::cred_def::CredentialDefinition; use crate::data_types::credential::CredentialValuesEncoding; -use crate::data_types::w3c::credential::{CredentialAttributes, CredentialSchema, W3CCredential}; +use crate::data_types::w3c::credential::{ + CredentialAttributes, CredentialSchema, CredentialStatus, W3CCredential, +}; use crate::data_types::w3c::credential_proof::{ CredentialProof, CredentialSignature, CredentialSignatureProof, }; @@ -114,9 +116,11 @@ pub fn credential_to_w3c( w3c_credential.set_credential_schema(CredentialSchema::new( credential.schema_id, credential.cred_def_id, - credential.rev_reg_id, CredentialValuesEncoding::Auto, )); + if let Some(rev_reg_id) = credential.rev_reg_id { + w3c_credential.set_credential_status(CredentialStatus::new(rev_reg_id)) + } w3c_credential.set_attributes(attributes); w3c_credential.add_proof(CredentialProof::AnonCredsSignatureProof(proof)); @@ -215,9 +219,9 @@ pub fn credential_from_w3c(w3c_credential: &W3CCredential) -> Result = credential_proof.mapping.revealed_attributes.clone(); @@ -825,13 +822,12 @@ fn collect_received_attrs_and_predicates_from_w3c_presentation( for verifiable_credential in proof.verifiable_credential.iter() { let presentation_proof = verifiable_credential.get_presentation_proof()?; + let rev_reg_id = verifiable_credential.get_rev_reg_id().cloned(); + let identifier: Identifier = Identifier { - schema_id: verifiable_credential.credential_schema.schema.clone(), - cred_def_id: verifiable_credential.credential_schema.definition.clone(), - rev_reg_id: verifiable_credential - .credential_schema - .revocation_registry - .clone(), + schema_id: verifiable_credential.schema_id().clone(), + cred_def_id: verifiable_credential.cred_def_id().clone(), + rev_reg_id, timestamp: None, }; for revealed_attribute in &presentation_proof.mapping.revealed_attributes { diff --git a/src/utils/base64.rs b/src/utils/base64.rs index a5c3b8c2..3ebc3b13 100644 --- a/src/utils/base64.rs +++ b/src/utils/base64.rs @@ -11,7 +11,7 @@ pub fn encode>(val: T) -> String { pub fn encode_json(val: T) -> String { let json = json!(val).to_string(); - encode(&json) + encode(json) } pub fn decode>(val: T) -> Result, Error> { diff --git a/src/utils/encoded_object.rs b/src/utils/encoded_object.rs new file mode 100644 index 00000000..26b5ea9f --- /dev/null +++ b/src/utils/encoded_object.rs @@ -0,0 +1,20 @@ +use crate::utils::base64; +use crate::Result; +use serde::de::DeserializeOwned; +use serde::Serialize; + +pub trait EncodedObject { + fn encode(&self) -> String + where + Self: Serialize, + { + base64::encode_json(self) + } + + fn decode(string: &str) -> Result + where + Self: DeserializeOwned, + { + base64::decode_json(string) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index a9bbe7af..d9be1bda 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -5,6 +5,8 @@ pub mod base58; pub mod base64; +pub mod encoded_object; + pub mod hash; pub mod query; diff --git a/tests/anoncreds_demos.rs b/tests/anoncreds_demos.rs index 5a7da097..5b833bc3 100644 --- a/tests/anoncreds_demos.rs +++ b/tests/anoncreds_demos.rs @@ -2952,8 +2952,8 @@ fn anoncreds_demo_works_for_issue_legacy_credential_convert_into_w3c_and_present assert_eq!( CredentialAttributeValue::Predicate(vec![PredicateAttribute { type_: PredicateAttributeType::AnonCredsPredicate, - p_type: PredicateTypes::GE, - p_value: 18, + predicate: PredicateTypes::GE, + value: 18, }]), presentation.verifiable_credential[0] .credential_subject @@ -3096,8 +3096,8 @@ fn anoncreds_demo_works_for_issue_w3c_credential_and_present_w3c_presentation() assert_eq!( CredentialAttributeValue::Predicate(vec![PredicateAttribute { type_: PredicateAttributeType::AnonCredsPredicate, - p_type: PredicateTypes::GE, - p_value: 18, + predicate: PredicateTypes::GE, + value: 18, }]), presentation.verifiable_credential[0] .credential_subject @@ -3636,8 +3636,8 @@ fn anoncreds_demo_works_for_issue_w3c_credential_add_identity_proof_present_w3c_ assert_eq!( CredentialAttributeValue::Predicate(vec![PredicateAttribute { type_: PredicateAttributeType::AnonCredsPredicate, - p_type: PredicateTypes::GE, - p_value: 18, + predicate: PredicateTypes::GE, + value: 18, }]), presentation.verifiable_credential[0] .credential_subject @@ -3812,8 +3812,8 @@ fn anoncreds_demo_works_for_issue_w3c_credential_and_present_w3c_presentation_fo assert_eq!( CredentialAttributeValue::Predicate(vec![PredicateAttribute { type_: PredicateAttributeType::AnonCredsPredicate, - p_type: PredicateTypes::GE, - p_value: 18, + predicate: PredicateTypes::GE, + value: 18, }]), presentation.verifiable_credential[0] .credential_subject diff --git a/tests/utils/mock.rs b/tests/utils/mock.rs index 2cfa799b..98503bab 100644 --- a/tests/utils/mock.rs +++ b/tests/utils/mock.rs @@ -625,12 +625,11 @@ impl<'a> Mock<'a> { .get(cred.credential_schema.definition.to_string().as_str()) .unwrap(); { - let (rev_state, timestamp) = - if let Some(id) = &cred.credential_schema.revocation_registry { - self.prover_wallets[prover_id].rev_states.get(id).unwrap() - } else { - &(None, None) - }; + let (rev_state, timestamp) = if let Some(id) = cred.get_rev_reg_id() { + self.prover_wallets[prover_id].rev_states.get(id).unwrap() + } else { + &(None, None) + }; let mut cred1 = present.add_credential(&cred, *timestamp, rev_state.as_ref()); for a in &values.0 {