Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #992 from Artemkaaas/bugfix/get-credentials-for-pr…
Browse files Browse the repository at this point in the history
…oof-req

Bugfix/get credentials for proof req
  • Loading branch information
jovfer authored Jul 27, 2018
2 parents 4f0ec82 + 5e114fe commit 53aed50
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 22 deletions.
11 changes: 9 additions & 2 deletions libindy/src/commands/anoncreds/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use self::indy_crypto::utils::json::{JsonDecodable, JsonEncodable};
use super::tails::SDKTailsAccessor;

use domain::anoncreds::schema::{Schema, schemas_map_to_schemas_v1_map};
use domain::anoncreds::credential::{Credential, CredentialInfo};
use domain::anoncreds::credential::{Credential, CredentialInfo, AttributeValues};
use domain::anoncreds::credential_definition::{CredentialDefinition, CredentialDefinitionV1, cred_defs_map_to_cred_defs_v1_map};
use domain::anoncreds::credential_offer::CredentialOffer;
use domain::anoncreds::credential_request::{CredentialRequest, CredentialRequestMetadata};
Expand Down Expand Up @@ -805,8 +805,15 @@ impl ProverCommandExecutor {
let (referent, credential) = self._get_credential(&credential_record)?;

if let Some(predicate) = predicate_info {

let cred_values_common_view: HashMap<String, AttributeValues> =
credential.values
.iter()
.map(|(key, value)| (attr_common_view(&key), value.clone()))
.collect();

let satisfy = self.anoncreds_service.prover.attribute_satisfy_predicate(predicate,
&credential.values[&attr_common_view(&predicate.name)].encoded)?;
&cred_values_common_view[&attr_common_view(&predicate.name)].encoded)?;
if !satisfy { continue; }
}

Expand Down
10 changes: 1 addition & 9 deletions libindy/src/commands/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,15 +388,7 @@ impl LedgerCommandExecutor {
CommonError::InvalidStructure(format!("Message is invalid json: {}", request)))));
}

let mut message_without_signatures = request.clone();
message_without_signatures.as_object_mut()
.map(|request| {
request.remove("signature");
request.remove("signatures");
request
}).ok_or(CommonError::InvalidState("Cannot deserialize request".to_string()))?;

let serialized_request = serialize_signature(message_without_signatures)?;
let serialized_request = serialize_signature(request.clone())?;
let signature = self.crypto_service.sign(&my_key, &serialized_request.as_bytes().to_vec())?;

match signature_type {
Expand Down
53 changes: 44 additions & 9 deletions libindy/src/utils/crypto/signature_serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ use errors::common::CommonError;
use utils::crypto::hash::Hash;

pub fn serialize_signature(v: Value) -> Result<String, CommonError> {
_serialize_signature(v, true)
}

fn _serialize_signature(v: Value, is_top_level: bool) -> Result<String, CommonError> {
match v {
Value::Bool(value) => Ok(if value { "True".to_string() } else { "False".to_string() }),
Value::Number(value) => Ok(value.to_string()),
Expand All @@ -16,7 +20,7 @@ pub fn serialize_signature(v: Value) -> Result<String, CommonError> {
let mut result = "".to_string();
let length = array.len();
for (index, element) in array.iter().enumerate() {
result += &serialize_signature(element.clone())?;
result += &_serialize_signature(element.clone(), false)?;
if index < length - 1 {
result += ",";
}
Expand All @@ -25,20 +29,23 @@ pub fn serialize_signature(v: Value) -> Result<String, CommonError> {
}
Value::Object(map) => {
let mut result = "".to_string();
let length = map.len();
for (index, key) in map.keys().enumerate() {
if key == "signature" { continue; } // Skip signature field as in python code
let mut in_middle = false;
for key in map.keys() {
// Skip signature field at top level as in python code
if is_top_level && (key == "signature" || key == "fees" || key == "signatures") { continue; }

if in_middle {
result += "|";
}

let mut value = map[key].clone();
if key == "raw" || key == "hash" || key == "enc" {
let mut ctx = Hash::new_context()?;
ctx.update(&value.as_str().ok_or(CommonError::InvalidState("Cannot update hash context".to_string()))?.as_bytes())?;
value = Value::String(ctx.finish2()?.as_ref().to_hex());
}
result = result + key + ":" + &serialize_signature(value)?;
if index < length - 1 {
result += "|";
}
result = result + key + ":" + &_serialize_signature(value, false)?;
in_middle = true;
}
Ok(result)
}
Expand Down Expand Up @@ -73,6 +80,34 @@ mod tests {
assert_eq!(serialize_signature(msg).unwrap(), result)
}


#[test]
fn signature_serialize_works_for_skipped_fields() {
let data = r#"{
"name": "John Doe",
"age": 43,
"operation": {
"hash": "cool hash",
"dest": 54
},
"fees": "fees1",
"signature": "sign1",
"signatures": "sign-m",
"phones": [
"1234567",
"2345678",
{"rust": 5, "age": 1},
3
]
}"#;
let msg: Value = serde_json::from_str(data).unwrap();

let result = "age:43|name:John Doe|operation:dest:54|hash:46aa0c92129b33ee72ee1478d2ae62fa6e756869dedc6c858af3214a6fcf1904|phones:1234567,2345678,age:1|rust:5,3";

assert_eq!(serialize_signature(msg).unwrap(), result)
}


#[test]
fn signature_serialize_works_with_raw() {
let data = r#"{
Expand Down Expand Up @@ -104,4 +139,4 @@ mod tests {
let serialized = serialize_signature(v).unwrap();
assert_eq!(serialized, "");
}
}
}
27 changes: 27 additions & 0 deletions libindy/tests/anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,33 @@ mod high_cases {

WalletUtils::close_wallet(wallet_handle).unwrap();
}

#[test]
fn prover_get_credentials_for_proof_req_works_for_predicate_uppercase() {
AnoncredsUtils::init_common_wallet();

let wallet_handle = WalletUtils::open_wallet(ANONCREDS_WALLET_CONFIG, WALLET_CREDENTIALS).unwrap();

let proof_req = json!({
"nonce":"123432421212",
"name":"proof_req_1",
"version":"0.1",
"requested_attributes": json!({}),
"requested_predicates": json!({
"predicate1_referent": json!({ "name":"AGe", "p_type":">=", "p_value":18 })
}),
}).to_string();

let credentials_json = AnoncredsUtils::prover_get_credentials_for_proof_req(wallet_handle, &proof_req).unwrap();

let credentials: CredentialsForProofRequest = serde_json::from_str(&credentials_json).unwrap();
assert_eq!(credentials.predicates.len(), 1);

let credentials_for_predicate_1 = credentials.predicates.get("predicate1_referent").unwrap();
assert_eq!(credentials_for_predicate_1.len(), 2);

WalletUtils::close_wallet(wallet_handle).unwrap();
}
}

mod predicate_restrictions_wql_format {
Expand Down
4 changes: 2 additions & 2 deletions libindy/tests/utils/anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ impl AnoncredsUtils {
"sex".to_string() => AttributeValues {raw: "male".to_string(), encoded: "2142657394558967239210949258394838228692050081607692519917028371144233115103".to_string()},
"name".to_string() => AttributeValues {raw: "Alexander".to_string(), encoded: "21332817548165488690172217217278169335".to_string()},
"height".to_string() => AttributeValues {raw: "170".to_string(), encoded: "170".to_string()},
"age".to_string() => AttributeValues {raw: "28".to_string(), encoded: "28".to_string()}
"Age".to_string() => AttributeValues {raw: "28".to_string(), encoded: "28".to_string()}
}
}

Expand Down Expand Up @@ -610,7 +610,7 @@ impl AnoncredsUtils {
"sex".to_string() => "male".to_string(),
"name".to_string() => "Alexander".to_string(),
"height".to_string() => "170".to_string(),
"age".to_string() => "28".to_string()
"Age".to_string() => "28".to_string()
}
}
}
Expand Down

0 comments on commit 53aed50

Please sign in to comment.