From 6f53dc0974d213e6466b0e1cd12edcd808d4f83c Mon Sep 17 00:00:00 2001 From: EmadAnwer Date: Thu, 4 Jul 2024 22:51:23 +0300 Subject: [PATCH] WPA: using static data to test the revocation validation --- aries_cloudagent/anoncreds/holder.py | 8 +-- aries_cloudagent/anoncreds/verifier.py | 50 +++++++++------- aries_cloudagent/vc/vc_di/prove.py | 82 +++++++++++++++++++++++++- aries_cloudagent/vc/vc_di/verify.py | 3 +- 4 files changed, 112 insertions(+), 31 deletions(-) diff --git a/aries_cloudagent/anoncreds/holder.py b/aries_cloudagent/anoncreds/holder.py index b6f1900f17..ee0feb9a93 100644 --- a/aries_cloudagent/anoncreds/holder.py +++ b/aries_cloudagent/anoncreds/holder.py @@ -717,16 +717,16 @@ async def create_presentation_w3c( cred, attr, reveal=True, - timestamp=timestamp, - rev_state=rev_state, + timestamp=meta.get("timestamp"), + rev_state=rev_states, ) for pred in meta["proof_preds"]: present_creds.add_predicates( cred, pred, - timestamp=timestamp, - rev_state=rev_state, + timestamp=meta.get("timestamp"), + rev_state=rev_states, ) try: diff --git a/aries_cloudagent/anoncreds/verifier.py b/aries_cloudagent/anoncreds/verifier.py index 8b5d0317b7..e94ebd02b5 100644 --- a/aries_cloudagent/anoncreds/verifier.py +++ b/aries_cloudagent/anoncreds/verifier.py @@ -499,9 +499,7 @@ async def verify_presentation( return (verified, msgs) async def verify_presentation_w3c( - self, - pres_req, - pres, + self, pres_req, pres, cred_metadata ) -> PresentationVerificationResult: """Verify a W3C presentation. @@ -529,27 +527,35 @@ async def verify_presentation_w3c( # TODO this should use the process_pres_identifiers() # method, which will also fetch the revocation info - for cred_def_id in cred_def_ids: - anoncreds_registry = self.profile.inject(AnonCredsRegistry) - # Build schemas for anoncreds - if cred_def_id not in cred_defs: - cred_def = ( - await anoncreds_registry.get_credential_definition( - self.profile, cred_def_id - ) - ).credential_definition.serialize() - cred_defs[cred_def_id] = cred_def - schema_id = cred_def["schemaId"] - schema = ( - await anoncreds_registry.get_schema(self.profile, schema_id) - ).serialize() - if schema["schema_id"] not in schemas: - schemas[schema["schema_id"]] = schema["schema"] + # for cred_def_id in cred_def_ids: + # anoncreds_registry = self.profile.inject(AnonCredsRegistry) + # # Build schemas for anoncreds + # if cred_def_id not in cred_defs: + # cred_def = ( + # await anoncreds_registry.get_credential_definition( + # self.profile, cred_def_id + # ) + # ).credential_definition.serialize() + # cred_defs[cred_def_id] = cred_def + # schema_id = cred_def["schemaId"] + # schema = ( + # await anoncreds_registry.get_schema(self.profile, schema_id) + # ).serialize() + # if schema["schema_id"] not in schemas: + # schemas[schema["schema_id"]] = schema["schema"] # TODO - this should get loaded from process_pres_identifiers() # (with schemas and cred defs) - rev_reg_defs = {} - rev_lists = {} + + anoncreds_verifier = AnonCredsVerifier(self.profile) + ( + schemas, + cred_defs, + rev_reg_defs, + rev_reg_entries, + ) = await anoncreds_verifier.process_pres_identifiers(cred_metadata) + # # rev_reg_defs = {} + # rev_lists = {} try: # TODO not sure why this attr causes an error @@ -566,7 +572,7 @@ async def verify_presentation_w3c( rev_reg_defs, [ rev_list - for timestamp_to_list in rev_lists.values() + for timestamp_to_list in rev_reg_entries.values() for rev_list in timestamp_to_list.values() ], ) diff --git a/aries_cloudagent/vc/vc_di/prove.py b/aries_cloudagent/vc/vc_di/prove.py index be7ed1fee5..ac935b25bd 100644 --- a/aries_cloudagent/vc/vc_di/prove.py +++ b/aries_cloudagent/vc/vc_di/prove.py @@ -1,18 +1,27 @@ """Verifiable Credential and Presentation proving methods.""" +import asyncio from hashlib import sha256 import time +from aries_cloudagent.anoncreds.models.anoncreds_revocation import ( + RevRegDef, + RevRegDefValue, +) +from aries_cloudagent.anoncreds.revocation import AnonCredsRevocation from ..ld_proofs import ( AuthenticationProofPurpose, ProofPurpose, LinkedDataProofException, ) -from ...anoncreds.holder import AnonCredsHolder +from ...anoncreds.holder import AnonCredsHolder, AnonCredsHolderError from ...anoncreds.verifier import AnonCredsVerifier from ...core.profile import Profile from anoncreds import ( W3cCredential, + RevocationStatusList, + CredentialRevocationState, + AnoncredsError, ) @@ -127,7 +136,7 @@ async def create_signed_anoncreds_presentation( if requires_revoc_status: w3c_creds_metadata[entry_idx]["rev_reg_id"] = w3c_cred.rev_reg_id - w3c_creds_metadata[entry_idx]["timestamp"] = w3c_cred.timestamp # missing + w3c_creds_metadata[entry_idx]["timestamp"] = non_revoked # missing for field in fields: path = field["path"][0] @@ -199,6 +208,37 @@ async def create_signed_anoncreds_presentation( rev_reg_entries, ) = await anoncreds_verifier.process_pres_identifiers(w3c_creds_metadata) + if rev_reg_defs: + revreg_def_v = list(rev_reg_defs.values())[0] + rev_reg_key = list(rev_reg_defs.keys())[0] + + rev_reg_def = { + rev_reg_key: RevRegDef( + issuer_id=revreg_def_v["issuerId"], + cred_def_id=revreg_def_v["credDefId"], + tag=revreg_def_v["tag"], + value=RevRegDefValue( + public_keys=revreg_def_v["value"]["publicKeys"], + tails_hash=revreg_def_v["value"]["tailsHash"], + tails_location=revreg_def_v["value"]["tailsLocation"], + max_cred_num=revreg_def_v["value"]["maxCredNum"], + ), + type=revreg_def_v["revocDefType"], + ) + } + + x = RevocationStatusList.load( + list(list(rev_reg_entries.values())[0].values())[0] + ).to_dict() + + del x["currentAccumulator"] + + rev_lists = {"e": list(x.values())} + + rev_lists["e"][2] = RevocationStatusList.load( + list(list(rev_reg_entries.values())[0].values())[0] + ) + # TODO use rev_reg_defs, rev_reg_entries to create revocation states ... # TODO possibly refactor this into a couple of methods - # one to create the proof request and another to sign it @@ -206,13 +246,49 @@ async def create_signed_anoncreds_presentation( if holder: # TODO match up the parameters with what the function is expecting ... anoncreds_holder = AnonCredsHolder(profile) + revocation = AnonCredsRevocation(profile) + rev_state = None + try: + + if rev_reg_defs: + + rev_reg_def = RevRegDef( + issuer_id=revreg_def_v["issuerId"], + cred_def_id=revreg_def_v["credDefId"], + tag=revreg_def_v["tag"], + value=RevRegDefValue( + public_keys=revreg_def_v["value"]["publicKeys"], + tails_hash=revreg_def_v["value"]["tailsHash"], + tails_location=revreg_def_v["value"]["tailsLocation"], + max_cred_num=revreg_def_v["value"]["maxCredNum"], + ), + type=revreg_def_v["revocDefType"], + ) + tails_local_path = await revocation.get_or_fetch_local_tails_path( + rev_reg_def + ) + rev_state = await asyncio.get_event_loop().run_in_executor( + None, + CredentialRevocationState.create, + rev_reg_def.serialize(), + RevocationStatusList.load( + list(list(rev_reg_entries.values())[0].values())[0] + ), + int(w3c_creds[0].rev_reg_index), + tails_local_path, + ) + + print(">>> rev_state:", rev_state) + + except AnoncredsError as err: + raise AnonCredsHolderError("Error creating revocation state") from err anoncreds_proof = await anoncreds_holder.create_presentation_w3c( presentation_request=anoncreds_proofrequest, requested_credentials_w3c=w3c_creds, credentials_w3c_metadata=w3c_creds_metadata, schemas=schemas, credential_definitions=cred_defs, - rev_states=None, + rev_states=rev_state, ) # TODO any processing to put the returned proof into DIF format diff --git a/aries_cloudagent/vc/vc_di/verify.py b/aries_cloudagent/vc/vc_di/verify.py index bc4ced8dd0..588b88ecce 100644 --- a/aries_cloudagent/vc/vc_di/verify.py +++ b/aries_cloudagent/vc/vc_di/verify.py @@ -58,8 +58,7 @@ async def verify_signed_anoncredspresentation( try: return await anoncreds_verifier.verify_presentation_w3c( - anoncreds_pres_req, - presentation, + anoncreds_pres_req, presentation, cred_metadata ) except Exception as e: raise e