UNPKG

@veramo/did-comm

Version:

Veramo messaging plugin implementing DIDComm v2.

344 lines (328 loc) 14.1 kB
import { DIDComm } from '../didcomm.js' import { IDIDManager, IIdentifier, IKeyManager, IResolver, TAgent } from '../../../core-types/src' import { createAgent } from '../../../core/src' import { DIDManager, MemoryDIDStore } from '../../../did-manager/src' import { KeyManager, MemoryKeyStore, MemoryPrivateKeyStore } from '../../../key-manager/src' import { KeyManagementSystem } from '../../../kms-local/src' import { DIDResolverPlugin } from '../../../did-resolver/src' import { DIDDocument, Resolver } from 'did-resolver' import { IDIDComm } from '../types/IDIDComm.js' import { ExampleDidProvider } from '../../../test-utils/src' import 'cross-fetch/polyfill' import { base64ToBytes, bytesToHex } from '../../../utils/src' import * as u8a from 'uint8arrays' const aliceDoc = { '@context': ['https://www.w3.org/ns/did/v1', 'https://w3id.org/security/suites/jws-2020/v1'], id: 'did:example:alice', authentication: [ { id: 'did:example:alice#key-1', type: 'JsonWebKey2020', controller: 'did:example:alice', publicKeyJwk: { kty: 'OKP', crv: 'Ed25519', x: 'G-boxFB6vOZBu-wXkm-9Lh79I8nf9Z50cILaOgKKGww', }, }, { id: 'did:example:alice#key-2', type: 'JsonWebKey2020', controller: 'did:example:alice', publicKeyJwk: { kty: 'EC', crv: 'P-256', x: '2syLh57B-dGpa0F8p1JrO6JU7UUSF6j7qL-vfk1eOoY', y: 'BgsGtI7UPsObMRjdElxLOrgAO9JggNMjOcfzEPox18w', }, }, { id: 'did:example:alice#key-3', type: 'JsonWebKey2020', controller: 'did:example:alice', publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: 'aToW5EaTq5mlAf8C5ECYDSkqsJycrW-e1SQ6_GJcAOk', y: 'JAGX94caA21WKreXwYUaOCYTBMrqaX4KWIlsQZTHWCk', }, }, ], keyAgreement: [ { id: 'did:example:alice#key-x25519-1', type: 'JsonWebKey2020', controller: 'did:example:alice', publicKeyJwk: { kty: 'OKP', crv: 'X25519', x: 'avH0O2Y4tqLAq8y9zpianr8ajii5m4F_mICrzNlatXs', }, }, { id: 'did:example:alice#key-p256-1', type: 'JsonWebKey2020', controller: 'did:example:alice', publicKeyJwk: { kty: 'EC', crv: 'P-256', x: 'L0crjMN1g0Ih4sYAJ_nGoHUck2cloltUpUVQDhF2nHE', y: 'SxYgE7CmEJYi7IDhgK5jI4ZiajO8jPRZDldVhqFpYoo', }, }, { id: 'did:example:alice#key-p521-1', type: 'JsonWebKey2020', controller: 'did:example:alice', publicKeyJwk: { kty: 'EC', crv: 'P-521', x: 'AHBEVPRhAv-WHDEvxVM9S0px9WxxwHL641Pemgk9sDdxvli9VpKCBdra5gg_4kupBDhz__AlaBgKOC_15J2Byptz', y: 'AciGcHJCD_yMikQvlmqpkBbVqqbg93mMVcgvXBYAQPP-u9AF7adybwZrNfHWCKAQwGF9ugd0Zhg7mLMEszIONFRk', }, }, ], } const bobDoc = { '@context': ['https://www.w3.org/ns/did/v2'], id: 'did:example:bob', keyAgreement: [ { id: 'did:example:bob#key-x25519-1', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'OKP', crv: 'X25519', x: 'GDTrI66K0pFfO54tlCSvfjjNapIs44dzpneBgyx0S3E', }, }, { id: 'did:example:bob#key-x25519-2', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'OKP', crv: 'X25519', x: 'UT9S3F5ep16KSNBBShU2wh3qSfqYjlasZimn0mB8_VM', }, }, { id: 'did:example:bob#key-x25519-3', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'OKP', crv: 'X25519', x: '82k2BTUiywKv49fKLZa-WwDi8RBf0tB0M8bvSAUQ3yY', }, }, { id: 'did:example:bob#key-p256-1', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'EC', crv: 'P-256', x: 'FQVaTOksf-XsCUrt4J1L2UGvtWaDwpboVlqbKBY2AIo', y: '6XFB9PYo7dyC5ViJSO9uXNYkxTJWn0d_mqJ__ZYhcNY', }, }, { id: 'did:example:bob#key-p256-2', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'EC', crv: 'P-256', x: 'n0yBsGrwGZup9ywKhzD4KoORGicilzIUyfcXb1CSwe0', y: 'ov0buZJ8GHzV128jmCw1CaFbajZoFFmiJDbMrceCXIw', }, }, { id: 'did:example:bob#key-p384-1', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'EC', crv: 'P-384', x: 'MvnE_OwKoTcJVfHyTX-DLSRhhNwlu5LNoQ5UWD9Jmgtdxp_kpjsMuTTBnxg5RF_Y', y: 'X_3HJBcKFQEG35PZbEOBn8u9_z8V1F9V1Kv-Vh0aSzmH-y9aOuDJUE3D4Hvmi5l7', }, }, { id: 'did:example:bob#key-p384-2', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'EC', crv: 'P-384', x: '2x3HOTvR8e-Tu6U4UqMd1wUWsNXMD0RgIunZTMcZsS-zWOwDgsrhYVHmv3k_DjV3', y: 'W9LLaBjlWYcXUxOf6ECSfcXKaC3-K9z4hCoP0PS87Q_4ExMgIwxVCXUEB6nf0GDd', }, }, { id: 'did:example:bob#key-p521-1', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'EC', crv: 'P-521', x: 'Af9O5THFENlqQbh2Ehipt1Yf4gAd9RCa3QzPktfcgUIFADMc4kAaYVViTaDOuvVS2vMS1KZe0D5kXedSXPQ3QbHi', y: 'ATZVigRQ7UdGsQ9j-omyff6JIeeUv3CBWYsZ0l6x3C_SYqhqVV7dEG-TafCCNiIxs8qeUiXQ8cHWVclqkH4Lo1qH', }, }, { id: 'did:example:bob#key-p521-2', type: 'JsonWebKey2020', controller: 'did:example:bob', publicKeyJwk: { kty: 'EC', crv: 'P-521', x: 'ATp_WxCfIK_SriBoStmA0QrJc2pUR1djpen0VdpmogtnKxJbitiPq-HJXYXDKriXfVnkrl2i952MsIOMfD2j0Ots', y: 'AEJipR0Dc-aBZYDqN51SKHYSWs9hM58SmRY1MxgXANgZrPaq1EeGMGOjkbLMEJtBThdjXhkS5VlXMkF0cYhZELiH', }, }, ], } const trustPingMessage = { type: 'https://didcomm.org/trust-ping/2.0/ping', from: 'did:example:alice', to: ['did:example:bob'], id: 'trust-ping-test', body: { responseRequested: true, }, } describe('trust-ping-interop', () => { let sender: IIdentifier let recipient: IIdentifier let agent: TAgent<IResolver & IKeyManager & IDIDManager & IDIDComm> beforeAll(async () => { agent = createAgent<IResolver & IKeyManager & IDIDManager & IDIDComm>({ plugins: [ new KeyManager({ store: new MemoryKeyStore(), kms: { local: new KeyManagementSystem(new MemoryPrivateKeyStore()), }, }), new DIDManager({ providers: { 'did:example': new ExampleDidProvider(), }, store: new MemoryDIDStore(), defaultProvider: 'did:example', }), new DIDResolverPlugin({ resolver: new Resolver({ example: async (did: string) => { let doc: DIDDocument if (did === 'did:example:alice') { doc = aliceDoc } else if (did === 'did:example:bob') { doc = bobDoc } else { throw new Error('Bad didUrl for fake resolver: ' + did) } // DIDResolutionResult return { didResolutionMetadata: {}, didDocument: doc, didDocumentMetadata: {}, } }, }), }), new DIDComm(), ], }) // https://identity.foundation/didcomm-messaging/spec/#a1-sender-secrets const senderSecretEd25519X = 'G-boxFB6vOZBu-wXkm-9Lh79I8nf9Z50cILaOgKKGww' const senderSecretEd25519D = 'pFRUKkyzx4kHdJtFSnlPA9WzqkDT1HWV0xZ5OYZd2SY' const senderSecretX25519X = 'avH0O2Y4tqLAq8y9zpianr8ajii5m4F_mICrzNlatXs' const senderSecretX25519D = 'r-jK2cO3taR8LQnJB1_ikLBTAnOtShJOsHXRUWT-aZA' sender = await agent.didManagerImport({ did: 'did:example:alice', keys: [ { type: 'Ed25519', kid: 'did:example:alice#key-1', publicKeyHex: bytesToHex(base64ToBytes(senderSecretEd25519X)), // we use stablelib/nacl for ed25519, and the preferred encoding for the privateKey there is a 64 byte // string, where the second half is the precomputed 32 byte encoding of the publicKey. This seems to be the // preferred encoding in other related libraries too, as the pre-computation speeds up the signing by a few // milliseconds. // https://github.com/StableLib/stablelib/blob/a89a438fcbf855de6b2e9faa2630f03c3f3b3a54/packages/ed25519/ed25519.ts#L669 // https://crypto.stackexchange.com/a/54367 // https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#ed25519 privateKeyHex: bytesToHex( u8a.concat([base64ToBytes(senderSecretEd25519D), base64ToBytes(senderSecretEd25519X)]), ), kms: 'local', }, { type: 'X25519', kid: 'did:example:alice#key-x25519-1', publicKeyHex: bytesToHex(base64ToBytes(senderSecretX25519X)), privateKeyHex: bytesToHex(base64ToBytes(senderSecretX25519D)), kms: 'local', }, ], provider: 'did:example', alias: 'alice', }) recipient = await agent.didManagerImport({ did: 'did:example:bob', keys: [ { type: 'X25519', kid: 'did:example:bob#key-x25519-1', publicKeyHex: bytesToHex(base64ToBytes('GDTrI66K0pFfO54tlCSvfjjNapIs44dzpneBgyx0S3E')), privateKeyHex: bytesToHex(base64ToBytes('b9NnuOCB0hm7YGNvaE9DMhwH_wjZA1-gWD6dA0JWdL0')), kms: 'local', }, { type: 'X25519', kid: 'did:example:bob#key-x25519-2', publicKeyHex: bytesToHex(base64ToBytes('UT9S3F5ep16KSNBBShU2wh3qSfqYjlasZimn0mB8_VM')), privateKeyHex: bytesToHex(base64ToBytes('p-vteoF1gopny1HXywt76xz_uC83UUmrgszsI-ThBKk')), kms: 'local', }, { type: 'X25519', kid: 'did:example:bob#key-x25519-3', publicKeyHex: bytesToHex(base64ToBytes('82k2BTUiywKv49fKLZa-WwDi8RBf0tB0M8bvSAUQ3yY')), privateKeyHex: bytesToHex(base64ToBytes('f9WJeuQXEItkGM8shN4dqFr5fLQLBasHnWZ-8dPaSo0')), kms: 'local', }, ], provider: 'did:example', alias: 'bob', }) }) it('should pack and unpack trust ping message with authcrypt packing', async () => { const packedMessage = await agent.packDIDCommMessage({ message: trustPingMessage, packing: 'authcrypt' }) const unpackedMessage = await agent.unpackDIDCommMessage(packedMessage) expect(unpackedMessage.message.id).toEqual(trustPingMessage.id) }) it('should unpack encrypted message from test vector', async () => { const unpackedMessage = await agent.unpackDIDCommMessage({ message: '{"protected":"eyJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIiwic2tpZCI6ImRpZDpleGFtcGxlOmFsaWNlI2tleS14MjU1MTktMSIsImVuYyI6IlhDMjBQIn0","iv":"VfXAqOwRdCqkCOXtCZmM7xRY6b2cTT5K","ciphertext":"_urtE_Pqw8rGEVkR4iKZiR9qs7U7CCiY5T5sujlSwJnI9V6l4MqXAkfQ_EmSS0bKqrpvB1kXT0vgQQUEfwUeqkXBGiNqd-lBopM1zbaUFIr8x7AobjiVlhDkoA0KVQqICuTUhmt3po5h3wTfNZtB1wiQPF3cYeXg9y6sUVAQ7DyAJdItFcYKiboB3b15nIIP1ld6Bb9r50KD3Gm_DQ","tag":"oq6URRWgtmXePhwQXLeZow","recipients":[{"encrypted_key":"iI92IB_c6z-z9OKbK6GMS54uPJrGefJ9BY5papAvc00","header":{"alg":"ECDH-1PU+XC20PKW","iv":"04K4bQO4q0-x3oiSwvx1vjfIo7DEggyl","tag":"q5DzsirJ4Qrnqr0zosx-sg","epk":{"kty":"OKP","crv":"X25519","x":"KqNpwX_5bvCFMpMwB-ww1z8mJB7jq8Sy1jSbQPHqHxA"},"kid":"did:example:bob#key-x25519-1"}},{"encrypted_key":"Z8mGUR1Q-UIOts1LxIhZNIzbcyp5vj_8ZTWuJ6CxWJE","header":{"alg":"ECDH-1PU+XC20PKW","iv":"g1LwvctMeKDtEcJKQGepuevJnho9WdnX","tag":"up_m3F6B-8RAWvlNEhD4Cg","epk":{"kty":"OKP","crv":"X25519","x":"11cPGXIykWfZBVyCIcn7CisnxXgIS988MtHYD9d3HlM"},"kid":"did:example:bob#key-x25519-2"}},{"encrypted_key":"CsnDZ8TEfeIa5Tu7XqYdxx3r5SnzQDssvhTcmkvzA8g","header":{"alg":"ECDH-1PU+XC20PKW","iv":"-2i2CV7T5ylzk7TLK81lKO1xlvRefIMW","tag":"RtaehpY4C6HxXSuy-PSd6w","epk":{"kty":"OKP","crv":"X25519","x":"nH9Pdu9RCm8znYmhCtGp9hPR_VuS6kcf5zJndTYBVzI"},"kid":"did:example:bob#key-x25519-3"}}]}', }) expect(unpackedMessage.message.id).toEqual(trustPingMessage.id) }) it('should pack and unpack trust ping message with anoncrypt packing', async () => { const packedMessage = await agent.packDIDCommMessage({ message: trustPingMessage, packing: 'anoncrypt' }) const unpackedMessage = await agent.unpackDIDCommMessage(packedMessage) expect(unpackedMessage.message.id).toEqual(trustPingMessage.id) }) it('should unpack encrypted message from test vector', async () => { const unpackedMessage = await agent.unpackDIDCommMessage({ message: '{"protected":"eyJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIiwic2tpZCI6ImRpZDpleGFtcGxlOmFsaWNlI2tleS14MjU1MTktMSIsImVuYyI6IlhDMjBQIn0","iv":"8e7Q16uLi4YL7VCEw2E2B9vlC9O7IVn4","ciphertext":"aE0DnTMiiPVxo0WaUNqma4qXnTzPojXnJOkv2vvJ36hoXc5gf5kyCXV8JGVmuR0ib62bZt8RhZCzt-2dmyJc9qot2oz7VesSfrxNOFb1-LB4Tfp2d1KVi96wCeQ_Ca5gr5RPRiQIBuoHHQsuZ2P1_9o49txTlt1AlCS4GwY4QCTnLVNyQTfDweQLwp-OJTMlDoKKgHzBljfovHv4yQ","tag":"ZeItOIGZS3-NvGMbDDKu3w","recipients":[{"encrypted_key":"wDMR_DerdPHrua7edijfseiVsTXKkHXou-U3y_XH2VE","header":{"alg":"ECDH-1PU+XC20PKW","iv":"K8twVbKqWnmISiiwnrCK8308vy0g0By9","tag":"fcgKH3VwAjpSnz-T0UP4bw","epk":{"kty":"OKP","crv":"X25519","x":"zN8qTfSPmxA_OwTnK-JOmVrpwvPTlhFuOXm9qlFsozc"},"kid":"did:example:bob#key-x25519-1"}},{"encrypted_key":"eEJ62Naux0w2xUz-5u2aA-Bt4mcxyeZDOUJS16PxUj8","header":{"alg":"ECDH-1PU+XC20PKW","iv":"uvkmZEbeJ-ThAYTcZHIdSW1O4diVWgTM","tag":"PKxx4DWaPAzWBW_pizYckw","epk":{"kty":"OKP","crv":"X25519","x":"90TtJUXASLgYRUctFByDBUNULqsB47W0-QisRdiDOhg"},"kid":"did:example:bob#key-x25519-2"}},{"encrypted_key":"GEYY8xb9e07x7mmJGrPAJssoZayTBUgDrF9RO2FWHEE","header":{"alg":"ECDH-1PU+XC20PKW","iv":"rp9Oi7vEkD0gJjPe3LMU_IR1Yq5_2umv","tag":"zvFBqklSbyRP4Lsp_eyQEg","epk":{"kty":"OKP","crv":"X25519","x":"R9AkOBdF4nN489pQgqI_NstsdrSpnNsGGEgjgNhdeE8"},"kid":"did:example:bob#key-x25519-3"}}]}', }) expect(unpackedMessage.message.id).toEqual(trustPingMessage.id) }) })