From ec5405f702d4033740569353149289166c50f0b8 Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Fri, 4 Aug 2023 19:24:27 +0200 Subject: [PATCH] feat(selective-disclosure): support multiple key types for generating requests fixes #946 --- __tests__/shared/handleSdrMessage.ts | 81 ++++++++++++++++++- __tests__/shared/resolveDid.ts | 2 +- .../src/action-handler.ts | 40 +++++++-- 3 files changed, 116 insertions(+), 7 deletions(-) diff --git a/__tests__/shared/handleSdrMessage.ts b/__tests__/shared/handleSdrMessage.ts index d24e08a2be..e2a663c2b7 100644 --- a/__tests__/shared/handleSdrMessage.ts +++ b/__tests__/shared/handleSdrMessage.ts @@ -34,7 +34,7 @@ export default (testContext: { afterAll(testContext.tearDown) it('should create identifier', async () => { - identifier = await agent.didManagerCreate({ kms: 'local', provider: 'did:ethr' }) + identifier = await agent.didManagerCreate({ kms: 'local', provider: 'did:key' }) expect(identifier).toHaveProperty('did') }) @@ -82,6 +82,85 @@ export default (testContext: { expect(message.raw).toEqual(JWT) }) + it('should create and handle an SDR message with Ed25519', async () => { + const sdrIssuer = await agent.didManagerCreate({ provider: 'did:key', options: { keyType: 'Ed25519' } }) + const req = await agent.createSelectiveDisclosureRequest({ + data: { + issuer: sdrIssuer.did, + tag: 'sdr-one', + claims: [ + { + reason: 'We need it', + claimType: 'name', + essential: true, + }, + ], + }, + }) + + const message = await agent.handleMessage({ + raw: req, + save: false, + }) + + expect(message.raw).toEqual(req) + }) + + it('should create and handle an SDR message with Secp256k1', async () => { + const sdrIssuer = await agent.didManagerCreate({ + provider: 'did:ethr', + }) + const req = await agent.createSelectiveDisclosureRequest({ + data: { + issuer: sdrIssuer.did, + tag: 'sdr-one', + claims: [ + { + reason: 'We need it', + claimType: 'name', + essential: true, + }, + ], + }, + }) + + const message = await agent.handleMessage({ + raw: req, + save: false, + }) + + expect(message.raw).toEqual(req) + }) + + it('should create and handle an SDR message with Secp256r1', async () => { + const sdrIssuer = await agent.didManagerCreate({ + provider: 'did:jwk', + options: { + keyType: 'Secp256r1', + } + }) + const req = await agent.createSelectiveDisclosureRequest({ + data: { + issuer: sdrIssuer.did, + tag: 'sdr-one', + claims: [ + { + reason: 'We need it', + claimType: 'name', + essential: true, + }, + ], + }, + }) + + const message = await agent.handleMessage({ + raw: req, + save: false, + }) + + expect(message.raw).toEqual(req) + }) + it('should be able to find the request message', async () => { const messages = await agent.dataStoreORMGetMessages() diff --git a/__tests__/shared/resolveDid.ts b/__tests__/shared/resolveDid.ts index 6c17315138..2fb1eeeb74 100644 --- a/__tests__/shared/resolveDid.ts +++ b/__tests__/shared/resolveDid.ts @@ -21,7 +21,7 @@ export default (testContext: { afterAll(testContext.tearDown) it('should resolve didUrl', async () => { - const didUrl = 'did:ethr:goerli:0xb09b66026ba5909a7cfe99b76875431d2b8d5190' + const didUrl = 'did:ethr:0xb09b66026ba5909a7cfe99b76875431d2b8d5190' const didDoc = (await agent.resolveDid({ didUrl })).didDocument expect(didDoc?.id).toEqual(didUrl) }) diff --git a/packages/selective-disclosure/src/action-handler.ts b/packages/selective-disclosure/src/action-handler.ts index 648a4e8996..6552e3bdb5 100644 --- a/packages/selective-disclosure/src/action-handler.ts +++ b/packages/selective-disclosure/src/action-handler.ts @@ -8,6 +8,7 @@ import { IKey, IKeyManager, TClaimsColumns, + TKeyType, VerifiableCredential, VerifiablePresentation, } from '@veramo/core-types' @@ -25,7 +26,22 @@ import { import schema from './plugin.schema.json' assert { type: 'json' } import { createJWT } from 'did-jwt' import Debug from 'debug' -import { asArray, bytesToBase64, computeEntryHash, decodeCredentialToObject, extractIssuer, } from '@veramo/utils' +import { + asArray, + bytesToBase64, + computeEntryHash, + decodeCredentialToObject, + extractIssuer, +} from '@veramo/utils' + +const KEY_ALG_MAPPING: Record = { + Secp256k1: 'ES256K', + Secp256r1: 'ES256', + Ed25519: 'EdDSA', + X25519: null, + Bls12381G1: null, + Bls12381G2: null, +} as const /** * This class adds support for creating @@ -73,8 +89,20 @@ export class SelectiveDisclosure implements IAgentPlugin { delete data.issuer Debug('veramo:selective-disclosure:create-sdr')('Signing SDR with', identifier.did) - const key = identifier.keys.find((k: IKey) => k.type === 'Secp256k1') + const key = identifier.keys.find((k: IKey) => { + return ( + Object.keys(KEY_ALG_MAPPING).includes(k.type) && + KEY_ALG_MAPPING[k.type] && + k.meta?.algorithms?.includes(KEY_ALG_MAPPING[k.type] ?? 'unsupported') + ) + }) + if (!key) throw Error('Signing key not found') + + const algorithm = KEY_ALG_MAPPING[key?.type ?? ''] + + if (!algorithm) throw Error('Unsupported key type') + const signer = (data: string | Uint8Array) => { let dataString, encoding: 'base64' | undefined if (typeof data === 'string') { @@ -83,7 +111,7 @@ export class SelectiveDisclosure implements IAgentPlugin { } else { ;(dataString = bytesToBase64(data)), (encoding = 'base64') } - return context.agent.keyManagerSign({ keyRef: key.kid, data: dataString, encoding }) + return context.agent.keyManagerSign({ keyRef: key.kid, data: dataString, encoding, algorithm }) } const jwt = await createJWT( { @@ -92,7 +120,7 @@ export class SelectiveDisclosure implements IAgentPlugin { }, { signer, - alg: 'ES256K', + alg: algorithm, issuer: identifier.did, }, ) @@ -198,7 +226,9 @@ export class SelectiveDisclosure implements IAgentPlugin { if ( credentialRequest.issuers && - !credentialRequest.issuers.map((i) => i.did).includes(extractIssuer(credential, { removeParameters: true })) + !credentialRequest.issuers + .map((i) => i.did) + .includes(extractIssuer(credential, { removeParameters: true })) ) { return false }