Skip to content

Commit

Permalink
Merge pull request #65 from Sphereon-Opensource/develop-143
Browse files Browse the repository at this point in the history
Big changes from previous PR plus some document changes
  • Loading branch information
nklomp authored Nov 10, 2021
2 parents cc7e592 + 58f1dfe commit 093e1dd
Show file tree
Hide file tree
Showing 53 changed files with 4,885 additions and 2,602 deletions.
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,12 @@ evaluate(presentationDefinition, verifiablePresentation)
```
##### Description
Evaluates whether a presentation submission meets the requested presentation definition

Since this method will be used both **before** and **after** creating a VerifiablePresentation, we accept both _signed_ and _unsigned_ version of a presentation here.
#### Parameters
| name | type | description|
|------|------|------------|
| `presentationDefinition` | `PresentationDefinition` | the presentation definition that initiated the request from the verifier |
| `verifiablePresentation` | `VerifiablePresentation` | the VP containing the required credentials and a `presentation_submission` object mapping back to the presentation definition |
| `presentation` | `Presentation` | the Presentation object containing the required credentials and a `presentation_submission` object mapping back to the presentation definition |

#### Return value
If evaluation is successful, `value` will be a non-null `PresentationSubmission` mapping the submitted credentials to the requested inputs.
Expand All @@ -207,7 +207,7 @@ interface EvaluationResults {

### SelectFrom
```typescript
selectFrom(presentationDefinition, credentials, holderDid)
selectFrom(presentationDefinition, credentials, holderDids)
```
##### Description
Gathers the matching credentials that fit a given presentation definition
Expand All @@ -217,7 +217,7 @@ Gathers the matching credentials that fit a given presentation definition
|------|------|------------|
| `presentationDefinition` | `PresentationDefinition` | the presentation definition that initiated the request from the verifier |
| `credentials` | `VerifiableCredential[]` | the array of verifiable credentials to select from |
| `holderDid` | `string` | the holder's did. this can be found in VerifiablePresentation's holder property |
| `holderDids` | `string[]` | the holder's dids. this can be found in VerifiablePresentation's holder property note that a wallet can have many holderDids retrieved from different places|

#### Return value
- If the selection was successful or partially successful, the `matches` array will consist of `SubmissionRequirementMatch` object(s), representing the matching credentials for each `SubmissionRequirement` in the `presentationDefinition` input parameter.
Expand Down Expand Up @@ -289,8 +289,23 @@ interface Checked {
```
status can have following values `'info' | 'warn' | 'error'`

## Further work:
1. Based on the [DIF documentation](https://identity.foundation/presentation-exchange/#input-evaluation)
>*4.3.1- If the Input Descriptor schema object uri is a hashlink or similar value that points to immutable content, then the content of the retrieved schema must also match* This hashlink validation is currently not included.

## Workflow Diagram
![Flow diagram](https://www.plantuml.com/plantuml/proxy?cache=no&src=https://raw.githubusercontent.com/Sphereon-Opensource/pe-js/develop/docs/simple-scenario.puml)
# Glossary

Term | Definition |
---- | ---------- |
Credential | A set of one or more claims made by an issuer. |
Verifiable Credential | Is a tamper-evident credential that has authorship that can be cryptographically verified. Verifiable credentials can be used to build verifiable presentations, which can also be cryptographically verified. The claims in a credential can be about different subjects. |
Presentation Definition | Presentation Definitions are objects that articulate what proofs a Verifier requires. |
Holder | Holders are entities that have one or more verifiable credentials in their possession. Holders are also the entities that submit proofs to Verifiers to satisfy the requirements described in a Presentation Definition.
Holder's Did | Unique ID URI string and PKI metadata document format for describing the cryptographic keys and other fundamental PKI values linked to a unique, user-controlled, self-sovereign identifier in holder's wallet|
Verifier | Verifiers are entities that define what proofs they require from a Holder (via a Presentation Definition) in order to proceed with an interaction. |
Issuer | A role an entity can perform by asserting claims about one or more subjects, creating a verifiable credential from these claims, and transmitting the verifiable credential to a holder. |
Presentation | Data derived from one or more verifiable credentials, issued by one or more issuers |
Verifiable Presentation | Is a tamper-evident presentation encoded in such a way that authorship of the data can be trusted after a process of cryptographic verification.

## Further work:
1. Implementation of presentation-exchange v2
2. In the [DIF documentation](https://identity.foundation/presentation-exchange/#input-evaluation) some entries are addressing `nested credentials` and `nested paths` these are currently not fully support yet.
41 changes: 41 additions & 0 deletions docs/simple-scenario.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@startuml

header PE-JS

title
PE-JS
Data Flow Diagram - version 0.1.0
end title


autonumber

participant "PE-JS-Verifier" as PE2 order 0 #ORANGE
participant "Verifier" as V order 1 #ORANGE
participant "Alice" as A order 2 #PINK
participant "Wallet" as W order 3 #YELLOW
participant "PE-JS" as PE order 4 #YELLOW

V -> W: PresentationDefinition
W -> A: Notification
A -> W: Accepts PresentationDefinition
W -> PE: evaluate(presentationDefinition, allAvailableCredentials[])
PE -> W: evaluation results
W -> A: from the credentials that you've selected, \na combination of these are acceptable
A -> W: selects a combination of credentials
W -> PE: selectFrom(2ndSetOfCredentials[])
PE -> W: selectFrom response
W -> PE: submissionFrom(selectableCredentials)
PE -> W: submissionFrom response

W -> PE: createPresentation(selectFromResult)
PE -> W: get an actual Presentation object
W -> W: signPresentation(presentation)

W -> V: VerifiablePresentation

V -> PE2: evaluate(VerifiableCredential)
PE2 -> V: evaluation result
V -> W: Pass/Fail response
W -> A: Pass/Fail notification
@enduml
4 changes: 4 additions & 0 deletions lib/evaluation/core/selectResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ export interface SelectResults {
errors?: Checked[];
matches?: SubmissionRequirementMatch[];
verifiableCredentials?: VerifiableCredential[];
/**
* Following are indexes of the verifiableCredentials passed to the selectFrom method that have been selected.
*/
vcIndexes?: number[];
warnings?: Checked[];
}
29 changes: 3 additions & 26 deletions lib/evaluation/core/submissionRequirementMatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,10 @@ import { Rules } from '@sphereon/pe-models';
export interface SubmissionRequirementMatch {
name?: string;
rule: Rules;
count: number;
min?: number;
count?: number;
max?: number;
matches: string[];
from?: string[];
from_nested?: SubmissionRequirementMatch[];
}

export const SubmissionRequirementMatch = class implements SubmissionRequirementMatch {
public name: string;
public rule: Rules;
public count: number;
public matches: string[]; // this can be later changed to VerifiableCredentials
public from?: string[];
public from_nested?: SubmissionRequirementMatch[];

public constructor(
name: string,
rule: Rules,
count: number,
matches: string[],
from?: string[],
from_nested?: SubmissionRequirementMatch[]
) {
this.name = name;
this.rule = rule;
this.count = count;
this.matches = matches;
this.from = from;
this.from_nested = from_nested;
}
};
63 changes: 33 additions & 30 deletions lib/evaluation/evaluationClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PresentationDefinition } from '@sphereon/pe-models';
import { PresentationDefinition, PresentationSubmission } from '@sphereon/pe-models';

import { Status } from '../ConstraintUtils';
import { VerifiablePresentation } from '../verifiablePresentation';
import { VerifiableCredential } from '../verifiablePresentation';

import { HandlerCheckResult } from './handlerCheckResult';
import {
Expand All @@ -19,15 +19,9 @@ import {
export class EvaluationClient {
constructor() {
this._results = [];
this._verifiablePresentation = {
'@context': [],
type: '',
holder: '',
verifiableCredential: [],
presentation_submission: { id: '', definition_id: '', descriptor_map: [] },
proof: { proofPurpose: '', type: '', jws: '', created: '', verificationMethod: '' },
};
this._did = '';
this._verifiableCredential = [];
this._presentationSubmission = {};
this._dids = [];
}

private failed_catched = {
Expand All @@ -38,17 +32,18 @@ export class EvaluationClient {
};

private _results: HandlerCheckResult[];
private _verifiablePresentation: VerifiablePresentation;
private _did: string;

public evaluate(pd: PresentationDefinition, vp: VerifiablePresentation): void {
this._did = vp.holder;
let currentHandler: EvaluationHandler = this.initEvaluationHandlers();
currentHandler.handle(pd, vp);
while (currentHandler.hasNext()) {
private _verifiableCredential: Partial<VerifiableCredential>[];
private _presentationSubmission: Partial<PresentationSubmission>;
private _dids: string[];

public evaluate(pd: PresentationDefinition, vcs: VerifiableCredential[], holderDids: string[]): void {
this._dids = holderDids;
let currentHandler: EvaluationHandler | undefined = this.initEvaluationHandlers();
currentHandler?.handle(pd, vcs);
while (currentHandler?.hasNext()) {
currentHandler = currentHandler.getNext();
try {
currentHandler.handle(pd, vp);
currentHandler?.handle(pd, vcs);
} catch (e) {
this.failed_catched.message += (e as Error).message;
this.failed_catched.stacktrace = e as string;
Expand All @@ -61,20 +56,28 @@ export class EvaluationClient {
return this._results;
}

public get did() {
return this._did;
public get dids() {
return this._dids;
}

public set dids(dids: string[]) {
this._dids = dids;
}

public get presentationSubmission(): PresentationSubmission {
return this._presentationSubmission as PresentationSubmission;
}

public set did(did: string) {
this._did = did;
public set presentationSubmission(presentationSubmission: Partial<PresentationSubmission>) {
this._presentationSubmission = presentationSubmission;
}

public get verifiablePresentation(): VerifiablePresentation {
return this._verifiablePresentation;
public get verifiableCredential(): VerifiableCredential[] {
return this._verifiableCredential as VerifiableCredential[];
}

public set verifiablePresentation(verifiablePresentation: VerifiablePresentation) {
this._verifiablePresentation = verifiablePresentation;
public set verifiableCredential(verifiableCredential: VerifiableCredential[]) {
this._verifiableCredential = verifiableCredential;
}

private initEvaluationHandlers() {
Expand All @@ -83,11 +86,11 @@ export class EvaluationClient {
uriEvaluation
.setNext(new InputDescriptorFilterEvaluationHandler(this))
.setNext(new PredicateRelatedFieldEvaluationHandler(this))
.setNext(new MarkForSubmissionEvaluationHandler(this))
.setNext(new LimitDisclosureEvaluationHandler(this))
.setNext(new SubjectIsIssuerEvaluationHandler(this))
.setNext(new SubjectIsHolderEvaluationHandler(this))
.setNext(new SameSubjectEvaluationHandler(this));
.setNext(new SameSubjectEvaluationHandler(this))
.setNext(new MarkForSubmissionEvaluationHandler(this));

return uriEvaluation;
}
Expand Down
Loading

0 comments on commit 093e1dd

Please sign in to comment.