diff --git a/CHANGELOG.md b/CHANGELOG.md index cf27dc6..68ba2d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # bedrock-vc-verifier ChangeLog +## 19.0.0 - 2023-11-TBD + +### Added +- Add support for verifying vcs with `ecdsa-sd-2023`, `ecdsa-rdfc-2019` and + `eddsa-rdfc-2022` signatures. +- Add missing peer dep `@bedrock/app-identity` v4.0. + +### Changed +- **BREAKING**: Update `@bedrock/data-integrity-context` peer dep to v3.0 that + uses `@digitalbazaar/data-integrity@2.0`. +- Use `@digitalbazaar/data-integrity@2.0`. Adds `legacyContext` flag to allow + use of legacy context and updates default context URL to + `https://w3id.org/security/data-integrity/v2`. + ## 18.1.0 - 2023-11-06 ### Added diff --git a/lib/config.js b/lib/config.js index 74ead57..1c88ff5 100644 --- a/lib/config.js +++ b/lib/config.js @@ -27,7 +27,10 @@ cfg.supportedSuites = [ 'Ed25519Signature2018', 'Ed25519Signature2020', 'eddsa-2022', - 'ecdsa-2019' + 'ecdsa-2019', + 'ecdsa-rdfc-2019', + 'eddsa-rdfc-2022', + 'ecdsa-sd-2023' ]; cfg.routes = { diff --git a/lib/suites.js b/lib/suites.js index 2b3dbed..af5bb6a 100644 --- a/lib/suites.js +++ b/lib/suites.js @@ -2,20 +2,35 @@ * Copyright (c) 2018-2022 Digital Bazaar, Inc. All rights reserved. */ import * as bedrock from '@bedrock/core'; +import { + createVerifyCryptosuite as createEcdsaSd2023VerifyCryptosuite +} from '@digitalbazaar/ecdsa-sd-2023-cryptosuite'; import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; import { cryptosuite as ecdsa2019CryptoSuite } from '@digitalbazaar/ecdsa-2019-cryptosuite'; +import { + cryptosuite as ecdsaRdfc2019CryptoSuite +} from '@digitalbazaar/ecdsa-rdfc-2019-cryptosuite'; import {Ed25519Signature2018} from '@digitalbazaar/ed25519-signature-2018'; import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020'; import { cryptosuite as eddsa2022CryptoSuite } from '@digitalbazaar/eddsa-2022-cryptosuite'; +import { + cryptosuite as eddsaRdfc2022CryptoSuite +} from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; // DataIntegrityProof should work for multiple cryptosuites const SUPPORTED_CRYPTOSUITES = new Map([ + ['ecdsa-rdfc-2019', ecdsaRdfc2019CryptoSuite], + ['eddsa-rdfc-2022', eddsaRdfc2022CryptoSuite], + ['ecdsa-sd-2023', createEcdsaSd2023VerifyCryptosuite()] +]); + +const SUPPORTED_LEGACY_CRYPTOSUITES = new Map([ ['ecdsa-2019', ecdsa2019CryptoSuite], - ['eddsa-2022', eddsa2022CryptoSuite] + ['eddsa-2022', eddsa2022CryptoSuite], ]); const SUPPORTED_LEGACY_SUITES = new Map([ @@ -31,6 +46,12 @@ export function createSuites() { if(LegacySuite) { return new LegacySuite(); } + const LegacyCryptosuite = SUPPORTED_LEGACY_CRYPTOSUITES.get(supportedSuite); + if(LegacyCryptosuite) { + return new DataIntegrityProof({ + cryptosuite: LegacyCryptosuite, legacyContext: true + }); + } const cryptosuite = SUPPORTED_CRYPTOSUITES.get(supportedSuite); if(cryptosuite) { return new DataIntegrityProof({cryptosuite}); diff --git a/package.json b/package.json index 58341f7..5fca65d 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,14 @@ }, "homepage": "https://github.com/digitalbazaar/bedrock-vc-verifier", "dependencies": { - "@digitalbazaar/data-integrity": "^1.5.0", + "@digitalbazaar/data-integrity": "^2.0.0", "@digitalbazaar/ecdsa-2019-cryptosuite": "^2.0.0", + "@digitalbazaar/ecdsa-rdfc-2019-cryptosuite": "^1.0.1", + "@digitalbazaar/ecdsa-sd-2023-cryptosuite": "^3.0.0", "@digitalbazaar/ed25519-signature-2018": "^4.0.0", "@digitalbazaar/ed25519-signature-2020": "^5.0.0", "@digitalbazaar/eddsa-2022-cryptosuite": "^1.0.0", + "@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.0.1", "@digitalbazaar/vc": "^6.0.0", "@digitalbazaar/vc-revocation-list": "^6.0.0", "@digitalbazaar/vc-status-list": "^7.0.0", @@ -40,9 +43,10 @@ "serialize-error": "^11.0.0" }, "peerDependencies": { + "@bedrock/app-identity": "^4.0.0", "@bedrock/core": "^6.0.1", "@bedrock/credentials-context": "^4.0.0", - "@bedrock/data-integrity-context": "^2.0.0", + "@bedrock/data-integrity-context": "^3.0.0", "@bedrock/did-context": "^5.0.0", "@bedrock/did-io": "^10.1.0", "@bedrock/express": "^8.0.0", diff --git a/test/mocha/20-verify.js b/test/mocha/20-verify.js index 6b756dd..0c57745 100644 --- a/test/mocha/20-verify.js +++ b/test/mocha/20-verify.js @@ -7,7 +7,11 @@ import {driver as _didKeyDriver} from '@digitalbazaar/did-method-key'; import {agent} from '@bedrock/https-agent'; import {documentLoader as brDocLoader} from '@bedrock/jsonld-document-loader'; import {CapabilityAgent} from '@digitalbazaar/webkms-client'; +import { + createDiscloseCryptosuite as createEcdsaSd2023DiscloseCryptosuite +} from '@digitalbazaar/ecdsa-sd-2023-cryptosuite'; import {createRequire} from 'node:module'; +import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020'; import {httpClient} from '@digitalbazaar/http-client'; import {klona} from 'klona'; @@ -137,7 +141,21 @@ describe('verify APIs', () => { } describe(description, () => { it('verifies a valid credential', async () => { - const verifiableCredential = klona(mockCredential); + let verifiableCredential = klona(mockCredential); + if(cryptosuite === 'ecdsa-sd-2023') { + const cryptosuite = createEcdsaSd2023DiscloseCryptosuite({ + selectivePointers: [ + '/credentialSubject/id' + ] + }); + const suite = new DataIntegrityProof({cryptosuite}); + const derivedVC = await vc.derive({ + verifiableCredential, + suite, + documentLoader: brDocLoader + }); + verifiableCredential = derivedVC; + } let error; let result; try { @@ -396,7 +414,10 @@ describe('verify APIs', () => { let description; const {type, cryptosuite} = mockCredential.proof; if(cryptosuite) { - if(cryptosuite === 'ecdsa-2019') { + if( + cryptosuite === 'ecdsa-2019' || cryptosuite === 'ecdsa-rdfc-2019' || + cryptosuite === 'ecdsa-sd-2023' + ) { const keyType = helpers.getEcdsaAlgorithms({ credential: mockCredential })[0]; @@ -414,7 +435,21 @@ describe('verify APIs', () => { const signingKey = methodFor({purpose: 'assertionMethod'}); const suite = new Ed25519Signature2020({key: signingKey}); - const verifiableCredential = klona(mockCredential); + let verifiableCredential = klona(mockCredential); + if(cryptosuite === 'ecdsa-sd-2023') { + const cryptosuite = createEcdsaSd2023DiscloseCryptosuite({ + selectivePointers: [ + '/credentialSubject/id' + ] + }); + const suite = new DataIntegrityProof({cryptosuite}); + const derivedVC = await vc.derive({ + verifiableCredential, + suite, + documentLoader: brDocLoader + }); + verifiableCredential = derivedVC; + } const presentation = vc.createPresentation({ holder: 'did:test:foo', id: 'urn:uuid:3e793029-d699-4096-8e74-5ebd956c3137', diff --git a/test/mocha/helpers.js b/test/mocha/helpers.js index 2246846..6da3cb7 100644 --- a/test/mocha/helpers.js +++ b/test/mocha/helpers.js @@ -292,7 +292,11 @@ export function getEcdsaAlgorithms({credential, presentation} = {}) { const proofs = Array.isArray(credential.proof) ? credential.proof : [credential.proof]; for(const proof of proofs) { - if(proof.cryptosuite === 'ecdsa-2019') { + if( + proof.cryptosuite === 'ecdsa-2019' || + proof.cryptosuite === 'ecdsa-rdfc-2019' || + proof.cryptosuite === 'ecdsa-sd-2023' + ) { const {verificationMethod} = proof; const multibaseMultikeyHeader = verificationMethod.substring('did:key:'.length).slice(0, 4); diff --git a/test/mocha/mock-credentials.json b/test/mocha/mock-credentials.json index 35f3740..9ca17b4 100644 --- a/test/mocha/mock-credentials.json +++ b/test/mocha/mock-credentials.json @@ -154,5 +154,153 @@ "proofPurpose": "assertionMethod", "proofValue": "zazcNJNFcU4kXM4sdBazy8z5Qmg6pjACuHnudfGj6nRgLoGNVy99f1vv6A4XEYAPFaBPUHuX4Tgdxpv3jED5aEWAreENcinDsoE2161kmuueMrToRFnJEb5Wp5F6mXdN3xXj" } + }, { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + { + "ex": "https://example.org/examples#", + "schema": "http://schema.org/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "BachelorDegree": "ex:BachelorDegree", + "UniversityDegreeCredential": "ex:UniversityDegreeCredential", + "degree": "ex:degree", + "name": { + "@id": "schema:name", + "@type": "rdf:HTML" + } + }, + "https://w3id.org/security/data-integrity/v2" + ], + "id": "http://example.gov/credentials/3732", + "type": [ "VerifiableCredential", "UniversityDegreeCredential" ], + "issuer": "did:key:z6MktoBabwy1eGdC7Dhf8tE7TKRzk22nomnAqYh9VZv3DQ1p", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + }, + "issuanceDate": "2023-11-09T16:00:00Z", + "proof": { + "type": "DataIntegrityProof", + "created": "2023-11-09T16:00:00Z", + "verificationMethod": "did:key:z6MktoBabwy1eGdC7Dhf8tE7TKRzk22nomnAqYh9VZv3DQ1p#z6MktoBabwy1eGdC7Dhf8tE7TKRzk22nomnAqYh9VZv3DQ1p", + "cryptosuite": "eddsa-rdfc-2022", + "proofPurpose": "assertionMethod", + "proofValue": "z4xs72qPFyVPwEnAUqs9VNtPTCEC6Y9nq3CzkGTFjxZuJ3kQXATCHGoqHK6gtGNcnBwQEwRebvy8H8BUZWGYhivES" + } + }, { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + { + "ex": "https://example.org/examples#", + "schema": "http://schema.org/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "BachelorDegree": "ex:BachelorDegree", + "UniversityDegreeCredential": "ex:UniversityDegreeCredential", + "degree": "ex:degree", + "name": { + "@id": "schema:name", + "@type": "rdf:HTML" + } + }, + "https://w3id.org/security/data-integrity/v2" + ], + "id": "http://example.gov/credentials/3732", + "type": [ "VerifiableCredential", "UniversityDegreeCredential" ], + "issuer": "did:key:zDnaeizTtXBxgFuk1No6urNmxtZBXC27Z6RPgaGLArtF8LmX2", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + }, + "issuanceDate": "2023-11-09T16:00:01Z", + "proof": { + "type": "DataIntegrityProof", + "created": "2023-11-09T16:00:01Z", + "verificationMethod": "did:key:zDnaeizTtXBxgFuk1No6urNmxtZBXC27Z6RPgaGLArtF8LmX2#zDnaeizTtXBxgFuk1No6urNmxtZBXC27Z6RPgaGLArtF8LmX2", + "cryptosuite": "ecdsa-rdfc-2019", + "proofPurpose": "assertionMethod", + "proofValue": "z5hubxPbarF7qeALkBzR1AWuVPKgMZYz5nEBQVwxMnV8w6J1Th6iD73fB6nPrH3u1HwCKNYb9jkznmKmC1yH1mtGg" + } + }, { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + { + "ex": "https://example.org/examples#", + "schema": "http://schema.org/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "BachelorDegree": "ex:BachelorDegree", + "UniversityDegreeCredential": "ex:UniversityDegreeCredential", + "degree": "ex:degree", + "name": { + "@id": "schema:name", + "@type": "rdf:HTML" + } + }, + "https://w3id.org/security/data-integrity/v2" + ], + "id": "http://example.gov/credentials/3732", + "type": [ "VerifiableCredential", "UniversityDegreeCredential" ], + "issuer": "did:key:z82Lkytz3HqpWiBmt2853ZgNgNG8qVoUJnyoMvGw6ZEBktGcwUVdKpUNJHct1wvp9pXjr7Y", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + }, + "issuanceDate": "2023-11-09T16:00:01Z", + "proof": { + "type": "DataIntegrityProof", + "created": "2023-11-09T16:00:01Z", + "verificationMethod": "did:key:z82Lkytz3HqpWiBmt2853ZgNgNG8qVoUJnyoMvGw6ZEBktGcwUVdKpUNJHct1wvp9pXjr7Y#z82Lkytz3HqpWiBmt2853ZgNgNG8qVoUJnyoMvGw6ZEBktGcwUVdKpUNJHct1wvp9pXjr7Y", + "cryptosuite": "ecdsa-rdfc-2019", + "proofPurpose": "assertionMethod", + "proofValue": "zJzP86yYYJC9Q7ZT37KxpbT1BgerusHR4rkYES6CJRWtm6sSRzVsbRVgVH3b4KfynS2UL5XAqpaM8P49VwXcUEjSdyEy9TqpDsrETBrrBVDdWBLAb32Y3FtfwiBoWDDkyzHm" + } + }, { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + { + "ex": "https://example.org/examples#", + "schema": "http://schema.org/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "BachelorDegree": "ex:BachelorDegree", + "UniversityDegreeCredential": "ex:UniversityDegreeCredential", + "degree": "ex:degree", + "name": { + "@id": "schema:name", + "@type": "rdf:HTML" + } + }, + "https://w3id.org/security/data-integrity/v2" + ], + "id": "http://example.gov/credentials/3732", + "type": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ], + "issuer": "did:key:zDnaeo2xFZXCN6rYcP8pnzZHNHHfDhdUPoJr1SsAnrjJ2NTfr", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + }, + "issuanceDate": "2023-11-13T23:37:40Z", + "proof": { + "id": "urn:uuid:61546421-352c-4fb0-8d30-a3bde6885118", + "type": "DataIntegrityProof", + "created": "2023-11-13T23:37:40Z", + "verificationMethod": "did:key:zDnaeo2xFZXCN6rYcP8pnzZHNHHfDhdUPoJr1SsAnrjJ2NTfr#zDnaeo2xFZXCN6rYcP8pnzZHNHHfDhdUPoJr1SsAnrjJ2NTfr", + "cryptosuite": "ecdsa-sd-2023", + "proofPurpose": "assertionMethod", + "proofValue": "u2V0AhVhAq8EBDGUSr8kIvdPawqmm8iEU0Adx6JP95a78yJXflyH6ItrdzHzLD7tbcLKVtBFf8md2AiRLEHlouvrjHMvGclgjgCQC0i6QhqBRCpio-5uv6pTQU-whdipvW0indlGrM82sy5VYICxR52p1dfygQ2Yxwc0I9DKbM-jXaLG7aFc4UYqQirVKhFhAEO5Y5aXCFbhrpoHsPuBEqHm9pf3otKPxDoGzraHoPUZ1wmsxJmV1QCFs7Xd_Ep3rqXDPJ7fGCkO7X69m_MwB_FhA5WhsP1oUAgvu-Ix-tmjUos6TkUb9--jn_tdpF0BHSWuSZkhbIohlS6SIKsxDeAPQX09yMC95kbmXNKaXIVr_F1hAIm0j5WB_FaJS1PUXSANSqz5ogjCpZUFEdAQvN3dwZh7AoTsAwmeo8yXBzFIxGyw9Zn4n6zhvq14EctX2rBZ8WFhAsP-KGVsXxFz0CLU_Kz4ckWIBqreCUbbIocc5EZ27FGvc3szjOXMeGWKMXoDab1Wd-JUTWt7HxXiMfhouVVKqk4JnL2lzc3Vlcm0vaXNzdWFuY2VEYXRl" + } } ] diff --git a/test/package.json b/test/package.json index 76001a3..51a8456 100644 --- a/test/package.json +++ b/test/package.json @@ -19,7 +19,7 @@ "@bedrock/app-identity": "^4.0.0", "@bedrock/core": "^6.0.1", "@bedrock/credentials-context": "^4.0.0", - "@bedrock/data-integrity-context": "^2.0.0", + "@bedrock/data-integrity-context": "^3.0.0", "@bedrock/did-context": "^5.0.0", "@bedrock/did-io": "^10.1.0", "@bedrock/edv-storage": "^18.0.0", @@ -34,7 +34,7 @@ "@bedrock/meter-usage-reporter": "^9.0.0", "@bedrock/mongodb": "^10.0.0", "@bedrock/multikey-context": "^2.0.0", - "@bedrock/oauth2-verifier": "^2.0.0", + "@bedrock/oauth2-verifier": "^2.0.2", "@bedrock/package-manager": "^3.0.0", "@bedrock/security-context": "^8.0.0", "@bedrock/server": "^5.0.0", @@ -49,13 +49,15 @@ "@bedrock/vc-verifier": "file:..", "@bedrock/veres-one-context": "^15.0.0", "@bedrock/zcap-storage": "^8.0.0", + "@digitalbazaar/data-integrity": "^2.0.0", "@digitalbazaar/did-method-key": "^3.0.0", + "@digitalbazaar/ecdsa-sd-2023-cryptosuite": "^3.0.0", "@digitalbazaar/ed25519-signature-2020": "^5.0.0", "@digitalbazaar/ed25519-verification-key-2020": "^4.0.0", "@digitalbazaar/edv-client": "^16.0.0", "@digitalbazaar/ezcap": "^4.0.0", "@digitalbazaar/http-client": "^4.0.0", - "@digitalbazaar/vc": "^6.0.0", + "@digitalbazaar/vc": "^6.1.0", "@digitalbazaar/vc-status-list-context": "^3.0.1", "@digitalbazaar/webkms-client": "^13.0.0", "c8": "^7.11.3",