From fd58feddb5062c5cf32efa8f3fc3546584c278f1 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 7 Dec 2022 17:22:06 +0100 Subject: [PATCH 01/17] do not validate and create ids for schema, cred defs and rev reg defs Signed-off-by: blu3beri --- .../src/data_types/anoncreds/cred_def.rs | 30 +- .../src/data_types/anoncreds/cred_offer.rs | 30 +- .../src/data_types/anoncreds/cred_request.rs | 18 +- .../src/data_types/anoncreds/credential.rs | 17 +- .../src/data_types/anoncreds/pres_request.rs | 89 +--- .../src/data_types/anoncreds/presentation.rs | 9 +- .../src/data_types/anoncreds/rev_reg_def.rs | 26 +- anoncreds/src/data_types/anoncreds/schema.rs | 65 --- .../src/data_types/identifiers/cred_def.rs | 422 ------------------ anoncreds/src/data_types/identifiers/mod.rs | 9 - .../src/data_types/identifiers/rev_reg.rs | 206 --------- .../src/data_types/identifiers/schema.rs | 231 ---------- anoncreds/src/data_types/mod.rs | 8 - anoncreds/src/ffi/cred_def.rs | 59 +-- anoncreds/src/ffi/cred_offer.rs | 27 +- anoncreds/src/ffi/credential.rs | 3 + anoncreds/src/ffi/object.rs | 9 +- anoncreds/src/ffi/presentation.rs | 101 ++++- anoncreds/src/ffi/revocation.rs | 30 +- anoncreds/src/ffi/schema.rs | 49 +- anoncreds/src/services/issuer.rs | 241 ++++------ anoncreds/src/services/prover.rs | 12 +- anoncreds/src/services/types.rs | 36 +- anoncreds/src/services/verifier.rs | 45 +- 24 files changed, 262 insertions(+), 1510 deletions(-) delete mode 100644 anoncreds/src/data_types/identifiers/cred_def.rs delete mode 100644 anoncreds/src/data_types/identifiers/mod.rs delete mode 100644 anoncreds/src/data_types/identifiers/rev_reg.rs delete mode 100644 anoncreds/src/data_types/identifiers/schema.rs diff --git a/anoncreds/src/data_types/anoncreds/cred_def.rs b/anoncreds/src/data_types/anoncreds/cred_def.rs index cc1e5b71..ed0984de 100644 --- a/anoncreds/src/data_types/anoncreds/cred_def.rs +++ b/anoncreds/src/data_types/anoncreds/cred_def.rs @@ -1,6 +1,4 @@ -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::identifiers::schema::SchemaId; -use crate::data_types::{ConversionError, Validatable, ValidationError}; +use crate::data_types::ConversionError; pub const CL_SIGNATURE_TYPE: &str = "CL"; @@ -38,27 +36,10 @@ pub enum CredentialDefinition { CredentialDefinitionV1(CredentialDefinitionV1), } -impl CredentialDefinition { - pub fn id(&self) -> &CredentialDefinitionId { - match self { - CredentialDefinition::CredentialDefinitionV1(c) => &c.id, - } - } -} - -impl Validatable for CredentialDefinition { - fn validate(&self) -> Result<(), ValidationError> { - match self { - CredentialDefinition::CredentialDefinitionV1(cred_def) => cred_def.validate(), - } - } -} - #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CredentialDefinitionV1 { - pub id: CredentialDefinitionId, - pub schema_id: SchemaId, + pub schema_id: String, #[serde(rename = "type")] pub signature_type: SignatureType, pub tag: String, @@ -76,13 +57,6 @@ impl CredentialDefinitionV1 { } } -impl Validatable for CredentialDefinitionV1 { - fn validate(&self) -> Result<(), ValidationError> { - self.id.validate()?; - self.schema_id.validate() - } -} - #[derive(Debug, Deserialize, Serialize)] pub struct CredentialDefinitionPrivate { pub value: ursa::cl::CredentialPrivateKey, diff --git a/anoncreds/src/data_types/anoncreds/cred_offer.rs b/anoncreds/src/data_types/anoncreds/cred_offer.rs index 1a37620c..2c0bb570 100644 --- a/anoncreds/src/data_types/anoncreds/cred_offer.rs +++ b/anoncreds/src/data_types/anoncreds/cred_offer.rs @@ -1,37 +1,11 @@ use super::nonce::Nonce; -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::identifiers::schema::SchemaId; -use crate::data_types::utils::Qualifiable; -use crate::data_types::{Validatable, ValidationError}; #[derive(Debug, Deserialize, Serialize)] pub struct CredentialOffer { - pub schema_id: SchemaId, - pub cred_def_id: CredentialDefinitionId, + pub schema_id: String, + pub cred_def_id: String, pub key_correctness_proof: ursa::cl::CredentialKeyCorrectnessProof, pub nonce: Nonce, #[serde(skip_serializing_if = "Option::is_none")] pub method_name: Option, } - -impl CredentialOffer { - #[allow(unused)] - pub fn to_unqualified(self) -> CredentialOffer { - let method_name = self.cred_def_id.get_method().map(str::to_owned); - CredentialOffer { - schema_id: self.schema_id.to_unqualified(), - cred_def_id: self.cred_def_id.to_unqualified(), - key_correctness_proof: self.key_correctness_proof, - nonce: self.nonce, - method_name, - } - } -} - -impl Validatable for CredentialOffer { - fn validate(&self) -> Result<(), ValidationError> { - self.schema_id.validate()?; - self.cred_def_id.validate()?; - Ok(()) - } -} diff --git a/anoncreds/src/data_types/anoncreds/cred_request.rs b/anoncreds/src/data_types/anoncreds/cred_request.rs index 9b09a71f..2f86317b 100644 --- a/anoncreds/src/data_types/anoncreds/cred_request.rs +++ b/anoncreds/src/data_types/anoncreds/cred_request.rs @@ -1,34 +1,18 @@ use super::nonce::Nonce; -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::utils::Qualifiable; use crate::data_types::{Validatable, ValidationError}; use indy_utils::did::DidValue; #[derive(Debug, Deserialize, Serialize)] pub struct CredentialRequest { pub prover_did: DidValue, - pub cred_def_id: CredentialDefinitionId, + pub cred_def_id: String, pub blinded_ms: ursa::cl::BlindedCredentialSecrets, pub blinded_ms_correctness_proof: ursa::cl::BlindedCredentialSecretsCorrectnessProof, pub nonce: Nonce, } -impl CredentialRequest { - #[allow(unused)] - pub fn to_unqualified(self) -> CredentialRequest { - CredentialRequest { - prover_did: self.prover_did.to_unqualified(), - cred_def_id: self.cred_def_id.to_unqualified(), - blinded_ms: self.blinded_ms, - blinded_ms_correctness_proof: self.blinded_ms_correctness_proof, - nonce: self.nonce, - } - } -} - impl Validatable for CredentialRequest { fn validate(&self) -> Result<(), ValidationError> { - self.cred_def_id.validate()?; self.prover_did.validate()?; Ok(()) } diff --git a/anoncreds/src/data_types/anoncreds/credential.rs b/anoncreds/src/data_types/anoncreds/credential.rs index fe2fb0b0..fb6f8cfe 100644 --- a/anoncreds/src/data_types/anoncreds/credential.rs +++ b/anoncreds/src/data_types/anoncreds/credential.rs @@ -2,16 +2,13 @@ use std::collections::HashMap; use zeroize::Zeroize; -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::identifiers::rev_reg::RevocationRegistryId; -use crate::data_types::identifiers::schema::SchemaId; use crate::data_types::{Validatable, ValidationError}; #[derive(Debug, Deserialize, Serialize)] pub struct Credential { - pub schema_id: SchemaId, - pub cred_def_id: CredentialDefinitionId, - pub rev_reg_id: Option, + pub schema_id: String, + pub cred_def_id: String, + pub rev_reg_id: Option, pub values: CredentialValues, pub signature: ursa::cl::CredentialSignature, pub signature_correctness_proof: ursa::cl::SignatureCorrectnessProof, @@ -49,8 +46,6 @@ impl Credential { impl Validatable for Credential { fn validate(&self) -> Result<(), ValidationError> { - self.schema_id.validate()?; - self.cred_def_id.validate()?; self.values.validate()?; if self.rev_reg_id.is_some() && (self.witness.is_none() || self.rev_reg.is_none()) { @@ -69,9 +64,9 @@ impl Validatable for Credential { pub struct CredentialInfo { pub referent: String, pub attrs: ShortCredentialValues, - pub schema_id: SchemaId, - pub cred_def_id: CredentialDefinitionId, - pub rev_reg_id: Option, + pub schema_id: String, + pub cred_def_id: String, + pub rev_reg_id: Option, pub cred_rev_id: Option, } diff --git a/anoncreds/src/data_types/anoncreds/pres_request.rs b/anoncreds/src/data_types/anoncreds/pres_request.rs index f654b4c2..15355a14 100644 --- a/anoncreds/src/data_types/anoncreds/pres_request.rs +++ b/anoncreds/src/data_types/anoncreds/pres_request.rs @@ -6,12 +6,8 @@ use serde_json::Value; use super::credential::Credential; use super::nonce::Nonce; -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::identifiers::rev_reg::RevocationRegistryId; -use crate::data_types::identifiers::schema::SchemaId; -use crate::data_types::utils::{qualifiable, Qualifiable}; +use crate::data_types::utils::qualifiable; use crate::data_types::{Validatable, ValidationError}; -use indy_utils::did::DidValue; use indy_utils::invalid; use indy_utils::query::Query; @@ -237,89 +233,6 @@ impl Validatable for PresentationRequest { } } -impl PresentationRequest { - #[allow(unused)] - pub fn to_unqualified(self) -> PresentationRequest { - let convert = |request: &mut PresentationRequestPayload| { - for (_, requested_attribute) in request.requested_attributes.iter_mut() { - requested_attribute.restrictions = requested_attribute - .restrictions - .as_mut() - .map(|ref mut restrictions| _convert_query_to_unqualified(&restrictions)); - } - for (_, requested_predicate) in request.requested_predicates.iter_mut() { - requested_predicate.restrictions = requested_predicate - .restrictions - .as_mut() - .map(|ref mut restrictions| _convert_query_to_unqualified(&restrictions)); - } - }; - - match self { - PresentationRequest::PresentationRequestV2(mut request) => { - convert(&mut request); - PresentationRequest::PresentationRequestV2(request) - } - PresentationRequest::PresentationRequestV1(mut request) => { - convert(&mut request); - PresentationRequest::PresentationRequestV1(request) - } - } - } -} - -fn _convert_query_to_unqualified(query: &Query) -> Query { - match query { - Query::Eq(tag_name, ref tag_value) => Query::Eq( - tag_name.to_string(), - _convert_value_to_unqualified(tag_name, tag_value), - ), - Query::Neq(ref tag_name, ref tag_value) => Query::Neq( - tag_name.to_string(), - _convert_value_to_unqualified(tag_name, tag_value), - ), - Query::In(ref tag_name, ref tag_values) => Query::In( - tag_name.to_string(), - tag_values - .iter() - .map(|tag_value| _convert_value_to_unqualified(tag_name, tag_value)) - .collect::>(), - ), - Query::And(ref queries) => Query::And( - queries - .iter() - .map(|query| _convert_query_to_unqualified(query)) - .collect::>(), - ), - Query::Or(ref queries) => Query::Or( - queries - .iter() - .map(|query| _convert_query_to_unqualified(query)) - .collect::>(), - ), - Query::Not(ref query) => _convert_query_to_unqualified(query), - query => query.clone(), - } -} - -fn _convert_value_to_unqualified(tag_name: &str, tag_value: &str) -> String { - match tag_name { - "issuer_did" | "schema_issuer_did" => DidValue(tag_value.to_string()).to_unqualified().0, - "schema_id" => SchemaId(tag_value.to_string()).to_unqualified().0, - "cred_def_id" => { - CredentialDefinitionId(tag_value.to_string()) - .to_unqualified() - .0 - } - "rev_reg_id" => { - RevocationRegistryId(tag_value.to_string()) - .to_unqualified() - .0 - } - _ => tag_value.to_string(), - } -} - fn _process_operator( restriction_op: &Query, version: &PresentationRequestVersion, diff --git a/anoncreds/src/data_types/anoncreds/presentation.rs b/anoncreds/src/data_types/anoncreds/presentation.rs index b6be7940..f5167122 100644 --- a/anoncreds/src/data_types/anoncreds/presentation.rs +++ b/anoncreds/src/data_types/anoncreds/presentation.rs @@ -1,8 +1,5 @@ use std::collections::HashMap; -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::identifiers::rev_reg::RevocationRegistryId; -use crate::data_types::identifiers::schema::SchemaId; use crate::data_types::Validatable; #[derive(Debug, Deserialize, Serialize)] @@ -64,9 +61,9 @@ pub struct AttributeValue { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct Identifier { - pub schema_id: SchemaId, - pub cred_def_id: CredentialDefinitionId, - pub rev_reg_id: Option, + pub schema_id: String, + pub cred_def_id: String, + pub rev_reg_id: Option, pub timestamp: Option, } diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index a01cb695..3a1b4be8 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -1,6 +1,3 @@ -use crate::data_types::identifiers::cred_def::CredentialDefinitionId; -use crate::data_types::identifiers::rev_reg::RevocationRegistryId; -use crate::data_types::utils::Qualifiable; use crate::data_types::{invalid, ConversionError, Validatable, ValidationError}; pub const CL_ACCUM: &str = "CL_ACCUM"; @@ -87,21 +84,14 @@ pub enum RevocationRegistryDefinition { } impl RevocationRegistryDefinition { - pub fn id(&self) -> &RevocationRegistryId { - match self { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(r) => &r.id, - } - } - pub fn to_unqualified(self) -> RevocationRegistryDefinition { match self { RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => { RevocationRegistryDefinition::RevocationRegistryDefinitionV1( RevocationRegistryDefinitionV1 { - id: v1.id.to_unqualified(), revoc_def_type: v1.revoc_def_type, tag: v1.tag, - cred_def_id: v1.cred_def_id.to_unqualified(), + cred_def_id: v1.cred_def_id, value: v1.value, }, ) @@ -110,24 +100,12 @@ impl RevocationRegistryDefinition { } } -impl Validatable for RevocationRegistryDefinition { - fn validate(&self) -> Result<(), ValidationError> { - match self { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => { - v1.id.validate()?; - } - } - Ok(()) - } -} - #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct RevocationRegistryDefinitionV1 { - pub id: RevocationRegistryId, pub revoc_def_type: RegistryType, pub tag: String, - pub cred_def_id: CredentialDefinitionId, + pub cred_def_id: String, pub value: RevocationRegistryDefinitionValue, } diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index 1ad884d9..2685615e 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -1,5 +1,3 @@ -use crate::data_types::identifiers::schema::SchemaId; -use crate::data_types::utils::Qualifiable; use crate::data_types::{Validatable, ValidationError}; use std::collections::HashSet; @@ -14,38 +12,9 @@ pub enum Schema { SchemaV1(SchemaV1), } -impl Schema { - pub fn id(&self) -> &SchemaId { - match self { - Schema::SchemaV1(s) => &s.id, - } - } - - pub fn to_unqualified(self) -> Schema { - match self { - Schema::SchemaV1(schema) => Schema::SchemaV1(SchemaV1 { - id: schema.id.to_unqualified(), - name: schema.name, - version: schema.version, - attr_names: schema.attr_names, - seq_no: schema.seq_no, - }), - } - } -} - -impl Validatable for Schema { - fn validate(&self) -> Result<(), ValidationError> { - match self { - Schema::SchemaV1(schema) => schema.validate(), - } - } -} - #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SchemaV1 { - pub id: SchemaId, pub name: String, pub version: String, #[serde(rename = "attrNames")] @@ -90,30 +59,6 @@ impl Into> for AttributeNames { } } -impl Validatable for SchemaV1 { - fn validate(&self) -> Result<(), ValidationError> { - self.attr_names.validate()?; - self.id.validate()?; - if let Some((_, _, name, version)) = self.id.parts() { - if name != self.name { - return Err(format!( - "Inconsistent Schema Id and Schema Name: {:?} and {}", - self.id, self.name, - ) - .into()); - } - if version != self.version { - return Err(format!( - "Inconsistent Schema Id and Schema Version: {:?} and {}", - self.id, self.version, - ) - .into()); - } - } - Ok(()) - } -} - impl Validatable for AttributeNames { fn validate(&self) -> Result<(), ValidationError> { if self.0.is_empty() { @@ -136,14 +81,9 @@ impl Validatable for AttributeNames { mod test_schema_validation { use super::*; - fn _schema_id_qualified() -> SchemaId { - SchemaId("schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string()) - } - #[test] fn test_valid_schema() { let schema_json = json!({ - "id": _schema_id_qualified(), "name": "gvt", "ver": "1.0", "version": "1.0", @@ -152,7 +92,6 @@ mod test_schema_validation { .to_string(); let schema: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); - schema.validate().unwrap(); assert_eq!(schema.name, "gvt"); assert_eq!(schema.version, "1.0"); } @@ -160,7 +99,6 @@ mod test_schema_validation { #[test] fn test_invalid_name_schema() { let schema_json = json!({ - "id": _schema_id_qualified(), "name": "gvt1", "ver": "1.0", "version": "1.0", @@ -169,13 +107,11 @@ mod test_schema_validation { .to_string(); let schema: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); - schema.validate().unwrap_err(); } #[test] fn test_invalid_version_schema() { let schema_json = json!({ - "id": _schema_id_qualified(), "name": "gvt", "ver": "1.0", "version": "1.1", @@ -184,6 +120,5 @@ mod test_schema_validation { .to_string(); let schema: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); - schema.validate().unwrap_err(); } } diff --git a/anoncreds/src/data_types/identifiers/cred_def.rs b/anoncreds/src/data_types/identifiers/cred_def.rs deleted file mode 100644 index a8cbcfc9..00000000 --- a/anoncreds/src/data_types/identifiers/cred_def.rs +++ /dev/null @@ -1,422 +0,0 @@ -use super::schema::SchemaId; -use crate::data_types::utils::{qualifiable, Qualifiable}; -use crate::data_types::{Validatable, ValidationError}; -use indy_utils::did::DidValue; -use indy_utils::qualifiable_type; - -use super::DELIMITER; - -qualifiable_type!(CredentialDefinitionId, "A credential definition identifier"); - -impl CredentialDefinitionId { - pub const PREFIX: &'static str = "creddef"; - pub const MARKER: &'static str = "3"; - - pub fn new( - did: &DidValue, - schema_id: &SchemaId, - signature_type: &str, - tag: &str, - ) -> CredentialDefinitionId { - let tag = if tag.is_empty() { - format!("") - } else { - format!("{}{}", DELIMITER, tag) - }; - let id = format!( - "{}{}{}{}{}{}{}{}", - did.0, - DELIMITER, - Self::MARKER, - DELIMITER, - signature_type, - DELIMITER, - schema_id.0, - tag - ); - Self::from(qualifiable::combine( - Self::PREFIX, - did.get_method(), - id.as_str(), - )) - } - - pub fn parts(&self) -> Option<(Option<&str>, DidValue, String, SchemaId, String)> { - let parts = self.0.split_terminator(DELIMITER).collect::>(); - - if parts.len() == 4 { - // Th7MpTaRZVRYnPiabds81Y:3:CL:1 - let did = parts[0].to_string(); - let signature_type = parts[2].to_string(); - let schema_id = parts[3].to_string(); - let tag = String::new(); - return Some(( - None, - DidValue(did), - signature_type, - SchemaId(schema_id), - tag, - )); - } - - if parts.len() == 5 { - // Th7MpTaRZVRYnPiabds81Y:3:CL:1:tag - let did = parts[0].to_string(); - let signature_type = parts[2].to_string(); - let schema_id = parts[3].to_string(); - let tag = parts[4].to_string(); - return Some(( - None, - DidValue(did), - signature_type, - SchemaId(schema_id), - tag, - )); - } - - if parts.len() == 7 { - // NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0 - let did = parts[0].to_string(); - let signature_type = parts[2].to_string(); - let schema_id = parts[3..7].join(DELIMITER); - let tag = String::new(); - return Some(( - None, - DidValue(did), - signature_type, - SchemaId(schema_id), - tag, - )); - } - - if parts.len() == 8 { - // NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag - let did = parts[0].to_string(); - let signature_type = parts[2].to_string(); - let schema_id = parts[3..7].join(DELIMITER); - let tag = parts[7].to_string(); - return Some(( - None, - DidValue(did), - signature_type, - SchemaId(schema_id), - tag, - )); - } - - if parts.len() == 9 { - // creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:3:tag - let method = parts[1]; - let did = parts[2..5].join(DELIMITER); - let signature_type = parts[6].to_string(); - let schema_id = parts[7].to_string(); - let tag = parts[8].to_string(); - return Some(( - Some(method), - DidValue(did), - signature_type, - SchemaId(schema_id), - tag, - )); - } - - if parts.len() == 16 { - // creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag - let method = parts[1]; - let did = parts[2..5].join(DELIMITER); - let signature_type = parts[6].to_string(); - let schema_id = parts[7..15].join(DELIMITER); - let tag = parts[15].to_string(); - return Some(( - Some(method), - DidValue(did), - signature_type, - SchemaId(schema_id), - tag, - )); - } - - None - } - - pub fn issuer_did(&self) -> Option { - self.parts().map(|(_, did, _, _, _)| did) - } -} - -impl Qualifiable for CredentialDefinitionId { - fn prefix() -> &'static str { - Self::PREFIX - } - - fn combine(method: Option<&str>, entity: &str) -> Self { - let cid = Self(entity.to_owned()); - match cid.parts() { - Some((_, did, sigtype, schema_id, tag)) => Self::new( - &did.default_method(method), - &schema_id.default_method(method), - &sigtype, - &tag, - ), - None => cid, - } - } - - fn to_unqualified(&self) -> Self { - match self.parts() { - Some((_, did, sig_type, schema_id, tag)) => Self::new( - &did.to_unqualified(), - &schema_id.to_unqualified(), - &sig_type, - &tag, - ), - None => self.clone(), - } - } -} - -impl Validatable for CredentialDefinitionId { - fn validate(&self) -> Result<(), ValidationError> { - self.parts().ok_or(format!( - "Credential Definition Id validation failed: {:?}, doesn't match pattern", - self.0 - ))?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn _did() -> DidValue { - DidValue("NcYxiDXkpYi6ov5FcYDi1e".to_string()) - } - - fn _signature_type() -> String { - "CL".to_string() - } - - fn _tag() -> String { - "tag".to_string() - } - - fn _did_qualified() -> DidValue { - DidValue("did:sov:NcYxiDXkpYi6ov5FcYDi1e".to_string()) - } - - fn _schema_id_seq_no() -> SchemaId { - SchemaId("1".to_string()) - } - - fn _schema_id_unqualified() -> SchemaId { - SchemaId("NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string()) - } - - fn _schema_id_qualified() -> SchemaId { - SchemaId("schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string()) - } - - fn _cred_def_id_unqualified() -> CredentialDefinitionId { - CredentialDefinitionId( - "NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag".to_string(), - ) - } - - fn _cred_def_id_unqualified_with_schema_as_seq_no() -> CredentialDefinitionId { - CredentialDefinitionId("NcYxiDXkpYi6ov5FcYDi1e:3:CL:1:tag".to_string()) - } - - fn _cred_def_id_unqualified_with_schema_as_seq_no_without_tag() -> CredentialDefinitionId { - CredentialDefinitionId("NcYxiDXkpYi6ov5FcYDi1e:3:CL:1".to_string()) - } - - fn _cred_def_id_unqualified_without_tag() -> CredentialDefinitionId { - CredentialDefinitionId( - "NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string(), - ) - } - - fn _cred_def_id_qualified_with_schema_as_seq_no() -> CredentialDefinitionId { - CredentialDefinitionId("creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:1:tag".to_string()) - } - - fn _cred_def_id_qualified() -> CredentialDefinitionId { - CredentialDefinitionId("creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag".to_string()) - } - - mod to_unqualified { - use super::*; - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified() { - assert_eq!( - _cred_def_id_unqualified(), - _cred_def_id_unqualified().to_unqualified() - ); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified_without_tag() { - assert_eq!( - _cred_def_id_unqualified_without_tag(), - _cred_def_id_unqualified_without_tag().to_unqualified() - ); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified_without_tag_with_schema_as_seq_no() { - assert_eq!( - _cred_def_id_unqualified_with_schema_as_seq_no(), - _cred_def_id_unqualified_with_schema_as_seq_no().to_unqualified() - ); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified_without_tag_with_schema_as_seq_no_without_tag( - ) { - assert_eq!( - _cred_def_id_unqualified_with_schema_as_seq_no_without_tag(), - _cred_def_id_unqualified_with_schema_as_seq_no_without_tag().to_unqualified() - ); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_qualified() { - assert_eq!( - _cred_def_id_unqualified(), - _cred_def_id_qualified().to_unqualified() - ); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_qualified_with_schema_as_seq_no() { - assert_eq!( - _cred_def_id_unqualified_with_schema_as_seq_no(), - _cred_def_id_qualified_with_schema_as_seq_no().to_unqualified() - ); - } - } - - mod parts { - use super::*; - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified() { - let (_, did, signature_type, schema_id, tag) = - _cred_def_id_unqualified().parts().unwrap(); - assert_eq!(_did(), did); - assert_eq!(_signature_type(), signature_type); - assert_eq!(_schema_id_unqualified(), schema_id); - assert_eq!(_tag(), tag); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified_without_tag() { - let (_, did, signature_type, schema_id, tag) = - _cred_def_id_unqualified_without_tag().parts().unwrap(); - assert_eq!(_did(), did); - assert_eq!(_signature_type(), signature_type); - assert_eq!(_schema_id_unqualified(), schema_id); - assert_eq!(String::new(), tag); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified_with_schema_as_seq() { - let (_, did, signature_type, schema_id, tag) = - _cred_def_id_unqualified_with_schema_as_seq_no() - .parts() - .unwrap(); - assert_eq!(_did(), did); - assert_eq!(_signature_type(), signature_type); - assert_eq!(_schema_id_seq_no(), schema_id); - assert_eq!(_tag(), tag); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_unqualified_with_schema_as_seq_without_tag() { - let (_, did, signature_type, schema_id, tag) = - _cred_def_id_unqualified_with_schema_as_seq_no_without_tag() - .parts() - .unwrap(); - assert_eq!(_did(), did); - assert_eq!(_signature_type(), signature_type); - assert_eq!(_schema_id_seq_no(), schema_id); - assert_eq!(String::new(), tag); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_qualified() { - let (_, did, signature_type, schema_id, tag) = - _cred_def_id_qualified().parts().unwrap(); - assert_eq!(_did_qualified(), did); - assert_eq!(_signature_type(), signature_type); - assert_eq!(_schema_id_qualified(), schema_id); - assert_eq!(_tag(), tag); - } - - #[test] - fn test_cred_def_id_parts_for_id_as_qualified_with_schema_as_seq() { - let (_, did, signature_type, schema_id, tag) = - _cred_def_id_qualified_with_schema_as_seq_no() - .parts() - .unwrap(); - assert_eq!(_did_qualified(), did); - assert_eq!(_signature_type(), signature_type); - assert_eq!(_schema_id_seq_no(), schema_id); - assert_eq!(_tag(), tag); - } - } - - mod validate { - use super::*; - - #[test] - fn test_validate_cred_def_id_as_unqualified() { - _cred_def_id_unqualified().validate().unwrap(); - } - - #[test] - fn test_validate_cred_def_id_as_unqualified_without_tag() { - _cred_def_id_unqualified_without_tag().validate().unwrap(); - } - - #[test] - fn test_validate_cred_def_id_as_unqualified_with_schema_as_seq_no() { - _cred_def_id_unqualified_with_schema_as_seq_no() - .validate() - .unwrap(); - } - - #[test] - fn test_validate_cred_def_id_as_unqualified_with_schema_as_seq_no_without_tag() { - _cred_def_id_unqualified_with_schema_as_seq_no_without_tag() - .validate() - .unwrap(); - } - - #[test] - fn test_validate_cred_def_id_as_fully_qualified() { - _cred_def_id_qualified().validate().unwrap(); - } - - #[test] - fn test_validate_cred_def_id_as_fully_qualified_with_schema_as_seq_no() { - _cred_def_id_qualified_with_schema_as_seq_no() - .validate() - .unwrap(); - } - } - - mod to_qualified { - use super::*; - - #[test] - fn test_red_def_to_qualified() { - assert_eq!( - _cred_def_id_unqualified().to_qualified("sov").unwrap(), - _cred_def_id_qualified() - ) - } - } -} diff --git a/anoncreds/src/data_types/identifiers/mod.rs b/anoncreds/src/data_types/identifiers/mod.rs deleted file mode 100644 index baeb606b..00000000 --- a/anoncreds/src/data_types/identifiers/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -/// Credential definition identifiers -pub mod cred_def; -/// Revocation registry identifiers -pub mod rev_reg; -/// V1 schema identifiers -pub mod schema; - -/// The standard delimiter used in identifier strings -pub const DELIMITER: &'static str = ":"; diff --git a/anoncreds/src/data_types/identifiers/rev_reg.rs b/anoncreds/src/data_types/identifiers/rev_reg.rs deleted file mode 100644 index 19d4b4fb..00000000 --- a/anoncreds/src/data_types/identifiers/rev_reg.rs +++ /dev/null @@ -1,206 +0,0 @@ -use once_cell::sync::Lazy; - -use regex::Regex; - -use super::cred_def::CredentialDefinitionId; -use super::DELIMITER; -use crate::data_types::utils::{qualifiable, Qualifiable}; -use crate::data_types::{Validatable, ValidationError}; -use indy_utils::did::DidValue; -use indy_utils::qualifiable_type; - -static QUALIFIED_REV_REG_ID: Lazy = Lazy::new(|| { - Regex::new("(^revreg:(?P[a-z0-9]+):)?(?P.+):4:(?P.+):(?P.+):(?P.+)$").unwrap() -}); - -qualifiable_type!(RevocationRegistryId, "A revocation registry identifier"); - -impl RevocationRegistryId { - pub const PREFIX: &'static str = "revreg"; - pub const MARKER: &'static str = "4"; - - pub fn new( - did: &DidValue, - cred_def_id: &CredentialDefinitionId, - rev_reg_type: &str, - tag: &str, - ) -> RevocationRegistryId { - let id = format!( - "{}{}{}{}{}{}{}{}{}", - did.0, - DELIMITER, - Self::MARKER, - DELIMITER, - cred_def_id.0, - DELIMITER, - rev_reg_type, - DELIMITER, - tag - ); - Self::from(qualifiable::combine( - Self::PREFIX, - did.get_method(), - id.as_str(), - )) - } - - pub fn parts(&self) -> Option<(DidValue, CredentialDefinitionId, String, String)> { - match QUALIFIED_REV_REG_ID.captures(&self.0) { - Some(caps) => Some(( - DidValue(caps["did"].to_string()), - CredentialDefinitionId(caps["cred_def_id"].to_string()), - caps["rev_reg_type"].to_string(), - caps["tag"].to_string(), - )), - None => None, - } - } -} - -impl Qualifiable for RevocationRegistryId { - fn prefix() -> &'static str { - Self::PREFIX - } - - fn combine(method: Option<&str>, entity: &str) -> Self { - let sid = Self(entity.to_owned()); - match sid.parts() { - Some((did, cred_def_id, rev_reg_type, tag)) => Self::new( - &did.default_method(method), - &cred_def_id.default_method(method), - &rev_reg_type, - &tag, - ), - None => sid, - } - } - - fn to_unqualified(&self) -> Self { - match self.parts() { - Some((did, cred_def_id, rev_reg_type, tag)) => Self::new( - &did.to_unqualified(), - &cred_def_id.to_unqualified(), - &rev_reg_type, - &tag, - ), - None => self.clone(), - } - } -} - -impl Validatable for RevocationRegistryId { - fn validate(&self) -> Result<(), ValidationError> { - self.parts().ok_or(format!( - "Revocation Registry Id validation failed: {:?}, doesn't match pattern", - self.0 - ))?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn _did() -> DidValue { - DidValue("NcYxiDXkpYi6ov5FcYDi1e".to_string()) - } - - fn _rev_reg_type() -> String { - "CL_ACCUM".to_string() - } - - fn _tag() -> String { - "TAG_1".to_string() - } - - fn _did_qualified() -> DidValue { - DidValue("did:sov:NcYxiDXkpYi6ov5FcYDi1e".to_string()) - } - - fn _cred_def_id_unqualified() -> CredentialDefinitionId { - CredentialDefinitionId( - "NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag".to_string(), - ) - } - - fn _cred_def_id_qualified() -> CredentialDefinitionId { - CredentialDefinitionId("creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag".to_string()) - } - - fn _rev_reg_id_unqualified() -> RevocationRegistryId { - RevocationRegistryId("NcYxiDXkpYi6ov5FcYDi1e:4:NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag:CL_ACCUM:TAG_1".to_string()) - } - - fn _rev_reg_id_qualified() -> RevocationRegistryId { - RevocationRegistryId("revreg:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:4:creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag:CL_ACCUM:TAG_1".to_string()) - } - - mod to_unqualified { - use super::*; - - #[test] - fn test_rev_reg_id_parts_for_id_as_unqualified() { - assert_eq!( - _rev_reg_id_unqualified(), - _rev_reg_id_unqualified().to_unqualified() - ); - } - - #[test] - fn test_rev_reg_id_parts_for_id_as_qualified() { - assert_eq!( - _rev_reg_id_unqualified(), - _rev_reg_id_qualified().to_unqualified() - ); - } - } - - mod parts { - use super::*; - - #[test] - fn test_rev_reg_id_parts_for_id_as_unqualified() { - let (did, cred_def_id, rev_reg_type, tag) = _rev_reg_id_unqualified().parts().unwrap(); - assert_eq!(_did(), did); - assert_eq!(_cred_def_id_unqualified(), cred_def_id); - assert_eq!(_rev_reg_type(), rev_reg_type); - assert_eq!(_tag(), tag); - } - - #[test] - fn test_rev_reg_id_parts_for_id_as_qualified() { - let (did, cred_def_id, rev_reg_type, tag) = _rev_reg_id_qualified().parts().unwrap(); - assert_eq!(_did_qualified(), did); - assert_eq!(_cred_def_id_qualified(), cred_def_id); - assert_eq!(_rev_reg_type(), rev_reg_type); - assert_eq!(_tag(), tag); - } - } - - mod validate { - use super::*; - - #[test] - fn test_validate_rev_reg_id_as_unqualified() { - _rev_reg_id_unqualified().validate().unwrap(); - } - - #[test] - fn test_validate_rev_reg_id_as_fully_qualified() { - _rev_reg_id_qualified().validate().unwrap(); - } - } - - mod to_qualified { - use super::*; - - #[test] - fn test_red_def_to_qualified() { - assert_eq!( - _rev_reg_id_unqualified().to_qualified("sov").unwrap(), - _rev_reg_id_qualified() - ) - } - } -} diff --git a/anoncreds/src/data_types/identifiers/schema.rs b/anoncreds/src/data_types/identifiers/schema.rs deleted file mode 100644 index a882419e..00000000 --- a/anoncreds/src/data_types/identifiers/schema.rs +++ /dev/null @@ -1,231 +0,0 @@ -use crate::data_types::utils::{qualifiable, Qualifiable}; -use crate::data_types::{Validatable, ValidationError}; -use indy_utils::did::DidValue; -use indy_utils::qualifiable_type; - -use super::DELIMITER; - -qualifiable_type!(SchemaId, "A V1 schema identifier"); - -impl SchemaId { - pub const PREFIX: &'static str = "schema"; - pub const MARKER: &'static str = "2"; - - pub fn new(did: &DidValue, name: &str, version: &str) -> SchemaId { - let id = format!( - "{}{}{}{}{}{}{}", - did.0, - DELIMITER, - Self::MARKER, - DELIMITER, - name, - DELIMITER, - version - ); - Self::from(qualifiable::combine( - Self::PREFIX, - did.get_method(), - id.as_str(), - )) - } - - pub fn parts(&self) -> Option<(Option<&str>, DidValue, String, String)> { - let parts = self.0.split_terminator(DELIMITER).collect::>(); - - if parts.len() == 1 { - // 1 - return None; - } - - if parts.len() == 4 { - // NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0 - let did = parts[0].to_string(); - let name = parts[2].to_string(); - let version = parts[3].to_string(); - return Some((None, DidValue(did), name, version)); - } - - if parts.len() == 8 { - // schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0 - let method = parts[1]; - let did = parts[2..5].join(DELIMITER); - let name = parts[6].to_string(); - let version = parts[7].to_string(); - return Some((Some(method), DidValue(did), name, version)); - } - - None - } -} - -impl Qualifiable for SchemaId { - fn prefix() -> &'static str { - Self::PREFIX - } - - fn combine(method: Option<&str>, entity: &str) -> Self { - let sid = Self(entity.to_owned()); - match sid.parts() { - Some((_, did, name, version)) => { - Self::new(&did.default_method(method), &name, &version) - } - None => sid, - } - } - - fn to_unqualified(&self) -> Self { - match self.parts() { - Some((method, did, name, version)) => { - let did = if let Some(method) = method { - did.remove_method(method) - } else { - did - }; - Self::new(&did, &name, &version) - } - None => self.clone(), - } - } -} - -impl Validatable for SchemaId { - fn validate(&self) -> Result<(), ValidationError> { - if self.0.parse::().is_ok() { - return Ok(()); - } - - self.parts().ok_or(format!( - "SchemaId validation failed: {:?}, doesn't match pattern", - self.0 - ))?; - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn _did() -> DidValue { - DidValue("NcYxiDXkpYi6ov5FcYDi1e".to_string()) - } - - fn _did_qualified() -> DidValue { - DidValue("did:sov:NcYxiDXkpYi6ov5FcYDi1e".to_string()) - } - - fn _schema_id_seq_no() -> SchemaId { - SchemaId("1".to_string()) - } - - fn _schema_id_unqualified() -> SchemaId { - SchemaId("NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string()) - } - - fn _schema_id_qualified() -> SchemaId { - SchemaId("schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string()) - } - - fn _schema_id_invalid() -> SchemaId { - SchemaId("NcYxiDXkpYi6ov5FcYDi1e:2".to_string()) - } - - mod to_unqualified { - use super::*; - - #[test] - fn test_schema_id_unqualify_for_id_as_seq_no() { - assert_eq!(_schema_id_seq_no(), _schema_id_seq_no().to_unqualified()); - } - - #[test] - fn test_schema_id_parts_for_id_as_unqualified() { - assert_eq!( - _schema_id_unqualified(), - _schema_id_unqualified().to_unqualified() - ); - } - - #[test] - fn test_schema_id_parts_for_id_as_qualified() { - assert_eq!( - _schema_id_unqualified(), - _schema_id_qualified().to_unqualified() - ); - } - - #[test] - fn test_schema_id_parts_for_invalid_unqualified() { - assert_eq!(_schema_id_invalid(), _schema_id_invalid().to_unqualified()); - } - } - - mod parts { - use super::*; - - #[test] - fn test_schema_id_parts_for_id_as_seq_no() { - assert!(_schema_id_seq_no().parts().is_none()); - } - - #[test] - fn test_schema_id_parts_for_id_as_unqualified() { - let (_, did, _, _) = _schema_id_unqualified().parts().unwrap(); - assert_eq!(_did(), did); - } - - #[test] - fn test_schema_id_parts_for_id_as_qualified() { - let (_, did, _, _) = _schema_id_qualified().parts().unwrap(); - assert_eq!(_did_qualified(), did); - } - - #[test] - fn test_schema_id_parts_for_invalid_unqualified() { - assert!(_schema_id_invalid().parts().is_none()); - } - } - - mod validate { - use super::*; - - #[test] - fn test_validate_schema_id_as_seq_no() { - _schema_id_seq_no().validate().unwrap(); - } - - #[test] - fn test_validate_schema_id_as_unqualified() { - _schema_id_unqualified().validate().unwrap(); - } - - #[test] - fn test_validate_schema_id_as_fully_qualified() { - _schema_id_qualified().validate().unwrap(); - } - - #[test] - fn test_validate_schema_id_for_invalid_unqualified() { - _schema_id_invalid().validate().unwrap_err(); - } - - #[test] - fn test_validate_schema_id_for_invalid_fully_qualified() { - let id = SchemaId("schema:sov:NcYxiDXkpYi6ov5FcYDi1e:2:1.0".to_string()); - id.validate().unwrap_err(); - } - } - - mod to_qualified { - use super::*; - - #[test] - fn test_schema_to_qualified() { - assert_eq!( - _schema_id_unqualified().to_qualified("sov").unwrap(), - _schema_id_qualified() - ) - } - } -} diff --git a/anoncreds/src/data_types/mod.rs b/anoncreds/src/data_types/mod.rs index 7f66b032..879aa0a8 100644 --- a/anoncreds/src/data_types/mod.rs +++ b/anoncreds/src/data_types/mod.rs @@ -11,11 +11,3 @@ pub use ursa; /// Type definitions related Indy credential issuance and verification pub mod anoncreds; - -mod identifiers; - -pub use identifiers::cred_def::*; -pub use identifiers::rev_reg::*; -pub use identifiers::schema::*; - -pub use identifiers::DELIMITER as IDENT_DELIMITER; diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index 49da0936..4c8768ed 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -1,22 +1,18 @@ -use std::os::raw::c_char; - -use ffi_support::{rust_string_to_c, FfiStr}; -use indy_utils::Qualifiable; +use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; -use super::object::{AnonCredsObjectId, ObjectHandle}; +use super::object::ObjectHandle; use crate::services::{ issuer::create_credential_definition, types::{ - CredentialDefinition, CredentialDefinitionConfig, CredentialDefinitionId, - CredentialDefinitionPrivate, CredentialKeyCorrectnessProof as KeyCorrectnessProof, - DidValue, SignatureType, + CredentialDefinition, CredentialDefinitionConfig, CredentialDefinitionPrivate, + CredentialKeyCorrectnessProof as KeyCorrectnessProof, SignatureType, }, }; #[no_mangle] pub extern "C" fn anoncreds_create_credential_definition( - origin_did: FfiStr, + schema_id: FfiStr, schema: ObjectHandle, tag: FfiStr, signature_type: FfiStr, @@ -29,13 +25,10 @@ pub extern "C" fn anoncreds_create_credential_definition( check_useful_c_ptr!(cred_def_p); check_useful_c_ptr!(cred_def_pvt_p); check_useful_c_ptr!(key_proof_p); - let origin_did = { - let did = origin_did - .as_opt_str() - .ok_or_else(|| err_msg!("Missing origin DID"))?; - DidValue::from_str(did)? - }; let tag = tag.as_opt_str().ok_or_else(|| err_msg!("Missing tag"))?; + let schema_id = schema_id + .as_opt_str() + .ok_or_else(|| err_msg!("Missing schema id"))?; let signature_type = { let stype = signature_type .as_opt_str() @@ -43,7 +36,7 @@ pub extern "C" fn anoncreds_create_credential_definition( SignatureType::from_str(stype).map_err(err_map!(Input))? }; let (cred_def, cred_def_pvt, key_proof) = create_credential_definition( - &origin_did, + schema_id.to_owned(), schema.load()?.cast_ref()?, tag, signature_type, @@ -69,40 +62,6 @@ impl_anoncreds_object_from_json!( anoncreds_credential_definition_from_json ); -impl AnonCredsObjectId for CredentialDefinition { - type Id = CredentialDefinitionId; - - fn get_id(&self) -> Self::Id { - match self { - CredentialDefinition::CredentialDefinitionV1(c) => c.id.clone(), - } - } -} - -#[no_mangle] -pub extern "C" fn anoncreds_credential_definition_get_attribute( - handle: ObjectHandle, - name: FfiStr, - result_p: *mut *const c_char, -) -> ErrorCode { - catch_error(|| { - check_useful_c_ptr!(result_p); - let cred_def = handle.load()?; - let cred_def = cred_def.cast_ref::()?; - let val = match name.as_opt_str().unwrap_or_default() { - "id" => cred_def.get_id().to_string(), - "schema_id" => match cred_def { - CredentialDefinition::CredentialDefinitionV1(cred_def) => { - cred_def.schema_id.to_string() - } - }, - s => return Err(err_msg!("Unsupported attribute: {}", s)), - }; - unsafe { *result_p = rust_string_to_c(val) }; - Ok(()) - }) -} - impl_anoncreds_object!(CredentialDefinitionPrivate, "CredentialDefinitionPrivate"); impl_anoncreds_object_from_json!( CredentialDefinitionPrivate, diff --git a/anoncreds/src/ffi/cred_offer.rs b/anoncreds/src/ffi/cred_offer.rs index db5c8279..0d59af3c 100644 --- a/anoncreds/src/ffi/cred_offer.rs +++ b/anoncreds/src/ffi/cred_offer.rs @@ -1,33 +1,26 @@ use ffi_support::FfiStr; -use indy_utils::Qualifiable; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; -use crate::services::{ - issuer::create_credential_offer, - types::{CredentialOffer, SchemaId}, -}; +use crate::services::{issuer::create_credential_offer, types::CredentialOffer}; #[no_mangle] pub extern "C" fn anoncreds_create_credential_offer( schema_id: FfiStr, - cred_def: ObjectHandle, + cred_def_id: FfiStr, key_proof: ObjectHandle, cred_offer_p: *mut ObjectHandle, ) -> ErrorCode { catch_error(|| { check_useful_c_ptr!(cred_offer_p); - let schema_id = { - let sid = schema_id - .as_opt_str() - .ok_or_else(|| err_msg!("Missing schema ID"))?; - SchemaId::from_str(sid)? - }; - let cred_offer = create_credential_offer( - &schema_id, - cred_def.load()?.cast_ref()?, - key_proof.load()?.cast_ref()?, - )?; + let schema_id = schema_id + .as_opt_str() + .ok_or_else(|| err_msg!("Missing schema ID"))?; + let cred_def_id = cred_def_id + .as_opt_str() + .ok_or_else(|| err_msg!("Missing cred def ID"))?; + let cred_offer = + create_credential_offer(schema_id, cred_def_id, key_proof.load()?.cast_ref()?)?; let cred_offer = ObjectHandle::create(cred_offer)?; unsafe { *cred_offer_p = cred_offer }; Ok(()) diff --git a/anoncreds/src/ffi/credential.rs b/anoncreds/src/ffi/credential.rs index 7302aa3e..15456d26 100644 --- a/anoncreds/src/ffi/credential.rs +++ b/anoncreds/src/ffi/credential.rs @@ -59,6 +59,7 @@ pub extern "C" fn anoncreds_create_credential( attr_names: FfiStrList, attr_raw_values: FfiStrList, attr_enc_values: FfiStrList, + rev_reg_id: FfiStr, revocation: *const FfiCredRevInfo, cred_p: *mut ObjectHandle, rev_reg_p: *mut ObjectHandle, @@ -74,6 +75,7 @@ pub extern "C" fn anoncreds_create_credential( "Mismatch between length of attribute names and raw values" )); } + let rev_reg_id = rev_reg_id.as_opt_str(); let enc_values = attr_enc_values.as_slice(); let mut cred_values = MakeCredentialValues::default(); let mut attr_idx = 0; @@ -137,6 +139,7 @@ pub extern "C" fn anoncreds_create_credential( cred_offer.load()?.cast_ref()?, cred_request.load()?.cast_ref()?, cred_values.into(), + rev_reg_id.map(String::from), revocation_config .as_ref() .map(RevocationConfig::as_ref_config) diff --git a/anoncreds/src/ffi/object.rs b/anoncreds/src/ffi/object.rs index 78f8620d..8dc1885b 100644 --- a/anoncreds/src/ffi/object.rs +++ b/anoncreds/src/ffi/object.rs @@ -233,15 +233,14 @@ impl AnonCredsObjectList { Ok(refs) } - pub fn refs_map(&self) -> Result::Id, &T>> + pub fn refs_map(&self, ids: &[String]) -> Result> where - T: AnyAnonCredsObject + AnonCredsObjectId + 'static, + T: AnyAnonCredsObject + 'static, { let mut refs = HashMap::with_capacity(self.0.len()); - for inst in self.0.iter() { + for (inst, id) in self.0.iter().zip(ids) { let inst = inst.cast_ref::()?; - let id = inst.get_id(); - refs.insert(id, inst); + refs.insert(id.to_owned(), inst); } Ok(refs) } diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index f5b56207..2e014075 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -4,12 +4,12 @@ use std::convert::TryInto; use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; -use super::object::{AnonCredsObject, AnonCredsObjectId, AnonCredsObjectList, ObjectHandle}; +use super::object::{AnonCredsObject, AnonCredsObjectList, ObjectHandle}; use super::util::{FfiList, FfiStrList}; use crate::error::Result; use crate::services::{ prover::create_presentation, - types::{PresentCredentials, Presentation, RevocationRegistryDefinition}, + types::{PresentCredentials, Presentation}, verifier::verify_presentation, }; @@ -65,17 +65,34 @@ pub extern "C" fn anoncreds_create_presentation( self_attest_values: FfiStrList, master_secret: ObjectHandle, schemas: FfiList, + // TODO: this is index-matched with schemas. Is there a better solution? + // since we have an objecthandle list for the schemas we can not add Ids to them + // Otherwise they all would need ids and we would like to seperate that + // Also, we kind of do the same with `self_attested_names` and `self_attested_values` + schema_ids: FfiStrList, cred_defs: FfiList, + cred_def_ids: FfiStrList, presentation_p: *mut ObjectHandle, ) -> ErrorCode { catch_error(|| { check_useful_c_ptr!(presentation_p); + if self_attest_names.len() != self_attest_values.len() { return Err(err_msg!( "Inconsistent lengths for self-attested value parameters" )); } + if schemas.len() != schema_ids.len() { + return Err(err_msg!("Inconsistent lengths for schemas and schemas ids")); + } + + if cred_defs.len() != cred_def_ids.len() { + return Err(err_msg!( + "Inconsistent lengths for cred defs and cred def ids" + )); + } + let entries = { let credentials = credentials.as_slice(); credentials.into_iter().try_fold( @@ -87,9 +104,6 @@ pub extern "C" fn anoncreds_create_presentation( )? }; - let schemas = AnonCredsObjectList::load(schemas.as_slice())?; - let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let self_attested = if !self_attest_names.is_empty() { let mut self_attested = HashMap::new(); for (name, raw) in self_attest_names @@ -147,13 +161,29 @@ pub extern "C" fn anoncreds_create_presentation( } } + let schema_ids: Vec = schema_ids + .as_slice() + .iter() + .map(|s| s.as_str().to_owned()) + .collect(); + let schemas = AnonCredsObjectList::load(schemas.as_slice())?; + let schemas = schemas.refs_map(&schema_ids)?; + + let cred_def_ids: Vec = cred_def_ids + .as_slice() + .iter() + .map(|s| s.as_str().to_owned()) + .collect(); + let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; + let cred_defs = cred_defs.refs_map(&cred_def_ids)?; + let presentation = create_presentation( pres_req.load()?.cast_ref()?, present_creds, self_attested, master_secret.load()?.cast_ref()?, - &schemas.refs_map()?, - &cred_defs.refs_map()?, + &schemas, + &cred_defs, )?; let presentation = ObjectHandle::create(presentation)?; unsafe { *presentation_p = presentation }; @@ -189,15 +219,31 @@ pub extern "C" fn anoncreds_verify_presentation( presentation: ObjectHandle, pres_req: ObjectHandle, schemas: FfiList, + schema_ids: FfiStrList, cred_defs: FfiList, + cred_def_ids: FfiStrList, rev_reg_defs: FfiList, + rev_reg_def_ids: FfiStrList, rev_reg_entries: FfiList, result_p: *mut i8, ) -> ErrorCode { catch_error(|| { - let schemas = AnonCredsObjectList::load(schemas.as_slice())?; - let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let rev_reg_defs = AnonCredsObjectList::load(rev_reg_defs.as_slice())?; + if schemas.len() != schema_ids.len() { + return Err(err_msg!("Inconsistent lengths for schemas and schemas ids")); + } + + if cred_defs.len() != cred_def_ids.len() { + return Err(err_msg!( + "Inconsistent lengths for cred defs and cred def ids" + )); + } + + if rev_reg_defs.len() != rev_reg_def_ids.len() { + return Err(err_msg!( + "Inconsistent lengths for rev reg defs and rev reg def ids" + )); + } + let rev_reg_entries = { let entries = rev_reg_entries.as_slice(); entries.into_iter().try_fold( @@ -213,20 +259,43 @@ pub extern "C" fn anoncreds_verify_presentation( if *idx > rev_reg_defs.len() { return Err(err_msg!("Invalid revocation registry entry index")); } - let id = rev_reg_defs[*idx] - .cast_ref::()? - .get_id(); + let id = rev_reg_def_ids.as_slice()[*idx].as_str().to_owned(); rev_regs .entry(id) .or_insert_with(HashMap::new) .insert(*timestamp, entry.cast_ref()?); } + + let schema_ids: Vec = schema_ids + .as_slice() + .iter() + .map(|s| s.as_str().to_owned()) + .collect(); + let schemas = AnonCredsObjectList::load(schemas.as_slice())?; + let schemas = schemas.refs_map(&schema_ids)?; + + let cred_def_ids: Vec = cred_def_ids + .as_slice() + .iter() + .map(|s| s.as_str().to_owned()) + .collect(); + let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; + let cred_defs = cred_defs.refs_map(&cred_def_ids)?; + + let rev_reg_def_ids: Vec = rev_reg_def_ids + .as_slice() + .iter() + .map(|s| s.as_str().to_owned()) + .collect(); + let rev_reg_defs = AnonCredsObjectList::load(rev_reg_defs.as_slice())?; + let rev_reg_defs = rev_reg_defs.refs_map(&rev_reg_def_ids)?; + let verify = verify_presentation( presentation.load()?.cast_ref()?, pres_req.load()?.cast_ref()?, - &schemas.refs_map()?, - &cred_defs.refs_map()?, - Some(&rev_reg_defs.refs_map()?), + &schemas, + &cred_defs, + Some(&rev_reg_defs), Some(&rev_regs), )?; unsafe { *result_p = verify as i8 }; diff --git a/anoncreds/src/ffi/revocation.rs b/anoncreds/src/ffi/revocation.rs index 08c8bb99..9e41cd50 100644 --- a/anoncreds/src/ffi/revocation.rs +++ b/anoncreds/src/ffi/revocation.rs @@ -3,10 +3,9 @@ use std::convert::TryInto; use std::os::raw::c_char; use ffi_support::{rust_string_to_c, FfiStr}; -use indy_utils::Qualifiable; use super::error::{catch_error, ErrorCode}; -use super::object::{AnonCredsObject, AnonCredsObjectId, ObjectHandle}; +use super::object::{AnonCredsObject, ObjectHandle}; use super::util::FfiList; use crate::error::Result; use crate::services::{ @@ -17,16 +16,15 @@ use crate::services::{ prover::create_or_update_revocation_state, tails::{TailsFileReader, TailsFileWriter}, types::{ - CredentialRevocationState, DidValue, IssuanceType, RegistryType, RevocationRegistry, + CredentialRevocationState, IssuanceType, RegistryType, RevocationRegistry, RevocationRegistryDefinition, RevocationRegistryDefinitionPrivate, RevocationRegistryDelta, - RevocationRegistryId, }, }; #[no_mangle] pub extern "C" fn anoncreds_create_revocation_registry( - origin_did: FfiStr, cred_def: ObjectHandle, + cred_def_id: FfiStr, tag: FfiStr, rev_reg_type: FfiStr, issuance_type: FfiStr, @@ -42,13 +40,10 @@ pub extern "C" fn anoncreds_create_revocation_registry( check_useful_c_ptr!(reg_def_private_p); check_useful_c_ptr!(reg_entry_p); check_useful_c_ptr!(reg_init_delta_p); - let origin_did = { - let did = origin_did - .as_opt_str() - .ok_or_else(|| err_msg!("Missing origin DID"))?; - DidValue::from_str(did)? - }; let tag = tag.as_opt_str().ok_or_else(|| err_msg!("Missing tag"))?; + let cred_def_id = cred_def_id + .as_opt_str() + .ok_or_else(|| err_msg!("Missing cred def id"))?; let rev_reg_type = { let rtype = rev_reg_type .as_opt_str() @@ -61,8 +56,8 @@ pub extern "C" fn anoncreds_create_revocation_registry( }; let mut tails_writer = TailsFileWriter::new(tails_dir_path.into_opt_string()); let (reg_def, reg_def_private, reg_entry, reg_init_delta) = create_revocation_registry( - &origin_did, cred_def.load()?.cast_ref()?, + cred_def_id, tag, rev_reg_type, issuance_type, @@ -173,16 +168,6 @@ impl_anoncreds_object_from_json!( anoncreds_revocation_registry_definition_from_json ); -impl AnonCredsObjectId for RevocationRegistryDefinition { - type Id = RevocationRegistryId; - - fn get_id(&self) -> Self::Id { - match self { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(r) => r.id.clone(), - } - } -} - #[no_mangle] pub extern "C" fn anoncreds_revocation_registry_definition_get_attribute( handle: ObjectHandle, @@ -194,7 +179,6 @@ pub extern "C" fn anoncreds_revocation_registry_definition_get_attribute( let reg_def = handle.load()?; let reg_def = reg_def.cast_ref::()?; let val = match name.as_opt_str().unwrap_or_default() { - "id" => reg_def.get_id().to_string(), "max_cred_num" => match reg_def { RevocationRegistryDefinition::RevocationRegistryDefinitionV1(r) => { r.value.max_cred_num.to_string() diff --git a/anoncreds/src/ffi/schema.rs b/anoncreds/src/ffi/schema.rs index 74a3c08e..26718564 100644 --- a/anoncreds/src/ffi/schema.rs +++ b/anoncreds/src/ffi/schema.rs @@ -1,19 +1,12 @@ -use std::os::raw::c_char; - -use ffi_support::{rust_string_to_c, FfiStr}; -use indy_utils::Qualifiable; +use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; -use super::object::{AnonCredsObjectId, ObjectHandle}; +use super::object::ObjectHandle; use super::util::FfiStrList; -use crate::services::{ - issuer::create_schema, - types::{DidValue, Schema, SchemaId}, -}; +use crate::services::{issuer::create_schema, types::Schema}; #[no_mangle] pub extern "C" fn anoncreds_create_schema( - origin_did: FfiStr, schema_name: FfiStr, schema_version: FfiStr, attr_names: FfiStrList, @@ -22,12 +15,6 @@ pub extern "C" fn anoncreds_create_schema( ) -> ErrorCode { catch_error(|| { check_useful_c_ptr!(result_p); - let origin_did = { - let did = origin_did - .as_opt_str() - .ok_or_else(|| err_msg!("Missing origin DID"))?; - DidValue::from_str(did)? - }; let schema_name = schema_name .as_opt_str() .ok_or_else(|| err_msg!("Missing schema name"))?; @@ -35,7 +22,6 @@ pub extern "C" fn anoncreds_create_schema( .as_opt_str() .ok_or_else(|| err_msg!("Missing schema version"))?; let schema = create_schema( - &origin_did, schema_name, schema_version, attr_names.to_string_vec()?.into(), @@ -51,34 +37,5 @@ pub extern "C" fn anoncreds_create_schema( }) } -#[no_mangle] -pub extern "C" fn anoncreds_schema_get_attribute( - handle: ObjectHandle, - name: FfiStr, - result_p: *mut *const c_char, -) -> ErrorCode { - catch_error(|| { - check_useful_c_ptr!(result_p); - let schema = handle.load()?; - let schema = schema.cast_ref::()?; - let val = match name.as_opt_str().unwrap_or_default() { - "id" => schema.get_id().to_string(), - s => return Err(err_msg!("Unsupported attribute: {}", s)), - }; - unsafe { *result_p = rust_string_to_c(val) }; - Ok(()) - }) -} - impl_anoncreds_object!(Schema, "Schema"); impl_anoncreds_object_from_json!(Schema, anoncreds_schema_from_json); - -impl AnonCredsObjectId for Schema { - type Id = SchemaId; - - fn get_id(&self) -> Self::Id { - match self { - Schema::SchemaV1(s) => s.id.clone(), - } - } -} diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index fc221322..8c9c35d7 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -18,24 +18,23 @@ use crate::ursa::cl::{ issuer::Issuer as CryptoIssuer, RevocationRegistryDelta as CryptoRevocationRegistryDelta, Witness, }; -use indy_utils::{Qualifiable, Validatable}; use super::tails::{TailsFileReader, TailsReader, TailsWriter}; pub fn create_schema( - origin_did: &DidValue, schema_name: &str, schema_version: &str, attr_names: AttributeNames, seq_no: Option, ) -> Result { - trace!("create_schema >>> origin_did: {:?}, schema_name: {:?}, schema_version: {:?}, attr_names: {:?}", - origin_did, schema_name, schema_version, attr_names); + trace!( + "create_schema >>> schema_name: {:?}, schema_version: {:?}, attr_names: {:?}", + schema_name, + schema_version, + attr_names + ); - origin_did.validate()?; - let schema_id = SchemaId::new(&origin_did, schema_name, schema_version); let schema = SchemaV1 { - id: schema_id, name: schema_name.to_string(), version: schema_version.to_string(), attr_names, @@ -44,35 +43,8 @@ pub fn create_schema( Ok(Schema::SchemaV1(schema)) } -pub fn make_credential_definition_id( - origin_did: &DidValue, - schema_id: &SchemaId, - schema_seq_no: Option, - tag: &str, - signature_type: SignatureType, -) -> Result { - let schema_id = match (origin_did.get_method(), schema_id.get_method()) { - (None, Some(_)) => { - return Err(err_msg!( - "Cannot use an unqualified Origin DID with fully qualified Schema ID", - )); - } - (method, _) => schema_id.default_method(method), - }; - let schema_infix_id = schema_seq_no - .map(|n| SchemaId(n.to_string())) - .unwrap_or(schema_id.clone()); - - Ok(CredentialDefinitionId::new( - origin_did, - &schema_infix_id, - &signature_type.to_str(), - tag, - )) -} - pub fn create_credential_definition( - origin_did: &DidValue, + schema_id: String, schema: &Schema, tag: &str, signature_type: SignatureType, @@ -91,17 +63,6 @@ pub fn create_credential_definition( let schema = match schema { Schema::SchemaV1(s) => s, }; - let cred_def_id = - make_credential_definition_id(origin_did, &schema.id, schema.seq_no, tag, signature_type)?; - - // Indy-Node requires the published schema ID field is the schema sequence number - let schema_id = SchemaId( - schema - .seq_no - .as_ref() - .map(|s| s.to_string()) - .unwrap_or(schema.id.0.clone()), - ); let credential_schema = build_credential_schema(&schema.attr_names.0)?; let non_credential_schema = build_non_credential_schema()?; @@ -114,8 +75,7 @@ pub fn create_credential_definition( )?; let cred_def = CredentialDefinition::CredentialDefinitionV1(CredentialDefinitionV1 { - id: cred_def_id, - schema_id, + schema_id: schema_id.to_owned(), signature_type, tag: tag.to_owned(), value: CredentialDefinitionData { @@ -140,37 +100,9 @@ pub fn create_credential_definition( Ok((cred_def, cred_def_private, cred_key_proof)) } -pub fn make_revocation_registry_id( - origin_did: &DidValue, - cred_def: &CredentialDefinition, - tag: &str, - rev_reg_type: RegistryType, -) -> Result { - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(c) => c, - }; - - let origin_did = match (origin_did.get_method(), cred_def.id.get_method()) { - (None, Some(_)) => { - return Err(err_msg!("Cannot use an unqualified Origin DID with a fully qualified Credential Definition ID")); - } - (Some(_), None) => { - return Err(err_msg!("Cannot use a fully qualified Origin DID with an unqualified Credential Definition ID")); - } - _ => origin_did, - }; - - Ok(RevocationRegistryId::new( - &origin_did, - &cred_def.id, - &rev_reg_type.to_str(), - tag, - )) -} - pub fn create_revocation_registry( - origin_did: &DidValue, cred_def: &CredentialDefinition, + cred_def_id: &str, tag: &str, rev_reg_type: RegistryType, issuance_type: IssuanceType, @@ -185,10 +117,8 @@ pub fn create_revocation_registry( where TW: TailsWriter, { - trace!("create_revocation_registry >>> origin_did: {:?}, cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}, issuance_type: {:?}", - origin_did, cred_def, tag, max_cred_num, rev_reg_type, issuance_type); - - let rev_reg_id = make_revocation_registry_id(origin_did, cred_def, tag, rev_reg_type)?; + trace!("create_revocation_registry >>> cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}, issuance_type: {:?}", + cred_def, tag, max_cred_num, rev_reg_type, issuance_type); let cred_def = match cred_def { CredentialDefinition::CredentialDefinitionV1(c) => c, @@ -219,10 +149,9 @@ where let revoc_reg_def = RevocationRegistryDefinition::RevocationRegistryDefinitionV1( RevocationRegistryDefinitionV1 { - id: rev_reg_id.clone(), revoc_def_type: rev_reg_type, tag: tag.to_string(), - cred_def_id: cred_def.id.clone(), + cred_def_id: cred_def_id.to_owned(), value: revoc_reg_def_value, }, ); @@ -291,24 +220,20 @@ pub fn update_revocation_registry( } pub fn create_credential_offer( - schema_id: &SchemaId, - cred_def: &CredentialDefinition, + schema_id: &str, + cred_def_id: &str, correctness_proof: &CredentialKeyCorrectnessProof, ) -> Result { - trace!("create_credential_offer >>> cred_def: {:?}", cred_def); + trace!("create_credential_offer >>> cred_def_id: {:?}", cred_def_id); let nonce = Nonce::new().map_err(err_map!(Unexpected, "Error creating nonce"))?; - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(c) => c, - }; - let key_correctness_proof = correctness_proof .try_clone() .map_err(err_map!(Unexpected))?; let credential_offer = CredentialOffer { - schema_id: schema_id.clone(), - cred_def_id: cred_def.id.clone(), + schema_id: schema_id.to_owned(), + cred_def_id: cred_def_id.to_owned(), key_correctness_proof: key_correctness_proof.value, nonce, method_name: None, @@ -324,6 +249,7 @@ pub fn create_credential( cred_offer: &CredentialOffer, cred_request: &CredentialRequest, cred_values: CredentialValues, + rev_reg_id: Option, revocation_config: Option, ) -> Result<( Credential, @@ -345,25 +271,64 @@ pub fn create_credential( }; let credential_values = build_credential_values(&cred_values.0, None)?; - let ( - credential_signature, - signature_correctness_proof, - rev_reg_id, - rev_reg, - rev_reg_delta, - witness, - ) = match revocation_config { - Some(revocation) => { - let (rev_reg_def, reg_reg_id) = match revocation.reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => { - (&v1.value, v1.id.clone()) - } - }; - let mut rev_reg = match revocation.registry { - RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), - }; - let (credential_signature, signature_correctness_proof, delta) = - CryptoIssuer::sign_credential_with_revoc( + let (credential_signature, signature_correctness_proof, rev_reg, rev_reg_delta, witness) = + match revocation_config { + Some(revocation) => { + let rev_reg_def = match revocation.reg_def { + RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => &v1.value, + }; + let mut rev_reg = match revocation.registry { + RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), + }; + let (credential_signature, signature_correctness_proof, delta) = + CryptoIssuer::sign_credential_with_revoc( + &cred_request.prover_did.0, + &cred_request.blinded_ms, + &cred_request.blinded_ms_correctness_proof, + cred_offer.nonce.as_native(), + cred_request.nonce.as_native(), + &credential_values, + &cred_public_key, + &cred_def_private.value, + revocation.registry_idx, + rev_reg_def.max_cred_num, + rev_reg_def.issuance_type.to_bool(), + &mut rev_reg, + &revocation.reg_def_private.value, + &revocation.tails_reader, + )?; + + let witness = { + let empty = HashSet::new(); + let (by_default, issued, revoked) = match rev_reg_def.issuance_type { + IssuanceType::ISSUANCE_ON_DEMAND => { + (false, revocation.registry_used, &empty) + } + IssuanceType::ISSUANCE_BY_DEFAULT => { + (true, &empty, revocation.registry_used) + } + }; + + let rev_reg_delta = + CryptoRevocationRegistryDelta::from_parts(None, &rev_reg, issued, revoked); + Witness::new( + revocation.registry_idx, + rev_reg_def.max_cred_num, + by_default, + &rev_reg_delta, + &revocation.tails_reader, + )? + }; + ( + credential_signature, + signature_correctness_proof, + Some(rev_reg), + delta, + Some(witness), + ) + } + None => { + let (signature, correctness_proof) = CryptoIssuer::sign_credential( &cred_request.prover_did.0, &cred_request.blinded_ms, &cred_request.blinded_ms_correctness_proof, @@ -372,58 +337,10 @@ pub fn create_credential( &credential_values, &cred_public_key, &cred_def_private.value, - revocation.registry_idx, - rev_reg_def.max_cred_num, - rev_reg_def.issuance_type.to_bool(), - &mut rev_reg, - &revocation.reg_def_private.value, - &revocation.tails_reader, )?; - - let cred_rev_reg_id = match cred_offer.method_name.as_ref() { - Some(ref _method_name) => Some(reg_reg_id.to_unqualified()), - _ => Some(reg_reg_id.clone()), - }; - let witness = { - let empty = HashSet::new(); - let (by_default, issued, revoked) = match rev_reg_def.issuance_type { - IssuanceType::ISSUANCE_ON_DEMAND => (false, revocation.registry_used, &empty), - IssuanceType::ISSUANCE_BY_DEFAULT => (true, &empty, revocation.registry_used), - }; - - let rev_reg_delta = - CryptoRevocationRegistryDelta::from_parts(None, &rev_reg, issued, revoked); - Witness::new( - revocation.registry_idx, - rev_reg_def.max_cred_num, - by_default, - &rev_reg_delta, - &revocation.tails_reader, - )? - }; - ( - credential_signature, - signature_correctness_proof, - cred_rev_reg_id, - Some(rev_reg), - delta, - Some(witness), - ) - } - None => { - let (signature, correctness_proof) = CryptoIssuer::sign_credential( - &cred_request.prover_did.0, - &cred_request.blinded_ms, - &cred_request.blinded_ms_correctness_proof, - cred_offer.nonce.as_native(), - cred_request.nonce.as_native(), - &credential_values, - &cred_public_key, - &cred_def_private.value, - )?; - (signature, correctness_proof, None, None, None, None) - } - }; + (signature, correctness_proof, None, None, None) + } + }; let credential = Credential { schema_id: cred_offer.schema_id.clone(), diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index 5b793cec..3e6fdbe1 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -16,7 +16,7 @@ use crate::ursa::cl::{ verifier::Verifier as CryptoVerifier, CredentialPublicKey, RevocationRegistry as CryptoRevocationRegistry, SubProofRequest, Witness, }; -use indy_utils::{Qualifiable, Validatable}; +use indy_utils::Validatable; use super::tails::TailsReader; @@ -131,8 +131,8 @@ pub fn create_presentation( credentials: PresentCredentials, self_attested: Option>, master_secret: &MasterSecret, - schemas: &HashMap, - cred_defs: &HashMap, + schemas: &HashMap, + cred_defs: &HashMap, ) -> Result { trace!("create_proof >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, self_attested: {:?}, master_secret: {:?}, schemas: {:?}, cred_defs: {:?}", credentials, pres_req, credentials, &self_attested, secret!(&master_secret), schemas, cred_defs); @@ -213,9 +213,9 @@ pub fn create_presentation( let identifier = match pres_req { PresentationRequest::PresentationRequestV1(_) => Identifier { - schema_id: credential.schema_id.to_unqualified(), - cred_def_id: credential.cred_def_id.to_unqualified(), - rev_reg_id: credential.rev_reg_id.as_ref().map(|id| id.to_unqualified()), + schema_id: credential.schema_id.clone(), + cred_def_id: credential.cred_def_id.clone(), + rev_reg_id: credential.rev_reg_id.clone(), timestamp: present.timestamp, }, PresentationRequest::PresentationRequestV2(_) => Identifier { diff --git a/anoncreds/src/services/types.rs b/anoncreds/src/services/types.rs index 6331a460..b93b9497 100644 --- a/anoncreds/src/services/types.rs +++ b/anoncreds/src/services/types.rs @@ -1,27 +1,25 @@ use std::collections::HashSet; use super::tails::TailsReader; -pub use crate::data_types::{ - anoncreds::{ - cred_def::{ - CredentialDefinition, CredentialDefinitionPrivate, CredentialKeyCorrectnessProof, - SignatureType, - }, - cred_offer::CredentialOffer, - cred_request::{CredentialRequest, CredentialRequestMetadata}, - credential::{AttributeValues, Credential, CredentialValues}, - master_secret::MasterSecret, - pres_request::PresentationRequest, - presentation::Presentation, - rev_reg::{RevocationRegistry, RevocationRegistryDelta}, - rev_reg_def::{ - IssuanceType, RegistryType, RevocationRegistryDefinition, - RevocationRegistryDefinitionPrivate, - }, - schema::{AttributeNames, Schema}, +pub use crate::data_types::anoncreds::{ + cred_def::{ + CredentialDefinition, CredentialDefinitionPrivate, CredentialKeyCorrectnessProof, + SignatureType, }, - CredentialDefinitionId, RevocationRegistryId, SchemaId, + cred_offer::CredentialOffer, + cred_request::{CredentialRequest, CredentialRequestMetadata}, + credential::{AttributeValues, Credential, CredentialValues}, + master_secret::MasterSecret, + pres_request::PresentationRequest, + presentation::Presentation, + rev_reg::{RevocationRegistry, RevocationRegistryDelta}, + rev_reg_def::{ + IssuanceType, RegistryType, RevocationRegistryDefinition, + RevocationRegistryDefinitionPrivate, + }, + schema::{AttributeNames, Schema}, }; + pub use indy_utils::did::DidValue; use indy_utils::{invalid, Validatable, ValidationError}; diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index bd132c4a..20829536 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -30,10 +30,10 @@ static INTERNAL_TAG_MATCHER: Lazy = pub fn verify_presentation( presentation: &Presentation, pres_req: &PresentationRequest, - schemas: &HashMap, - cred_defs: &HashMap, - rev_reg_defs: Option<&HashMap>, - rev_regs: Option<&HashMap>>, + schemas: &HashMap, + cred_defs: &HashMap, + rev_reg_defs: Option<&HashMap>, + rev_regs: Option<&HashMap>>, ) -> Result { trace!("verify >>> presentation: {:?}, pres_req: {:?}, schemas: {:?}, cred_defs: {:?}, rev_reg_defs: {:?} rev_regs: {:?}", presentation, pres_req, schemas, cred_defs, rev_reg_defs, rev_regs); @@ -675,28 +675,26 @@ fn gather_filter_info(referent: &str, identifiers: &HashMap) ) })?; - let (_, schema_issuer_did, schema_name, schema_version) = - identifier.schema_id.parts().ok_or_else(|| { - err_msg!( - "Invalid Schema ID `{}`: wrong number of parts", - identifier.schema_id.0 - ) - })?; + // TODO: how can we get these as as we can not extract them from the ID anymore + let schema_name = String::from(""); + let schema_version = String::from(""); + let schema_issuer_did = String::from(""); + let cred_def_issuer_did = Some(String::from("")); - let issuer_did = identifier.cred_def_id.issuer_did().ok_or_else(|| { + let issuer_did = cred_def_issuer_did.ok_or_else(|| { err_msg!( "Invalid Credential Definition ID `{}`: wrong number of parts", - identifier.cred_def_id.0 + identifier.cred_def_id ) })?; Ok(Filter { - schema_id: identifier.schema_id.0.to_string(), + schema_id: identifier.schema_id.clone(), schema_name, - schema_issuer_did: schema_issuer_did.0, + schema_issuer_did, schema_version, - cred_def_id: identifier.cred_def_id.0.to_string(), - issuer_did: issuer_did.0, + cred_def_id: identifier.cred_def_id.clone(), + issuer_did, }) } @@ -1166,20 +1164,21 @@ mod tests { let mut res: HashMap = HashMap::new(); res.insert( "referent_1".to_string(), + // TODO: what does this do Identifier { timestamp: Some(1234), - schema_id: SchemaId(String::new()), - cred_def_id: CredentialDefinitionId(String::new()), - rev_reg_id: Some(RevocationRegistryId(String::new())), + schema_id: String::new(), + cred_def_id: String::new(), + rev_reg_id: Some(String::new()), }, ); res.insert( "referent_2".to_string(), Identifier { timestamp: None, - schema_id: SchemaId(String::new()), - cred_def_id: CredentialDefinitionId(String::new()), - rev_reg_id: Some(RevocationRegistryId(String::new())), + schema_id: String::new(), + cred_def_id: String::new(), + rev_reg_id: Some(String::new()), }, ); res From c9de6d280093a6ba5d8a17e60aae17768f85c9f0 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 7 Dec 2022 17:35:20 +0100 Subject: [PATCH 02/17] tests pass Signed-off-by: blu3beri --- .../src/data_types/anoncreds/pres_request.rs | 100 ------------------ .../src/data_types/anoncreds/rev_reg_def.rs | 17 --- anoncreds/src/data_types/anoncreds/schema.rs | 4 +- anoncreds/tests/anoncreds_demos.rs | 12 +-- 4 files changed, 8 insertions(+), 125 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/pres_request.rs b/anoncreds/src/data_types/anoncreds/pres_request.rs index 15355a14..5a76995a 100644 --- a/anoncreds/src/data_types/anoncreds/pres_request.rs +++ b/anoncreds/src/data_types/anoncreds/pres_request.rs @@ -328,104 +328,4 @@ mod tests { serde_json::from_str::(&req_json).unwrap_err(); } } - - mod to_unqualified { - use super::*; - - const DID_QUALIFIED: &str = "did:sov:NcYxiDXkpYi6ov5FcYDi1e"; - const DID_UNQUALIFIED: &str = "NcYxiDXkpYi6ov5FcYDi1e"; - const SCHEMA_ID_QUALIFIED: &str = "schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0"; - const SCHEMA_ID_UNQUALIFIED: &str = "NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0"; - const CRED_DEF_ID_QUALIFIED: &str = "creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag"; - const CRED_DEF_ID_UNQUALIFIED: &str = - "NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag"; - const REV_REG_ID_QUALIFIED: &str = "revreg:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:4:creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag:CL_ACCUM:TAG_1"; - const REV_REG_ID_UNQUALIFIED: &str = "NcYxiDXkpYi6ov5FcYDi1e:4:NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag:CL_ACCUM:TAG_1"; - - #[test] - fn presentation_request_to_unqualified() { - let mut requested_attributes: HashMap = HashMap::new(); - requested_attributes.insert( - "attr1_referent".to_string(), - AttributeInfo { - name: Some("name".to_string()), - names: None, - restrictions: Some(Query::And(vec![ - Query::Eq("issuer_did".to_string(), DID_QUALIFIED.to_string()), - Query::Eq("schema_id".to_string(), SCHEMA_ID_QUALIFIED.to_string()), - Query::Eq("cred_def_id".to_string(), CRED_DEF_ID_QUALIFIED.to_string()), - ])), - non_revoked: None, - }, - ); - - let mut requested_predicates: HashMap = HashMap::new(); - requested_predicates.insert( - "predicate1_referent".to_string(), - PredicateInfo { - name: "age".to_string(), - p_type: PredicateTypes::GE, - p_value: 0, - restrictions: Some(Query::And(vec![ - Query::Eq("schema_issuer_did".to_string(), DID_QUALIFIED.to_string()), - Query::Eq("rev_reg_id".to_string(), REV_REG_ID_QUALIFIED.to_string()), - ])), - non_revoked: None, - }, - ); - - let request = PresentationRequest::PresentationRequestV2(PresentationRequestPayload { - nonce: Nonce::from_dec("112233445566").unwrap(), //Nonce::new().unwrap(), - name: "presentation_request_to_unqualified".to_string(), - version: "1.0".to_string(), - requested_attributes, - requested_predicates, - non_revoked: None, - }); - - let mut expected_requested_attributes: HashMap = HashMap::new(); - expected_requested_attributes.insert( - "attr1_referent".to_string(), - AttributeInfo { - name: Some("name".to_string()), - names: None, - restrictions: Some(Query::And(vec![ - Query::Eq("issuer_did".to_string(), DID_UNQUALIFIED.to_string()), - Query::Eq("schema_id".to_string(), SCHEMA_ID_UNQUALIFIED.to_string()), - Query::Eq( - "cred_def_id".to_string(), - CRED_DEF_ID_UNQUALIFIED.to_string(), - ), - ])), - non_revoked: None, - }, - ); - - let mut expected_requested_predicates: HashMap = HashMap::new(); - expected_requested_predicates.insert( - "predicate1_referent".to_string(), - PredicateInfo { - name: "age".to_string(), - p_type: PredicateTypes::GE, - p_value: 0, - restrictions: Some(Query::And(vec![ - Query::Eq("schema_issuer_did".to_string(), DID_UNQUALIFIED.to_string()), - Query::Eq("rev_reg_id".to_string(), REV_REG_ID_UNQUALIFIED.to_string()), - ])), - non_revoked: None, - }, - ); - - let request = request.to_unqualified(); - assert_eq!( - expected_requested_attributes, - request.value().requested_attributes - ); - assert_eq!( - expected_requested_predicates, - request.value().requested_predicates - ); - assert_eq!(PresentationRequestVersion::V2, request.version()); - } - } } diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index 3a1b4be8..0faabb1a 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -83,23 +83,6 @@ pub enum RevocationRegistryDefinition { RevocationRegistryDefinitionV1(RevocationRegistryDefinitionV1), } -impl RevocationRegistryDefinition { - pub fn to_unqualified(self) -> RevocationRegistryDefinition { - match self { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1( - RevocationRegistryDefinitionV1 { - revoc_def_type: v1.revoc_def_type, - tag: v1.tag, - cred_def_id: v1.cred_def_id, - value: v1.value, - }, - ) - } - } - } -} - #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct RevocationRegistryDefinitionV1 { diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index 2685615e..2694cd33 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -106,7 +106,7 @@ mod test_schema_validation { }) .to_string(); - let schema: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); + let _: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); } #[test] @@ -119,6 +119,6 @@ mod test_schema_validation { }) .to_string(); - let schema: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); + let _: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); } } diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 9ae775bd..b8e9edcd 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -25,7 +25,6 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates Schema - would be published to the ledger let gvt_schema = issuer::create_schema( - &issuer_wallet.did, GVT_SCHEMA_NAME, "1.0", GVT_SCHEMA_ATTRIBUTES[..].into(), @@ -35,7 +34,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates Credential Definition let cred_def_parts = issuer::create_credential_definition( - &issuer_wallet.did, + "SAMPLE_ID".to_owned(), &gvt_schema, "tag", SignatureType::CL, @@ -51,8 +50,8 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates a Credential Offer let cred_offer = issuer::create_credential_offer( - gvt_schema.id(), - &gvt_cred_def, + "SCHEMA_ID", + "CRED_DEF_ID", &issuer_wallet.cred_defs[0].key_proof, ) .expect("Error creating credential offer"); @@ -88,6 +87,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { &cred_request, cred_values.into(), None, + None, ) .expect("Error creating credential"); @@ -147,10 +147,10 @@ fn anoncreds_works_for_single_issuer_single_prover() { ); let mut schemas = HashMap::new(); - schemas.insert(gvt_schema.id().clone(), &gvt_schema); + schemas.insert(String::from("SCHEMA_ID"), &gvt_schema); let mut cred_defs = HashMap::new(); - cred_defs.insert(gvt_cred_def.id().clone(), &*gvt_cred_def); + cred_defs.insert(String::from("CRED_DEF_ID"), &*gvt_cred_def); let presentation = prover::create_presentation( &pres_request, From 38e9a55c379694112b04c9def4ad3807e79bbe4c Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 7 Dec 2022 17:47:36 +0100 Subject: [PATCH 03/17] brought back ffi method to get schema from cred def Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/schema.rs | 2 +- anoncreds/src/ffi/cred_def.rs | 27 +++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index 2694cd33..8cb00688 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -106,7 +106,7 @@ mod test_schema_validation { }) .to_string(); - let _: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); + let _: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); } #[test] diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index 4c8768ed..7bd58714 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -1,4 +1,6 @@ -use ffi_support::FfiStr; +use std::ffi::c_char; + +use ffi_support::{rust_string_to_c, FfiStr}; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; @@ -56,6 +58,29 @@ pub extern "C" fn anoncreds_create_credential_definition( }) } +#[no_mangle] +pub extern "C" fn anoncreds_credential_definition_get_attribute( + handle: ObjectHandle, + name: FfiStr, + result_p: *mut *const c_char, +) -> ErrorCode { + catch_error(|| { + check_useful_c_ptr!(result_p); + let cred_def = handle.load()?; + let cred_def = cred_def.cast_ref::()?; + let val = match name.as_opt_str().unwrap_or_default() { + "schema_id" => match cred_def { + CredentialDefinition::CredentialDefinitionV1(cred_def) => { + cred_def.schema_id.to_string() + } + }, + s => return Err(err_msg!("Unsupported attribute: {}", s)), + }; + unsafe { *result_p = rust_string_to_c(val) }; + Ok(()) + }) +} + impl_anoncreds_object!(CredentialDefinition, "CredentialDefinition"); impl_anoncreds_object_from_json!( CredentialDefinition, From 210a2df05b7d096c8d8332b09d0304afe53aa8a9 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 8 Dec 2022 10:34:25 +0100 Subject: [PATCH 04/17] added a wrapper around the SchemaId type Signed-off-by: blu3beri --- .../src/data_types/anoncreds/cred_def.rs | 4 ++- .../src/data_types/anoncreds/cred_offer.rs | 4 +-- .../src/data_types/anoncreds/credential.rs | 6 ++-- .../src/data_types/anoncreds/presentation.rs | 4 ++- anoncreds/src/data_types/anoncreds/schema.rs | 28 +++++++++++++++++++ anoncreds/src/ffi/cred_def.rs | 6 +++- anoncreds/src/ffi/cred_offer.rs | 6 +++- anoncreds/src/ffi/credential.rs | 2 +- anoncreds/src/ffi/object.rs | 7 +++-- anoncreds/src/ffi/presentation.rs | 13 +++++---- anoncreds/src/services/issuer.rs | 5 ++-- anoncreds/src/services/prover.rs | 4 +-- anoncreds/src/services/verifier.rs | 13 +++++---- 13 files changed, 75 insertions(+), 27 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/cred_def.rs b/anoncreds/src/data_types/anoncreds/cred_def.rs index ed0984de..fc9e268b 100644 --- a/anoncreds/src/data_types/anoncreds/cred_def.rs +++ b/anoncreds/src/data_types/anoncreds/cred_def.rs @@ -1,5 +1,7 @@ use crate::data_types::ConversionError; +use super::schema::SchemaId; + pub const CL_SIGNATURE_TYPE: &str = "CL"; #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -39,7 +41,7 @@ pub enum CredentialDefinition { #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CredentialDefinitionV1 { - pub schema_id: String, + pub schema_id: SchemaId, #[serde(rename = "type")] pub signature_type: SignatureType, pub tag: String, diff --git a/anoncreds/src/data_types/anoncreds/cred_offer.rs b/anoncreds/src/data_types/anoncreds/cred_offer.rs index 2c0bb570..6eb4999b 100644 --- a/anoncreds/src/data_types/anoncreds/cred_offer.rs +++ b/anoncreds/src/data_types/anoncreds/cred_offer.rs @@ -1,8 +1,8 @@ -use super::nonce::Nonce; +use super::{nonce::Nonce, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] pub struct CredentialOffer { - pub schema_id: String, + pub schema_id: SchemaId, pub cred_def_id: String, pub key_correctness_proof: ursa::cl::CredentialKeyCorrectnessProof, pub nonce: Nonce, diff --git a/anoncreds/src/data_types/anoncreds/credential.rs b/anoncreds/src/data_types/anoncreds/credential.rs index fb6f8cfe..27abb704 100644 --- a/anoncreds/src/data_types/anoncreds/credential.rs +++ b/anoncreds/src/data_types/anoncreds/credential.rs @@ -4,9 +4,11 @@ use zeroize::Zeroize; use crate::data_types::{Validatable, ValidationError}; +use super::schema::SchemaId; + #[derive(Debug, Deserialize, Serialize)] pub struct Credential { - pub schema_id: String, + pub schema_id: SchemaId, pub cred_def_id: String, pub rev_reg_id: Option, pub values: CredentialValues, @@ -64,7 +66,7 @@ impl Validatable for Credential { pub struct CredentialInfo { pub referent: String, pub attrs: ShortCredentialValues, - pub schema_id: String, + pub schema_id: SchemaId, pub cred_def_id: String, pub rev_reg_id: Option, pub cred_rev_id: Option, diff --git a/anoncreds/src/data_types/anoncreds/presentation.rs b/anoncreds/src/data_types/anoncreds/presentation.rs index f5167122..4aa90650 100644 --- a/anoncreds/src/data_types/anoncreds/presentation.rs +++ b/anoncreds/src/data_types/anoncreds/presentation.rs @@ -2,6 +2,8 @@ use std::collections::HashMap; use crate::data_types::Validatable; +use super::schema::SchemaId; + #[derive(Debug, Deserialize, Serialize)] pub struct Presentation { pub proof: ursa::cl::Proof, @@ -61,7 +63,7 @@ pub struct AttributeValue { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct Identifier { - pub schema_id: String, + pub schema_id: SchemaId, pub cred_def_id: String, pub rev_reg_id: Option, pub timestamp: Option, diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index 8cb00688..e1776f5e 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -1,10 +1,38 @@ use crate::data_types::{Validatable, ValidationError}; use std::collections::HashSet; +use std::fmt::Display; use std::iter::FromIterator; pub const MAX_ATTRIBUTES_COUNT: usize = 125; +#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Default)] +pub struct SchemaId(String); + +impl SchemaId { + pub fn new(schema_id: String) -> Self { + SchemaId(schema_id) + } +} + +impl Into for SchemaId { + fn into(self) -> String { + self.0 + } +} + +impl<'a> Into<&'a str> for SchemaId { + fn into(self) -> &'a str { + self.0.as_str() + } +} + +impl Display for SchemaId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(tag = "ver")] pub enum Schema { diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index 7bd58714..c329c223 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -4,6 +4,7 @@ use ffi_support::{rust_string_to_c, FfiStr}; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; +use crate::data_types::anoncreds::schema::SchemaId; use crate::services::{ issuer::create_credential_definition, types::{ @@ -28,9 +29,12 @@ pub extern "C" fn anoncreds_create_credential_definition( check_useful_c_ptr!(cred_def_pvt_p); check_useful_c_ptr!(key_proof_p); let tag = tag.as_opt_str().ok_or_else(|| err_msg!("Missing tag"))?; - let schema_id = schema_id + let schema_id = { + let schema_id = schema_id .as_opt_str() .ok_or_else(|| err_msg!("Missing schema id"))?; + SchemaId::new(schema_id.to_owned()) + }; let signature_type = { let stype = signature_type .as_opt_str() diff --git a/anoncreds/src/ffi/cred_offer.rs b/anoncreds/src/ffi/cred_offer.rs index 0d59af3c..69e80da1 100644 --- a/anoncreds/src/ffi/cred_offer.rs +++ b/anoncreds/src/ffi/cred_offer.rs @@ -2,6 +2,7 @@ use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; +use crate::data_types::anoncreds::schema::SchemaId; use crate::services::{issuer::create_credential_offer, types::CredentialOffer}; #[no_mangle] @@ -13,9 +14,12 @@ pub extern "C" fn anoncreds_create_credential_offer( ) -> ErrorCode { catch_error(|| { check_useful_c_ptr!(cred_offer_p); - let schema_id = schema_id + let schema_id = { + let schema_id = schema_id .as_opt_str() .ok_or_else(|| err_msg!("Missing schema ID"))?; + SchemaId::new(schema_id.to_string()) + }; let cred_def_id = cred_def_id .as_opt_str() .ok_or_else(|| err_msg!("Missing cred def ID"))?; diff --git a/anoncreds/src/ffi/credential.rs b/anoncreds/src/ffi/credential.rs index 15456d26..8abdc241 100644 --- a/anoncreds/src/ffi/credential.rs +++ b/anoncreds/src/ffi/credential.rs @@ -233,7 +233,7 @@ pub extern "C" fn anoncreds_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.schema_id.to_string()), + "schema_id" => rust_string_to_c(cred.schema_id.to_owned()), "cred_def_id" => rust_string_to_c(cred.cred_def_id.to_string()), "rev_reg_id" => cred .rev_reg_id diff --git a/anoncreds/src/ffi/object.rs b/anoncreds/src/ffi/object.rs index 8dc1885b..68a07f44 100644 --- a/anoncreds/src/ffi/object.rs +++ b/anoncreds/src/ffi/object.rs @@ -1,4 +1,5 @@ use std::any::TypeId; +use std::cmp::Eq; use std::collections::{BTreeMap, HashMap}; use std::fmt::Debug; use std::hash::{Hash, Hasher}; @@ -233,14 +234,14 @@ impl AnonCredsObjectList { Ok(refs) } - pub fn refs_map(&self, ids: &[String]) -> Result> + pub fn refs_map(&self, ids: &[I]) -> Result> where - T: AnyAnonCredsObject + 'static, + T: AnyAnonCredsObject + 'static, I: Eq + Hash, { let mut refs = HashMap::with_capacity(self.0.len()); for (inst, id) in self.0.iter().zip(ids) { let inst = inst.cast_ref::()?; - refs.insert(id.to_owned(), inst); + refs.insert(id, inst); } Ok(refs) } diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index 2e014075..4b035c9a 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -6,6 +6,7 @@ use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; use super::object::{AnonCredsObject, AnonCredsObjectList, ObjectHandle}; use super::util::{FfiList, FfiStrList}; +use crate::data_types::anoncreds::schema::{SchemaId, Schema}; use crate::error::Result; use crate::services::{ prover::create_presentation, @@ -161,13 +162,13 @@ pub extern "C" fn anoncreds_create_presentation( } } - let schema_ids: Vec = schema_ids + let schema_ids: Vec = schema_ids .as_slice() .iter() - .map(|s| s.as_str().to_owned()) + .map(|s| SchemaId::new(s.as_str().to_owned())) .collect(); let schemas = AnonCredsObjectList::load(schemas.as_slice())?; - let schemas = schemas.refs_map(&schema_ids)?; + let schemas = schemas.refs_map::(&schema_ids)?; let cred_def_ids: Vec = cred_def_ids .as_slice() @@ -266,13 +267,13 @@ pub extern "C" fn anoncreds_verify_presentation( .insert(*timestamp, entry.cast_ref()?); } - let schema_ids: Vec = schema_ids + let schema_ids: Vec = schema_ids .as_slice() .iter() - .map(|s| s.as_str().to_owned()) + .map(|s| SchemaId::new(s.as_str().to_owned())) .collect(); let schemas = AnonCredsObjectList::load(schemas.as_slice())?; - let schemas = schemas.refs_map(&schema_ids)?; + let schemas = schemas.refs_map::(&schema_ids)?; let cred_def_ids: Vec = cred_def_ids .as_slice() diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index 8c9c35d7..16aeedad 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -2,6 +2,7 @@ use std::collections::{BTreeSet, HashSet}; use std::iter::FromIterator; use super::types::*; +use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ cred_def::{CredentialDefinitionData, CredentialDefinitionV1}, nonce::Nonce, @@ -44,7 +45,7 @@ pub fn create_schema( } pub fn create_credential_definition( - schema_id: String, + schema_id: SchemaId, schema: &Schema, tag: &str, signature_type: SignatureType, @@ -220,7 +221,7 @@ pub fn update_revocation_registry( } pub fn create_credential_offer( - schema_id: &str, + schema_id: SchemaId, cred_def_id: &str, correctness_proof: &CredentialKeyCorrectnessProof, ) -> Result { diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index 3e6fdbe1..f992acf0 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -7,7 +7,7 @@ use crate::data_types::anoncreds::{ presentation::{ AttributeValue, Identifier, RequestedProof, RevealedAttributeGroupInfo, RevealedAttributeInfo, SubProofReferent, - }, + }, schema::SchemaId, }; use crate::error::Result; use crate::services::helpers::*; @@ -131,7 +131,7 @@ pub fn create_presentation( credentials: PresentCredentials, self_attested: Option>, master_secret: &MasterSecret, - schemas: &HashMap, + schemas: &HashMap<&SchemaId, &Schema>, cred_defs: &HashMap, ) -> Result { trace!("create_proof >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, self_attested: {:?}, master_secret: {:?}, schemas: {:?}, cred_defs: {:?}", diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index 20829536..d466948e 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -5,6 +5,7 @@ use regex::Regex; use super::helpers::*; use super::types::*; +use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ nonce::Nonce, pres_request::{AttributeInfo, NonRevocedInterval, PredicateInfo, PresentationRequestPayload}, @@ -16,7 +17,7 @@ use indy_utils::query::Query; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Filter { - schema_id: String, + schema_id: SchemaId, schema_issuer_did: String, schema_name: String, schema_version: String, @@ -30,7 +31,7 @@ static INTERNAL_TAG_MATCHER: Lazy = pub fn verify_presentation( presentation: &Presentation, pres_req: &PresentationRequest, - schemas: &HashMap, + schemas: &HashMap<&SchemaId, &Schema>, cred_defs: &HashMap, rev_reg_defs: Option<&HashMap>, rev_regs: Option<&HashMap>>, @@ -781,7 +782,7 @@ fn process_filter( filter ); match tag { - tag_ @ "schema_id" => precess_filed(tag_, &filter.schema_id, tag_value), + tag_ @ "schema_id" => precess_filed(tag_, filter.schema_id.into(), tag_value), tag_ @ "schema_issuer_did" => precess_filed(tag_, &filter.schema_issuer_did, tag_value), tag_ @ "schema_name" => precess_filed(tag_, &filter.schema_name, tag_value), tag_ @ "schema_version" => precess_filed(tag_, &filter.schema_version, tag_value), @@ -851,6 +852,8 @@ fn is_attr_operator(key: &str) -> bool { #[cfg(test)] mod tests { + use crate::data_types::anoncreds::schema::SchemaV1; + use super::*; pub const SCHEMA_ID: &str = "123"; @@ -1167,7 +1170,7 @@ mod tests { // TODO: what does this do Identifier { timestamp: Some(1234), - schema_id: String::new(), + schema_id: SchemaId::default(), cred_def_id: String::new(), rev_reg_id: Some(String::new()), }, @@ -1176,7 +1179,7 @@ mod tests { "referent_2".to_string(), Identifier { timestamp: None, - schema_id: String::new(), + schema_id: SchemaId::default(), cred_def_id: String::new(), rev_reg_id: Some(String::new()), }, From d3e6205376a832e347fdbf0a8dbfc1909f3fdace Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 8 Dec 2022 10:51:25 +0100 Subject: [PATCH 05/17] ran formatter Signed-off-by: blu3beri --- anoncreds/src/ffi/cred_def.rs | 4 ++-- anoncreds/src/ffi/cred_offer.rs | 4 ++-- anoncreds/src/ffi/object.rs | 3 ++- anoncreds/src/ffi/presentation.rs | 2 +- anoncreds/src/services/prover.rs | 3 ++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index c329c223..8734d3ba 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -31,8 +31,8 @@ pub extern "C" fn anoncreds_create_credential_definition( let tag = tag.as_opt_str().ok_or_else(|| err_msg!("Missing tag"))?; let schema_id = { let schema_id = schema_id - .as_opt_str() - .ok_or_else(|| err_msg!("Missing schema id"))?; + .as_opt_str() + .ok_or_else(|| err_msg!("Missing schema id"))?; SchemaId::new(schema_id.to_owned()) }; let signature_type = { diff --git a/anoncreds/src/ffi/cred_offer.rs b/anoncreds/src/ffi/cred_offer.rs index 69e80da1..f7dd3ce0 100644 --- a/anoncreds/src/ffi/cred_offer.rs +++ b/anoncreds/src/ffi/cred_offer.rs @@ -16,8 +16,8 @@ pub extern "C" fn anoncreds_create_credential_offer( check_useful_c_ptr!(cred_offer_p); let schema_id = { let schema_id = schema_id - .as_opt_str() - .ok_or_else(|| err_msg!("Missing schema ID"))?; + .as_opt_str() + .ok_or_else(|| err_msg!("Missing schema ID"))?; SchemaId::new(schema_id.to_string()) }; let cred_def_id = cred_def_id diff --git a/anoncreds/src/ffi/object.rs b/anoncreds/src/ffi/object.rs index 68a07f44..e0936183 100644 --- a/anoncreds/src/ffi/object.rs +++ b/anoncreds/src/ffi/object.rs @@ -236,7 +236,8 @@ impl AnonCredsObjectList { pub fn refs_map(&self, ids: &[I]) -> Result> where - T: AnyAnonCredsObject + 'static, I: Eq + Hash, + T: AnyAnonCredsObject + 'static, + I: Eq + Hash, { let mut refs = HashMap::with_capacity(self.0.len()); for (inst, id) in self.0.iter().zip(ids) { diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index 4b035c9a..0a8a188e 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -6,7 +6,7 @@ use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; use super::object::{AnonCredsObject, AnonCredsObjectList, ObjectHandle}; use super::util::{FfiList, FfiStrList}; -use crate::data_types::anoncreds::schema::{SchemaId, Schema}; +use crate::data_types::anoncreds::schema::{Schema, SchemaId}; use crate::error::Result; use crate::services::{ prover::create_presentation, diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index f992acf0..51635272 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -7,7 +7,8 @@ use crate::data_types::anoncreds::{ presentation::{ AttributeValue, Identifier, RequestedProof, RevealedAttributeGroupInfo, RevealedAttributeInfo, SubProofReferent, - }, schema::SchemaId, + }, + schema::SchemaId, }; use crate::error::Result; use crate::services::helpers::*; From 39667a0e4614ac26219480d19b0358d150f64614 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 8 Dec 2022 16:42:35 +0100 Subject: [PATCH 06/17] added thin wrapper around anoncred ids Signed-off-by: blu3beri --- .../src/data_types/anoncreds/cred_def.rs | 4 +- anoncreds/src/data_types/anoncreds/macros.rs | 38 +++++++++++++++++++ anoncreds/src/data_types/anoncreds/mod.rs | 3 ++ .../src/data_types/anoncreds/rev_reg_def.rs | 4 +- anoncreds/src/data_types/anoncreds/schema.rs | 29 +------------- anoncreds/src/ffi/cred_def.rs | 2 +- anoncreds/src/ffi/object.rs | 2 +- anoncreds/src/ffi/presentation.rs | 20 +++++----- anoncreds/src/services/issuer.rs | 8 ++-- anoncreds/src/services/prover.rs | 6 ++- anoncreds/src/services/verifier.rs | 23 ++++++----- anoncreds/tests/anoncreds_demos.rs | 8 ++-- 12 files changed, 88 insertions(+), 59 deletions(-) create mode 100644 anoncreds/src/data_types/anoncreds/macros.rs diff --git a/anoncreds/src/data_types/anoncreds/cred_def.rs b/anoncreds/src/data_types/anoncreds/cred_def.rs index fc9e268b..681e6754 100644 --- a/anoncreds/src/data_types/anoncreds/cred_def.rs +++ b/anoncreds/src/data_types/anoncreds/cred_def.rs @@ -1,9 +1,11 @@ -use crate::data_types::ConversionError; +use crate::{data_types::ConversionError, impl_anoncreds_object_identifier}; use super::schema::SchemaId; pub const CL_SIGNATURE_TYPE: &str = "CL"; +impl_anoncreds_object_identifier!(CredentialDefinitionId); + #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum SignatureType { CL, diff --git a/anoncreds/src/data_types/anoncreds/macros.rs b/anoncreds/src/data_types/anoncreds/macros.rs new file mode 100644 index 00000000..06661ead --- /dev/null +++ b/anoncreds/src/data_types/anoncreds/macros.rs @@ -0,0 +1,38 @@ +#[macro_export] +macro_rules! impl_anoncreds_object_identifier { + + ($i:ident) => { + #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Default)] + pub struct $i(pub String); + + impl $i { + pub fn new(s: impl Into) -> Self { + Self(s.into()) + } + } + + impl Into for $i { + fn into(self) -> String { + self.0 + } + } + + impl From for $i { + fn from(value: String) -> Self { + $i::new(value) + } + } + + impl From<&str> for $i { + fn from(value: &str) -> Self { + $i::new(value.to_owned()) + } + } + + impl std::fmt::Display for $i { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } + } + } +} diff --git a/anoncreds/src/data_types/anoncreds/mod.rs b/anoncreds/src/data_types/anoncreds/mod.rs index 3d815be1..a6a8bc3c 100644 --- a/anoncreds/src/data_types/anoncreds/mod.rs +++ b/anoncreds/src/data_types/anoncreds/mod.rs @@ -30,3 +30,6 @@ pub mod rev_reg_def; /// V1 credential schemas pub mod schema; + +/// Macros for the data types +pub mod macros; diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index 0faabb1a..c357a4c0 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -1,10 +1,12 @@ -use crate::data_types::{invalid, ConversionError, Validatable, ValidationError}; +use crate::{data_types::{invalid, ConversionError, Validatable, ValidationError}, impl_anoncreds_object_identifier}; pub const CL_ACCUM: &str = "CL_ACCUM"; pub const ISSUANCE_BY_DEFAULT: &str = "ISSUANCE_BY_DEFAULT"; pub const ISSUANCE_ON_DEMAND: &str = "ISSUANCE_ON_DEMAND"; +impl_anoncreds_object_identifier!(RevocationRegistryDefinitionId); + #[allow(non_camel_case_types)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum IssuanceType { diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index e1776f5e..60a28440 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -1,37 +1,12 @@ use crate::data_types::{Validatable, ValidationError}; +use crate::impl_anoncreds_object_identifier; use std::collections::HashSet; -use std::fmt::Display; use std::iter::FromIterator; pub const MAX_ATTRIBUTES_COUNT: usize = 125; -#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Default)] -pub struct SchemaId(String); - -impl SchemaId { - pub fn new(schema_id: String) -> Self { - SchemaId(schema_id) - } -} - -impl Into for SchemaId { - fn into(self) -> String { - self.0 - } -} - -impl<'a> Into<&'a str> for SchemaId { - fn into(self) -> &'a str { - self.0.as_str() - } -} - -impl Display for SchemaId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} +impl_anoncreds_object_identifier!(SchemaId); #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(tag = "ver")] diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index 8734d3ba..92cf423c 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -75,7 +75,7 @@ pub extern "C" fn anoncreds_credential_definition_get_attribute( let val = match name.as_opt_str().unwrap_or_default() { "schema_id" => match cred_def { CredentialDefinition::CredentialDefinitionV1(cred_def) => { - cred_def.schema_id.to_string() + cred_def.schema_id.to_owned() } }, s => return Err(err_msg!("Unsupported attribute: {}", s)), diff --git a/anoncreds/src/ffi/object.rs b/anoncreds/src/ffi/object.rs index e0936183..539f8ad4 100644 --- a/anoncreds/src/ffi/object.rs +++ b/anoncreds/src/ffi/object.rs @@ -234,7 +234,7 @@ impl AnonCredsObjectList { Ok(refs) } - pub fn refs_map(&self, ids: &[I]) -> Result> + pub fn refs_map<'a, I, T>(&'a self, ids: &'a [I]) -> Result> where T: AnyAnonCredsObject + 'static, I: Eq + Hash, diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index 0a8a188e..65ae8aee 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -6,7 +6,9 @@ use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; use super::object::{AnonCredsObject, AnonCredsObjectList, ObjectHandle}; use super::util::{FfiList, FfiStrList}; +use crate::data_types::anoncreds::rev_reg_def::{RevocationRegistryDefinitionId, RevocationRegistryDefinition}; use crate::data_types::anoncreds::schema::{Schema, SchemaId}; +use crate::data_types::anoncreds::cred_def::{CredentialDefinition, CredentialDefinitionId}; use crate::error::Result; use crate::services::{ prover::create_presentation, @@ -170,13 +172,13 @@ pub extern "C" fn anoncreds_create_presentation( let schemas = AnonCredsObjectList::load(schemas.as_slice())?; let schemas = schemas.refs_map::(&schema_ids)?; - let cred_def_ids: Vec = cred_def_ids + let cred_def_ids: Vec = cred_def_ids .as_slice() .iter() - .map(|s| s.as_str().to_owned()) + .map(|s| CredentialDefinitionId::new(s.as_str().to_owned())) .collect(); let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let cred_defs = cred_defs.refs_map(&cred_def_ids)?; + let cred_defs = cred_defs.refs_map::(&cred_def_ids)?; let presentation = create_presentation( pres_req.load()?.cast_ref()?, @@ -275,21 +277,21 @@ pub extern "C" fn anoncreds_verify_presentation( let schemas = AnonCredsObjectList::load(schemas.as_slice())?; let schemas = schemas.refs_map::(&schema_ids)?; - let cred_def_ids: Vec = cred_def_ids + let cred_def_ids: Vec = cred_def_ids .as_slice() .iter() - .map(|s| s.as_str().to_owned()) + .map(|s| CredentialDefinitionId::new(s.as_str().to_owned())) .collect(); let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let cred_defs = cred_defs.refs_map(&cred_def_ids)?; + let cred_defs = cred_defs.refs_map::(&cred_def_ids)?; - let rev_reg_def_ids: Vec = rev_reg_def_ids + let rev_reg_def_ids: Vec = rev_reg_def_ids .as_slice() .iter() - .map(|s| s.as_str().to_owned()) + .map(|s| RevocationRegistryDefinitionId::new(s.as_str().to_owned())) .collect(); let rev_reg_defs = AnonCredsObjectList::load(rev_reg_defs.as_slice())?; - let rev_reg_defs = rev_reg_defs.refs_map(&rev_reg_def_ids)?; + let rev_reg_defs = rev_reg_defs.refs_map::(&rev_reg_def_ids)?; let verify = verify_presentation( presentation.load()?.cast_ref()?, diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index 16aeedad..cfc68d5a 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -45,7 +45,7 @@ pub fn create_schema( } pub fn create_credential_definition( - schema_id: SchemaId, + schema_id: impl Into, schema: &Schema, tag: &str, signature_type: SignatureType, @@ -76,7 +76,7 @@ pub fn create_credential_definition( )?; let cred_def = CredentialDefinition::CredentialDefinitionV1(CredentialDefinitionV1 { - schema_id: schema_id.to_owned(), + schema_id: schema_id.into().to_owned(), signature_type, tag: tag.to_owned(), value: CredentialDefinitionData { @@ -221,7 +221,7 @@ pub fn update_revocation_registry( } pub fn create_credential_offer( - schema_id: SchemaId, + schema_id: impl Into, cred_def_id: &str, correctness_proof: &CredentialKeyCorrectnessProof, ) -> Result { @@ -233,7 +233,7 @@ pub fn create_credential_offer( .try_clone() .map_err(err_map!(Unexpected))?; let credential_offer = CredentialOffer { - schema_id: schema_id.to_owned(), + schema_id: schema_id.into().to_owned(), cred_def_id: cred_def_id.to_owned(), key_correctness_proof: key_correctness_proof.value, nonce, diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index 51635272..b4483076 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -9,6 +9,7 @@ use crate::data_types::anoncreds::{ RevealedAttributeInfo, SubProofReferent, }, schema::SchemaId, + cred_def::CredentialDefinitionId, }; use crate::error::Result; use crate::services::helpers::*; @@ -133,7 +134,7 @@ pub fn create_presentation( self_attested: Option>, master_secret: &MasterSecret, schemas: &HashMap<&SchemaId, &Schema>, - cred_defs: &HashMap, + cred_defs: &HashMap<&CredentialDefinitionId, &CredentialDefinition>, ) -> Result { trace!("create_proof >>> credentials: {:?}, pres_req: {:?}, credentials: {:?}, self_attested: {:?}, master_secret: {:?}, schemas: {:?}, cred_defs: {:?}", credentials, pres_req, credentials, &self_attested, secret!(&master_secret), schemas, cred_defs); @@ -176,7 +177,8 @@ pub fn create_presentation( Schema::SchemaV1(schema) => schema, }; - let cred_def = *cred_defs.get(&credential.cred_def_id).ok_or_else(|| { + let cred_def_id = CredentialDefinitionId::new(credential.cred_def_id.clone()); + let cred_def = *cred_defs.get(&cred_def_id).ok_or_else(|| { err_msg!( "Credential Definition not provided for ID: {}", credential.cred_def_id diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index d466948e..c21f5889 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -5,6 +5,8 @@ use regex::Regex; use super::helpers::*; use super::types::*; +use crate::data_types::anoncreds::cred_def::CredentialDefinitionId; +use crate::data_types::anoncreds::rev_reg_def::RevocationRegistryDefinitionId; use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ nonce::Nonce, @@ -32,8 +34,8 @@ pub fn verify_presentation( presentation: &Presentation, pres_req: &PresentationRequest, schemas: &HashMap<&SchemaId, &Schema>, - cred_defs: &HashMap, - rev_reg_defs: Option<&HashMap>, + cred_defs: &HashMap<&CredentialDefinitionId, &CredentialDefinition>, + rev_reg_defs: Option<&HashMap<&RevocationRegistryDefinitionId, &RevocationRegistryDefinition>>, rev_regs: Option<&HashMap>>, ) -> Result { trace!("verify >>> presentation: {:?}, pres_req: {:?}, schemas: {:?}, cred_defs: {:?}, rev_reg_defs: {:?} rev_regs: {:?}", @@ -87,7 +89,8 @@ pub fn verify_presentation( Schema::SchemaV1(schema) => schema, }; - let cred_def = match cred_defs.get(&identifier.cred_def_id).ok_or_else(|| { + let cred_def_id = CredentialDefinitionId::new(identifier.cred_def_id.clone()); + let cred_def = match cred_defs.get(&cred_def_id).ok_or_else(|| { err_msg!( "Credential Definition not provided for ID: {:?}", identifier.cred_def_id @@ -111,11 +114,12 @@ pub fn verify_presentation( )); } - let rev_reg_def = Some(rev_reg_defs.as_ref().unwrap().get(&rev_reg_id).ok_or_else( + let rev_reg_def_id = RevocationRegistryDefinitionId::new(rev_reg_id.clone()); + let rev_reg_def = Some(rev_reg_defs.as_ref().unwrap().get(&rev_reg_def_id).ok_or_else( || { err_msg!( "Revocation Registry Definition not provided for ID: {:?}", - rev_reg_id + rev_reg_def_id ) }, )?); @@ -782,7 +786,7 @@ fn process_filter( filter ); match tag { - tag_ @ "schema_id" => precess_filed(tag_, filter.schema_id.into(), tag_value), + tag_ @ "schema_id" => precess_filed(tag_, filter.schema_id.to_string(), tag_value), tag_ @ "schema_issuer_did" => precess_filed(tag_, &filter.schema_issuer_did, tag_value), tag_ @ "schema_name" => precess_filed(tag_, &filter.schema_name, tag_value), tag_ @ "schema_version" => precess_filed(tag_, &filter.schema_version, tag_value), @@ -796,7 +800,8 @@ fn process_filter( } } -fn precess_filed(filed: &str, filter_value: &str, tag_value: &str) -> Result<()> { +fn precess_filed(filed: &str, filter_value: impl Into, tag_value: &str) -> Result<()> { + let filter_value = filter_value.into(); if filter_value == tag_value { Ok(()) } else { @@ -852,8 +857,6 @@ fn is_attr_operator(key: &str) -> bool { #[cfg(test)] mod tests { - use crate::data_types::anoncreds::schema::SchemaV1; - use super::*; pub const SCHEMA_ID: &str = "123"; @@ -901,7 +904,7 @@ mod tests { fn filter() -> Filter { Filter { - schema_id: SCHEMA_ID.to_string(), + schema_id: SchemaId::new(SCHEMA_ID.to_string()), schema_name: SCHEMA_NAME.to_string(), schema_issuer_did: SCHEMA_ISSUER_DID.to_string(), schema_version: SCHEMA_VERSION.to_string(), diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index b8e9edcd..6974aa02 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use anoncreds::{ issuer, prover, types::{CredentialDefinitionConfig, MakeCredentialValues, PresentCredentials, SignatureType}, - verifier, + verifier, data_types::anoncreds::{schema::SchemaId, cred_def::CredentialDefinitionId}, }; use serde_json::json; @@ -147,10 +147,12 @@ fn anoncreds_works_for_single_issuer_single_prover() { ); let mut schemas = HashMap::new(); - schemas.insert(String::from("SCHEMA_ID"), &gvt_schema); + let schema_id = SchemaId::new("SCHEMA_ID"); + schemas.insert(&schema_id, &gvt_schema); let mut cred_defs = HashMap::new(); - cred_defs.insert(String::from("CRED_DEF_ID"), &*gvt_cred_def); + let cred_def_id = CredentialDefinitionId::new("CRED_DEF_ID"); + cred_defs.insert(&cred_def_id, &*gvt_cred_def); let presentation = prover::create_presentation( &pres_request, From 71faf19abf56a919535b41c130aaaff18095e60d Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 8 Dec 2022 17:15:40 +0100 Subject: [PATCH 07/17] ran formatter Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/macros.rs | 3 +-- .../src/data_types/anoncreds/rev_reg_def.rs | 5 ++++- anoncreds/src/ffi/presentation.rs | 17 +++++++++++----- anoncreds/src/services/prover.rs | 2 +- anoncreds/src/services/verifier.rs | 20 +++++++++++-------- anoncreds/tests/anoncreds_demos.rs | 3 ++- 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/macros.rs b/anoncreds/src/data_types/anoncreds/macros.rs index 06661ead..1c6b46d4 100644 --- a/anoncreds/src/data_types/anoncreds/macros.rs +++ b/anoncreds/src/data_types/anoncreds/macros.rs @@ -1,6 +1,5 @@ #[macro_export] macro_rules! impl_anoncreds_object_identifier { - ($i:ident) => { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Default)] pub struct $i(pub String); @@ -34,5 +33,5 @@ macro_rules! impl_anoncreds_object_identifier { write!(f, "{}", self.0) } } - } + }; } diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index c357a4c0..4b60836a 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -1,4 +1,7 @@ -use crate::{data_types::{invalid, ConversionError, Validatable, ValidationError}, impl_anoncreds_object_identifier}; +use crate::{ + data_types::{invalid, ConversionError, Validatable, ValidationError}, + impl_anoncreds_object_identifier, +}; pub const CL_ACCUM: &str = "CL_ACCUM"; diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index 65ae8aee..e865d9c9 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -6,9 +6,11 @@ use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; use super::object::{AnonCredsObject, AnonCredsObjectList, ObjectHandle}; use super::util::{FfiList, FfiStrList}; -use crate::data_types::anoncreds::rev_reg_def::{RevocationRegistryDefinitionId, RevocationRegistryDefinition}; -use crate::data_types::anoncreds::schema::{Schema, SchemaId}; use crate::data_types::anoncreds::cred_def::{CredentialDefinition, CredentialDefinitionId}; +use crate::data_types::anoncreds::rev_reg_def::{ + RevocationRegistryDefinition, RevocationRegistryDefinitionId, +}; +use crate::data_types::anoncreds::schema::{Schema, SchemaId}; use crate::error::Result; use crate::services::{ prover::create_presentation, @@ -178,7 +180,8 @@ pub extern "C" fn anoncreds_create_presentation( .map(|s| CredentialDefinitionId::new(s.as_str().to_owned())) .collect(); let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let cred_defs = cred_defs.refs_map::(&cred_def_ids)?; + let cred_defs = + cred_defs.refs_map::(&cred_def_ids)?; let presentation = create_presentation( pres_req.load()?.cast_ref()?, @@ -283,7 +286,8 @@ pub extern "C" fn anoncreds_verify_presentation( .map(|s| CredentialDefinitionId::new(s.as_str().to_owned())) .collect(); let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let cred_defs = cred_defs.refs_map::(&cred_def_ids)?; + let cred_defs = + cred_defs.refs_map::(&cred_def_ids)?; let rev_reg_def_ids: Vec = rev_reg_def_ids .as_slice() @@ -291,7 +295,10 @@ pub extern "C" fn anoncreds_verify_presentation( .map(|s| RevocationRegistryDefinitionId::new(s.as_str().to_owned())) .collect(); let rev_reg_defs = AnonCredsObjectList::load(rev_reg_defs.as_slice())?; - let rev_reg_defs = rev_reg_defs.refs_map::(&rev_reg_def_ids)?; + let rev_reg_defs = rev_reg_defs + .refs_map::( + &rev_reg_def_ids, + )?; let verify = verify_presentation( presentation.load()?.cast_ref()?, diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index b4483076..63c85677 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet}; use super::types::*; use crate::data_types::anoncreds::{ + cred_def::CredentialDefinitionId, credential::AttributeValues, pres_request::{PresentationRequestPayload, RequestedAttributeInfo, RequestedPredicateInfo}, presentation::{ @@ -9,7 +10,6 @@ use crate::data_types::anoncreds::{ RevealedAttributeInfo, SubProofReferent, }, schema::SchemaId, - cred_def::CredentialDefinitionId, }; use crate::error::Result; use crate::services::helpers::*; diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index c21f5889..ad774ecb 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -115,14 +115,18 @@ pub fn verify_presentation( } let rev_reg_def_id = RevocationRegistryDefinitionId::new(rev_reg_id.clone()); - let rev_reg_def = Some(rev_reg_defs.as_ref().unwrap().get(&rev_reg_def_id).ok_or_else( - || { - err_msg!( - "Revocation Registry Definition not provided for ID: {:?}", - rev_reg_def_id - ) - }, - )?); + let rev_reg_def = Some( + rev_reg_defs + .as_ref() + .unwrap() + .get(&rev_reg_def_id) + .ok_or_else(|| { + err_msg!( + "Revocation Registry Definition not provided for ID: {:?}", + rev_reg_def_id + ) + })?, + ); let rev_reg = Some( rev_regs diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 6974aa02..3b38dc96 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -1,9 +1,10 @@ use std::collections::HashMap; use anoncreds::{ + data_types::anoncreds::{cred_def::CredentialDefinitionId, schema::SchemaId}, issuer, prover, types::{CredentialDefinitionConfig, MakeCredentialValues, PresentCredentials, SignatureType}, - verifier, data_types::anoncreds::{schema::SchemaId, cred_def::CredentialDefinitionId}, + verifier, }; use serde_json::json; From ac55a6c04f1d596a0c49ac5cd776375e6196c7b3 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Tue, 13 Dec 2022 13:49:38 +0100 Subject: [PATCH 08/17] add validation to the identifier Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/macros.rs | 17 +++++++++++++++++ indy-utils/src/validation.rs | 1 + 2 files changed, 18 insertions(+) diff --git a/anoncreds/src/data_types/anoncreds/macros.rs b/anoncreds/src/data_types/anoncreds/macros.rs index 1c6b46d4..6229b07a 100644 --- a/anoncreds/src/data_types/anoncreds/macros.rs +++ b/anoncreds/src/data_types/anoncreds/macros.rs @@ -10,6 +10,23 @@ macro_rules! impl_anoncreds_object_identifier { } } + impl crate::data_types::Validatable for $i { + fn validate(&self) -> Result<(), crate::data_types::ValidationError> { + // taken from: https://www.regextester.com/94092 + let uri_regex = regex::Regex::new(r"\w+:(\/?\/?)[^\s]+").unwrap(); + uri_regex + .captures(&self.0) + .ok_or_else(|| { + indy_utils::invalid!( + "type: {}, identifier: {} is invalid. It MUST be a URI.", + stringify!($i), + self.0 + ) + }) + .map(|_| ()) + } + } + impl Into for $i { fn into(self) -> String { self.0 diff --git a/indy-utils/src/validation.rs b/indy-utils/src/validation.rs index dfa41a01..53d68eaf 100644 --- a/indy-utils/src/validation.rs +++ b/indy-utils/src/validation.rs @@ -10,6 +10,7 @@ macro_rules! invalid { } /// Trait for data types which need validation after being loaded from external sources +/// TODO: this should not default to Ok(()) pub trait Validatable { fn validate(&self) -> Result<(), ValidationError> { Ok(()) From b91b83eb73de6f2e53a514e20364524aae8793e4 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Tue, 13 Dec 2022 14:44:44 +0100 Subject: [PATCH 09/17] use CredentialDefinitionId internally more Signed-off-by: blu3beri --- .../src/data_types/anoncreds/cred_def.rs | 8 ++++++ .../src/data_types/anoncreds/cred_offer.rs | 4 +-- .../src/data_types/anoncreds/cred_request.rs | 4 +-- .../src/data_types/anoncreds/credential.rs | 4 +-- anoncreds/src/data_types/anoncreds/macros.rs | 12 ++++++-- .../src/data_types/anoncreds/presentation.rs | 4 +-- .../src/data_types/anoncreds/rev_reg_def.rs | 10 ++++++- anoncreds/src/data_types/anoncreds/schema.rs | 6 ++++ anoncreds/src/ffi/cred_def.rs | 2 +- anoncreds/src/ffi/cred_offer.rs | 12 +++++--- anoncreds/src/ffi/presentation.rs | 28 ++++++++++--------- anoncreds/src/services/issuer.rs | 19 ++++++++----- anoncreds/src/services/prover.rs | 10 +++---- anoncreds/src/services/verifier.rs | 16 +++++------ anoncreds/tests/anoncreds_demos.rs | 10 ++++--- 15 files changed, 96 insertions(+), 53 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/cred_def.rs b/anoncreds/src/data_types/anoncreds/cred_def.rs index 681e6754..55f769de 100644 --- a/anoncreds/src/data_types/anoncreds/cred_def.rs +++ b/anoncreds/src/data_types/anoncreds/cred_def.rs @@ -1,3 +1,5 @@ +use indy_utils::{Validatable, ValidationError}; + use crate::{data_types::ConversionError, impl_anoncreds_object_identifier}; use super::schema::SchemaId; @@ -61,6 +63,12 @@ impl CredentialDefinitionV1 { } } +impl Validatable for CredentialDefinitionV1 { + fn validate(&self) -> Result<(), ValidationError> { + self.schema_id.validate() + } +} + #[derive(Debug, Deserialize, Serialize)] pub struct CredentialDefinitionPrivate { pub value: ursa::cl::CredentialPrivateKey, diff --git a/anoncreds/src/data_types/anoncreds/cred_offer.rs b/anoncreds/src/data_types/anoncreds/cred_offer.rs index 6eb4999b..8e080270 100644 --- a/anoncreds/src/data_types/anoncreds/cred_offer.rs +++ b/anoncreds/src/data_types/anoncreds/cred_offer.rs @@ -1,9 +1,9 @@ -use super::{nonce::Nonce, schema::SchemaId}; +use super::{cred_def::CredentialDefinitionId, nonce::Nonce, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] pub struct CredentialOffer { pub schema_id: SchemaId, - pub cred_def_id: String, + pub cred_def_id: CredentialDefinitionId, pub key_correctness_proof: ursa::cl::CredentialKeyCorrectnessProof, pub nonce: Nonce, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/anoncreds/src/data_types/anoncreds/cred_request.rs b/anoncreds/src/data_types/anoncreds/cred_request.rs index 2f86317b..eda68cb1 100644 --- a/anoncreds/src/data_types/anoncreds/cred_request.rs +++ b/anoncreds/src/data_types/anoncreds/cred_request.rs @@ -1,11 +1,11 @@ -use super::nonce::Nonce; +use super::{cred_def::CredentialDefinitionId, nonce::Nonce}; use crate::data_types::{Validatable, ValidationError}; use indy_utils::did::DidValue; #[derive(Debug, Deserialize, Serialize)] pub struct CredentialRequest { pub prover_did: DidValue, - pub cred_def_id: String, + pub cred_def_id: CredentialDefinitionId, pub blinded_ms: ursa::cl::BlindedCredentialSecrets, pub blinded_ms_correctness_proof: ursa::cl::BlindedCredentialSecretsCorrectnessProof, pub nonce: Nonce, diff --git a/anoncreds/src/data_types/anoncreds/credential.rs b/anoncreds/src/data_types/anoncreds/credential.rs index 27abb704..e65459f8 100644 --- a/anoncreds/src/data_types/anoncreds/credential.rs +++ b/anoncreds/src/data_types/anoncreds/credential.rs @@ -4,12 +4,12 @@ use zeroize::Zeroize; use crate::data_types::{Validatable, ValidationError}; -use super::schema::SchemaId; +use super::{cred_def::CredentialDefinitionId, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] pub struct Credential { pub schema_id: SchemaId, - pub cred_def_id: String, + pub cred_def_id: CredentialDefinitionId, pub rev_reg_id: Option, pub values: CredentialValues, pub signature: ursa::cl::CredentialSignature, diff --git a/anoncreds/src/data_types/anoncreds/macros.rs b/anoncreds/src/data_types/anoncreds/macros.rs index 6229b07a..1e6f9459 100644 --- a/anoncreds/src/data_types/anoncreds/macros.rs +++ b/anoncreds/src/data_types/anoncreds/macros.rs @@ -8,12 +8,20 @@ macro_rules! impl_anoncreds_object_identifier { pub fn new(s: impl Into) -> Self { Self(s.into()) } + + pub fn validated_new( + s: impl Into, + ) -> Result { + let s = Self(s.into()); + s.validate()?; + Ok(s) + } } impl crate::data_types::Validatable for $i { fn validate(&self) -> Result<(), crate::data_types::ValidationError> { - // taken from: https://www.regextester.com/94092 - let uri_regex = regex::Regex::new(r"\w+:(\/?\/?)[^\s]+").unwrap(); + // TODO: better URI regex + let uri_regex = regex::Regex::new(r".*").unwrap(); uri_regex .captures(&self.0) .ok_or_else(|| { diff --git a/anoncreds/src/data_types/anoncreds/presentation.rs b/anoncreds/src/data_types/anoncreds/presentation.rs index 4aa90650..a744e26b 100644 --- a/anoncreds/src/data_types/anoncreds/presentation.rs +++ b/anoncreds/src/data_types/anoncreds/presentation.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::data_types::Validatable; -use super::schema::SchemaId; +use super::{cred_def::CredentialDefinitionId, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] pub struct Presentation { @@ -64,7 +64,7 @@ pub struct AttributeValue { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct Identifier { pub schema_id: SchemaId, - pub cred_def_id: String, + pub cred_def_id: CredentialDefinitionId, pub rev_reg_id: Option, pub timestamp: Option, } diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index 4b60836a..9d50a1eb 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -3,6 +3,8 @@ use crate::{ impl_anoncreds_object_identifier, }; +use super::cred_def::CredentialDefinitionId; + pub const CL_ACCUM: &str = "CL_ACCUM"; pub const ISSUANCE_BY_DEFAULT: &str = "ISSUANCE_BY_DEFAULT"; @@ -93,10 +95,16 @@ pub enum RevocationRegistryDefinition { pub struct RevocationRegistryDefinitionV1 { pub revoc_def_type: RegistryType, pub tag: String, - pub cred_def_id: String, + pub cred_def_id: CredentialDefinitionId, pub value: RevocationRegistryDefinitionValue, } +impl Validatable for RevocationRegistryDefinitionV1 { + fn validate(&self) -> Result<(), ValidationError> { + self.cred_def_id.validate() + } +} + #[derive(Debug, Deserialize, Serialize)] pub struct RevocationRegistryDefinitionPrivate { pub value: ursa::cl::RevocationKeyPrivate, diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index 60a28440..c28c01bb 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -62,6 +62,12 @@ impl Into> for AttributeNames { } } +impl Validatable for SchemaV1 { + fn validate(&self) -> Result<(), ValidationError> { + self.attr_names.validate() + } +} + impl Validatable for AttributeNames { fn validate(&self) -> Result<(), ValidationError> { if self.0.is_empty() { diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index 92cf423c..73489fbf 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -33,7 +33,7 @@ pub extern "C" fn anoncreds_create_credential_definition( let schema_id = schema_id .as_opt_str() .ok_or_else(|| err_msg!("Missing schema id"))?; - SchemaId::new(schema_id.to_owned()) + SchemaId::validated_new(schema_id)? }; let signature_type = { let stype = signature_type diff --git a/anoncreds/src/ffi/cred_offer.rs b/anoncreds/src/ffi/cred_offer.rs index f7dd3ce0..83773b6f 100644 --- a/anoncreds/src/ffi/cred_offer.rs +++ b/anoncreds/src/ffi/cred_offer.rs @@ -2,6 +2,7 @@ use ffi_support::FfiStr; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; +use crate::data_types::anoncreds::cred_def::CredentialDefinitionId; use crate::data_types::anoncreds::schema::SchemaId; use crate::services::{issuer::create_credential_offer, types::CredentialOffer}; @@ -18,11 +19,14 @@ pub extern "C" fn anoncreds_create_credential_offer( let schema_id = schema_id .as_opt_str() .ok_or_else(|| err_msg!("Missing schema ID"))?; - SchemaId::new(schema_id.to_string()) + SchemaId::validated_new(schema_id)? + }; + let cred_def_id = { + cred_def_id + .as_opt_str() + .ok_or_else(|| err_msg!("Missing cred def ID"))?; + CredentialDefinitionId::validated_new(cred_def_id)? }; - let cred_def_id = cred_def_id - .as_opt_str() - .ok_or_else(|| err_msg!("Missing cred def ID"))?; let cred_offer = create_credential_offer(schema_id, cred_def_id, key_proof.load()?.cast_ref()?)?; let cred_offer = ObjectHandle::create(cred_offer)?; diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index e865d9c9..c9b3261d 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -166,22 +166,24 @@ pub extern "C" fn anoncreds_create_presentation( } } - let schema_ids: Vec = schema_ids - .as_slice() - .iter() - .map(|s| SchemaId::new(s.as_str().to_owned())) - .collect(); + let mut schema_identifiers: Vec = vec![]; + for schema_id in schema_ids.as_slice().iter() { + let s = SchemaId::validated_new(schema_id.as_str())?; + schema_identifiers.push(s); + } + + let mut cred_def_identifiers: Vec = vec![]; + for cred_def_id in cred_def_ids.as_slice().iter() { + let cred_def_id = CredentialDefinitionId::validated_new(cred_def_id.as_str())?; + cred_def_identifiers.push(cred_def_id); + } + let schemas = AnonCredsObjectList::load(schemas.as_slice())?; - let schemas = schemas.refs_map::(&schema_ids)?; + let schemas = schemas.refs_map::(&schema_identifiers)?; - let cred_def_ids: Vec = cred_def_ids - .as_slice() - .iter() - .map(|s| CredentialDefinitionId::new(s.as_str().to_owned())) - .collect(); let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let cred_defs = - cred_defs.refs_map::(&cred_def_ids)?; + let cred_defs = cred_defs + .refs_map::(&cred_def_identifiers)?; let presentation = create_presentation( pres_req.load()?.cast_ref()?, diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index cfc68d5a..d186b7f4 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -1,7 +1,10 @@ use std::collections::{BTreeSet, HashSet}; use std::iter::FromIterator; +use indy_utils::Validatable; + use super::types::*; +use crate::data_types::anoncreds::cred_def::CredentialDefinitionId; use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ cred_def::{CredentialDefinitionData, CredentialDefinitionV1}, @@ -152,7 +155,7 @@ where RevocationRegistryDefinitionV1 { revoc_def_type: rev_reg_type, tag: tag.to_string(), - cred_def_id: cred_def_id.to_owned(), + cred_def_id: CredentialDefinitionId::new(cred_def_id), value: revoc_reg_def_value, }, ); @@ -221,11 +224,13 @@ pub fn update_revocation_registry( } pub fn create_credential_offer( - schema_id: impl Into, - cred_def_id: &str, + schema_id: SchemaId, + cred_def_id: CredentialDefinitionId, correctness_proof: &CredentialKeyCorrectnessProof, ) -> Result { trace!("create_credential_offer >>> cred_def_id: {:?}", cred_def_id); + schema_id.validate()?; + cred_def_id.validate()?; let nonce = Nonce::new().map_err(err_map!(Unexpected, "Error creating nonce"))?; @@ -233,8 +238,8 @@ pub fn create_credential_offer( .try_clone() .map_err(err_map!(Unexpected))?; let credential_offer = CredentialOffer { - schema_id: schema_id.into().to_owned(), - cred_def_id: cred_def_id.to_owned(), + schema_id, + cred_def_id, key_correctness_proof: key_correctness_proof.value, nonce, method_name: None, @@ -344,8 +349,8 @@ pub fn create_credential( }; let credential = Credential { - schema_id: cred_offer.schema_id.clone(), - cred_def_id: cred_offer.cred_def_id.clone(), + schema_id: cred_offer.schema_id.to_owned(), + cred_def_id: cred_offer.cred_def_id.to_owned(), rev_reg_id, values: cred_values, signature: credential_signature, diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index 63c85677..ddf927db 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -64,7 +64,7 @@ pub fn create_credential_request( let credential_request = CredentialRequest { prover_did: prover_did.clone(), - cred_def_id: credential_offer.cred_def_id.clone(), + cred_def_id: credential_offer.cred_def_id.to_owned(), blinded_ms, blinded_ms_correctness_proof, nonce, @@ -216,14 +216,14 @@ pub fn create_presentation( let identifier = match pres_req { PresentationRequest::PresentationRequestV1(_) => Identifier { - schema_id: credential.schema_id.clone(), - cred_def_id: credential.cred_def_id.clone(), + schema_id: credential.schema_id.to_owned(), + cred_def_id: credential.cred_def_id.to_owned(), rev_reg_id: credential.rev_reg_id.clone(), timestamp: present.timestamp, }, PresentationRequest::PresentationRequestV2(_) => Identifier { - schema_id: credential.schema_id.clone(), - cred_def_id: credential.cred_def_id.clone(), + schema_id: credential.schema_id.to_owned(), + cred_def_id: credential.cred_def_id.to_owned(), rev_reg_id: credential.rev_reg_id.clone(), timestamp: present.timestamp, }, diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index ad774ecb..4b84b3ef 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -24,7 +24,7 @@ pub struct Filter { schema_name: String, schema_version: String, issuer_did: String, - cred_def_id: String, + cred_def_id: CredentialDefinitionId, } static INTERNAL_TAG_MATCHER: Lazy = @@ -698,11 +698,11 @@ fn gather_filter_info(referent: &str, identifiers: &HashMap) })?; Ok(Filter { - schema_id: identifier.schema_id.clone(), + schema_id: identifier.schema_id.to_owned(), schema_name, schema_issuer_did, schema_version, - cred_def_id: identifier.cred_def_id.clone(), + cred_def_id: identifier.cred_def_id.to_owned(), issuer_did, }) } @@ -794,7 +794,7 @@ fn process_filter( tag_ @ "schema_issuer_did" => precess_filed(tag_, &filter.schema_issuer_did, tag_value), tag_ @ "schema_name" => precess_filed(tag_, &filter.schema_name, tag_value), tag_ @ "schema_version" => precess_filed(tag_, &filter.schema_version, tag_value), - tag_ @ "cred_def_id" => precess_filed(tag_, &filter.cred_def_id, tag_value), + tag_ @ "cred_def_id" => precess_filed(tag_, &filter.cred_def_id.to_string(), tag_value), tag_ @ "issuer_did" => precess_filed(tag_, &filter.issuer_did, tag_value), x if is_attr_internal_tag(x, attr_value_map) => { check_internal_tag_revealed_value(x, tag_value, attr_value_map) @@ -908,11 +908,11 @@ mod tests { fn filter() -> Filter { Filter { - schema_id: SchemaId::new(SCHEMA_ID.to_string()), + schema_id: SchemaId::new(SCHEMA_ID), schema_name: SCHEMA_NAME.to_string(), schema_issuer_did: SCHEMA_ISSUER_DID.to_string(), schema_version: SCHEMA_VERSION.to_string(), - cred_def_id: CRED_DEF_ID.to_string(), + cred_def_id: CredentialDefinitionId::new(CRED_DEF_ID), issuer_did: ISSUER_DID.to_string(), } } @@ -1178,7 +1178,7 @@ mod tests { Identifier { timestamp: Some(1234), schema_id: SchemaId::default(), - cred_def_id: String::new(), + cred_def_id: CredentialDefinitionId::default(), rev_reg_id: Some(String::new()), }, ); @@ -1187,7 +1187,7 @@ mod tests { Identifier { timestamp: None, schema_id: SchemaId::default(), - cred_def_id: String::new(), + cred_def_id: CredentialDefinitionId::default(), rev_reg_id: Some(String::new()), }, ); diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 3b38dc96..232a95c0 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -15,6 +15,8 @@ mod utils; pub static GVT_SCHEMA_NAME: &'static str = "gvt"; pub static GVT_SCHEMA_ATTRIBUTES: &[&'static str; 4] = &["name", "age", "sex", "height"]; +pub static SCHEMA_ID: &str = "mock:uri"; +pub static CRED_DEF_ID: &str = "mock:uri"; #[test] fn anoncreds_works_for_single_issuer_single_prover() { @@ -51,8 +53,8 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates a Credential Offer let cred_offer = issuer::create_credential_offer( - "SCHEMA_ID", - "CRED_DEF_ID", + SchemaId::new(SCHEMA_ID), + CredentialDefinitionId::new(CRED_DEF_ID), &issuer_wallet.cred_defs[0].key_proof, ) .expect("Error creating credential offer"); @@ -148,11 +150,11 @@ fn anoncreds_works_for_single_issuer_single_prover() { ); let mut schemas = HashMap::new(); - let schema_id = SchemaId::new("SCHEMA_ID"); + let schema_id = SchemaId::new(SCHEMA_ID); schemas.insert(&schema_id, &gvt_schema); let mut cred_defs = HashMap::new(); - let cred_def_id = CredentialDefinitionId::new("CRED_DEF_ID"); + let cred_def_id = CredentialDefinitionId::new(CRED_DEF_ID); cred_defs.insert(&cred_def_id, &*gvt_cred_def); let presentation = prover::create_presentation( From e4d5b2218b17d73fb3cccb9d0c0285e65979117d Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 11:40:02 +0000 Subject: [PATCH 10/17] use CredentialDefinitionId internal Signed-off-by: blu3beri --- anoncreds/src/services/issuer.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index d186b7f4..e28f9251 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -106,7 +106,7 @@ pub fn create_credential_definition( pub fn create_revocation_registry( cred_def: &CredentialDefinition, - cred_def_id: &str, + cred_def_id: impl Into, tag: &str, rev_reg_type: RegistryType, issuance_type: IssuanceType, @@ -121,9 +121,13 @@ pub fn create_revocation_registry( where TW: TailsWriter, { + let cred_def_id = cred_def_id.into(); + trace!("create_revocation_registry >>> cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}, issuance_type: {:?}", cred_def, tag, max_cred_num, rev_reg_type, issuance_type); + cred_def_id.validate()?; + let cred_def = match cred_def { CredentialDefinition::CredentialDefinitionV1(c) => c, }; @@ -155,7 +159,7 @@ where RevocationRegistryDefinitionV1 { revoc_def_type: rev_reg_type, tag: tag.to_string(), - cred_def_id: CredentialDefinitionId::new(cred_def_id), + cred_def_id, value: revoc_reg_def_value, }, ); @@ -224,10 +228,12 @@ pub fn update_revocation_registry( } pub fn create_credential_offer( - schema_id: SchemaId, - cred_def_id: CredentialDefinitionId, + schema_id: impl Into, + cred_def_id: impl Into, correctness_proof: &CredentialKeyCorrectnessProof, ) -> Result { + let schema_id = schema_id.into(); + let cred_def_id = cred_def_id.into(); trace!("create_credential_offer >>> cred_def_id: {:?}", cred_def_id); schema_id.validate()?; cred_def_id.validate()?; From 7c31824bbc67d7d531b6c5ddc481c748d07e2fd0 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 11:45:25 +0000 Subject: [PATCH 11/17] removed todo for schema index matching Signed-off-by: blu3beri --- anoncreds/src/ffi/presentation.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index c9b3261d..efcf17c3 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -70,10 +70,6 @@ pub extern "C" fn anoncreds_create_presentation( self_attest_values: FfiStrList, master_secret: ObjectHandle, schemas: FfiList, - // TODO: this is index-matched with schemas. Is there a better solution? - // since we have an objecthandle list for the schemas we can not add Ids to them - // Otherwise they all would need ids and we would like to seperate that - // Also, we kind of do the same with `self_attested_names` and `self_attested_values` schema_ids: FfiStrList, cred_defs: FfiList, cred_def_ids: FfiStrList, From a02dee0cd3523ea0ed670befaffb2abbb365bdda Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 13:46:10 +0000 Subject: [PATCH 12/17] added more validation Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/credential.rs | 2 +- anoncreds/src/data_types/anoncreds/macros.rs | 6 ++++-- anoncreds/src/services/issuer.rs | 7 ++++--- anoncreds/src/services/verifier.rs | 1 - anoncreds/tests/anoncreds_demos.rs | 6 +++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/credential.rs b/anoncreds/src/data_types/anoncreds/credential.rs index e65459f8..cf149c02 100644 --- a/anoncreds/src/data_types/anoncreds/credential.rs +++ b/anoncreds/src/data_types/anoncreds/credential.rs @@ -67,7 +67,7 @@ pub struct CredentialInfo { pub referent: String, pub attrs: ShortCredentialValues, pub schema_id: SchemaId, - pub cred_def_id: String, + pub cred_def_id: CredentialDefinitionId, pub rev_reg_id: Option, pub cred_rev_id: Option, } diff --git a/anoncreds/src/data_types/anoncreds/macros.rs b/anoncreds/src/data_types/anoncreds/macros.rs index 1e6f9459..948c49ce 100644 --- a/anoncreds/src/data_types/anoncreds/macros.rs +++ b/anoncreds/src/data_types/anoncreds/macros.rs @@ -20,8 +20,10 @@ macro_rules! impl_anoncreds_object_identifier { impl crate::data_types::Validatable for $i { fn validate(&self) -> Result<(), crate::data_types::ValidationError> { - // TODO: better URI regex - let uri_regex = regex::Regex::new(r".*").unwrap(); + // TODO: stricten the URI regex. + // Right now everything after the first colon is allowed, we might want to restrict + // this + let uri_regex = regex::Regex::new(r"^[a-zA-Z0-9\+\-\.]+:.+$").unwrap(); uri_regex .captures(&self.0) .ok_or_else(|| { diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index e28f9251..ba09e56e 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -58,12 +58,15 @@ pub fn create_credential_definition( CredentialDefinitionPrivate, CredentialKeyCorrectnessProof, )> { + let schema_id = schema_id.into(); trace!( "create_credential_definition >>> schema: {:?}, config: {:?}", schema, config ); + schema_id.validate()?; + let schema = match schema { Schema::SchemaV1(s) => s, }; @@ -79,7 +82,7 @@ pub fn create_credential_definition( )?; let cred_def = CredentialDefinition::CredentialDefinitionV1(CredentialDefinitionV1 { - schema_id: schema_id.into().to_owned(), + schema_id, signature_type, tag: tag.to_owned(), value: CredentialDefinitionData { @@ -122,10 +125,8 @@ where TW: TailsWriter, { let cred_def_id = cred_def_id.into(); - trace!("create_revocation_registry >>> cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}, issuance_type: {:?}", cred_def, tag, max_cred_num, rev_reg_type, issuance_type); - cred_def_id.validate()?; let cred_def = match cred_def { diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index 4b84b3ef..cc9cc950 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -1174,7 +1174,6 @@ mod tests { let mut res: HashMap = HashMap::new(); res.insert( "referent_1".to_string(), - // TODO: what does this do Identifier { timestamp: Some(1234), schema_id: SchemaId::default(), diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 232a95c0..59023994 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -37,7 +37,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates Credential Definition let cred_def_parts = issuer::create_credential_definition( - "SAMPLE_ID".to_owned(), + SCHEMA_ID, &gvt_schema, "tag", SignatureType::CL, @@ -53,8 +53,8 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates a Credential Offer let cred_offer = issuer::create_credential_offer( - SchemaId::new(SCHEMA_ID), - CredentialDefinitionId::new(CRED_DEF_ID), + SCHEMA_ID, + CRED_DEF_ID, &issuer_wallet.cred_defs[0].key_proof, ) .expect("Error creating credential offer"); From c6ade21b723ef309d6f5a921fa7069e6fc4ec1e4 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 13:55:22 +0000 Subject: [PATCH 13/17] validate schema and credential definition Signed-off-by: blu3beri --- anoncreds/src/ffi/presentation.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index efcf17c3..897f4eb5 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -270,22 +270,24 @@ pub extern "C" fn anoncreds_verify_presentation( .insert(*timestamp, entry.cast_ref()?); } - let schema_ids: Vec = schema_ids - .as_slice() - .iter() - .map(|s| SchemaId::new(s.as_str().to_owned())) - .collect(); + let mut schema_identifiers: Vec = vec![]; + for schema_id in schema_ids.as_slice().iter() { + let s = SchemaId::validated_new(schema_id.as_str())?; + schema_identifiers.push(s); + } + + let mut cred_def_identifiers: Vec = vec![]; + for cred_def_id in cred_def_ids.as_slice().iter() { + let cred_def_id = CredentialDefinitionId::validated_new(cred_def_id.as_str())?; + cred_def_identifiers.push(cred_def_id); + } + let schemas = AnonCredsObjectList::load(schemas.as_slice())?; - let schemas = schemas.refs_map::(&schema_ids)?; + let schemas = schemas.refs_map::(&schema_identifiers)?; - let cred_def_ids: Vec = cred_def_ids - .as_slice() - .iter() - .map(|s| CredentialDefinitionId::new(s.as_str().to_owned())) - .collect(); let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; let cred_defs = - cred_defs.refs_map::(&cred_def_ids)?; + cred_defs.refs_map::(&cred_def_identifiers)?; let rev_reg_def_ids: Vec = rev_reg_def_ids .as_slice() From aa6cc35c706b89177da61d044df068bdb8acb945 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 13:57:26 +0000 Subject: [PATCH 14/17] ran formatter Signed-off-by: blu3beri --- anoncreds/src/ffi/presentation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index 897f4eb5..ab8cceb7 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -286,8 +286,8 @@ pub extern "C" fn anoncreds_verify_presentation( let schemas = schemas.refs_map::(&schema_identifiers)?; let cred_defs = AnonCredsObjectList::load(cred_defs.as_slice())?; - let cred_defs = - cred_defs.refs_map::(&cred_def_identifiers)?; + let cred_defs = cred_defs + .refs_map::(&cred_def_identifiers)?; let rev_reg_def_ids: Vec = rev_reg_def_ids .as_slice() From d191d988427bf043cd69e4d880160b71f24a8a64 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 14:18:53 +0000 Subject: [PATCH 15/17] validate by default Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/macros.rs | 12 +++++------ anoncreds/src/ffi/cred_def.rs | 2 +- anoncreds/src/ffi/cred_offer.rs | 4 ++-- anoncreds/src/ffi/presentation.rs | 21 ++++++++++---------- anoncreds/src/services/prover.rs | 2 +- anoncreds/src/services/verifier.rs | 8 ++++---- anoncreds/tests/anoncreds_demos.rs | 4 ++-- 7 files changed, 27 insertions(+), 26 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/macros.rs b/anoncreds/src/data_types/anoncreds/macros.rs index 948c49ce..b62ea8d6 100644 --- a/anoncreds/src/data_types/anoncreds/macros.rs +++ b/anoncreds/src/data_types/anoncreds/macros.rs @@ -5,13 +5,11 @@ macro_rules! impl_anoncreds_object_identifier { pub struct $i(pub String); impl $i { - pub fn new(s: impl Into) -> Self { + pub fn new_unchecked(s: impl Into) -> Self { Self(s.into()) } - pub fn validated_new( - s: impl Into, - ) -> Result { + pub fn new(s: impl Into) -> Result { let s = Self(s.into()); s.validate()?; Ok(s) @@ -43,15 +41,17 @@ macro_rules! impl_anoncreds_object_identifier { } } + // TODO: replace these with TryInto impl From for $i { fn from(value: String) -> Self { - $i::new(value) + $i::new_unchecked(value) } } + // TODO: replace these with TryInto impl From<&str> for $i { fn from(value: &str) -> Self { - $i::new(value.to_owned()) + $i::new_unchecked(value.to_owned()) } } diff --git a/anoncreds/src/ffi/cred_def.rs b/anoncreds/src/ffi/cred_def.rs index 73489fbf..98d6d4b1 100644 --- a/anoncreds/src/ffi/cred_def.rs +++ b/anoncreds/src/ffi/cred_def.rs @@ -33,7 +33,7 @@ pub extern "C" fn anoncreds_create_credential_definition( let schema_id = schema_id .as_opt_str() .ok_or_else(|| err_msg!("Missing schema id"))?; - SchemaId::validated_new(schema_id)? + SchemaId::new(schema_id)? }; let signature_type = { let stype = signature_type diff --git a/anoncreds/src/ffi/cred_offer.rs b/anoncreds/src/ffi/cred_offer.rs index 83773b6f..f4adcf18 100644 --- a/anoncreds/src/ffi/cred_offer.rs +++ b/anoncreds/src/ffi/cred_offer.rs @@ -19,13 +19,13 @@ pub extern "C" fn anoncreds_create_credential_offer( let schema_id = schema_id .as_opt_str() .ok_or_else(|| err_msg!("Missing schema ID"))?; - SchemaId::validated_new(schema_id)? + SchemaId::new(schema_id)? }; let cred_def_id = { cred_def_id .as_opt_str() .ok_or_else(|| err_msg!("Missing cred def ID"))?; - CredentialDefinitionId::validated_new(cred_def_id)? + CredentialDefinitionId::new(cred_def_id)? }; let cred_offer = create_credential_offer(schema_id, cred_def_id, key_proof.load()?.cast_ref()?)?; diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index ab8cceb7..58b9caec 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -164,13 +164,13 @@ pub extern "C" fn anoncreds_create_presentation( let mut schema_identifiers: Vec = vec![]; for schema_id in schema_ids.as_slice().iter() { - let s = SchemaId::validated_new(schema_id.as_str())?; + let s = SchemaId::new(schema_id.as_str())?; schema_identifiers.push(s); } let mut cred_def_identifiers: Vec = vec![]; for cred_def_id in cred_def_ids.as_slice().iter() { - let cred_def_id = CredentialDefinitionId::validated_new(cred_def_id.as_str())?; + let cred_def_id = CredentialDefinitionId::new(cred_def_id.as_str())?; cred_def_identifiers.push(cred_def_id); } @@ -272,16 +272,22 @@ pub extern "C" fn anoncreds_verify_presentation( let mut schema_identifiers: Vec = vec![]; for schema_id in schema_ids.as_slice().iter() { - let s = SchemaId::validated_new(schema_id.as_str())?; + let s = SchemaId::new(schema_id.as_str())?; schema_identifiers.push(s); } let mut cred_def_identifiers: Vec = vec![]; for cred_def_id in cred_def_ids.as_slice().iter() { - let cred_def_id = CredentialDefinitionId::validated_new(cred_def_id.as_str())?; + let cred_def_id = CredentialDefinitionId::new(cred_def_id.as_str())?; cred_def_identifiers.push(cred_def_id); } + let mut rev_reg_def_identifiers: Vec = vec![]; + for rev_reg_def_id in rev_reg_def_ids.as_slice().iter() { + let rev_reg_def_id = RevocationRegistryDefinitionId::new(rev_reg_def_id.as_str())?; + rev_reg_def_identifiers.push(rev_reg_def_id); + } + let schemas = AnonCredsObjectList::load(schemas.as_slice())?; let schemas = schemas.refs_map::(&schema_identifiers)?; @@ -289,15 +295,10 @@ pub extern "C" fn anoncreds_verify_presentation( let cred_defs = cred_defs .refs_map::(&cred_def_identifiers)?; - let rev_reg_def_ids: Vec = rev_reg_def_ids - .as_slice() - .iter() - .map(|s| RevocationRegistryDefinitionId::new(s.as_str().to_owned())) - .collect(); let rev_reg_defs = AnonCredsObjectList::load(rev_reg_defs.as_slice())?; let rev_reg_defs = rev_reg_defs .refs_map::( - &rev_reg_def_ids, + &rev_reg_def_identifiers, )?; let verify = verify_presentation( diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index ddf927db..c6dc6df5 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -177,7 +177,7 @@ pub fn create_presentation( Schema::SchemaV1(schema) => schema, }; - let cred_def_id = CredentialDefinitionId::new(credential.cred_def_id.clone()); + let cred_def_id = CredentialDefinitionId::new(credential.cred_def_id.clone())?; let cred_def = *cred_defs.get(&cred_def_id).ok_or_else(|| { err_msg!( "Credential Definition not provided for ID: {}", diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index cc9cc950..8a14f27d 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -89,7 +89,7 @@ pub fn verify_presentation( Schema::SchemaV1(schema) => schema, }; - let cred_def_id = CredentialDefinitionId::new(identifier.cred_def_id.clone()); + let cred_def_id = CredentialDefinitionId::new(identifier.cred_def_id.clone())?; let cred_def = match cred_defs.get(&cred_def_id).ok_or_else(|| { err_msg!( "Credential Definition not provided for ID: {:?}", @@ -114,7 +114,7 @@ pub fn verify_presentation( )); } - let rev_reg_def_id = RevocationRegistryDefinitionId::new(rev_reg_id.clone()); + let rev_reg_def_id = RevocationRegistryDefinitionId::new(rev_reg_id.clone())?; let rev_reg_def = Some( rev_reg_defs .as_ref() @@ -908,11 +908,11 @@ mod tests { fn filter() -> Filter { Filter { - schema_id: SchemaId::new(SCHEMA_ID), + schema_id: SchemaId::new_unchecked(SCHEMA_ID), schema_name: SCHEMA_NAME.to_string(), schema_issuer_did: SCHEMA_ISSUER_DID.to_string(), schema_version: SCHEMA_VERSION.to_string(), - cred_def_id: CredentialDefinitionId::new(CRED_DEF_ID), + cred_def_id: CredentialDefinitionId::new_unchecked(CRED_DEF_ID), issuer_did: ISSUER_DID.to_string(), } } diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 59023994..0816794f 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -150,11 +150,11 @@ fn anoncreds_works_for_single_issuer_single_prover() { ); let mut schemas = HashMap::new(); - let schema_id = SchemaId::new(SCHEMA_ID); + let schema_id = SchemaId::new_unchecked(SCHEMA_ID); schemas.insert(&schema_id, &gvt_schema); let mut cred_defs = HashMap::new(); - let cred_def_id = CredentialDefinitionId::new(CRED_DEF_ID); + let cred_def_id = CredentialDefinitionId::new_unchecked(CRED_DEF_ID); cred_defs.insert(&cred_def_id, &*gvt_cred_def); let presentation = prover::create_presentation( From b321bd404c74a8832f0b5a5e6b56c28d174076a8 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 14 Dec 2022 21:00:51 +0100 Subject: [PATCH 16/17] wrapper around rev_reg_id Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/cred_offer.rs | 10 ++++++++++ anoncreds/src/data_types/anoncreds/cred_request.rs | 1 + anoncreds/src/data_types/anoncreds/credential.rs | 9 ++++++--- anoncreds/src/data_types/anoncreds/presentation.rs | 4 ++-- anoncreds/src/data_types/anoncreds/rev_reg.rs | 4 +++- anoncreds/src/data_types/anoncreds/schema.rs | 7 ++++--- anoncreds/src/ffi/credential.rs | 5 +++-- anoncreds/src/ffi/presentation.rs | 2 ++ anoncreds/src/services/issuer.rs | 10 +++++++++- anoncreds/src/services/verifier.rs | 7 ++++--- 10 files changed, 44 insertions(+), 15 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/cred_offer.rs b/anoncreds/src/data_types/anoncreds/cred_offer.rs index 8e080270..1a130a60 100644 --- a/anoncreds/src/data_types/anoncreds/cred_offer.rs +++ b/anoncreds/src/data_types/anoncreds/cred_offer.rs @@ -1,3 +1,5 @@ +use indy_utils::{Validatable, ValidationError}; + use super::{cred_def::CredentialDefinitionId, nonce::Nonce, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] @@ -9,3 +11,11 @@ pub struct CredentialOffer { #[serde(skip_serializing_if = "Option::is_none")] pub method_name: Option, } + +impl Validatable for CredentialOffer { + fn validate(&self) -> Result<(), ValidationError> { + self.schema_id.validate()?; + self.cred_def_id.validate()?; + Ok(()) + } +} diff --git a/anoncreds/src/data_types/anoncreds/cred_request.rs b/anoncreds/src/data_types/anoncreds/cred_request.rs index eda68cb1..b134863c 100644 --- a/anoncreds/src/data_types/anoncreds/cred_request.rs +++ b/anoncreds/src/data_types/anoncreds/cred_request.rs @@ -14,6 +14,7 @@ pub struct CredentialRequest { impl Validatable for CredentialRequest { fn validate(&self) -> Result<(), ValidationError> { self.prover_did.validate()?; + self.cred_def_id.validate()?; Ok(()) } } diff --git a/anoncreds/src/data_types/anoncreds/credential.rs b/anoncreds/src/data_types/anoncreds/credential.rs index cf149c02..97cada6b 100644 --- a/anoncreds/src/data_types/anoncreds/credential.rs +++ b/anoncreds/src/data_types/anoncreds/credential.rs @@ -4,13 +4,13 @@ use zeroize::Zeroize; use crate::data_types::{Validatable, ValidationError}; -use super::{cred_def::CredentialDefinitionId, schema::SchemaId}; +use super::{cred_def::CredentialDefinitionId, schema::SchemaId, rev_reg::RevocationRegistryId}; #[derive(Debug, Deserialize, Serialize)] pub struct Credential { pub schema_id: SchemaId, pub cred_def_id: CredentialDefinitionId, - pub rev_reg_id: Option, + pub rev_reg_id: Option, pub values: CredentialValues, pub signature: ursa::cl::CredentialSignature, pub signature_correctness_proof: ursa::cl::SignatureCorrectnessProof, @@ -49,6 +49,9 @@ impl Credential { impl Validatable for Credential { fn validate(&self) -> Result<(), ValidationError> { self.values.validate()?; + self.schema_id.validate()?; + self.cred_def_id.validate()?; + self.rev_reg_id.as_ref().map(|i| i.validate()).transpose()?; if self.rev_reg_id.is_some() && (self.witness.is_none() || self.rev_reg.is_none()) { return Err("Credential validation failed: `witness` and `rev_reg` must be passed for revocable Credential".into()); @@ -68,7 +71,7 @@ pub struct CredentialInfo { pub attrs: ShortCredentialValues, pub schema_id: SchemaId, pub cred_def_id: CredentialDefinitionId, - pub rev_reg_id: Option, + pub rev_reg_id: Option, pub cred_rev_id: Option, } diff --git a/anoncreds/src/data_types/anoncreds/presentation.rs b/anoncreds/src/data_types/anoncreds/presentation.rs index a744e26b..74d717ec 100644 --- a/anoncreds/src/data_types/anoncreds/presentation.rs +++ b/anoncreds/src/data_types/anoncreds/presentation.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::data_types::Validatable; -use super::{cred_def::CredentialDefinitionId, schema::SchemaId}; +use super::{cred_def::CredentialDefinitionId, schema::SchemaId, rev_reg::RevocationRegistryId}; #[derive(Debug, Deserialize, Serialize)] pub struct Presentation { @@ -65,7 +65,7 @@ pub struct AttributeValue { pub struct Identifier { pub schema_id: SchemaId, pub cred_def_id: CredentialDefinitionId, - pub rev_reg_id: Option, + pub rev_reg_id: Option, pub timestamp: Option, } diff --git a/anoncreds/src/data_types/anoncreds/rev_reg.rs b/anoncreds/src/data_types/anoncreds/rev_reg.rs index fdcd91c6..e19a2188 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg.rs @@ -1,6 +1,8 @@ use std::collections::HashSet; -use crate::data_types::Validatable; +use crate::{data_types::Validatable, impl_anoncreds_object_identifier}; + +impl_anoncreds_object_identifier!(RevocationRegistryId); #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(tag = "ver")] diff --git a/anoncreds/src/data_types/anoncreds/schema.rs b/anoncreds/src/data_types/anoncreds/schema.rs index c28c01bb..c648a6ba 100644 --- a/anoncreds/src/data_types/anoncreds/schema.rs +++ b/anoncreds/src/data_types/anoncreds/schema.rs @@ -64,7 +64,8 @@ impl Into> for AttributeNames { impl Validatable for SchemaV1 { fn validate(&self) -> Result<(), ValidationError> { - self.attr_names.validate() + self.attr_names.validate()?; + Ok(()) } } @@ -115,7 +116,7 @@ mod test_schema_validation { }) .to_string(); - let _: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); + serde_json::from_str::(&schema_json).unwrap(); } #[test] @@ -128,6 +129,6 @@ mod test_schema_validation { }) .to_string(); - let _: SchemaV1 = serde_json::from_str(&schema_json).unwrap(); + serde_json::from_str::(&schema_json).unwrap(); } } diff --git a/anoncreds/src/ffi/credential.rs b/anoncreds/src/ffi/credential.rs index 8abdc241..865a21e1 100644 --- a/anoncreds/src/ffi/credential.rs +++ b/anoncreds/src/ffi/credential.rs @@ -8,6 +8,7 @@ use ffi_support::{rust_string_to_c, FfiStr}; use super::error::{catch_error, ErrorCode}; use super::object::{AnonCredsObject, ObjectHandle}; use super::util::{FfiList, FfiStrList}; +use crate::data_types::anoncreds::rev_reg::RevocationRegistryId; use crate::error::Result; use crate::services::{ issuer::create_credential, @@ -75,7 +76,7 @@ pub extern "C" fn anoncreds_create_credential( "Mismatch between length of attribute names and raw values" )); } - let rev_reg_id = rev_reg_id.as_opt_str(); + let rev_reg_id = rev_reg_id.as_opt_str().map(RevocationRegistryId::new).transpose()?; let enc_values = attr_enc_values.as_slice(); let mut cred_values = MakeCredentialValues::default(); let mut attr_idx = 0; @@ -139,7 +140,7 @@ pub extern "C" fn anoncreds_create_credential( cred_offer.load()?.cast_ref()?, cred_request.load()?.cast_ref()?, cred_values.into(), - rev_reg_id.map(String::from), + rev_reg_id, revocation_config .as_ref() .map(RevocationConfig::as_ref_config) diff --git a/anoncreds/src/ffi/presentation.rs b/anoncreds/src/ffi/presentation.rs index 58b9caec..4c38e403 100644 --- a/anoncreds/src/ffi/presentation.rs +++ b/anoncreds/src/ffi/presentation.rs @@ -7,6 +7,7 @@ use super::error::{catch_error, ErrorCode}; use super::object::{AnonCredsObject, AnonCredsObjectList, ObjectHandle}; use super::util::{FfiList, FfiStrList}; use crate::data_types::anoncreds::cred_def::{CredentialDefinition, CredentialDefinitionId}; +use crate::data_types::anoncreds::rev_reg::RevocationRegistryId; use crate::data_types::anoncreds::rev_reg_def::{ RevocationRegistryDefinition, RevocationRegistryDefinitionId, }; @@ -264,6 +265,7 @@ pub extern "C" fn anoncreds_verify_presentation( return Err(err_msg!("Invalid revocation registry entry index")); } let id = rev_reg_def_ids.as_slice()[*idx].as_str().to_owned(); + let id = RevocationRegistryId::new(id)?; rev_regs .entry(id) .or_insert_with(HashMap::new) diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index ba09e56e..3c4084e8 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -5,6 +5,7 @@ use indy_utils::Validatable; use super::types::*; use crate::data_types::anoncreds::cred_def::CredentialDefinitionId; +use crate::data_types::anoncreds::rev_reg::RevocationRegistryId; use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ cred_def::{CredentialDefinitionData, CredentialDefinitionV1}, @@ -262,7 +263,7 @@ pub fn create_credential( cred_offer: &CredentialOffer, cred_request: &CredentialRequest, cred_values: CredentialValues, - rev_reg_id: Option, + rev_reg_id: Option, revocation_config: Option, ) -> Result<( Credential, @@ -273,6 +274,13 @@ pub fn create_credential( cred_values: {:?}, revocation_config: {:?}", cred_def, secret!(&cred_def_private), &cred_offer.nonce, &cred_request, secret!(&cred_values), revocation_config, ); + let rev_reg_id = match rev_reg_id { + Some(id) => { + id.validate()?; + Some(id) + }, + None => None + }; let cred_public_key = match cred_def { CredentialDefinition::CredentialDefinitionV1(cd) => { diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index 8a14f27d..c2b9c7e2 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -6,6 +6,7 @@ use regex::Regex; use super::helpers::*; use super::types::*; use crate::data_types::anoncreds::cred_def::CredentialDefinitionId; +use crate::data_types::anoncreds::rev_reg::RevocationRegistryId; use crate::data_types::anoncreds::rev_reg_def::RevocationRegistryDefinitionId; use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ @@ -36,7 +37,7 @@ pub fn verify_presentation( schemas: &HashMap<&SchemaId, &Schema>, cred_defs: &HashMap<&CredentialDefinitionId, &CredentialDefinition>, rev_reg_defs: Option<&HashMap<&RevocationRegistryDefinitionId, &RevocationRegistryDefinition>>, - rev_regs: Option<&HashMap>>, + rev_regs: Option<&HashMap>>, ) -> Result { trace!("verify >>> presentation: {:?}, pres_req: {:?}, schemas: {:?}, cred_defs: {:?}, rev_reg_defs: {:?} rev_regs: {:?}", presentation, pres_req, schemas, cred_defs, rev_reg_defs, rev_regs); @@ -1178,7 +1179,7 @@ mod tests { timestamp: Some(1234), schema_id: SchemaId::default(), cred_def_id: CredentialDefinitionId::default(), - rev_reg_id: Some(String::new()), + rev_reg_id: Some(RevocationRegistryId::default()), }, ); res.insert( @@ -1187,7 +1188,7 @@ mod tests { timestamp: None, schema_id: SchemaId::default(), cred_def_id: CredentialDefinitionId::default(), - rev_reg_id: Some(String::new()), + rev_reg_id: Some(RevocationRegistryId::default()), }, ); res From 57ed97ad4288a1d4bcc57b0e4611cf0f96025774 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 15 Dec 2022 09:45:56 +0100 Subject: [PATCH 17/17] formatted code Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/credential.rs | 2 +- anoncreds/src/data_types/anoncreds/presentation.rs | 2 +- anoncreds/src/ffi/credential.rs | 5 ++++- anoncreds/src/services/issuer.rs | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/credential.rs b/anoncreds/src/data_types/anoncreds/credential.rs index 97cada6b..8055ad88 100644 --- a/anoncreds/src/data_types/anoncreds/credential.rs +++ b/anoncreds/src/data_types/anoncreds/credential.rs @@ -4,7 +4,7 @@ use zeroize::Zeroize; use crate::data_types::{Validatable, ValidationError}; -use super::{cred_def::CredentialDefinitionId, schema::SchemaId, rev_reg::RevocationRegistryId}; +use super::{cred_def::CredentialDefinitionId, rev_reg::RevocationRegistryId, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] pub struct Credential { diff --git a/anoncreds/src/data_types/anoncreds/presentation.rs b/anoncreds/src/data_types/anoncreds/presentation.rs index 74d717ec..6714e445 100644 --- a/anoncreds/src/data_types/anoncreds/presentation.rs +++ b/anoncreds/src/data_types/anoncreds/presentation.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::data_types::Validatable; -use super::{cred_def::CredentialDefinitionId, schema::SchemaId, rev_reg::RevocationRegistryId}; +use super::{cred_def::CredentialDefinitionId, rev_reg::RevocationRegistryId, schema::SchemaId}; #[derive(Debug, Deserialize, Serialize)] pub struct Presentation { diff --git a/anoncreds/src/ffi/credential.rs b/anoncreds/src/ffi/credential.rs index 865a21e1..d2f010c3 100644 --- a/anoncreds/src/ffi/credential.rs +++ b/anoncreds/src/ffi/credential.rs @@ -76,7 +76,10 @@ pub extern "C" fn anoncreds_create_credential( "Mismatch between length of attribute names and raw values" )); } - let rev_reg_id = rev_reg_id.as_opt_str().map(RevocationRegistryId::new).transpose()?; + let rev_reg_id = rev_reg_id + .as_opt_str() + .map(RevocationRegistryId::new) + .transpose()?; let enc_values = attr_enc_values.as_slice(); let mut cred_values = MakeCredentialValues::default(); let mut attr_idx = 0; diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index 3c4084e8..a53dab9b 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -278,8 +278,8 @@ pub fn create_credential( Some(id) => { id.validate()?; Some(id) - }, - None => None + } + None => None, }; let cred_public_key = match cred_def {