diff --git a/assertions.js b/assertions.js index 074bed1..810d307 100644 --- a/assertions.js +++ b/assertions.js @@ -5,6 +5,7 @@ import chai from 'chai'; import jsonld from 'jsonld'; const should = chai.should(); +const {expect} = chai; // RegExp with bs58 characters in it const bs58 = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/; @@ -298,3 +299,35 @@ export function shouldHaveProofValue({proof, expectedPrefix, encodingName}) { true, `Expected "proof.proofValue" to be a valid ${encodingName} value`); } + +export async function shouldBeProofValue({credentials, verifier}) { + expect(credentials, 'Expected test data to be generated.').to.exist; + expect(credentials.clone('issuedVc'), 'Expected a valid Vc to be issued.'). + to.exist; + // proofValue is added after signing so we can + // safely delete it for this test + const noProofValue = credentials.clone('issuedVc'); + delete noProofValue.proof.proofValue; + await verificationFail({ + credential: noProofValue, + verifier, + reason: 'MUST not verify VC with no "proofValue".' + }); + // null should be an invalid proofValue for almost any proof + const nullProofValue = credentials.clone('issuedVc'); + nullProofValue.proof.proofValue = null; + await verificationFail({ + credential: nullProofValue, + verifier, + reason: 'MUST not verify VC with "proofValue" null.' + }); + const noProofValueHeader = credentials.clone('issuedVc'); + // Remove the multibase header to cause validation error + noProofValueHeader.proof.proofValue = noProofValueHeader.proof.proofValue. + slice(1); + await verificationFail({ + credential: noProofValueHeader, + verifier, + reason: 'MUST not verify VC with invalid multibase header on "proofValue"' + }); +} diff --git a/suites/verify.js b/suites/verify.js index b517702..95746ea 100644 --- a/suites/verify.js +++ b/suites/verify.js @@ -1,8 +1,11 @@ /*! * Copyright (c) 2024 Digital Bazaar, Inc. */ -import {verificationFail, verificationSuccess} from '../assertions.js'; -import {expect} from 'chai'; +import { + shouldBeProofValue, + verificationFail, + verificationSuccess +} from '../assertions.js'; export function runDataIntegrityProofVerifyTests({ endpoints, @@ -101,22 +104,32 @@ export function runDataIntegrityProofVerifyTests({ reason: 'MUST not verify VC w/o "proof.proofPurpose"' }); }); - it(`If the "proof.type" field is not the string ` + - `"${expectedProofType}", an error MUST be raised.`, - async function() { - const credential = credentials.clone('invalidProofType'); - await verificationFail({credential, verifier}); - }); - it('If the "proof.verificationMethod" field is invalid, an error ' + - 'MUST be raised.', async function() { - const credential = credentials.clone('invalidVm'); - await verificationFail({credential, verifier}); - }); - it('If the "proof.proofPurpose" field is invalid, an error MUST ' + - 'be raised.', async function() { - const credential = credentials.clone('invalidProofPurpose'); - await verificationFail({credential, verifier}); - }); + // use updated statement for DataIntegrityProof tests + if(expectedProofType === 'DataIntegrityProof') { + it('The type property MUST contain the string DataIntegrityProof.', + async function() { + this.test.link = 'https://w3c.github.io/vc-data-integrity/#proofs:~:text=The%20type%20property%20MUST%20contain%20the%20string%20DataIntegrityProof.'; + const credential = credentials.clone('invalidProofType'); + await verificationFail({ + credential, + verifier, + reason: 'Should not verify VC with invalid "proof.type"' + }); + }); + } else { + // if the expectedProofType if Ed25519Sig etc. use the + // deprecated statement + it(`If the "proof.type" field is not the string ` + + `"${expectedProofType}", an error MUST be raised.`, + async function() { + const credential = credentials.clone('invalidProofType'); + await verificationFail({ + credential, + verifier, + reason: 'Should not verify VC with invalid "proof.type"' + }); + }); + } it('If expectedProofPurpose was given, and it does not match ' + 'proof.proofPurpose, an error MUST be raised and SHOULD convey an ' + 'error type of PROOF_VERIFICATION_ERROR.', async function() { @@ -311,35 +324,3 @@ export function runDataIntegrityProofVerifyTests({ } }); } - -async function shouldBeProofValue({credentials, verifier}) { - expect(credentials, 'Expected test data to be generated.').to.exist; - expect(credentials.clone('issuedVc'), 'Expected a valid Vc to be issued.'). - to.exist; - // proofValue is added after signing so we can - // safely delete it for this test - const noProofValue = credentials.clone('issuedVc'); - delete noProofValue.proof.proofValue; - await verificationFail({ - credential: noProofValue, - verifier, - reason: 'MUST not verify VC with no "proofValue".' - }); - // null should be an invalid proofValue for almost any proof - const nullProofValue = credentials.clone('issuedVc'); - nullProofValue.proof.proofValue = null; - await verificationFail({ - credential: nullProofValue, - verifier, - reason: 'MUST not verify VC with "proofValue" null.' - }); - const noProofValueHeader = credentials.clone('issuedVc'); - // Remove the multibase header to cause validation error - noProofValueHeader.proof.proofValue = noProofValueHeader.proof.proofValue. - slice(1); - await verificationFail({ - credential: noProofValueHeader, - verifier, - reason: 'MUST not verify VC with invalid multibase header on "proofValue"' - }); -} diff --git a/vc-generator/generators.js b/vc-generator/generators.js index f090025..48a1ae5 100644 --- a/vc-generator/generators.js +++ b/vc-generator/generators.js @@ -308,6 +308,7 @@ function invalidVm({ suite, selectiveSuite, credential, + //FIXME this generator should support non-string verificationMethods mockVM = 'did:key:invalidVm', ...args }) {