Skip to content

Commit

Permalink
fix: apply new contract
Browse files Browse the repository at this point in the history
  • Loading branch information
elribonazo committed Apr 25, 2024
1 parent 3ab67e3 commit cae043b
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 113 deletions.
4 changes: 0 additions & 4 deletions src/domain/buildingBlocks/Pollux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ type CredentialRequestTuple<

export type PresentationJWTOptions = {
jwtAlg?: string[],
jwtVcAlg?: string[],
jwtVpAlg?: string[]
}

export class PresentationOptions {
Expand All @@ -40,8 +38,6 @@ export class PresentationOptions {
this.domain = options.domain ?? 'N/A';
this.jwt = options.jwt ?? {
jwtAlg: ['ES256K'],
jwtVcAlg: ['ES256K'],
jwtVpAlg: ['ES256K'],
};
}
}
Expand Down
22 changes: 4 additions & 18 deletions src/domain/models/VerifiableCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,14 @@ export type InputDescriptor = {
format?: DefinitionFormat,
}

export type JWT_FORMAT = {
jwt_vc?: {
alg: string[]
},
jwt_vp?: {
alg: string[]
}
}

export enum SubmissionDescriptorFormat {
JWT_VC = 'jwt_vc'
}

export type DefinitionFormat = {
jwt?: JWT_FORMAT
jwt: {
alg: string[]
},
};

export type PresentationDefinitionRequest = {
Expand All @@ -84,20 +77,13 @@ export type DescriptorItem = {
path_nested?: DescriptorItem
}

export type VerifiableCredentialSubmission = {
comment?: string,
vc: JWTCredentialPayload | any,
proof: Proof
}

export type PresentationSubmission = {
presentation_submission: {
id: string,
definition_id: string,
descriptor_map: DescriptorItem[]
},
verifiable_credential: VerifiableCredentialSubmission[],
proof?: Proof
verifiable_presentation: string[],
}

export enum JWTVerifiableCredentialProperties {
Expand Down
116 changes: 29 additions & 87 deletions src/pollux/Pollux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
InputField,
InputLimitDisclosure,
InputDescriptor,
JWT_FORMAT,
PrivateKey,
PresentationSubmission,
DescriptorItem,
Expand All @@ -28,6 +27,7 @@ import {
ProofTypesEnum,
ProofPurpose,
SubmissionDescriptorFormat,
DefinitionFormat,
} from "../domain";
import { AnonCredsCredential } from "./models/AnonCredsVerifiableCredential";

Expand Down Expand Up @@ -69,14 +69,14 @@ export default class Pollux implements IPollux {

const descriptorItems: DescriptorItem[] = presentationDefinition.inputDescriptors.map(
(inputDescriptor) => {
if (inputDescriptor.format && (!inputDescriptor.format.jwt || !inputDescriptor.format.jwt?.jwt_vp || !inputDescriptor.format.jwt?.jwt_vc)) {
if (!inputDescriptor.format || !inputDescriptor.format.jwt || !inputDescriptor.format.jwt.alg) {
//TODO: Improive error
throw new Error("Invalid format")
}
return {
id: inputDescriptor.id,
format: "jwt_vc",
path: "$.verifiableCredential[0]"
path: "$.verifiablePresentation[0]"
}
});

Expand Down Expand Up @@ -114,25 +114,12 @@ export default class Pollux implements IPollux {
definition_id: presentationDefinition.id,
descriptor_map: descriptorItems
},
verifiable_credential: [
{
vc: credential.vc,
proof: {
type: ProofTypesEnum.JsonWebSignature2020,
created: Date().toString(),
proofPurpose: ProofPurpose.AUTHENTTICATION,
verificationMethod: verificationMethod,
jws: credential.id
}
}
],
proof: {
type: ProofTypesEnum.JsonWebSignature2020,
proofPurpose: ProofPurpose.AUTHENTTICATION,
verificationMethod: subject,
jws: jws
}
verifiable_presentation: [
credential.id,
jws
]
}

return presentationSubmission
} else {
throw new PolluxError.CredsentialTypeNotSupported()
Expand All @@ -147,42 +134,20 @@ export default class Pollux implements IPollux {

const {
presentation_submission,
verifiable_credential,
proof
verifiable_presentation,
} = data;

//Validate required fields
if (!presentation_submission || (typeof presentation_submission !== "object")) {
return false;
}

if (!verifiable_credential ||
!Array.isArray(verifiable_credential)
if (!verifiable_presentation ||
!Array.isArray(verifiable_presentation)
) {
return false;
}

if (!proof || (typeof proof !== "object")) {
return false;
}

const {
type,
proofPurpose,
verificationMethod,
jws
} = proof;

//Validate proof types
if (
!type || (typeof type !== "string") ||
!verificationMethod || (typeof verificationMethod !== "string") ||
!jws || (typeof jws !== "string") ||
!proofPurpose || (typeof proofPurpose !== "string") || proofPurpose !== ProofPurpose.AUTHENTTICATION
) {
return false
}

return true;
}

Expand All @@ -201,9 +166,7 @@ export default class Pollux implements IPollux {
throw new Error("Required field options jwt is undefined")
}

if (!jwtOptions.jwtAlg &&
!jwtOptions.jwtVcAlg &&
!jwtOptions.jwtVpAlg) {
if (!jwtOptions.jwtAlg) {
throw new PolluxError.InvalidJWTPresentationDefinitionError("Presentation options didn't include jwtAlg, jwtVcAlg or jwtVpAlg, one of them is required.")
}

Expand All @@ -212,7 +175,6 @@ export default class Pollux implements IPollux {
return [
...all,
...(proof.requiredFields ?? []),
//...(proof.trustIssuers ?? [])
]
}, []);

Expand All @@ -236,30 +198,27 @@ export default class Pollux implements IPollux {
optional: false
})

const format: DefinitionFormat = {
jwt: {
alg: jwtOptions.jwtAlg ?? []
},

}

const inputDescriptor: InputDescriptor = {
id: uuid(),
name: options.name,
purpose: options.purpose,
constraints: constaints
}

const format: JWT_FORMAT = {
jwt_vc: {
alg: jwtOptions.jwtVcAlg ?? []
},
jwt_vp: {
alg: jwtOptions.jwtVpAlg ?? []
}
constraints: constaints,
format: format
}

const presentationDefinitionRequest: PresentationDefinitionRequest = {
id: uuid(),
inputDescriptors: [
inputDescriptor
],
format: {
jwt: format
}
format: format
}

return presentationDefinitionRequest
Expand All @@ -270,36 +229,23 @@ export default class Pollux implements IPollux {
if (!isValidPresentationSubmission) {
throw new Error("Invalid presentationSubmission object")
}

if (!presentationSubmission.proof ||
!presentationSubmission.proof.jws) {
throw new Error("Invalid presentationSubmission object, signed jws is required")
}

const descriptorMapper = new DescriptorPath(presentationSubmission);
const descriptorMaps = presentationSubmission.presentation_submission.descriptor_map;

//Validate all the descriptor items
for (let descriptorItem of descriptorMaps) {

if (descriptorItem.format === SubmissionDescriptorFormat.JWT_VC) {
const [credentialObject] = descriptorMapper.getValue(descriptorItem.path);
if (!credentialObject || !credentialObject.vc || !credentialObject.proof || !credentialObject.proof.jws) {
const [jws] = descriptorMapper.getValue(descriptorItem.path);
if (!jws) {
throw new Error("Invalid Credential Object");
}
const vc = credentialObject.vc;
const proof = credentialObject.proof;
const jws = proof.jws;

const isPrismJWTCredentialType = vc.type !== undefined &&
Array.isArray(vc.type) &&
vc.type.includes(CredentialType.JWT);
const credential = JWTCredential.fromJWS(jws);
const isPrismJWTCredentialType = credential.type !== undefined &&
Array.isArray(credential.type) &&
credential.type.includes(CredentialType.JWT);

if (!isPrismJWTCredentialType) {
throw new Error("Invalid JWT Credential only prism/jwt is supported for jwt_vc");
}

const issuer = vc.issuer;
const issuer = credential.issuer;
const credentialValid = await this.jwt.verify(issuer, jws);
if (!credentialValid) {
return false
Expand All @@ -308,10 +254,6 @@ export default class Pollux implements IPollux {
debugger;
}
}

//Get the proof on the root of the submission, this should contain a challenge signed by the user, a verificationMethod, and a keyPurpose
//To verify, we grab the subject's did, and resolve it using castor to extract the correct "keyPurpose key".
//We instanciate the key using Apollo or something and verify the challenge signature using Apollo.
return true;
}

Expand Down
6 changes: 2 additions & 4 deletions tests/pollux/Pollux.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -872,10 +872,8 @@ describe("Pollux", () => {
expect(presentationDefinition).haveOwnProperty("id");
expect(presentationDefinition).haveOwnProperty("format");
expect(presentationDefinition).haveOwnProperty("inputDescriptors");
expect(presentationDefinition.format.jwt).haveOwnProperty("jwt_vc");
expect(presentationDefinition.format.jwt).haveOwnProperty("jwt_vp");
expect(presentationDefinition.format.jwt?.jwt_vc?.alg).contains('ES256K');
expect(presentationDefinition.format.jwt?.jwt_vp?.alg).contains('ES256K');
expect(presentationDefinition.format).haveOwnProperty("jwt");
expect(presentationDefinition.format.jwt?.alg).contains('ES256K');
expect(Array.isArray(presentationDefinition.inputDescriptors)).to.eq(true)
expect(presentationDefinition.inputDescriptors.length).to.eq(1)
expect(presentationDefinition.inputDescriptors.at(0)).haveOwnProperty('constraints');
Expand Down

0 comments on commit cae043b

Please sign in to comment.