UNPKG

@microsoft/useragent-sdk

Version:

SDK for building decentralized identity wallets and enterprise agents.

193 lines 12.5 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const JwsToken_1 = require("../../../../../src/crypto/protocols/jose/jws/JwsToken"); const OctKey_1 = require("../../../../../src/crypto/keys/Oct/OctKey"); const KeyStoreInMemory_1 = require("../../../../../src/crypto/keyStore/KeyStoreInMemory"); const CryptoFactory_1 = require("../../../../../src/crypto/plugin/CryptoFactory"); const SubtleCryptoNode_1 = require("../../../../../src/crypto/plugin/SubtleCryptoNode"); const ProtectionFormat_1 = require("../../../../../src/crypto/keyStore/ProtectionFormat"); const SubtleCryptoExtension_1 = require("../../../../../src/crypto/plugin/SubtleCryptoExtension"); const JoseProtocol_1 = require("../../../../../src/crypto/protocols/jose/JoseProtocol"); const typescript_map_1 = require("typescript-map"); const JoseConstants_1 = require("../../../../../src/crypto/protocols/jose/JoseConstants"); const KeyContainer_1 = require("../../../../../src/crypto/keys/KeyContainer"); describe('JwsToken', () => { it('should create a jws token', async () => { const payload = 'test payload'; const keyStore = new KeyStoreInMemory_1.default(); const seedReference = 'seed'; await keyStore.save(seedReference, new KeyContainer_1.default(new OctKey_1.default('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))); const subtle = SubtleCryptoNode_1.default.getSubtleCrypto(); const options = { algorithm: { name: 'ECDSA', namedCurve: 'P-256K', hash: { name: 'SHA-256' } }, cryptoFactory: new CryptoFactory_1.default(keyStore, subtle) }; const generate = new SubtleCryptoExtension_1.default(options.cryptoFactory); const privateKey = await generate.generatePairwiseKey(options.algorithm, seedReference, 'did:personaId', 'did:peerId'); privateKey.alg = 'ES256K'; privateKey.defaultSignAlgorithm = 'ES256K'; await keyStore.save('key', new KeyContainer_1.default(privateKey)); const jwsToken = new JwsToken_1.default(options); const signature = await jwsToken.sign('key', Buffer.from(payload), ProtectionFormat_1.ProtectionFormat.JwsGeneralJson); expect(signature).toBeDefined(); }); it('should create, validate and serialize a JwsToken', async () => { const payload = 'The true sign of intelligence is not knowledge but imagination.'; const keyStore = new KeyStoreInMemory_1.default(); await keyStore.save('seed', new KeyContainer_1.default(new OctKey_1.default('ABEE'))); const cryptoFactory = new CryptoFactory_1.default(keyStore, SubtleCryptoNode_1.default.getSubtleCrypto()); const options = { cryptoFactory: cryptoFactory, options: new typescript_map_1.TSMap(), payloadProtection: new JoseProtocol_1.default() }; const alg = { name: 'RSASSA-PKCS1-V1_5', hash: 'SHA-256', modulusLength: 2048, publicExponent: new Uint8Array([0x01, 0x00, 0x01]) }; const generator = new SubtleCryptoExtension_1.default(cryptoFactory); const privateKey = await generator.generatePairwiseKey(alg, 'seed', 'persona', 'peer'); expect(privateKey.alg).toBeUndefined(); privateKey.alg = 'RS256'; await keyStore.save('key', new KeyContainer_1.default(privateKey)); // sign const signature = await options.payloadProtection.sign('key', Buffer.from(payload), 'JwsGeneralJson', options); const signatures = signature.get(JoseConstants_1.default.tokenSignatures); expect(signatures[0].protected).toBeDefined(); expect(signatures[0].signature).toBeDefined(); expect(signature.get(JoseConstants_1.default.tokenPayload)).toEqual(Buffer.from(payload)); // serialize let serialized = options.payloadProtection.serialize(signature, 'JwsGeneralJson', options); let parsed = JSON.parse(serialized); expect(parsed['payload']).toBeDefined(); expect(parsed['signatures']).toBeDefined(); // deserialize let deserialized = options.payloadProtection.deserialize(serialized, 'JwsGeneralJson', options); let deSignatures = deserialized.get(JoseConstants_1.default.tokenSignatures); expect(deSignatures[0].protected).toEqual(signatures[0].protected); expect(deSignatures[0].signature).toEqual(signatures[0].signature); expect(deserialized.get(JoseConstants_1.default.tokenPayload)).toEqual(signature.get(JoseConstants_1.default.tokenPayload)); // validate const publicKeyContainer = (await keyStore.get('key', true)).getKey(); const result = await options.payloadProtection.verify([publicKeyContainer], Buffer.from(payload), signature, options); expect(result.result).toBeTruthy(); // Flat serialization serialized = options.payloadProtection.serialize(signature, 'JwsFlatJson', options); parsed = JSON.parse(serialized); expect(parsed['payload']).toBeDefined(); expect(parsed['protected']).toBeDefined(); expect(parsed['signature']).toBeDefined(); deserialized = options.payloadProtection.deserialize(serialized, 'JwsFlatJson', options); deSignatures = deserialized.get(JoseConstants_1.default.tokenSignatures); expect(deSignatures[0].protected).toEqual(signatures[0].protected); expect(deSignatures[0].signature).toEqual(signatures[0].signature); expect(deserialized.get(JoseConstants_1.default.tokenPayload)).toEqual(signature.get(JoseConstants_1.default.tokenPayload)); // Compact serialization serialized = options.payloadProtection.serialize(signature, 'JwsCompactJson', options); parsed = serialized.split('.'); expect(parsed.length).toEqual(3); deserialized = options.payloadProtection.deserialize(serialized, 'JwsCompactJson', options); deSignatures = deserialized.get(JoseConstants_1.default.tokenSignatures); expect(deSignatures[0].protected).toEqual(signatures[0].protected); expect(deSignatures[0].signature).toEqual(signatures[0].signature); expect(deserialized.get(JoseConstants_1.default.tokenPayload)).toEqual(signature.get(JoseConstants_1.default.tokenPayload)); }); // tslint:disable-next-line: max-func-body-length it('should set headers in JwsToken', async () => { const payload = 'The true sign of intelligence is not knowledge but imagination.'; const keyStore = new KeyStoreInMemory_1.default(); await keyStore.save('seed', new KeyContainer_1.default(new OctKey_1.default('ABEE'))); const cryptoFactory = new CryptoFactory_1.default(keyStore, SubtleCryptoNode_1.default.getSubtleCrypto()); const options = { cryptoFactory: cryptoFactory, options: new typescript_map_1.TSMap([ [JoseConstants_1.default.optionHeader, new typescript_map_1.TSMap([['test', 'ES256K']])], [JoseConstants_1.default.optionProtectedHeader, new typescript_map_1.TSMap([['test', 'elo']])] ]), payloadProtection: new JoseProtocol_1.default() }; const alg = { name: 'ECDSA', namedCurve: 'P-256K', hash: { name: 'SHA-256' }, format: 'DER' }; const generator = new SubtleCryptoExtension_1.default(cryptoFactory); const privateKey = await generator.generatePairwiseKey(alg, 'seed', 'persona', 'peer'); privateKey.alg = 'ES256K'; await keyStore.save('key', new KeyContainer_1.default(privateKey)); let publicKey = await keyStore.get('key', true); // sign const signature = await options.payloadProtection.sign('key', Buffer.from(payload), 'JwsGeneralJson', options); const signatures = signature.get(JoseConstants_1.default.tokenSignatures); expect(signatures[0].protected.get('test')).toEqual('elo'); expect(signatures[0].header.get('test')).toEqual('ES256K'); expect(signatures[0].signature).toBeDefined(); expect(signature.get(JoseConstants_1.default.tokenPayload)).toEqual(Buffer.from(payload)); // serialize let serialized = options.payloadProtection.serialize(signature, 'JwsGeneralJson', options); let parsed = JSON.parse(serialized); expect(parsed['payload']).toBeDefined(); expect(parsed['signatures']).toBeDefined(); // deserialize let deserialized = options.payloadProtection.deserialize(serialized, 'JwsGeneralJson', options); let deSignatures = deserialized.get(JoseConstants_1.default.tokenSignatures); expect(deSignatures[0].protected).toEqual(signatures[0].protected); expect(deSignatures[0].header).toEqual(signatures[0].header); expect(deSignatures[0].signature).toEqual(signatures[0].signature); expect(deserialized.get(JoseConstants_1.default.tokenPayload)).toEqual(signature.get(JoseConstants_1.default.tokenPayload)); // validate const publicKeyContainer = (await keyStore.get('key', true)).getKey(); const result = await options.payloadProtection.verify([publicKeyContainer], Buffer.from(payload), signature, options); expect(result.result).toBeTruthy(); // Flat serialization serialized = options.payloadProtection.serialize(signature, 'JwsFlatJson', options); parsed = JSON.parse(serialized); expect(parsed['payload']).toBeDefined(); expect(parsed['protected']).toBeDefined(); expect(parsed['header']).toBeDefined(); expect(parsed['signature']).toBeDefined(); deserialized = options.payloadProtection.deserialize(serialized, 'JwsFlatJson', options); deSignatures = deserialized.get(JoseConstants_1.default.tokenSignatures); expect(deSignatures[0].protected).toEqual(signatures[0].protected); expect(deSignatures[0].header).toEqual(signatures[0].header); expect(deSignatures[0].signature).toEqual(signatures[0].signature); expect(deserialized.get(JoseConstants_1.default.tokenPayload)).toEqual(signature.get(JoseConstants_1.default.tokenPayload)); // Compact serialization serialized = options.payloadProtection.serialize(signature, 'JwsCompactJson', options); parsed = serialized.split('.'); expect(parsed.length).toEqual(3); deserialized = options.payloadProtection.deserialize(serialized, 'JwsCompactJson', options); deSignatures = deserialized.get(JoseConstants_1.default.tokenSignatures); expect(deSignatures[0].protected).toEqual(signatures[0].protected); expect(deSignatures[0].signature).toEqual(signatures[0].signature); expect(deserialized.get(JoseConstants_1.default.tokenPayload)).toEqual(signature.get(JoseConstants_1.default.tokenPayload)); // negative cases let throwed = false; try { options.payloadProtection.serialize(signature, 'bluesky', options); } catch (err) { throwed = true; expect(err.message).toEqual(`Format 'bluesky' is not supported`); } expect(throwed).toBeTruthy(); throwed = false; try { options.payloadProtection.deserialize(serialized, 'bluesky', options); } catch (err) { throwed = true; expect(err.message).toEqual(`Format 'bluesky' is not supported`); } expect(throwed).toBeTruthy(); const sigs = signature.get(JoseConstants_1.default.tokenSignatures); sigs[0].protected.set('alg', ''); throwed = false; try { await options.payloadProtection.verify([publicKey], Buffer.from(payload), signature, options); } catch (err) { expect(err.message).toEqual('Unable to validate signature as no signature algorithm has been specified in the header.'); throwed = true; } expect(throwed).toBeTruthy(); }); }); //# sourceMappingURL=JwsToken.spec.js.map