From de4e35b242a0bad25e9a7fa16473982a7d6bd99c Mon Sep 17 00:00:00 2001 From: "artem.ivanov" Date: Tue, 16 Jan 2024 09:58:14 +0300 Subject: [PATCH] Added check for predicates Signed-off-by: artem.ivanov --- Cargo.toml | 2 +- src/data_types/pres_request.rs | 12 +++++++ src/data_types/w3c/proof.rs | 35 ++++++++++++++++-- src/services/w3c/helpers.rs | 41 +++++++++------------ src/services/w3c/verifier.rs | 65 ++++++++++++++-------------------- 5 files changed, 89 insertions(+), 66 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 04c68278..2e851ca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ vendored = ["anoncreds-clsignatures/openssl_vendored"] w3c = ["base64", "chrono", "rmp-serde"] [dependencies] -anoncreds-clsignatures = "0.3.0" +anoncreds-clsignatures = "0.3.1" bs58 = "0.4.0" env_logger = { version = "0.9.3", optional = true } ffi-support = { version = "0.4.0", optional = true } diff --git a/src/data_types/pres_request.rs b/src/data_types/pres_request.rs index e58bfe68..0838b2d6 100644 --- a/src/data_types/pres_request.rs +++ b/src/data_types/pres_request.rs @@ -1,3 +1,4 @@ +use anoncreds_clsignatures::PredicateType; use std::collections::HashMap; use std::fmt; @@ -219,6 +220,17 @@ impl fmt::Display for PredicateTypes { } } +impl From for PredicateType { + fn from(value: PredicateTypes) -> Self { + match value { + PredicateTypes::GE => PredicateType::GE, + PredicateTypes::GT => PredicateType::GT, + PredicateTypes::LE => PredicateType::LE, + PredicateTypes::LT => PredicateType::LT, + } + } +} + #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct RequestedAttributeInfo { pub attr_referent: String, diff --git a/src/data_types/w3c/proof.rs b/src/data_types/w3c/proof.rs index 7f45ec61..48da8817 100644 --- a/src/data_types/w3c/proof.rs +++ b/src/data_types/w3c/proof.rs @@ -314,11 +314,42 @@ pub(crate) mod tests { }, "m2":"2553030889054034879941219523536672152702359185828546810612564355745759663351165380563310203986319611277915826660660011443138240248924364893067083241825560", "revealed_attrs":{ - "name":"66682250590915135919393234675423675079281389286836524491448775067034910960723" + "name":"27034640024117331033063128044004318218486816931520886405535659934417438781507", + "height":"178" }, "v":"241132863422049783305938040060597331735278274539541049316128678268379301866997158072011728743321723078574060931449243960464715113938435991871547190135480379265493203441002211218757120311064385792274455797457074741542288420192538286547871288116110058144080647854995527978708188991483561739974917309498779192480418427060775726652318167442183177955447797995160859302520108340826199956754805286213211181508112097818654928169122460464135690611512133363376553662825967455495276836834812520601471833287810311342575033448652033691127511180098524259451386027266077398672694996373787324223860522678035901333613641370426224798680813171225438770578377781015860719028452471648107174226406996348525110692233661632116547069810544117288754524961349911209241835217711929316799411645465546281445291569655422683908113895340361971530636987203042713656548617543163562701947578529101436799250628979720035967402306966520999250819096598649121167" }, - "ge_proofs":[] + "ge_proofs":[ + { + "alpha":"91220714671444392049098338684790704633533569564315230075539856448338492680812282072362540735427809388270066455205446617374273995782554023377399804680731177040820232234103905929245544987284390459421201350502799357084572144630393229752965186421948202493395713653211261041852571798619503895533346500039830736972086153800117378029361886647047095376275665663965834031955496258448997095624866059846872981856675389692109959092094806511454852995405728568479147049053492114956054980496971797079430191367299794264478249696184662697292162371750117069888618647245378182107893472040860186518606846123082528380203115122049346720684632822988124624232104408068871143529062290368275811065489280640284628547286984413518627275012302744149723004365305203107751097864041449256066333845275140021245574457318613498147991578104948027924350075803209003472770171508", + "mj":"10619618416826273180397098803657766447651768379400923597030398076034183761672856302638410567535231814845543058601785335204535280819985764784669686133824906415128411093552997221368", + "predicate":{ + "attr_name":"age", + "p_type":"GE", + "value":18 + }, + "r":{ + "0":"1588773841780214552359776199576628657422386379581875893884372384945078939367811669090633715735973102089830616387572913590903177855451313150803976101815197814546943692782886723295746289356733941843720702593284085499174918510800622738993820307452003642209484819110747316677067093332440085440025164455806240551962801578883036541149230246370241587135313625002361803674314220240325030115679027145118594398919147306855967972213149349618757473914836569589409360381363133999563340224289773423298061372462452654469527456288604836354940362627104777524515399631756958068413497302427594449392887094786817130374459442258515737158811686608247853699920092770291702232183843727566921363528103710173784544959052443469285368754401657196", + "1":"1256637461243595604322863152096695336988741930946020430733567407182983540413613586145869057743579927372473885067510018613665224897849401692855807875596945318002448112389712134976382615924445697735114266283359186511759922024528029759666589075823639433029347021711617386390388119939639554649246510017374304289842894121976296696383665849531200028223642037058012440962161711327633361506751679881935716365348597650188385003189685455873956352275864507358751108468616792212883072002977937356183984733305883101734940610235124050728483164184768583108042582305043633880442432266261059349235842130246766593025175585949268421893519917461893052466099961687152805398299274146695036237567981404300725384720284767733503300712690230066", + "2":"1180470752287078364045027938881431613908286199987885445191097018463514753226258434971970185913902638482837033208536492358985171746629207883670533746365587515021341605180977408566855989917724250395423339932092420398421191723451854001132891740727213359926397393866003819102156139645294868568720892107454597994399663270849626034194812335352358683129740790900198708737271280718525529045149216850592542049021883013759819845832517077594258837166386555069713745897243088088130250768210556913814239420667349881002746337249159009429446096267443703716720519147423788417467630700941214871833654279244114934863266782981572888619570061750211802733422965672862460857370701115334422790171062624083846772286688851070554099303963921104", + "3":"1554750004410378527983822806396206150464097753774479793235223765194888527957776464556761722575086189610621769436280902828919918551500848757948401036034758232620903277502984809681150532613764145652533551203089474969485186034939651354452101784526177955451238190690104076761670672401174038610412812526020744038000502620834777200034105678723861330359048143413197833551785458979800481541528932013012871846192835556374129289856524600042093496469951221267239541036695781151538783592366750845197652975087446697387386311902873270860149765323323187433441607423920187284116094929609221567374838533141008330348008068772941193691271050660162302081076236856953603634061067389248305683590442781682491548673677254798771710885037796659", + "DELTA":"1591114056356953008302389836487088294824152830750916368566265981893546977236615844801936236823422986263596737827206475075016247008711981755783323755057168890433204544347517827221359538571606352035283603183519055880349734991132973043683139771266391445623003841750375768863170117737306760487644386418014467864235824811986915610106599990309382168306174519569960373054711786607068624060933746910803303786482726306172443849393961664884433192775912375242311944208345972180566879252202193002582502332472161772185829653341558236501172811022440617874812946623249952881355038481568373284396730255846889188942800549892176796330313537049720141217138331376836082910824922102630062526235501539331525707791179105054842938922082273341" + }, + "t":{ + "0":"64866996697789195209280610141661958251568008114948414934413958296971339012889321602743229534701276778987450376839584381564432237982467665325878769345568644118005387300780740353119586313215268801420656057929003191994949238757497970606857982612190953040166976139020384044674984753007915757233780798405084657312596339298214440966181148595394143651090062868272637661599156374401948677255896118592942051029425966532644474294261068933998155420437467426800184193783489247605940353558912734022194504744614576990377832513342220548575580079569434063529465779643924541222580028865234979421406039311319392788727862833372661812079", + "1":"67303978424359582715108363896151264391768399044745955395288155914114263062414166017940570134013652095220132600639211498623236325803113232769613832542046971180853882781339367205952142717758262234340067056755607062165703827148360166612839585924791432604865318898396310692070583836581734207887652888544729655037417276262346412915175935713397032895503260779806300967606578152659383022978757619384247504049549400918184711168027828295536608102556236260070926784249029255670389326662927138230386472848194253812563583749887864868539756587998651377854124493763184412004468888027472328169903649172001104488180406594526088065364", + "2":"18436150017847362148503422934807623982558815194978492560526315168833670353679306438499002886985324139611559716808905964012901082839923805866332404521363415208828633794588913271582024302442760509341860860452135384881748467914499903893497021322668173317724455347588723088645268399003636488636255170578169602866806870175728380227213849553021449146855307562973456748083976082888488765887213872710497047213304951072622398573443877599885784967211283713595363564060299966480075439924341684314227193969890983198284879899534016462786708400323988903624076030501131051782105520306583282647892201684723226256941851600164798261880", + "3":"80540787074475770948660676781681004318473659262891446094891575133006197034890969100212418274423711067808416693520604223042156316702551364570788698259945859278631567782188001291620437568959698091422096339806965811163965272534011394991383654588148424651132454462060754800885777955043665365498632157797055058151411264229226312327674056428967625747209116555960361444208812300676158339558611501661414801144395602242708550065513573607276358638179403543703279653212854355283229216684185613541665048996953524052618105804915972281524980080258106845176656276743289508024830814580864628715844679439025023554817148003637660059887", + "DELTA":"38128302244645018703614537759663050901282421681496452389916789850297775528223375163975708479447627776714574447185672092288753220297481568686299394510463089778981483516150456298091794185362061077601863665101246931716529026964302951763043406542033213721811976816002462606153992893712899928899436878697876337417072593686060699133798221124684368093425078651290877250512092087658564967995284650495307815179709968706695989964533230783143390286689612896716897737374321292841418619819673977548636000164967688437443605065985702273593701939206841156162246473653997008652142246744504615370364717636163329586868597033790427165825" + }, + "u":{ + "0":"6426124753400912236632328522015044090086922220319370716985855652608326099686652357532800961549405711164418863901623019555846606630251161505603206034811202965910995811690795138214", + "1":"3909215487926900168604769541427083916058262011373000358888936014541302480601270653036273837969290381956761016976440071404509435892364951044838810885942402174245287406904366305456", + "2":"7652194204529394001615049073842780065526835674980893677706271902982921524392585624184469677898007893338946001313177343952762715670988112050727645115894537310867340212405807178105", + "3":"1041238499986953151033833015824013914006748060477385128094301887263879042479529065682677955278085858226310034138770368152097812384789680952282311296092825182415553982591317576772" + } + } + ] } })).unwrap() } diff --git a/src/services/w3c/helpers.rs b/src/services/w3c/helpers.rs index 81c791b9..b21858dd 100644 --- a/src/services/w3c/helpers.rs +++ b/src/services/w3c/helpers.rs @@ -2,7 +2,6 @@ use crate::data_types::w3c::credential::W3CCredential; use crate::data_types::w3c::credential_attributes::CredentialAttributeValue; use crate::error::Result; use crate::helpers::attr_common_view; -use std::collections::HashMap; impl W3CCredential { pub(crate) fn get_case_insensitive_attribute( @@ -19,31 +18,25 @@ impl W3CCredential { .ok_or_else(|| err_msg!("Credential attribute {} not found", requested_attribute)) } - pub(crate) fn has_attribute(&self, requested_attribute: &str) -> bool { - let (_, value) = match self.get_case_insensitive_attribute(requested_attribute) { - Ok(value) => value, - _ => { - return false; - } - }; - matches!(value, CredentialAttributeValue::Attribute(_)) - } - - pub(crate) fn has_predicate(&self, requested_predicate: &str) -> bool { - let (_, value) = match self.get_case_insensitive_attribute(requested_predicate) { - Ok(value) => value, - Err(_) => return false, - }; - matches!(value, CredentialAttributeValue::Predicate(_)) + pub(crate) fn get_attribute(&self, requested_attribute: &str) -> Result<(String, String)> { + let (attribute, value) = self.get_case_insensitive_attribute(requested_attribute)?; + match value { + CredentialAttributeValue::Attribute(value) => Ok((attribute, value)), + CredentialAttributeValue::Predicate(_) => Err(err_msg!( + "Credential attribute {} not found", + requested_attribute + )), + } } - pub(crate) fn get_attributes(&self) -> HashMap { - let mut attributes: HashMap = HashMap::new(); - for (name, attribute) in self.credential_subject.attributes.0.iter() { - if let CredentialAttributeValue::Attribute(attribute) = attribute { - attributes.insert(name.to_string(), attribute.to_string()); - } + pub(crate) fn get_predicate(&self, requested_predicate: &str) -> Result<(String, bool)> { + let (attribute, value) = self.get_case_insensitive_attribute(requested_predicate)?; + match value { + CredentialAttributeValue::Predicate(value) => Ok((attribute, value)), + CredentialAttributeValue::Attribute(_) => Err(err_msg!( + "Credential predicate {} not found", + requested_predicate + )), } - attributes } } diff --git a/src/services/w3c/verifier.rs b/src/services/w3c/verifier.rs index 2361668c..946d3ad4 100644 --- a/src/services/w3c/verifier.rs +++ b/src/services/w3c/verifier.rs @@ -70,15 +70,7 @@ pub fn verify_presentation( let mut sub_proofs: Vec = Vec::with_capacity(presentation.verifiable_credential.len()); - let iter = presentation - .verifiable_credential - .iter() - .zip(credential_proofs); - - for (verifiable_credential, credential_proof) in iter { - let attributes = verifiable_credential.get_attributes(); - verify_revealed_attributes(&attributes, &credential_proof)?; - + for credential_proof in credential_proofs { let mut revealed_attribute: HashSet = credential_proof.mapping.revealed_attributes.clone(); revealed_attribute.extend(credential_proof.mapping.revealed_attribute_groups.clone()); @@ -153,12 +145,11 @@ fn check_requested_attribute<'a>( for (credential, proof) in iter { if let Some(ref name) = attribute.name { if proof.mapping.revealed_attributes.contains(referent) { - if !credential.has_attribute(name) { - return Err(err_msg!( - "Credential does not contain revealed attribute {}", - name - )); - } + let (_, value) = credential.get_attribute(name)?; + + let encoded = encode_credential_attribute(&value)?; + verify_revealed_attribute_value(name, &proof.sub_proof, &encoded)?; + check_credential_restrictions( credential, attribute.restrictions.as_ref(), @@ -166,8 +157,10 @@ fn check_requested_attribute<'a>( cred_defs, proof, )?; + return Ok(credential); } + if proof.mapping.unrevealed_attributes.contains(referent) { check_credential_restrictions( credential, @@ -182,12 +175,11 @@ fn check_requested_attribute<'a>( if let Some(ref names) = attribute.names { if proof.mapping.revealed_attribute_groups.contains(referent) { for name in names { - if !credential.has_attribute(name) { - return Err(err_msg!( - "Credential does not contain revealed attribute {}", - name - )); - } + let (_, value) = credential.get_attribute(name)?; + + let encoded = encode_credential_attribute(&value)?; + verify_revealed_attribute_value(name, &proof.sub_proof, &encoded)?; + check_credential_restrictions( credential, attribute.restrictions.as_ref(), @@ -223,12 +215,21 @@ fn check_requested_predicate<'a>( for (credential, proof) in iter { if proof.mapping.predicates.contains(referent) { - if !credential.has_predicate(&predicate.name) { + let (predicate_name, _) = credential.get_predicate(&predicate.name)?; + + let matches_cl_proof_predicate = proof.sub_proof.predicates().into_iter().find(|p| { + p.attr_name == predicate_name + && p.p_type == predicate.p_type.clone().into() + && p.value == predicate.p_value + }); + + if matches_cl_proof_predicate.is_none() { return Err(err_msg!( - "Credential does not contain revealed attribute {}", + "Predicate does not match to requested {}", predicate.name )); } + check_credential_restrictions( credential, predicate.restrictions.as_ref(), @@ -236,12 +237,13 @@ fn check_requested_predicate<'a>( cred_defs, proof, )?; + return Ok(credential); } } Err(err_msg!( - "Presentation does not contain attribute {}", + "Presentation does not contain predicate {}", predicate.name )) } @@ -277,21 +279,6 @@ fn check_request_data( Ok(()) } -fn verify_revealed_attributes( - attributes: &HashMap, - credential_proof: &CredentialPresentationProofValue, -) -> Result<()> { - attributes - .iter() - .map(|(name, value)| { - encode_credential_attribute(value).and_then(|encoded| { - verify_revealed_attribute_value(name, &credential_proof.sub_proof, &encoded) - }) - }) - .collect::>>()?; - Ok(()) -} - #[cfg(test)] pub(crate) mod tests { use super::*;