Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked w3c credentials and presentations to use DataIntegrityProof instead of custom AnonCreds context #291

Merged
merged 24 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3018ce6
Code clean up
Artemkaaas Nov 16, 2023
7f94ee1
Drop explicit mapping
Artemkaaas Nov 15, 2023
fff5700
Fixed merge errors
Artemkaaas Nov 16, 2023
f37fe19
feat: Cover w3/verifier service with unit tests
Abdulbois Nov 29, 2023
c1f4098
Refactored verifier tests
Artemkaaas Nov 30, 2023
61229fc
Refactor and add unit tests into w3c/verifier service
Abdulbois Nov 30, 2023
aa1c030
Corrected tests for interval override
Artemkaaas Nov 30, 2023
3b899c3
Corrected demo test for missing attribute
Artemkaaas Dec 1, 2023
ee628db
Code refactoring
Artemkaaas Dec 2, 2023
895fb3f
Added check of encoded attributes
Artemkaaas Dec 4, 2023
2cb5373
Fixed rebase errors
Artemkaaas Dec 8, 2023
677df35
Reworked w3c credentials and presentations to match new design
Artemkaaas Dec 19, 2023
00e98cb
Added helper method to get anoncred integrity proof details
Artemkaaas Dec 20, 2023
08a26ec
Clean up proof structure
Artemkaaas Dec 20, 2023
a2a178e
Corrected cross installation to use its lock file
Artemkaaas Dec 20, 2023
fbde450
Corrected context definition
Artemkaaas Dec 20, 2023
2e76692
Code refactoring
Artemkaaas Dec 21, 2023
a97b32f
Corrected proof value encoding
Artemkaaas Dec 21, 2023
90554f0
Process review comments
Artemkaaas Dec 21, 2023
da90f11
Removed empty file
Artemkaaas Dec 21, 2023
9efd971
Added proofPurpose and verificationMethod to proof
Artemkaaas Dec 22, 2023
8395ad0
Added proofPurpose and verificationMethod to proof
Artemkaaas Dec 22, 2023
2696d43
Not set credentialSubject `id` when derive credential
Artemkaaas Dec 22, 2023
4ae0d15
Merge remote-tracking branch 'origin/main' into anoncreds-w3c-format-…
Artemkaaas Jan 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ vendored = ["anoncreds-clsignatures/openssl_vendored"]
w3c = ["base64", "chrono"]

[dependencies]
anoncreds-clsignatures = "0.2.4"
anoncreds-clsignatures = "0.3.0"
bs58 = "0.4.0"
env_logger = { version = "0.9.3", optional = true }
ffi-support = { version = "0.4.0", optional = true }
Expand Down
109 changes: 16 additions & 93 deletions docs/design/w3c/w3c-representation.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,18 @@ Methods purpose - have to forms of credentials (probably even duplicate in walle
/// Convert credential in legacy form into W3C AnonCreds credential form
///
/// # 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
/// cred: object handle pointing to credential in legacy form to convert
/// cred_def: object handle pointing to the credential definition
/// w3c_version: version of w3c verifiable credential specification (1.1 or 2.0) to use
/// cred_p: reference that will contain converted credential (in W3C form) instance pointer
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_credential_to_w3c(
cred: ObjectHandle,
cred_def: ObjectHandle,
w3c_version: FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

Expand All @@ -75,90 +77,6 @@ pub extern "C" fn anoncreds_credential_from_w3c(
) -> ErrorCode {}
```

#### Credential object helper methods

```rust
/// 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_p: reference that will contain update credential
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_w3c_credential_add_non_anoncreds_integrity_proof(
cred: ObjectHandle,
proof: FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

/// Add context to W3C AnonCreds credential
///
/// # Params
/// cred - object handle pointing to W3C AnonCreds credential
/// context - context to add into credential
/// cred_p: reference that will contain update credential
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_w3c_credential_add_context(
cred: ObjectHandle,
context: FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

/// Add type to W3C AnonCreds credential
///
/// # Params
/// cred - object handle pointing to W3C AnonCreds credential
/// type - type to add into credential
/// cred_p: reference that will contain update credential
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_w3c_credential_add_type(
cred: ObjectHandle,
type_: FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

/// Set subject id to W3C AnonCreds credential
///
/// # Params
/// cred - object handle pointing to W3C AnonCreds credential
/// id - subject id to add into credential
/// cred_p: reference that will contain update credential
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_w3c_credential_set_subject_id(
cred: ObjectHandle,
id: FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

/// Set id to W3C AnonCreds credential
///
/// # Params
/// cred - object handle pointing to W3C AnonCreds credential
/// id - id to add into credential
/// cred_p: reference that will contain update credential
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_w3c_credential_set_id(
cred: ObjectHandle,
id: FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}
```

#### Flow methods duplication

The idea for this approach to duplicate all issuance/presentation related methods for w3c standard.
Expand Down Expand Up @@ -242,6 +160,7 @@ pub extern "C" fn anoncreds_create_w3c_credential_request(
/// attr_names: list of attribute names
/// attr_raw_values: list of attribute raw values
/// revocation: object handle pointing to the credential revocation info
/// w3c_version: version of w3c verifiable credential specification (1.1 or 2.0) to use
/// cred_p: reference that will contain credential (in W3C form) instance pointer
///
/// # Returns
Expand All @@ -255,6 +174,7 @@ pub extern "C" fn anoncreds_create_w3c_credential(
attr_names: FfiStrList,
attr_raw_values: FfiStrList,
revocation: *const FfiCredRevInfo,
w3c_version: *const FfiStr,
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

Expand All @@ -280,20 +200,21 @@ pub extern "C" fn anoncreds_process_w3c_credential(
cred_p: *mut ObjectHandle,
) -> ErrorCode {}

/// Get value of requested credential attribute as string
/// Get credential signature information required for proof building and verification
/// This information is aggregated from `anoncredsvc-2023` and `anoncredspresvc-2023` proofs.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swcurran my suggestion would still be to add some more dashes, and make pres -> proof. Proof is what also seems to have been used in bbs suite.

So anoncreds-vc-2023 and anoncreds-vc-proof-2023. Or maybe something like ac-vc-23 and ac-vc-proof-23 (or cl-vc-23)

/// It's needed for Holder and Verifier for public entities resolving
/// {`schema_id`, `cred_def_id`, `rev_reg_id`, `rev_reg_index`, `timestamp`}
///
/// # 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
/// cred_proof_info_p: reference that will contain credential information
///
/// # Returns
/// Error code
#[no_mangle]
pub extern "C" fn anoncreds_w3c_credential_get_attribute(
pub extern "C" fn anoncreds_w3c_credential_get_integrity_proof_details(
handle: ObjectHandle,
name: FfiStr,
result_p: *mut *const c_char,
cred_proof_info_p: *mut ObjectHandle,
) -> ErrorCode {}

/// Create W3C Presentation according to the specification.
Expand All @@ -307,6 +228,7 @@ pub extern "C" fn anoncreds_w3c_credential_get_attribute(
/// schema_ids: list of schemas ids
/// cred_defs: list of credential definitions
/// cred_def_ids: list of credential definitions ids
/// w3c_version: version of w3c verifiable presentation specification (1.1 or 2.0) to use
/// presentation_p: reference that will contain created presentation (in W3C form) instance pointer.
///
/// # Returns
Expand All @@ -322,6 +244,7 @@ pub extern "C" fn anoncreds_create_w3c_presentation(
cred_defs: FfiList<ObjectHandle>,
cred_def_ids: FfiStrList,
presentation_p: *mut ObjectHandle,
w3c_version: FfiStr,
) -> ErrorCode {}

/// Verity W3C styled Presentation
Expand Down
83 changes: 6 additions & 77 deletions src/data_types/credential.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[cfg(feature = "zeroize")]
Expand Down Expand Up @@ -74,16 +73,6 @@ impl Validatable for Credential {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct CredentialInfo {
pub referent: String,
pub attrs: RawCredentialValues,
pub schema_id: SchemaId,
pub cred_def_id: CredentialDefinitionId,
pub rev_reg_id: Option<RevocationRegistryDefinitionId>,
pub cred_rev_id: Option<String>,
}

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

Expand Down Expand Up @@ -126,20 +115,12 @@ impl From<&CredentialValues> for RawCredentialValues {
}

impl RawCredentialValues {
pub fn encode(&self, encoding: &CredentialValuesEncoding) -> Result<CredentialValues, Error> {
match encoding {
CredentialValuesEncoding::Auto => {
let mut cred_values = MakeCredentialValues::default();
for (attribute, raw_value) in self.0.iter() {
cred_values.add_raw(attribute, raw_value)?;
}
Ok(cred_values.into())
}
encoding => Err(err_msg!(
"Credential values encoding {:?} is not supported",
encoding
)),
pub fn encode(&self) -> Result<CredentialValues, Error> {
let mut cred_values = MakeCredentialValues::default();
for (attribute, raw_value) in self.0.iter() {
cred_values.add_raw(attribute, raw_value)?;
}
Ok(cred_values.into())
}
}

Expand Down Expand Up @@ -178,55 +159,3 @@ pub struct AttributeValues {
pub raw: String,
pub encoded: String,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CredentialValuesEncoding {
Auto,
Other(String),
}

impl ToString for CredentialValuesEncoding {
fn to_string(&self) -> String {
match self {
CredentialValuesEncoding::Auto => "auto".to_string(),
CredentialValuesEncoding::Other(other) => other.to_string(),
}
}
}

impl From<&str> for CredentialValuesEncoding {
fn from(value: &str) -> Self {
match value {
"auto" => CredentialValuesEncoding::Auto,
other => CredentialValuesEncoding::Other(other.to_string()),
}
}
}

impl Serialize for CredentialValuesEncoding {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Value::String(self.to_string()).serialize(serializer)
}
}

impl<'de> Deserialize<'de> for CredentialValuesEncoding {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Value::deserialize(deserializer)
.map_err(de::Error::custom)?
.as_str()
.map(CredentialValuesEncoding::from)
.ok_or_else(|| de::Error::custom("Cannot parse credential value encoding"))
}
}

impl Default for CredentialValuesEncoding {
fn default() -> Self {
CredentialValuesEncoding::Auto
}
}
4 changes: 3 additions & 1 deletion src/data_types/pres_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,13 @@ pub struct AttributeInfo {
pub non_revoked: Option<NonRevokedInterval>,
}

pub type PredicateValue = i32;

#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct PredicateInfo {
pub name: String,
pub p_type: PredicateTypes,
pub p_value: i32,
pub p_value: PredicateValue,
pub restrictions: Option<Query>,
pub non_revoked: Option<NonRevokedInterval>,
}
Expand Down
55 changes: 31 additions & 24 deletions src/data_types/w3c/constants.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
use crate::data_types::w3c::context::{Context, Contexts};
use once_cell::sync::Lazy;
use serde_json::{json, Value};
use std::collections::HashSet;

use crate::data_types::w3c::credential::{Contexts, Types};
use crate::data_types::w3c::credential::Types;
use crate::data_types::w3c::uri::URI;

// Contexts
pub const W3C_CONTEXT: &str = "https://www.w3.org/2018/credentials/v1";
pub const W3C_ANONCREDS_CONTEXT: &str = "https://raw.githubusercontent.com/hyperledger/anoncreds-spec/main/data/anoncreds-w3c-context.json";
pub const W3C_VC_1_1_BASE_CONTEXT: &str = "https://www.w3.org/2018/credentials/v1";
pub const W3C_VC_2_0_BASE_CONTEXT: &str = "https://www.w3.org/ns/credentials/v2";
pub const W3C_DATA_INTEGRITY_CONTEXT: &str = "https://w3id.org/security/data-integrity/v2";

// Types
pub const W3C_CREDENTIAL_TYPE: &str = "VerifiableCredential";
pub const W3C_PRESENTATION_TYPE: &str = "VerifiablePresentation";
pub const W3C_ANONCREDS_CREDENTIAL_TYPE: &str = "AnonCredsCredential";
pub const W3C_ANONCREDS_PRESENTATION_TYPE: &str = "AnonCredsPresentation";

pub(crate) static ANONCREDS_CONTEXTS: Lazy<Contexts> = Lazy::new(|| {
Contexts(HashSet::from([
URI::from(W3C_CONTEXT),
URI::from(W3C_ANONCREDS_CONTEXT),
]))
pub static ISSUER_DEPENDENT_VOCABULARY: Lazy<Value> = Lazy::new(|| {
json!({
"@vocab": "https://www.w3.org/ns/credentials/issuer-dependent#"
})
});

pub(crate) static ANONCREDS_CREDENTIAL_TYPES: Lazy<Types> = Lazy::new(|| {
Types(HashSet::from([
String::from(W3C_CREDENTIAL_TYPE),
String::from(W3C_ANONCREDS_CREDENTIAL_TYPE),
]))
pub(crate) static ANONCREDS_VC_1_1_CONTEXTS: Lazy<Contexts> = Lazy::new(|| {
Contexts(vec![
Context::URI(URI::from(W3C_VC_1_1_BASE_CONTEXT)),
Context::URI(URI::from(W3C_DATA_INTEGRITY_CONTEXT)),
Context::Object(ISSUER_DEPENDENT_VOCABULARY.clone()),
])
});

pub(crate) static ANONCREDS_PRESENTATION_TYPES: Lazy<Types> = Lazy::new(|| {
Types(HashSet::from([
String::from(W3C_PRESENTATION_TYPE),
String::from(W3C_ANONCREDS_PRESENTATION_TYPE),
]))
pub(crate) static ANONCREDS_VC_2_0_CONTEXTS: Lazy<Contexts> = Lazy::new(|| {
Contexts(vec![
Context::URI(URI::from(W3C_VC_2_0_BASE_CONTEXT)),
Context::Object(ISSUER_DEPENDENT_VOCABULARY.clone()),
])
});

// Types
pub const W3C_CREDENTIAL_TYPE: &str = "VerifiableCredential";
pub const W3C_PRESENTATION_TYPE: &str = "VerifiablePresentation";

pub(crate) static ANONCREDS_CREDENTIAL_TYPES: Lazy<Types> =
Lazy::new(|| Types(HashSet::from([String::from(W3C_CREDENTIAL_TYPE)])));

pub(crate) static ANONCREDS_PRESENTATION_TYPES: Lazy<Types> =
Lazy::new(|| Types(HashSet::from([String::from(W3C_PRESENTATION_TYPE)])));
Loading