def _mergeInvitaion(self, invitationData): linkInvitation = invitationData.get('link-invitation') linkName = linkInvitation['name'] link = self.wallet.getLink(linkName) invitationProofRequests = invitationData.get('proof-requests', None) if invitationProofRequests: for icr in invitationProofRequests: # match is found if name and version are same matchedProofRequest = next( (cr for cr in link.proofRequests if (cr.name == icr[NAME] and cr.version == icr[VERSION])), None) # if link.requestedProofs contains any claim request if matchedProofRequest: # merge 'attributes' and 'verifiableAttributes' matchedProofRequest.attributes = { **matchedProofRequest.attributes, **icr[ATTRIBUTES] } matchedProofRequest.verifiableAttributes = list( set(matchedProofRequest.verifiableAttributes).union( icr[VERIFIABLE_ATTRIBUTES])) else: # otherwise append proof request to link link.proofRequests.append( ProofRequest(icr[NAME], icr[VERSION], icr[ATTRIBUTES], icr[VERIFIABLE_ATTRIBUTES])) return link else: raise LinkAlreadyExists
def loadInvitation(self, invitationData): linkInvitation = invitationData["link-invitation"] remoteIdentifier = linkInvitation[f.IDENTIFIER.nm] # TODO signature should be validated! signature = invitationData["sig"] linkInvitationName = linkInvitation[NAME] remoteEndPoint = linkInvitation.get("endpoint", None) remote_verkey = linkInvitation.get("verkey", None) linkNonce = linkInvitation[NONCE] proofRequestsJson = invitationData.get("proof-requests", None) proofRequests = [] if proofRequestsJson: for cr in proofRequestsJson: proofRequests.append( ProofRequest(cr[NAME], cr[VERSION], cr[ATTRIBUTES], cr[VERIFIABLE_ATTRIBUTES])) self.notifyMsgListener("1 link invitation found for {}.". format(linkInvitationName)) self.notifyMsgListener("Creating Link for {}.". format(linkInvitationName)) # TODO: Would we always have a trust anchor corresponding to a link? li = Link(name=linkInvitationName, trustAnchor=linkInvitationName, remoteIdentifier=remoteIdentifier, remoteEndPoint=remoteEndPoint, invitationNonce=linkNonce, proofRequests=proofRequests, remote_verkey=remote_verkey) self.wallet.addLink(li) return li
def handleProofRequest(self, msg): body, _ = msg link = self._getLinkByTarget(getCryptonym(body.get(IDENTIFIER))) proofReqName = body.get(NAME) proofReqExist = False for request in link.proofRequests: if request.name == proofReqName: proofReqExist = True break self.notifyMsgListener( ' Proof request {} received from {}.\n'.format( proofReqName, link.name)) if not proofReqExist: link.proofRequests.append( ProofRequest( name=proofReqName, version=body.get(VERSION), attributes=body.get(ATTRIBUTES), verifiableAttributes=body.get(VERIFIABLE_ATTRIBUTES))) else: self.notifyMsgListener( ' Proof request {} already exist.\n'.format(proofReqName))
def sendProofReq(self, link: Link, proofReqSchemaKey): if self._proofRequestsSchema and (proofReqSchemaKey in self._proofRequestsSchema): proofRequest = self._proofRequestsSchema[proofReqSchemaKey] proofRequest = ProofRequest( proofRequest[NAME], proofRequest[VERSION], getNonceForProof(link.invitationNonce), proofRequest[ATTRIBUTES], proofRequest[VERIFIABLE_ATTRIBUTES] if VERIFIABLE_ATTRIBUTES in proofRequest else [], proofRequest[PREDICATES] if PREDICATES in proofRequest else []) op = { TYPE: PROOF_REQUEST, PROOF_REQUEST_FIELD: proofRequest.to_str_dict() } self.signAndSendToLink(msg=op, linkName=link.name) else: return ERR_NO_PROOF_REQUEST_SCHEMA_FOUND
async def sendProofAsync(self, link: Link, proofRequest: ProofRequest): # TODO _F_ this nonce should be from the Proof Request, not from an # invitation proofInput = ProofInput( nonce=proofRequest.nonce, revealedAttrs=proofRequest.verifiableAttributes, predicates=proofRequest.predicates) # TODO rename presentProof to buildProof or generateProof proof = await self.prover.presentProof(proofInput) proof.requestedProof.self_attested_attrs.update( proofRequest.selfAttestedAttrs) op = { TYPE: PROOF, NONCE: link.invitationNonce, PROOF_FIELD: proof.to_str_dict(), PROOF_REQUEST_FIELD: proofRequest.to_str_dict() } self.signAndSendToLink(msg=op, linkName=link.name)
def handleProofRequest(self, msg): body, _ = msg link = self._getLinkByTarget(getCryptonym(body.get(IDENTIFIER))) proofRequest = body.get(PROOF_REQUEST_FIELD) proofRequest = ProofRequest.from_str_dict(proofRequest) proofReqExist = False for request in link.proofRequests: if request.name == proofRequest.name: proofReqExist = True break self.notifyMsgListener( ' Proof request {} received from {}.\n'.format( proofRequest.name, link.name)) if not proofReqExist: link.proofRequests.append(proofRequest) else: self.notifyMsgListener( ' Proof request {} already exist.\n'.format( proofRequest.name))
async def verifyProof(self, msg: Any): body, (frm, _) = msg link = self.verifyAndGetLink(msg) if not link: raise NotImplementedError proof = body[PROOF_FIELD] proofRequest = ProofRequest.from_str_dict(body[PROOF_REQUEST_FIELD]) nonce = getNonceForProof(body[NONCE]) proofName = proofRequest.name proofs = {} for key, p in proof['proofs'].items(): schema = await self.verifier.wallet.getSchema( ID(schemaId=int(p['schema_seq_no']))) pk = await self.verifier.wallet.getPublicKey( ID(schemaKey=schema.getKey())) proofs[key] = ProofInfo.from_str_dict(p, str(pk.N)) proof = FullProof( proofs, AggregatedProof.from_str_dict(proof['aggregated_proof']), RequestedProof.from_str_dict(proof['requested_proof'])) proofInput = ProofInput( nonce=int(proofRequest.nonce), revealedAttrs=proofRequest.verifiableAttributes, predicates=proofRequest.predicates) result = await self.verifier.verify(proofInput, proof) self.logger.info('Proof "{}" accepted with nonce {}'.format( proofName, nonce)) self.logger.info('Verifying proof "{}" from {}'.format( proofName, link.name)) status = 'verified' if result else 'failed verification' resp = { TYPE: PROOF_STATUS, DATA: ' Your Proof {} {} was received and {}\n'.format( proofRequest.name, proofRequest.version, status), } self.signAndSend(resp, link.localIdentifier, frm, origReqId=body.get(f.REQ_ID.nm)) if result: for uuid, attribute in proofInput.revealedAttrs.items(): # Log attributes that were verified self.logger.info('verified {}: {}'.format( attribute.name, proof.requestedProof.revealed_attrs[uuid][1])) self.logger.info( 'Verified that proof "{}" contains attributes ' 'from claim(s) issued by: {}'.format( proofName, ", ".join( sorted([v.issuer_did for k, v in proof.proofs.items()])))) await self._postProofVerif(proofName, link, frm) else: self.logger.info( 'Verification failed for proof {} from {} '.format( proofName, link.name))