Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/funke-mdoc #166

Merged
merged 23 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
PresentationSignCallBackParams,
PresentationSubmissionLocation,
ProofOptions,
SdJwtDecodedVerifiableCredentialWithKbJwtInput,
SelectResults,
SignatureOptions,
Status,
Expand Down Expand Up @@ -57,5 +56,4 @@ export {
PresentationResult,
PresentationFromOpts,
PresentationSubmissionLocation,
SdJwtDecodedVerifiableCredentialWithKbJwtInput,
};
41 changes: 25 additions & 16 deletions lib/PEX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import {

import { Status } from './ConstraintUtils';
import { EvaluationClientWrapper, EvaluationResults, SelectResults } from './evaluation';
import { PresentationEvaluationResults } from './evaluation/core';
import { PresentationEvaluationResults } from './evaluation';
import {
PartialSdJwtDecodedVerifiableCredential,
PartialSdJwtKbJwt,
PresentationFromOpts,
PresentationResult,
PresentationSignCallBackParams,
PresentationSubmissionLocation,
SdJwtDecodedVerifiableCredentialWithKbJwtInput,
SdJwtKbJwtInput,
VerifiablePresentationFromOpts,
VerifiablePresentationResult,
} from './signing';
Expand Down Expand Up @@ -72,16 +72,16 @@ export class PEX {
*/
public evaluatePresentation(
presentationDefinition: IPresentationDefinition,
presentations: OrArray<OriginalVerifiablePresentation | IPresentation>,
presentations: OrArray<OriginalVerifiablePresentation | IPresentation | PartialSdJwtDecodedVerifiableCredential>,
opts?: {
limitDisclosureSignatureSuites?: string[];
restrictToFormats?: Format;
restrictToDIDMethods?: string[];
presentationSubmission?: PresentationSubmission;
/**
* The location of the presentation submission. By default {@link PresentationSubmissionLocation.PRESENTATION}
* is used when one W3C presentation is passed (not as array) , while {@link PresentationSubmissionLocation.EXTERNAL} is
* used when an array is passed or the presentation is not a W3C presentation
* is used when one presentation is passed (not as array), while {@link PresentationSubmissionLocation.EXTERNAL} is
* used when an array is passed
*/
presentationSubmissionLocation?: PresentationSubmissionLocation;
generatePresentationSubmission?: boolean;
Expand Down Expand Up @@ -117,7 +117,10 @@ export class PEX {
CredentialMapper.isW3cPresentation(wrappedPresentations[0].presentation) &&
!generatePresentationSubmission
) {
presentationSubmission = wrappedPresentations[0].decoded.presentation_submission;
const decoded = wrappedPresentations[0].decoded;
if ('presentation_submission' in decoded) {
presentationSubmission = decoded.presentation_submission;
}
if (!presentationSubmission) {
throw Error(`Either a presentation submission as part of the VP or provided in options was expected`);
}
Expand All @@ -134,7 +137,9 @@ export class PEX {
// TODO: we should probably add support for holder dids in the kb-jwt of an SD-JWT. We can extract this from the
// `wrappedPresentation.original.compactKbJwt`, but as HAIP doesn't use dids, we'll leave it for now.
const holderDIDs = wrappedPresentations
.map((p) => (CredentialMapper.isW3cPresentation(p.presentation) && p.presentation.holder ? p.presentation.holder : undefined))
.map((p) => {
return CredentialMapper.isW3cPresentation(p.presentation) && p.presentation.holder ? p.presentation.holder : undefined;
})
.filter((d): d is string => d !== undefined);

const updatedOpts = {
Expand Down Expand Up @@ -310,7 +315,7 @@ export class PEX {
*/
hasher?: Hasher;
},
): IPresentation | SdJwtDecodedVerifiableCredentialWithKbJwtInput {
): IPresentation | PartialSdJwtDecodedVerifiableCredential {
const credentials = Array.isArray(selectedCredentials) ? selectedCredentials : [selectedCredentials];

// for SD-JWT we want to return the SD-JWT with only the needed disclosures (so filter disclosures array, and update the compactSdJwt)
Expand Down Expand Up @@ -350,18 +355,19 @@ export class PEX {
// alg MUST be set by the signer
header: {
typ: 'kb+jwt',
// aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib
},
// aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib
payload: {
iat: new Date().getTime(),
sd_hash: sdHash,
},
} satisfies SdJwtKbJwtInput;
} satisfies PartialSdJwtKbJwt;

return {
const sdJwtDecodedPresentation: PartialSdJwtDecodedVerifiableCredential = {
...decoded,
kbJwt,
};
return sdJwtDecodedPresentation;
} else {
if (!selectedCredentials) {
throw Error(`At least a verifiable credential needs to be passed in to create a presentation`);
Expand Down Expand Up @@ -525,7 +531,9 @@ export class PEX {

let presentation = presentationResult.presentation;

if (CredentialMapper.isSdJwtDecodedCredential(presentationResult.presentation)) {
// Select type without kbJwt as isSdJwtDecodedCredential and won't accept the partial sdvc type
if (CredentialMapper.isSdJwtDecodedCredential(presentationResult.presentation as SdJwtDecodedVerifiableCredential)) {
const sdJwtPresentation = presentation as SdJwtDecodedVerifiableCredential;
if (!this.options?.hasher) {
throw new Error('Hasher must be provided when creating a presentation with an SD-JWT VC');
}
Expand All @@ -538,19 +546,20 @@ export class PEX {
// alg MUST be set by the signer
header: {
typ: 'kb+jwt',
alg: hashAlg,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanderPostma I think this is a mistake, and shouldn't have been added here. The hashAlg is different from the signing alg.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, I already removed it from verifiablePresentationFrom but in constructPresentation it's still there

},
// aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib
payload: {
iat: new Date().getTime(),
nonce: proofOptions?.nonce,
sd_hash: sdHash,
},
} satisfies SdJwtKbJwtInput;
} satisfies PartialSdJwtKbJwt;

presentation = {
...presentation,
...sdJwtPresentation,
kbJwt,
};
} satisfies PartialSdJwtDecodedVerifiableCredential;
}

const callBackParams: PresentationSignCallBackParams = {
Expand Down
6 changes: 5 additions & 1 deletion lib/evaluation/handlers/didRestrictionEvaluationHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ export class DIDRestrictionEvaluationHandler extends AbstractEvaluationHandler {
return typeof wrappedVc.credential.issuer === 'object' ? wrappedVc.credential.issuer.id : wrappedVc.credential.issuer;
} else if (CredentialMapper.isSdJwtDecodedCredential(wrappedVc.credential)) {
return wrappedVc.credential.decodedPayload.iss;
} else if (CredentialMapper.isWrappedMdocCredential(wrappedVc)) {
if (typeof wrappedVc.decoded === 'object' && wrappedVc.decoded.iss !== undefined) {
return wrappedVc.decoded.iss;
}
throw new Error('cannot get issuer from the supplied mdoc credential');
}

throw new Error('Unsupported credential type');
}

Expand Down
22 changes: 9 additions & 13 deletions lib/signing/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
IProofType,
OriginalVerifiableCredential,
SdJwtDecodedVerifiableCredential,
SdJwtVcKbJwtPayload,
W3CVerifiablePresentation,
} from '@sphereon/ssi-types';
import { SdJwtVcKbJwtHeader } from '@sphereon/ssi-types/src/types/sd-jwt-vc';

import { PresentationEvaluationResults } from '../evaluation';

Expand Down Expand Up @@ -84,18 +86,12 @@ export enum PresentationSubmissionLocation {
PRESENTATION, // Part of the VP itself
}

export interface SdJwtKbJwtInput {
header: {
typ: 'kb+jwt';
};
payload: {
iat: number;
sd_hash: string;
nonce?: string;
};
}
export type PartialSdJwtKbJwt = {
header: Partial<SdJwtVcKbJwtHeader>;
payload: Partial<SdJwtVcKbJwtPayload>;
};

export type SdJwtDecodedVerifiableCredentialWithKbJwtInput = SdJwtDecodedVerifiableCredential & { kbJwt: SdJwtKbJwtInput };
export type PartialSdJwtDecodedVerifiableCredential = Omit<SdJwtDecodedVerifiableCredential, 'kbJwt'> & { kbJwt: PartialSdJwtKbJwt };

/**
* The result object containing the presentation and presentation submission
Expand All @@ -104,7 +100,7 @@ export interface PresentationResult {
/**
* The resulting presentation, can have an embedded submission data depending on the location parameter
*/
presentation: IPresentation | SdJwtDecodedVerifiableCredentialWithKbJwtInput;
presentation: IPresentation | SdJwtDecodedVerifiableCredential | PartialSdJwtDecodedVerifiableCredential;

/**
* The resulting location of the presentation submission.
Expand Down Expand Up @@ -193,7 +189,7 @@ export interface PresentationSignCallBackParams {
* and only the optional KB-JWT should be appended to the `compactSdJwt` property. If no KB-JWT is needed on the presentation, the `compactSdJwt` property
* from the decoded SD-JWT can be returned as-is.
*/
presentation: IPresentation | SdJwtDecodedVerifiableCredentialWithKbJwtInput;
presentation: IPresentation | SdJwtDecodedVerifiableCredential | PartialSdJwtDecodedVerifiableCredential;

/**
* A partial proof value the callback can use to complete. If proofValue or JWS was supplied the proof could be complete already
Expand Down
1 change: 1 addition & 0 deletions lib/validation/bundlers/presentationSubmissionVB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export class PresentationSubmissionVB extends ValidationBundler<PresentationSubm
'di_vc',
'di_vp',
'vc+sd-jwt',
'mso_mdoc',
];

for (let i = 0; i < descriptor_map.length; i++) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sphereon/pex",
"version": "4.1.0",
"version": "5.0.0-unstable.0",
"description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification",
"main": "dist/main/index.js",
"module": "dist/module/index.js",
Expand Down Expand Up @@ -47,7 +47,7 @@
"@sd-jwt/present": "^0.6.1",
"@sd-jwt/types": "^0.6.1",
"@sphereon/pex-models": "^2.3.1",
"@sphereon/ssi-types": "0.22.0",
"@sphereon/ssi-types": "0.29.1-unstable.121",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1",
"jwt-decode": "^3.1.2",
Expand Down
Loading
Loading