Skip to content

Commit

Permalink
Merge pull request #309 from DSRCorporation/fix/attributes
Browse files Browse the repository at this point in the history
W3C: Removed logic connected to stripping out id property of credential attributes
  • Loading branch information
andrewwhitehead committed Jan 24, 2024
2 parents 8c7a83a + d4f71d9 commit 7f91a67
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 70 deletions.
25 changes: 5 additions & 20 deletions src/data_types/w3c/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::string::ToString;

use crate::data_types::w3c::constants::ANONCREDS_CREDENTIAL_TYPES;
use crate::data_types::w3c::context::Contexts;
use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;
use crate::data_types::w3c::proof::{
CredentialPresentationProofValue, CredentialSignatureProofValue, DataIntegrityProof,
};
Expand Down Expand Up @@ -46,15 +46,6 @@ pub struct Types(pub HashSet<String>);

pub type IssuanceDate = DateTime<Utc>;

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CredentialSubject {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<URI>,
#[serde(flatten)]
pub attributes: CredentialAttributes,
}

pub type NonAnonCredsDataIntegrityProof = serde_json::Value;

#[allow(clippy::large_enum_variant)]
Expand All @@ -68,7 +59,7 @@ pub enum CredentialProof {
impl W3CCredential {
pub fn new(
issuer: IssuerId,
attributes: CredentialAttributes,
credential_subject: CredentialSubject,
proof: DataIntegrityProof,
version: Option<&VerifiableCredentialSpecVersion>,
) -> Self {
Expand All @@ -82,18 +73,15 @@ impl W3CCredential {
type_: ANONCREDS_CREDENTIAL_TYPES.clone(),
issuance_date,
issuer,
credential_subject: CredentialSubject {
id: None,
attributes,
},
credential_subject,
proof: OneOrMany::Many(vec![CredentialProof::DataIntegrityProof(proof)]),
valid_from: None,
id: None,
}
}

pub(crate) fn derive(
attributes: CredentialAttributes,
credential_subject: CredentialSubject,
proof: DataIntegrityProof,
credential: &W3CCredential,
) -> W3CCredential {
Expand All @@ -104,10 +92,7 @@ impl W3CCredential {
id: credential.id.clone(),
issuance_date: credential.issuance_date,
valid_from: credential.valid_from,
credential_subject: CredentialSubject {
id: None,
attributes,
},
credential_subject,
proof: OneOrMany::One(CredentialProof::DataIntegrityProof(proof)),
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/data_types/w3c/credential_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ use std::collections::HashMap;
use zeroize::Zeroize;

#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct CredentialAttributes(pub HashMap<String, CredentialAttributeValue>);
pub struct CredentialSubject(pub HashMap<String, CredentialAttributeValue>);

#[cfg(feature = "zeroize")]
impl Drop for CredentialAttributes {
impl Drop for CredentialSubject {
fn drop(&mut self) {
self.zeroize();
}
}

#[cfg(feature = "zeroize")]
impl Zeroize for CredentialAttributes {
impl Zeroize for CredentialSubject {
fn zeroize(&mut self) {
for attr in self.0.values_mut() {
if let CredentialAttributeValue::String(attr) = attr {
Expand All @@ -25,7 +25,7 @@ impl Zeroize for CredentialAttributes {
}
}

impl Validatable for CredentialAttributes {
impl Validatable for CredentialSubject {
fn validate(&self) -> std::result::Result<(), ValidationError> {
if self.0.is_empty() {
return Err(
Expand All @@ -36,9 +36,9 @@ impl Validatable for CredentialAttributes {
}
}

impl From<&CredentialValues> for CredentialAttributes {
impl From<&CredentialValues> for CredentialSubject {
fn from(values: &CredentialValues) -> Self {
CredentialAttributes(
CredentialSubject(
values
.0
.iter()
Expand All @@ -60,7 +60,7 @@ impl From<&CredentialValues> for CredentialAttributes {
}
}

impl CredentialAttributes {
impl CredentialSubject {
pub(crate) fn add_attribute(&mut self, attribute: String, value: CredentialAttributeValue) {
self.0.insert(attribute, value);
}
Expand Down
4 changes: 2 additions & 2 deletions src/ffi/w3c/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ffi::c_char;
use std::ptr;

use crate::data_types::w3c::credential::W3CCredential;
use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;
use crate::data_types::w3c::proof::CredentialProofDetails;
use crate::error::Result;
use crate::ffi::credential::{FfiCredRevInfo, _link_secret, _revocation_config};
Expand Down Expand Up @@ -247,7 +247,7 @@ impl_anoncreds_object!(CredentialProofDetails, "CredentialProofInfo");
pub(crate) fn _credential_attributes(
attr_names: FfiStrList,
attr_raw_values: FfiStrList,
) -> Result<CredentialAttributes> {
) -> Result<CredentialSubject> {
if attr_names.is_empty() {
return Err(err_msg!("Cannot create credential with no attribute"));
}
Expand Down
15 changes: 6 additions & 9 deletions src/services/w3c/credential_conversion.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::data_types::cred_def::CredentialDefinition;
use crate::data_types::w3c::credential::W3CCredential;
use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;
use crate::data_types::w3c::proof::{CredentialSignatureProofValue, DataIntegrityProof};
use crate::data_types::w3c::VerifiableCredentialSpecVersion;
use crate::types::Credential;
Expand Down Expand Up @@ -100,7 +100,7 @@ pub fn credential_to_w3c(

let credential = credential.try_clone()?;
let issuer = cred_def.issuer_id.clone();
let attributes = CredentialAttributes::from(&credential.values);
let attributes = CredentialSubject::from(&credential.values);
let signature = CredentialSignatureProofValue {
schema_id: credential.schema_id,
cred_def_id: credential.cred_def_id,
Expand Down Expand Up @@ -207,7 +207,7 @@ pub fn credential_from_w3c(w3c_credential: &W3CCredential) -> Result<Credential,
w3c_credential.validate()?;

let credential_signature = w3c_credential.get_credential_signature_proof()?;
let values = w3c_credential.credential_subject.attributes.encode()?;
let values = w3c_credential.credential_subject.encode()?;

let credential = Credential {
values,
Expand Down Expand Up @@ -314,7 +314,7 @@ pub(crate) mod tests {
pub fn w3c_credential() -> W3CCredential {
W3CCredential::new(
issuer_id(),
CredentialAttributes::try_from(&cred_values()).unwrap(),
CredentialSubject::try_from(&cred_values()).unwrap(),
DataIntegrityProof::new_credential_proof(&credential_signature_proof()).unwrap(),
None,
)
Expand Down Expand Up @@ -346,11 +346,8 @@ pub(crate) mod tests {
assert_eq!(w3c_credential.context, expected_context.clone());
assert_eq!(w3c_credential.type_, ANONCREDS_CREDENTIAL_TYPES.clone());

let expected_attributes = CredentialAttributes::from(&legacy_credential.values);
assert_eq!(
w3c_credential.credential_subject.attributes,
expected_attributes
);
let expected_attributes = CredentialSubject::from(&legacy_credential.values);
assert_eq!(w3c_credential.credential_subject, expected_attributes);

let proof = w3c_credential
.get_credential_signature_proof()
Expand Down
1 change: 0 additions & 1 deletion src/services/w3c/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ impl W3CCredential {
) -> Result<(String, CredentialAttributeValue)> {
let requested_attribute = attr_common_view(requested_attribute);
self.credential_subject
.attributes
.0
.iter()
.find(|(attribute, _)| attr_common_view(attribute) == requested_attribute)
Expand Down
4 changes: 2 additions & 2 deletions src/services/w3c/issuer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::data_types::cred_def::CredentialDefinition;
use crate::data_types::w3c::credential::W3CCredential;
use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;
use crate::data_types::w3c::proof::{CredentialSignatureProofValue, DataIntegrityProof};
use crate::data_types::w3c::VerifiableCredentialSpecVersion;
use crate::error::Result;
Expand Down Expand Up @@ -86,7 +86,7 @@ pub fn create_credential(
cred_def_private: &CredentialDefinitionPrivate,
cred_offer: &CredentialOffer,
cred_request: &CredentialRequest,
raw_credential_values: CredentialAttributes,
raw_credential_values: CredentialSubject,
revocation_config: Option<CredentialRevocationConfig>,
version: Option<VerifiableCredentialSpecVersion>,
) -> Result<W3CCredential> {
Expand Down
11 changes: 5 additions & 6 deletions src/services/w3c/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::types::{
};
use crate::utils::validation::Validatable;

use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;
use crate::data_types::w3c::proof::{
CredentialPresentationProofValue, DataIntegrityProof, PresentationProofValue,
};
Expand Down Expand Up @@ -102,7 +102,7 @@ pub fn process_credential(
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.credential_subject.attributes.encode()?;
let cred_values = w3c_credential.credential_subject.encode()?;

let proof = w3c_credential.get_mut_data_integrity_proof()?;
let mut credential_signature = proof.get_credential_signature_proof()?;
Expand Down Expand Up @@ -161,8 +161,7 @@ pub fn create_presentation(
continue;
}
let credential = present.cred;
let credential_values: CredentialValues =
credential.credential_subject.attributes.encode()?;
let credential_values: CredentialValues = credential.credential_subject.encode()?;
let proof = credential.get_credential_signature_proof()?;

proof_builder.add_sub_proof(
Expand Down Expand Up @@ -220,8 +219,8 @@ pub fn create_presentation(
fn build_credential_attributes<'p>(
pres_req: &PresentationRequestPayload,
credentials: &PresentCredential<'p, W3CCredential>,
) -> Result<CredentialAttributes> {
let mut attributes = CredentialAttributes::default();
) -> Result<CredentialSubject> {
let mut attributes = CredentialSubject::default();

for (referent, reveal) in credentials.requested_attributes.iter() {
let requested_attribute = pres_req
Expand Down
6 changes: 3 additions & 3 deletions src/services/w3c/types.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::data_types::w3c::credential_attributes::CredentialAttributeValue;
use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;

#[derive(Debug, Default)]
pub struct MakeCredentialAttributes(pub(crate) CredentialAttributes);
pub struct MakeCredentialAttributes(pub(crate) CredentialSubject);

impl MakeCredentialAttributes {
pub fn add(&mut self, name: impl Into<String>, raw: impl Into<String>) {
Expand All @@ -12,7 +12,7 @@ impl MakeCredentialAttributes {
}
}

impl From<MakeCredentialAttributes> for CredentialAttributes {
impl From<MakeCredentialAttributes> for CredentialSubject {
fn from(m: MakeCredentialAttributes) -> Self {
m.0
}
Expand Down
12 changes: 5 additions & 7 deletions src/services/w3c/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn check_credential_restrictions(
};
let filter = gather_filter_info(&identifier, schemas, cred_defs)?;
let mut attr_value_map: HashMap<String, Option<String>> = HashMap::new();
for (attribute, value) in credential.credential_subject.attributes.0.iter() {
for (attribute, value) in credential.credential_subject.0.iter() {
if let CredentialAttributeValue::String(value) = value {
attr_value_map.insert(attribute.to_owned(), Some(value.to_string()));
}
Expand Down Expand Up @@ -378,7 +378,7 @@ pub(crate) mod tests {
use super::*;
use crate::data_types::nonce::Nonce;
use crate::data_types::pres_request::{AttributeInfo, PredicateTypes};
use crate::data_types::w3c::credential_attributes::CredentialAttributes;
use crate::data_types::w3c::credential_attributes::CredentialSubject;
use crate::data_types::w3c::proof::tests::{
credential_pres_proof_value, presentation_proof_value,
};
Expand All @@ -393,8 +393,8 @@ pub(crate) mod tests {
const PROOF_TIMESTAMP_TO: u64 = 50;
const PROOF_TIMESTAMP: u64 = 50;

fn credential_attributes() -> CredentialAttributes {
CredentialAttributes(HashMap::from([
fn credential_attributes() -> CredentialSubject {
CredentialSubject(HashMap::from([
(
"name".to_string(),
CredentialAttributeValue::String("Alice".to_string()),
Expand Down Expand Up @@ -779,9 +779,7 @@ pub(crate) mod tests {
mut presentation: W3CPresentation,
) {
// empty credential_subject means there is no revealed attributes - only unrevealed
presentation.verifiable_credential[0]
.credential_subject
.attributes = CredentialAttributes::default();
presentation.verifiable_credential[0].credential_subject = CredentialSubject::default();

check_request_data(
&_presentation_request_with_single_attribute(),
Expand Down
6 changes: 0 additions & 6 deletions tests/anoncreds_demos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2979,7 +2979,6 @@ fn anoncreds_demo_works_for_issue_legacy_credential_convert_into_w3c_and_present
&CredentialAttributeValue::String("Alex".to_string()),
presentation.verifiable_credential[0]
.credential_subject
.attributes
.0
.get("name")
.unwrap()
Expand All @@ -2989,7 +2988,6 @@ fn anoncreds_demo_works_for_issue_legacy_credential_convert_into_w3c_and_present
CredentialAttributeValue::Bool(true),
presentation.verifiable_credential[0]
.credential_subject
.attributes
.0
.get("age")
.cloned()
Expand Down Expand Up @@ -3298,7 +3296,6 @@ fn anoncreds_demo_works_for_issue_two_credentials_in_different_forms_and_present
&CredentialAttributeValue::String("Alex".to_string()),
presentation.verifiable_credential[0]
.credential_subject
.attributes
.0
.get("name")
.unwrap()
Expand All @@ -3308,7 +3305,6 @@ fn anoncreds_demo_works_for_issue_two_credentials_in_different_forms_and_present
&CredentialAttributeValue::String("male".to_string()),
presentation.verifiable_credential[0]
.credential_subject
.attributes
.0
.get("sex")
.unwrap()
Expand All @@ -3318,7 +3314,6 @@ fn anoncreds_demo_works_for_issue_two_credentials_in_different_forms_and_present
&CredentialAttributeValue::String("Developer".to_string()),
presentation.verifiable_credential[1]
.credential_subject
.attributes
.0
.get("role")
.unwrap()
Expand All @@ -3328,7 +3323,6 @@ fn anoncreds_demo_works_for_issue_two_credentials_in_different_forms_and_present
&CredentialAttributeValue::String("IT".to_string()),
presentation.verifiable_credential[1]
.credential_subject
.attributes
.0
.get("department")
.unwrap()
Expand Down
6 changes: 5 additions & 1 deletion tests/utils/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use super::storage::ProverWallet;
pub const GVT_SCHEMA_NAME: &str = "Government Schema";
pub const GVT_SCHEMA_ID: &str = "schema:government";
pub const GVT_SCHEMA_VERSION: &str = "1.0";
pub const GVT_SCHEMA_ATTRIBUTES: &[&str; 4] = &["name", "age", "sex", "height"];
pub const GVT_SCHEMA_ATTRIBUTES: &[&str; 5] = &["id", "name", "age", "sex", "height"];

pub const GVT_CRED_DEF_ID: &str = "creddef:government";
pub const GVT_CRED_DEF_TAG: &str = "govermenttag";
Expand Down Expand Up @@ -195,6 +195,9 @@ pub fn credential_values(name: &str) -> MakeCredentialValues {
match name {
GVT_CRED => {
let mut gvt_cred_values = MakeCredentialValues::default();
gvt_cred_values
.add_raw("id", "example_id")
.expect("Error encoding attribute");
gvt_cred_values
.add_raw("sex", "male")
.expect("Error encoding attribute");
Expand Down Expand Up @@ -230,6 +233,7 @@ pub fn raw_credential_values(name: &str) -> MakeCredentialAttributes {
match name {
GVT_CRED => {
let mut gvt_cred_values = MakeCredentialAttributes::default();
gvt_cred_values.add("id", "example_id");
gvt_cred_values.add("sex", "male");
gvt_cred_values.add("name", "Alex");
gvt_cred_values.add("height", "175");
Expand Down
Loading

0 comments on commit 7f91a67

Please sign in to comment.