From e9fc8619a781b347ff98204084aa096de5c715a2 Mon Sep 17 00:00:00 2001 From: seebees Date: Tue, 21 Apr 2020 11:39:43 -0700 Subject: [PATCH] chore: move to eslint and prettier for tests Now that all the source files have been updated, and verified with the old tests update the tests. This process helps ensure that all changes are **only** formatting. --- ...raphic_materials_cache_key_helpers.test.ts | 18 +- ...cryptographic_materials_decorators.test.ts | 275 +- modules/cache-material/test/fixtures.ts | 436 +- ...ocal_cryptographic_materials_cache.test.ts | 32 +- .../caching_materials_manager_browser.test.ts | 22 +- .../test/sha512.test.ts | 76 +- .../caching_materials_manager_node.test.ts | 22 +- .../test/sha512.test.ts | 14 +- modules/decrypt-browser/test/decrypt.test.ts | 36 +- modules/decrypt-browser/test/fixtures.ts | 5663 +++++++++- .../decrypt-node/test/decipher_stream.test.ts | 37 +- modules/decrypt-node/test/decrypt.test.ts | 73 +- modules/decrypt-node/test/fixtures.ts | 55 +- .../decrypt-node/test/verify_stream.test.ts | 31 +- modules/encrypt-browser/test/encrypt.test.ts | 55 +- modules/encrypt-node/test/encrypt.test.ts | 81 +- .../test/framed_encrypt_stream.test.ts | 75 +- modules/hkdf-node/test/fixtures.ts | 9743 ++++++++++++++++- modules/hkdf-node/test/test.ts | 126 +- .../decrypt_materials_manager_node.test.ts | 72 +- .../test/get_decrypt_test_iterator.test.ts | 96 +- .../test/get_encrypt_test_iterator.test.ts | 57 +- .../test/kms_keyring_browser.test.ts | 42 +- .../test/kms_keyring_node.test.ts | 24 +- modules/kms-keyring/test/helpers.test.ts | 105 +- .../test/kms_client_supplier.test.ts | 48 +- .../test/kms_keyring.constructor.test.ts | 110 +- .../test/kms_keyring.ondecrypt.test.ts | 616 +- .../test/kms_keyring.onencrypt.test.ts | 208 +- .../test/region_from_kms_key_arn.test.ts | 44 +- ...er_cryptographic_materials_manager.test.ts | 319 +- .../test/keyring_helpers.test.ts | 34 +- .../test/material_helpers.test.ts | 557 +- .../test/material_helpers.test.ts | 243 +- ...de_cryptographic_materials_manager.test.ts | 204 +- .../test/algorithm_suites.test.ts | 17 +- .../test/clone_cryptographic_material.test.ts | 129 +- .../test/cryptographic_material.test.ts | 897 +- modules/material-management/test/ecc.test.ts | 289 +- .../test/encrypted_data_key.test.ts | 6 +- .../test/environmental_integration.test.ts | 4 +- .../test/immutable_class.test.ts | 86 +- .../material-management/test/keyring.test.ts | 136 +- .../test/multi_keyring.test.ts | 289 +- .../test/node_algorithms.test.ts | 8 +- .../test/pem_helpers.test.ts | 50 +- .../test/signature_key.test.ts | 186 +- .../test/web_crypto_algorithms.test.ts | 29 +- .../test/raw_aes_keyring_browser.test.ts | 161 +- .../test/raw_aes_keyring_node.test.ts | 119 +- .../test/raw_aes_encrypted_data_keys.test.ts | 147 +- .../raw-keyring/test/raw_aes_material.test.ts | 17 +- .../test/raw_keyring_decorators.test.ts | 100 +- .../test/get_import_options.test.ts | 51 +- .../test/raw_rsa_keyring_web_crypto.test.ts | 170 +- .../test/raw_rsa_keyring_node.test.ts | 211 +- modules/serialize/test/aad_factory.test.ts | 121 +- modules/serialize/test/concat_buffers.test.ts | 12 +- .../serialize/test/decode_body_header.test.ts | 261 +- .../test/deserialize_factory.test.ts | 387 +- .../serialize/test/ecdsa_signatures.test.ts | 1471 ++- modules/serialize/test/fixtures.ts | 1821 ++- modules/serialize/test/kdf_info.test.ts | 4 +- modules/serialize/test/read_elements.test.ts | 138 +- .../serialize/test/serialize_factory.test.ts | 234 +- modules/serialize/test/signature_info.test.ts | 5 +- .../test/backend-factory.test.ts | 178 +- modules/web-crypto-backend/test/fixtures.ts | 180 +- .../test/promisify-ms-crypto.test.ts | 12 +- .../test/synchronous_random_values.test.ts | 4 +- package.json | 4 +- 71 files changed, 24494 insertions(+), 3089 deletions(-) diff --git a/modules/cache-material/test/build_cryptographic_materials_cache_key_helpers.test.ts b/modules/cache-material/test/build_cryptographic_materials_cache_key_helpers.test.ts index 5d389fbce..0dacbef1e 100644 --- a/modules/cache-material/test/build_cryptographic_materials_cache_key_helpers.test.ts +++ b/modules/cache-material/test/build_cryptographic_materials_cache_key_helpers.test.ts @@ -5,21 +5,27 @@ import { expect } from 'chai' import { buildCryptographicMaterialsCacheKeyHelpers } from '../src/build_cryptographic_materials_cache_key_helpers' -import { encryptionContextVectors, encryptedDataKeyVectors, encryptCacheKeyVectors, decryptCacheKeyVectors } from './fixtures' +import { + encryptionContextVectors, + encryptedDataKeyVectors, + encryptCacheKeyVectors, + decryptCacheKeyVectors, +} from './fixtures' import { createHash } from 'crypto' const fromUtf8 = (input: string) => Buffer.from(input, 'utf8') const toUtf8 = (input: Uint8Array) => Buffer.from(input).toString('utf8') -const sha512 = async (...data: (Uint8Array|string)[]) => data - .map(item => typeof item === 'string' ? Buffer.from(item, 'hex') : item) - .reduce((hash, item) => hash.update(item), createHash('sha512')) - .digest() +const sha512 = async (...data: (Uint8Array | string)[]) => + data + .map((item) => (typeof item === 'string' ? Buffer.from(item, 'hex') : item)) + .reduce((hash, item) => hash.update(item), createHash('sha512')) + .digest() const { encryptionContextHash, encryptedDataKeysHash, buildEncryptionMaterialCacheKey, - buildDecryptionMaterialCacheKey + buildDecryptionMaterialCacheKey, } = buildCryptographicMaterialsCacheKeyHelpers(fromUtf8, toUtf8, sha512) describe('buildCryptographicMaterialsCacheKeyHelpers::encryptionContextHash', () => { diff --git a/modules/cache-material/test/caching_cryptographic_materials_decorators.test.ts b/modules/cache-material/test/caching_cryptographic_materials_decorators.test.ts index 7916c23b5..6a6fae299 100644 --- a/modules/cache-material/test/caching_cryptographic_materials_decorators.test.ts +++ b/modules/cache-material/test/caching_cryptographic_materials_decorators.test.ts @@ -8,7 +8,7 @@ import { decorateProperties, cacheEntryHasExceededLimits, getEncryptionMaterials, - decryptMaterials + decryptMaterials, } from '../src/caching_cryptographic_materials_decorators' import { getLocalCryptographicMaterialsCache } from '../src/get_local_cryptographic_materials_cache' import { buildCryptographicMaterialsCacheKeyHelpers } from '../src/build_cryptographic_materials_cache_key_helpers' @@ -20,7 +20,7 @@ import { KeyringTraceFlag, EncryptedDataKey, NodeEncryptionMaterial, - NodeDecryptionMaterial + NodeDecryptionMaterial, } from '@aws-crypto/material-management' describe('decorateProperties', () => { @@ -32,7 +32,7 @@ describe('decorateProperties', () => { maxAge: 10, partition: 'something', maxBytesEncrypted: 100, - maxMessagesEncrypted: 200 + maxMessagesEncrypted: 200, } as any) expect(test._cache).to.equal('cache') @@ -49,7 +49,7 @@ describe('decorateProperties', () => { const input = { backingMaterialsManager: 'backingMaterialsManager' as any, maxAge: 10, - partition: 'something' + partition: 'something', } as any expect(() => decorateProperties(test, input)).to.throw() }) @@ -59,7 +59,7 @@ describe('decorateProperties', () => { const input = { cache: 'cache' as any, maxAge: 10, - partition: 'something' + partition: 'something', } as any expect(() => decorateProperties(test, input)).to.throw() }) @@ -69,7 +69,7 @@ describe('decorateProperties', () => { const input = { cache: 'cache' as any, backingMaterialsManager: 'backingMaterialsManager' as any, - partition: 'something' + partition: 'something', } as any expect(() => decorateProperties(test, input)).to.throw() }) @@ -81,7 +81,7 @@ describe('decorateProperties', () => { backingMaterialsManager: 'backingMaterialsManager' as any, maxAge: 10, partition: 'something', - maxBytesEncrypted: -1 + maxBytesEncrypted: -1, } as any expect(() => decorateProperties(test, input)).to.throw() }) @@ -93,7 +93,7 @@ describe('decorateProperties', () => { backingMaterialsManager: 'backingMaterialsManager' as any, maxAge: 10, partition: 'something', - maxMessagesEncrypted: -1 + maxMessagesEncrypted: -1, } as any expect(() => decorateProperties(test, input)).to.throw() }) @@ -103,7 +103,7 @@ describe('decorateProperties', () => { const input = { cache: 'cache' as any, backingMaterialsManager: 'backingMaterialsManager' as any, - maxAge: 10 + maxAge: 10, } as any expect(() => decorateProperties(test, input)).to.throw() }) @@ -120,7 +120,7 @@ describe('cacheEntryHasExceededLimits', () => { maxAge, partition: 'something', maxBytesEncrypted, - maxMessagesEncrypted + maxMessagesEncrypted, } as any) test.cacheEntryHasExceededLimits = cacheEntryHasExceededLimits() @@ -129,7 +129,7 @@ describe('cacheEntryHasExceededLimits', () => { const entry = { now: Date.now(), messagesEncrypted: 0, - bytesEncrypted: 0 + bytesEncrypted: 0, } as any expect(test.cacheEntryHasExceededLimits(entry)).to.equal(false) @@ -140,7 +140,7 @@ describe('cacheEntryHasExceededLimits', () => { // Time is in the past, so I have to subtract. now: Date.now() - maxAge, messagesEncrypted: maxBytesEncrypted, - bytesEncrypted: maxMessagesEncrypted + bytesEncrypted: maxMessagesEncrypted, } as any expect(test.cacheEntryHasExceededLimits(entry)).to.equal(false) @@ -151,7 +151,7 @@ describe('cacheEntryHasExceededLimits', () => { // Time is in the past, so I have to subtract. now: Date.now() - (maxAge + 1), messagesEncrypted: maxBytesEncrypted - 1, - bytesEncrypted: maxMessagesEncrypted - 1 + bytesEncrypted: maxMessagesEncrypted - 1, } as any expect(test.cacheEntryHasExceededLimits(entry)).to.equal(true) @@ -162,7 +162,7 @@ describe('cacheEntryHasExceededLimits', () => { // Time is in the past, so I have to subtract. now: Date.now() - maxAge, messagesEncrypted: maxBytesEncrypted + 1, - bytesEncrypted: maxMessagesEncrypted + bytesEncrypted: maxMessagesEncrypted, } as any expect(test.cacheEntryHasExceededLimits(entry)).to.equal(true) @@ -173,7 +173,7 @@ describe('cacheEntryHasExceededLimits', () => { // Time is in the past, so I have to subtract. now: Date.now() - maxAge, messagesEncrypted: maxBytesEncrypted, - bytesEncrypted: maxMessagesEncrypted + 1 + bytesEncrypted: maxMessagesEncrypted + 1, } as any expect(test.cacheEntryHasExceededLimits(entry)).to.equal(true) @@ -184,28 +184,55 @@ describe('Cryptographic Material Functions', () => { const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 const nodeSuite = new NodeAlgorithmSuite(suiteId) - const udk128 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + const udk128 = new Uint8Array([ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + ]) const encryptTrace = { keyNamespace: 'keyNamespace', keyName: 'keyName', - flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, } const decryptTrace = { keyNamespace: 'keyNamespace', keyName: 'keyName', - flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, } - const edk1 = new EncryptedDataKey({ providerId: 'keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array([1]) }) - const edk2 = new EncryptedDataKey({ providerId: 'p2', providerInfo: 'pi2', encryptedDataKey: new Uint8Array([2]) }) + const edk1 = new EncryptedDataKey({ + providerId: 'keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array([1]), + }) + const edk2 = new EncryptedDataKey({ + providerId: 'p2', + providerInfo: 'pi2', + encryptedDataKey: new Uint8Array([2]), + }) const encryptionMaterial = new NodeEncryptionMaterial(nodeSuite, {}) .setUnencryptedDataKey(udk128, encryptTrace) .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - const decryptionMaterial = new NodeDecryptionMaterial(nodeSuite, {}) - .setUnencryptedDataKey(udk128, decryptTrace) + const decryptionMaterial = new NodeDecryptionMaterial( + nodeSuite, + {} + ).setUnencryptedDataKey(udk128, decryptTrace) const context = {} @@ -214,22 +241,29 @@ describe('Cryptographic Material Functions', () => { const _maxMessagesEncrypted = 10 const _cache = getLocalCryptographicMaterialsCache(100) const _backingMaterialsManager = { - getEncryptionMaterials () { + getEncryptionMaterials() { return encryptionMaterial }, - decryptMaterials () { + decryptMaterials() { return decryptionMaterial - } + }, } as any const _partition = 'partition' const fromUtf8 = (input: string) => Buffer.from(input, 'utf8') const toUtf8 = (input: Uint8Array) => Buffer.from(input).toString('utf8') - const sha512 = async (...data: (Uint8Array|string)[]) => data - .map(item => typeof item === 'string' ? Buffer.from(item, 'hex') : item) - .reduce((hash, item) => hash.update(item), createHash('sha512')) - .digest() - const cacheKeyHelpers = buildCryptographicMaterialsCacheKeyHelpers(fromUtf8, toUtf8, sha512) + const sha512 = async (...data: (Uint8Array | string)[]) => + data + .map((item) => + typeof item === 'string' ? Buffer.from(item, 'hex') : item + ) + .reduce((hash, item) => hash.update(item), createHash('sha512')) + .digest() + const cacheKeyHelpers = buildCryptographicMaterialsCacheKeyHelpers( + fromUtf8, + toUtf8, + sha512 + ) const testCMM = { _partition, @@ -240,7 +274,7 @@ describe('Cryptographic Material Functions', () => { _backingMaterialsManager, _cacheEntryHasExceededLimits: cacheEntryHasExceededLimits(), getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), - decryptMaterials: decryptMaterials(cacheKeyHelpers) + decryptMaterials: decryptMaterials(cacheKeyHelpers), } as any describe('getEncryptionMaterials', () => { @@ -249,12 +283,16 @@ describe('Cryptographic Material Functions', () => { suite: nodeSuite, encryptionContext: context, frameLength: 10, - plaintextLength: 10 + plaintextLength: 10, }) // The response must be cloned... i.e. not the same. expect(test === encryptionMaterial).to.equal(false) - expect(test.encryptionContext).to.deep.equal(encryptionMaterial.encryptionContext) - expect(test.getUnencryptedDataKey()).to.deep.equal(encryptionMaterial.getUnencryptedDataKey()) + expect(test.encryptionContext).to.deep.equal( + encryptionMaterial.encryptionContext + ) + expect(test.getUnencryptedDataKey()).to.deep.equal( + encryptionMaterial.getUnencryptedDataKey() + ) }) it('Check for early return (Postcondition): If I can not cache the EncryptionMaterial, do not even look.', async () => { @@ -264,21 +302,23 @@ describe('Cryptographic Material Functions', () => { _maxBytesEncrypted, _maxMessagesEncrypted, _cache: { - getEncryptionMaterial () { + getEncryptionMaterial() { throw new Error('should not happen') - } + }, }, _backingMaterialsManager, _cacheEntryHasExceededLimits: cacheEntryHasExceededLimits(), getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), - decryptMaterials: decryptMaterials(cacheKeyHelpers) + decryptMaterials: decryptMaterials(cacheKeyHelpers), } as any const testSuiteCacheSafe = await testCMM.getEncryptionMaterials({ - suite: new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16), + suite: new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ), encryptionContext: context, frameLength: 10, - plaintextLength: 10 + plaintextLength: 10, }) // The response was not cloned... because it did not come from the cache expect(testSuiteCacheSafe === encryptionMaterial).to.equal(true) @@ -286,7 +326,7 @@ describe('Cryptographic Material Functions', () => { const testPlaintext = await testCMM.getEncryptionMaterials({ suite: nodeSuite, encryptionContext: context, - frameLength: 10 + frameLength: 10, }) // The response was not cloned... because it did not come from the cache expect(testPlaintext === encryptionMaterial).to.equal(true) @@ -300,12 +340,12 @@ describe('Cryptographic Material Functions', () => { _maxBytesEncrypted, _maxMessagesEncrypted, _cache: { - getEncryptionMaterial () { + getEncryptionMaterial() { assertCount += 1 return { - response: encryptionMaterial + response: encryptionMaterial, } - } + }, }, _backingMaterialsManager, _cacheEntryHasExceededLimits: () => { @@ -315,14 +355,14 @@ describe('Cryptographic Material Functions', () => { getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), decryptMaterials: () => { throw new Error('this should never happen') - } + }, } as any await testCMM.getEncryptionMaterials({ suite: nodeSuite, encryptionContext: context, frameLength: 10, - plaintextLength: 10 + plaintextLength: 10, }) expect(assertCount).to.equal(2) @@ -334,20 +374,51 @@ describe('Cryptographic Material Functions', () => { const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 const nodeSuite = new NodeAlgorithmSuite(suiteId) - const udk128 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + const udk128 = new Uint8Array([ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + ]) const encryptTrace = { keyNamespace: 'keyNamespace', keyName: 'keyName', - flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, } - const edk1 = new EncryptedDataKey({ providerId: 'keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array([1]) }) - const edk2 = new EncryptedDataKey({ providerId: 'p2', providerInfo: 'pi2', encryptedDataKey: new Uint8Array([2]) }) + const edk1 = new EncryptedDataKey({ + providerId: 'keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array([1]), + }) + const edk2 = new EncryptedDataKey({ + providerId: 'p2', + providerInfo: 'pi2', + encryptedDataKey: new Uint8Array([2]), + }) const encryptionMaterial = new NodeEncryptionMaterial(nodeSuite, {}) .setUnencryptedDataKey(udk128, encryptTrace) - .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + .addEncryptedDataKey( + edk2, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) const testCMM = { _partition, @@ -355,16 +426,16 @@ describe('Cryptographic Material Functions', () => { _maxBytesEncrypted, _maxMessagesEncrypted, _cache: { - getEncryptionMaterial () { + getEncryptionMaterial() { throw new Error('this should never happen') }, - del () {} + del() {}, }, _backingMaterialsManager: { - getEncryptionMaterials () { + getEncryptionMaterials() { assertCount += 1 return encryptionMaterial - } + }, }, _cacheEntryHasExceededLimits: () => { throw new Error('this should never happen') @@ -372,14 +443,14 @@ describe('Cryptographic Material Functions', () => { getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), decryptMaterials: () => { throw new Error('this should never happen') - } + }, } as any const test = await testCMM.getEncryptionMaterials({ suite: nodeSuite, encryptionContext: context, frameLength: 10, - plaintextLength: 10 + plaintextLength: 10, }) expect(assertCount).to.equal(1) @@ -389,23 +460,55 @@ describe('Cryptographic Material Functions', () => { it('Postcondition: If the material has exceeded limits it MUST NOT be cloned.', async () => { let assertCount = 0 - const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + const suiteId = + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 const nodeSuite = new NodeAlgorithmSuite(suiteId) - const udk128 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + const udk128 = new Uint8Array([ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + ]) const encryptTrace = { keyNamespace: 'keyNamespace', keyName: 'keyName', - flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, } - const edk1 = new EncryptedDataKey({ providerId: 'keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array([1]) }) - const edk2 = new EncryptedDataKey({ providerId: 'p2', providerInfo: 'pi2', encryptedDataKey: new Uint8Array([2]) }) + const edk1 = new EncryptedDataKey({ + providerId: 'keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array([1]), + }) + const edk2 = new EncryptedDataKey({ + providerId: 'p2', + providerInfo: 'pi2', + encryptedDataKey: new Uint8Array([2]), + }) const encryptionMaterial = new NodeEncryptionMaterial(nodeSuite, {}) .setUnencryptedDataKey(udk128, encryptTrace) - .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + .addEncryptedDataKey( + edk2, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) const testCMM = { _partition, @@ -413,17 +516,17 @@ describe('Cryptographic Material Functions', () => { _maxBytesEncrypted, _maxMessagesEncrypted, _cache: { - getEncryptionMaterial () { + getEncryptionMaterial() { assertCount += 1 return false }, - del () {} + del() {}, }, _backingMaterialsManager: { - getEncryptionMaterials () { + getEncryptionMaterials() { assertCount += 1 return encryptionMaterial - } + }, }, _cacheEntryHasExceededLimits: () => { // This is the test. @@ -435,14 +538,14 @@ describe('Cryptographic Material Functions', () => { getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), decryptMaterials: () => { throw new Error('this should never happen') - } + }, } as any const test = await testCMM.getEncryptionMaterials({ suite: nodeSuite, encryptionContext: context, frameLength: 10, - plaintextLength: 10 + plaintextLength: 10, }) expect(assertCount).to.equal(3) @@ -455,12 +558,16 @@ describe('Cryptographic Material Functions', () => { const test = await testCMM.decryptMaterials({ suite: nodeSuite, encryptionContext: context, - encryptedDataKeys: [edk1] + encryptedDataKeys: [edk1], }) // The response must be cloned... i.e. not the same. expect(test === decryptionMaterial).to.equal(false) - expect(test.encryptionContext).to.deep.equal(decryptionMaterial.encryptionContext) - expect(test.getUnencryptedDataKey()).to.deep.equal(decryptionMaterial.getUnencryptedDataKey()) + expect(test.encryptionContext).to.deep.equal( + decryptionMaterial.encryptionContext + ) + expect(test.getUnencryptedDataKey()).to.deep.equal( + decryptionMaterial.getUnencryptedDataKey() + ) }) it('Check for early return (Postcondition): If I can not cache the DecryptionMaterial, do not even look.', async () => { @@ -470,20 +577,22 @@ describe('Cryptographic Material Functions', () => { _maxBytesEncrypted, _maxMessagesEncrypted, _cache: { - getDecryptionMaterial () { + getDecryptionMaterial() { throw new Error('should not happen') - } + }, }, _backingMaterialsManager, _cacheEntryHasExceededLimits: cacheEntryHasExceededLimits(), getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), - decryptMaterials: decryptMaterials(cacheKeyHelpers) + decryptMaterials: decryptMaterials(cacheKeyHelpers), } as any const testSuiteCacheSafe = await testCMM.decryptMaterials({ - suite: new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16), + suite: new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ), encryptionContext: context, - encryptedDataKeys: [edk1] + encryptedDataKeys: [edk1], }) // The response was not cloned... because it did not come from the cache expect(testSuiteCacheSafe === decryptionMaterial).to.equal(true) @@ -497,12 +606,12 @@ describe('Cryptographic Material Functions', () => { _maxBytesEncrypted, _maxMessagesEncrypted, _cache: { - getDecryptionMaterial () { + getDecryptionMaterial() { assertCount += 1 return { - response: decryptionMaterial + response: decryptionMaterial, } - } + }, }, _backingMaterialsManager, _cacheEntryHasExceededLimits: () => { @@ -510,13 +619,13 @@ describe('Cryptographic Material Functions', () => { return false }, getEncryptionMaterials: getEncryptionMaterials(cacheKeyHelpers), - decryptMaterials: decryptMaterials(cacheKeyHelpers) + decryptMaterials: decryptMaterials(cacheKeyHelpers), } as any await testCMM.decryptMaterials({ suite: nodeSuite, encryptionContext: context, - encryptedDataKeys: [edk1] + encryptedDataKeys: [edk1], }) expect(assertCount).to.equal(2) }) diff --git a/modules/cache-material/test/fixtures.ts b/modules/cache-material/test/fixtures.ts index 2d20a99c5..08e578960 100644 --- a/modules/cache-material/test/fixtures.ts +++ b/modules/cache-material/test/fixtures.ts @@ -3,19 +3,152 @@ /* eslint-env mocha */ -import { EncryptedDataKey, AlgorithmSuiteIdentifier } from '@aws-crypto/material-management' +import { + EncryptedDataKey, + AlgorithmSuiteIdentifier, +} from '@aws-crypto/material-management' const partitionName = 'c15b9079-6d0e-42b6-8784-5e804b025692' const encryptionContextEmpty = { name: 'encryptionContextEmpty', encryptionContext: {}, - hash: new Uint8Array([ 207, 131, 225, 53, 126, 239, 184, 189, 241, 84, 40, 80, 214, 109, 128, 7, 214, 32, 228, 5, 11, 87, 21, 220, 131, 244, 169, 33, 211, 108, 233, 206, 71, 208, 209, 60, 93, 133, 242, 176, 255, 131, 24, 210, 135, 126, 236, 47, 99, 185, 49, 189, 71, 65, 122, 129, 165, 56, 50, 122, 249, 39, 218, 62 ]) + hash: new Uint8Array([ + 207, + 131, + 225, + 53, + 126, + 239, + 184, + 189, + 241, + 84, + 40, + 80, + 214, + 109, + 128, + 7, + 214, + 32, + 228, + 5, + 11, + 87, + 21, + 220, + 131, + 244, + 169, + 33, + 211, + 108, + 233, + 206, + 71, + 208, + 209, + 60, + 93, + 133, + 242, + 176, + 255, + 131, + 24, + 210, + 135, + 126, + 236, + 47, + 99, + 185, + 49, + 189, + 71, + 65, + 122, + 129, + 165, + 56, + 50, + 122, + 249, + 39, + 218, + 62, + ]), } const encryptionContextFull = { name: 'encryptionContextFull', - encryptionContext: { 'this': 'is', 'a': 'non-empty', 'encryption': 'context' }, - hash: new Uint8Array([ 4, 250, 62, 217, 137, 103, 44, 245, 231, 15, 24, 164, 62, 35, 99, 8, 4, 29, 75, 147, 51, 243, 111, 68, 2, 126, 189, 113, 20, 150, 243, 92, 188, 56, 128, 79, 167, 9, 114, 93, 83, 189, 146, 168, 7, 189, 229, 174, 231, 68, 184, 217, 66, 18, 60, 223, 54, 127, 13, 7, 230, 79, 129, 73 ]) + encryptionContext: { this: 'is', a: 'non-empty', encryption: 'context' }, + hash: new Uint8Array([ + 4, + 250, + 62, + 217, + 137, + 103, + 44, + 245, + 231, + 15, + 24, + 164, + 62, + 35, + 99, + 8, + 4, + 29, + 75, + 147, + 51, + 243, + 111, + 68, + 2, + 126, + 189, + 113, + 20, + 150, + 243, + 92, + 188, + 56, + 128, + 79, + 167, + 9, + 114, + 93, + 83, + 189, + 146, + 168, + 7, + 189, + 229, + 174, + 231, + 68, + 184, + 217, + 66, + 18, + 60, + 223, + 54, + 127, + 13, + 7, + 230, + 79, + 129, + 73, + ]), } const encryptedDataKey1 = { @@ -23,9 +156,113 @@ const encryptedDataKey1 = { edk: new EncryptedDataKey({ providerId: 'this is a provider ID', providerInfo: 'this is some key info', - encryptedDataKey: new Uint8Array([ 115, 117, 112, 101, 114, 32, 115, 101, 99, 114, 101, 116, 32, 107, 101, 121, 44, 32, 110, 111, 119, 32, 119, 105, 116, 104, 32, 101, 110, 99, 114, 121, 112, 116, 105, 111, 110, 33 ]) + encryptedDataKey: new Uint8Array([ + 115, + 117, + 112, + 101, + 114, + 32, + 115, + 101, + 99, + 114, + 101, + 116, + 32, + 107, + 101, + 121, + 44, + 32, + 110, + 111, + 119, + 32, + 119, + 105, + 116, + 104, + 32, + 101, + 110, + 99, + 114, + 121, + 112, + 116, + 105, + 111, + 110, + 33, + ]), }), - hash: new Uint8Array([ 77, 138, 5, 121, 139, 177, 158, 207, 197, 6, 86, 176, 225, 219, 17, 12, 235, 246, 228, 224, 132, 42, 230, 70, 246, 37, 237, 230, 33, 29, 39, 194, 212, 238, 126, 96, 150, 9, 3, 1, 92, 86, 80, 70, 2, 224, 146, 138, 202, 66, 93, 30, 70, 149, 167, 23, 3, 188, 218, 146, 233, 75, 48, 137 ]) + hash: new Uint8Array([ + 77, + 138, + 5, + 121, + 139, + 177, + 158, + 207, + 197, + 6, + 86, + 176, + 225, + 219, + 17, + 12, + 235, + 246, + 228, + 224, + 132, + 42, + 230, + 70, + 246, + 37, + 237, + 230, + 33, + 29, + 39, + 194, + 212, + 238, + 126, + 96, + 150, + 9, + 3, + 1, + 92, + 86, + 80, + 70, + 2, + 224, + 146, + 138, + 202, + 66, + 93, + 30, + 70, + 149, + 167, + 23, + 3, + 188, + 218, + 146, + 233, + 75, + 48, + 137, + ]), } const encryptedDataKey2 = { @@ -33,56 +270,180 @@ const encryptedDataKey2 = { edk: new EncryptedDataKey({ providerId: 'another provider ID!', providerInfo: 'this is some different key info', - encryptedDataKey: new Uint8Array([ 98, 101, 116, 116, 101, 114, 32, 115, 117, 112, 101, 114, 32, 115, 101, 99, 114, 101, 116, 32, 107, 101, 121, 44, 32, 110, 111, 119, 32, 119, 105, 116, 104, 32, 101, 110, 99, 114, 121, 112, 116, 105, 111, 110, 33 ]) + encryptedDataKey: new Uint8Array([ + 98, + 101, + 116, + 116, + 101, + 114, + 32, + 115, + 117, + 112, + 101, + 114, + 32, + 115, + 101, + 99, + 114, + 101, + 116, + 32, + 107, + 101, + 121, + 44, + 32, + 110, + 111, + 119, + 32, + 119, + 105, + 116, + 104, + 32, + 101, + 110, + 99, + 114, + 121, + 112, + 116, + 105, + 111, + 110, + 33, + ]), }), - hash: new Uint8Array([ 193, 42, 195, 148, 243, 54, 161, 194, 35, 244, 192, 45, 15, 222, 20, 45, 36, 116, 66, 187, 117, 154, 224, 104, 188, 16, 209, 47, 224, 236, 73, 51, 105, 132, 145, 12, 220, 38, 127, 135, 115, 178, 189, 130, 252, 5, 29, 132, 33, 124, 116, 155, 177, 152, 194, 255, 29, 26, 220, 153, 47, 96, 252, 239 ]) + hash: new Uint8Array([ + 193, + 42, + 195, + 148, + 243, + 54, + 161, + 194, + 35, + 244, + 192, + 45, + 15, + 222, + 20, + 45, + 36, + 116, + 66, + 187, + 117, + 154, + 224, + 104, + 188, + 16, + 209, + 47, + 224, + 236, + 73, + 51, + 105, + 132, + 145, + 12, + 220, + 38, + 127, + 135, + 115, + 178, + 189, + 130, + 252, + 5, + 29, + 132, + 33, + 124, + 116, + 155, + 177, + 152, + 194, + 255, + 29, + 26, + 220, + 153, + 47, + 96, + 252, + 239, + ]), } -export const encryptionContextVectors = [encryptionContextEmpty, encryptionContextFull] +export const encryptionContextVectors = [ + encryptionContextEmpty, + encryptionContextFull, +] export const encryptedDataKeyVectors = [encryptedDataKey1, encryptedDataKey2] -type VectorHack = {arguments: [string, any], id: string} +type VectorHack = { arguments: [string, any]; id: string } export const encryptCacheKeyVectors: VectorHack[] = [ { arguments: [ partitionName, { suite: undefined, - encryptionContext: encryptionContextEmpty.encryptionContext - } + encryptionContext: encryptionContextEmpty.encryptionContext, + }, ], - id: 'rkrFAso1YyPbOJbmwVMjrPw+wwLJT7xusn8tA8zMe9e3+OqbtfDueB7bvoKLU3fsmdUvZ6eMt7mBp1ThMMB25Q==' + id: + 'rkrFAso1YyPbOJbmwVMjrPw+wwLJT7xusn8tA8zMe9e3+OqbtfDueB7bvoKLU3fsmdUvZ6eMt7mBp1ThMMB25Q==', }, { arguments: [ partitionName, { - suite: { id: AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 }, - encryptionContext: encryptionContextEmpty.encryptionContext - } + suite: { + id: + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + }, + encryptionContext: encryptionContextEmpty.encryptionContext, + }, ], - id: '3icBIkLK4V3fVwbm3zSxUdUQV6ZvZYUOLl8buN36g6gDMqAkghcGryxX7QiVABkW1JhB6GRp5z+bzbiuciBcKQ==' + id: + '3icBIkLK4V3fVwbm3zSxUdUQV6ZvZYUOLl8buN36g6gDMqAkghcGryxX7QiVABkW1JhB6GRp5z+bzbiuciBcKQ==', }, { arguments: [ partitionName, { suite: undefined, - encryptionContext: encryptionContextFull.encryptionContext - } + encryptionContext: encryptionContextFull.encryptionContext, + }, ], - id: 'IHiUHYOUVUEFTc3BcZPJDlsWct2Qy1A7JdfQl9sQoV/ILIbRpoz9q7RtGd/MlibaGl5ihE66cN8ygM8A5rtYbg==' + id: + 'IHiUHYOUVUEFTc3BcZPJDlsWct2Qy1A7JdfQl9sQoV/ILIbRpoz9q7RtGd/MlibaGl5ihE66cN8ygM8A5rtYbg==', }, { arguments: [ partitionName, { - suite: { id: AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 }, - encryptionContext: encryptionContextFull.encryptionContext - } + suite: { + id: + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + }, + encryptionContext: encryptionContextFull.encryptionContext, + }, ], - id: 'mRNK7qhTb/kJiiyGPgAevp0gwFRcET4KeeNYwZHhoEDvSUzQiDgl8Of+YRDaVzKxAqpNBgcAuFXde9JlaRRsmw==' - } + id: + 'mRNK7qhTb/kJiiyGPgAevp0gwFRcET4KeeNYwZHhoEDvSUzQiDgl8Of+YRDaVzKxAqpNBgcAuFXde9JlaRRsmw==', + }, ] export const decryptCacheKeyVectors: VectorHack[] = [ @@ -90,22 +451,29 @@ export const decryptCacheKeyVectors: VectorHack[] = [ arguments: [ partitionName, { - suite: { id: AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 }, + suite: { + id: AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256, + }, encryptedDataKeys: [encryptedDataKey1.edk], - encryptionContext: encryptionContextEmpty.encryptionContext - } + encryptionContext: encryptionContextEmpty.encryptionContext, + }, ], - id: 'n0zVzk9QIVxhz6ET+aJIKKOJNxtpGtSe1yAbu7WU5l272Iw/jmhlER4psDHJs9Mr8KYiIvLGSXzggNDCc23+9w==' + id: + 'n0zVzk9QIVxhz6ET+aJIKKOJNxtpGtSe1yAbu7WU5l272Iw/jmhlER4psDHJs9Mr8KYiIvLGSXzggNDCc23+9w==', }, { arguments: [ partitionName, { - suite: { id: AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 }, + suite: { + id: + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + }, encryptedDataKeys: [encryptedDataKey1.edk, encryptedDataKey2.edk], - encryptionContext: encryptionContextFull.encryptionContext - } + encryptionContext: encryptionContextFull.encryptionContext, + }, ], - id: '+rtwUe38CGnczGmYu12iqGWHIyDyZ44EvYQ4S6ACmsgS8VaEpiw0RTGpDk6Z/7YYN/jVHOAcNKDyCNP8EmstFg==' - } + id: + '+rtwUe38CGnczGmYu12iqGWHIyDyZ44EvYQ4S6ACmsgS8VaEpiw0RTGpDk6Z/7YYN/jVHOAcNKDyCNP8EmstFg==', + }, ] diff --git a/modules/cache-material/test/get_local_cryptographic_materials_cache.test.ts b/modules/cache-material/test/get_local_cryptographic_materials_cache.test.ts index fc9a92623..2f5b39026 100644 --- a/modules/cache-material/test/get_local_cryptographic_materials_cache.test.ts +++ b/modules/cache-material/test/get_local_cryptographic_materials_cache.test.ts @@ -9,10 +9,12 @@ import { NodeAlgorithmSuite, NodeEncryptionMaterial, NodeDecryptionMaterial, - AlgorithmSuiteIdentifier + AlgorithmSuiteIdentifier, } from '@aws-crypto/material-management' -const nodeSuite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) +const nodeSuite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 +) const encryptionMaterial = new NodeEncryptionMaterial(nodeSuite, {}) const decryptionMaterial = new NodeDecryptionMaterial(nodeSuite, {}) @@ -22,7 +24,7 @@ describe('getLocalCryptographicMaterialsCache', () => { getDecryptionMaterial, del, putEncryptionMaterial, - putDecryptionMaterial + putDecryptionMaterial, } = getLocalCryptographicMaterialsCache(100) it('putEncryptionMaterial', () => { @@ -58,7 +60,9 @@ describe('getLocalCryptographicMaterialsCache', () => { it('Precondition: Only cache EncryptionMaterial that is cacheSafe.', () => { const key = 'some encryption key' - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const response: any = new NodeEncryptionMaterial(suite, {}) expect(() => putEncryptionMaterial(key, response, 1)).to.throw() @@ -86,7 +90,9 @@ describe('getLocalCryptographicMaterialsCache', () => { it('Precondition: Only cache DecryptionMaterial that is cacheSafe.', () => { const key = 'some decryption key' - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const response: any = new NodeEncryptionMaterial(suite, {}) expect(() => putDecryptionMaterial(key, response)).to.throw() @@ -148,7 +154,7 @@ describe('cache eviction', () => { it('putDecryptionMaterial can exceed capacity', () => { const { getDecryptionMaterial, - putDecryptionMaterial + putDecryptionMaterial, } = getLocalCryptographicMaterialsCache(1) const key1 = 'key lost' @@ -167,7 +173,7 @@ describe('cache eviction', () => { const { getDecryptionMaterial, putDecryptionMaterial, - del + del, } = getLocalCryptographicMaterialsCache(1) const key = 'key deleted' @@ -182,14 +188,14 @@ describe('cache eviction', () => { it('putDecryptionMaterial can be garbage collected', async () => { const { getDecryptionMaterial, - putDecryptionMaterial + putDecryptionMaterial, } = getLocalCryptographicMaterialsCache(1, 10) const key = 'key lost' const response: any = decryptionMaterial putDecryptionMaterial(key, response, 1) - await new Promise(resolve => setTimeout(resolve, 20)) + await new Promise((resolve) => setTimeout(resolve, 20)) const lost = getDecryptionMaterial(key) expect(lost).to.equal(false) }) @@ -197,7 +203,7 @@ describe('cache eviction', () => { it('putEncryptionMaterial can exceed capacity', () => { const { getEncryptionMaterial, - putEncryptionMaterial + putEncryptionMaterial, } = getLocalCryptographicMaterialsCache(1) const key1 = 'key lost' @@ -216,7 +222,7 @@ describe('cache eviction', () => { const { getEncryptionMaterial, putEncryptionMaterial, - del + del, } = getLocalCryptographicMaterialsCache(1, 10) const key = 'key lost' @@ -231,14 +237,14 @@ describe('cache eviction', () => { it('putEncryptionMaterial can be garbage collected', async () => { const { getEncryptionMaterial, - putEncryptionMaterial + putEncryptionMaterial, } = getLocalCryptographicMaterialsCache(1, 10) const key = 'key lost' const response: any = encryptionMaterial putEncryptionMaterial(key, response, 1, 1) - await new Promise(resolve => setTimeout(resolve, 20)) + await new Promise((resolve) => setTimeout(resolve, 20)) const lost = getEncryptionMaterial(key, 1) expect(lost).to.equal(false) }) diff --git a/modules/caching-materials-manager-browser/test/caching_materials_manager_browser.test.ts b/modules/caching-materials-manager-browser/test/caching_materials_manager_browser.test.ts index b65d21d0b..6072609c5 100644 --- a/modules/caching-materials-manager-browser/test/caching_materials_manager_browser.test.ts +++ b/modules/caching-materials-manager-browser/test/caching_materials_manager_browser.test.ts @@ -6,21 +6,21 @@ import { expect } from 'chai' // import 'mocha' import { WebCryptoCachingMaterialsManager } from '../src/index' -import { } from '@aws-crypto/cache-material' +import {} from '@aws-crypto/cache-material' import { KeyringWebCrypto, WebCryptoDefaultCryptographicMaterialsManager, - WebCryptoEncryptionMaterial, // eslint-disable-line no-unused-vars - WebCryptoDecryptionMaterial // eslint-disable-line no-unused-vars + WebCryptoEncryptionMaterial, + WebCryptoDecryptionMaterial, } from '@aws-crypto/material-management-browser' describe('WebCryptoCachingMaterialsManager', () => { it('constructor will decorate', () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } @@ -37,10 +37,12 @@ describe('WebCryptoCachingMaterialsManager', () => { partition, maxAge, maxBytesEncrypted, - maxMessagesEncrypted + maxMessagesEncrypted, }) - expect(test._backingMaterialsManager).to.be.instanceOf(WebCryptoDefaultCryptographicMaterialsManager) + expect(test._backingMaterialsManager).to.be.instanceOf( + WebCryptoDefaultCryptographicMaterialsManager + ) expect(test._cache).to.equal(cache) expect(test._partition).to.equal(partition) expect(test._maxAge).to.equal(maxAge) @@ -50,10 +52,10 @@ describe('WebCryptoCachingMaterialsManager', () => { it('Precondition: A partition value must exist for WebCryptoCachingMaterialsManager.', () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } @@ -64,7 +66,7 @@ describe('WebCryptoCachingMaterialsManager', () => { const test = new WebCryptoCachingMaterialsManager({ backingMaterials: keyring, cache, - maxAge + maxAge, }) /* 64 Bytes of data encoded as base64 will be 88 characters long. */ diff --git a/modules/caching-materials-manager-browser/test/sha512.test.ts b/modules/caching-materials-manager-browser/test/sha512.test.ts index 75037236d..3994cabb4 100644 --- a/modules/caching-materials-manager-browser/test/sha512.test.ts +++ b/modules/caching-materials-manager-browser/test/sha512.test.ts @@ -7,7 +7,72 @@ import { expect } from 'chai' import { sha512 } from '../src/sha512' // sha512('asdf') -const fixture = new Uint8Array([64, 27, 9, 234, 179, 192, 19, 212, 202, 84, 146, 43, 184, 2, 190, 200, 253, 83, 24, 25, 43, 10, 117, 242, 1, 216, 179, 114, 116, 41, 8, 15, 179, 55, 89, 26, 189, 62, 68, 69, 59, 149, 69, 85, 183, 160, 129, 46, 16, 129, 195, 155, 116, 2, 147, 247, 101, 234, 231, 49, 245, 166, 94, 209]) +const fixture = new Uint8Array([ + 64, + 27, + 9, + 234, + 179, + 192, + 19, + 212, + 202, + 84, + 146, + 43, + 184, + 2, + 190, + 200, + 253, + 83, + 24, + 25, + 43, + 10, + 117, + 242, + 1, + 216, + 179, + 114, + 116, + 41, + 8, + 15, + 179, + 55, + 89, + 26, + 189, + 62, + 68, + 69, + 59, + 149, + 69, + 85, + 183, + 160, + 129, + 46, + 16, + 129, + 195, + 155, + 116, + 2, + 147, + 247, + 101, + 234, + 231, + 49, + 245, + 166, + 94, + 209, +]) describe('WebCryptoCachingMaterialsManager', () => { it('can hash a string', async () => { @@ -17,13 +82,18 @@ describe('WebCryptoCachingMaterialsManager', () => { it('can hash a Uint8Array', async () => { // the string 'asdf' as utf-8 encoded bytes - const test = await sha512(new Uint8Array([ 97, 115, 100, 102 ])) + const test = await sha512(new Uint8Array([97, 115, 100, 102])) expect(test).to.deep.equal(fixture) }) it('can hash a mix of arguments', async () => { // the string 'asdf' as a mix of strings and binary - const test = await sha512('a', new Uint8Array([115]), 'd', new Uint8Array([102])) + const test = await sha512( + 'a', + new Uint8Array([115]), + 'd', + new Uint8Array([102]) + ) expect(test).to.deep.equal(fixture) }) }) diff --git a/modules/caching-materials-manager-node/test/caching_materials_manager_node.test.ts b/modules/caching-materials-manager-node/test/caching_materials_manager_node.test.ts index 62bffdfb1..15a43f842 100644 --- a/modules/caching-materials-manager-node/test/caching_materials_manager_node.test.ts +++ b/modules/caching-materials-manager-node/test/caching_materials_manager_node.test.ts @@ -5,21 +5,21 @@ import { expect } from 'chai' import { NodeCachingMaterialsManager } from '../src/index' -import { } from '@aws-crypto/cache-material' +import {} from '@aws-crypto/cache-material' import { KeyringNode, NodeDefaultCryptographicMaterialsManager, - NodeEncryptionMaterial, // eslint-disable-line no-unused-vars - NodeDecryptionMaterial // eslint-disable-line no-unused-vars + NodeEncryptionMaterial, + NodeDecryptionMaterial, } from '@aws-crypto/material-management-node' describe('NodeCachingMaterialsManager', () => { it('constructor will decorate', () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } @@ -36,10 +36,12 @@ describe('NodeCachingMaterialsManager', () => { partition, maxAge, maxBytesEncrypted, - maxMessagesEncrypted + maxMessagesEncrypted, }) - expect(test._backingMaterialsManager).to.be.instanceOf(NodeDefaultCryptographicMaterialsManager) + expect(test._backingMaterialsManager).to.be.instanceOf( + NodeDefaultCryptographicMaterialsManager + ) expect(test._cache).to.equal(cache) expect(test._partition).to.equal(partition) expect(test._maxAge).to.equal(maxAge) @@ -49,10 +51,10 @@ describe('NodeCachingMaterialsManager', () => { it('Precondition: A partition value must exist for NodeCachingMaterialsManager.', () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } @@ -63,7 +65,7 @@ describe('NodeCachingMaterialsManager', () => { const test = new NodeCachingMaterialsManager({ backingMaterials: keyring, cache, - maxAge + maxAge, }) /* Binary data is being transformed to base64. * 64 bits of base64 encoded data is 88 characters. diff --git a/modules/caching-materials-manager-node/test/sha512.test.ts b/modules/caching-materials-manager-node/test/sha512.test.ts index bb463dec6..9373c921f 100644 --- a/modules/caching-materials-manager-node/test/sha512.test.ts +++ b/modules/caching-materials-manager-node/test/sha512.test.ts @@ -7,7 +7,10 @@ import { expect } from 'chai' import { sha512 } from '../src/sha512' // sha512('asdf') -const fixture = Buffer.from('QBsJ6rPAE9TKVJIruAK+yP1TGBkrCnXyAdizcnQpCA+zN1kavT5ERTuVRVW3oIEuEIHDm3QCk/dl6ucx9aZe0Q==', 'base64') +const fixture = Buffer.from( + 'QBsJ6rPAE9TKVJIruAK+yP1TGBkrCnXyAdizcnQpCA+zN1kavT5ERTuVRVW3oIEuEIHDm3QCk/dl6ucx9aZe0Q==', + 'base64' +) describe('WebCryptoCachingMaterialsManager', () => { it('can hash a string', async () => { @@ -17,13 +20,18 @@ describe('WebCryptoCachingMaterialsManager', () => { it('can hash a Uint8Array', async () => { // the string 'asdf' as utf-8 encoded bytes - const test = await sha512(Buffer.from([ 97, 115, 100, 102 ])) + const test = await sha512(Buffer.from([97, 115, 100, 102])) expect(test).to.deep.equal(fixture) }) it('can hash a mix of arguments', async () => { // the string 'asdf' as a mix of strings and binary - const test = await sha512('a', new Uint8Array([115]), 'd', Buffer.from([102])) + const test = await sha512( + 'a', + new Uint8Array([115]), + 'd', + Buffer.from([102]) + ) expect(test).to.deep.equal(fixture) }) }) diff --git a/modules/decrypt-browser/test/decrypt.test.ts b/modules/decrypt-browser/test/decrypt.test.ts index 7640f9900..241b28837 100644 --- a/modules/decrypt-browser/test/decrypt.test.ts +++ b/modules/decrypt-browser/test/decrypt.test.ts @@ -15,8 +15,12 @@ describe('decrypt', () => { fixtures.ciphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384() ) - expect(messageHeader.suiteId).to.equal(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - expect(messageHeader.encryptionContext).to.deep.equal(fixtures.encryptionContext()) + expect(messageHeader.suiteId).to.equal( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + expect(messageHeader.encryptionContext).to.deep.equal( + fixtures.encryptionContext() + ) expect(test).to.deep.equal(fixtures.plaintext()) }) @@ -24,22 +28,28 @@ describe('decrypt', () => { return decrypt( fixtures.decryptKeyring(), fixtures.frameSequenceOutOfOrder() - ).then(() => { - throw new Error('should not succeed') - }, err => { - expect(err).to.be.instanceOf(Error) - }) + ).then( + () => { + throw new Error('should not succeed') + }, + (err) => { + expect(err).to.be.instanceOf(Error) + } + ) }) it('Postcondition: subtleVerify must validate the signature.', async () => { return decrypt( fixtures.decryptKeyring(), fixtures.invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384() - ).then(() => { - throw new Error('should not succeed') - }, err => { - expect(err).to.be.instanceOf(Error) - expect(err.message).to.equal('Invalid Signature') - }) + ).then( + () => { + throw new Error('should not succeed') + }, + (err) => { + expect(err).to.be.instanceOf(Error) + expect(err.message).to.equal('Invalid Signature') + } + ) }) }) diff --git a/modules/decrypt-browser/test/fixtures.ts b/modules/decrypt-browser/test/fixtures.ts index c633fe858..f744233e8 100644 --- a/modules/decrypt-browser/test/fixtures.ts +++ b/modules/decrypt-browser/test/fixtures.ts @@ -4,58 +4,5671 @@ /* eslint-env mocha */ import { - WebCryptoDecryptionMaterial, // eslint-disable-line no-unused-vars - WebCryptoEncryptionMaterial, // eslint-disable-line no-unused-vars + WebCryptoDecryptionMaterial, + WebCryptoEncryptionMaterial, KeyringWebCrypto, KeyringTraceFlag, - importForWebCryptoDecryptionMaterial + importForWebCryptoDecryptionMaterial, } from '@aws-crypto/material-management-browser' -export function ciphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 () { - return new Uint8Array([1, 128, 3, 120, 152, 39, 185, 111, 47, 165, 9, 162, 229, 10, 42, 28, 134, 86, 134, 57, 0, 112, 0, 2, 0, 21, 97, 119, 115, 45, 99, 114, 121, 112, 116, 111, 45, 112, 117, 98, 108, 105, 99, 45, 107, 101, 121, 0, 68, 65, 110, 89, 116, 70, 69, 101, 119, 90, 109, 43, 50, 56, 75, 104, 73, 71, 112, 120, 56, 82, 104, 107, 97, 85, 97, 76, 99, 99, 74, 112, 121, 102, 49, 110, 119, 73, 86, 81, 70, 71, 109, 121, 112, 103, 122, 104, 72, 50, 88, 100, 83, 73, 66, 74, 52, 115, 75, 105, 83, 72, 51, 99, 107, 122, 119, 61, 61, 0, 6, 115, 105, 109, 112, 108, 101, 0, 7, 99, 111, 110, 116, 101, 120, 116, 0, 1, 0, 1, 107, 0, 1, 107, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 145, 102, 170, 98, 142, 150, 6, 52, 206, 143, 212, 191, 251, 240, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 34, 13, 100, 212, 135, 138, 87, 224, 143, 81, 80, 103, 165, 73, 32, 201, 85, 20, 102, 94, 240, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 57, 122, 63, 111, 60, 86, 216, 227, 41, 135, 153, 3, 185, 146, 121, 226, 96, 140, 133, 7, 108, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 187, 57, 143, 182, 231, 34, 100, 85, 193, 111, 48, 197, 231, 237, 92, 237, 200, 232, 110, 33, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 27, 168, 206, 28, 12, 247, 55, 12, 177, 129, 72, 230, 229, 113, 77, 48, 28, 126, 216, 32, 175, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 132, 109, 27, 21, 79, 80, 166, 225, 107, 189, 218, 203, 249, 24, 174, 153, 124, 14, 184, 164, 218, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 232, 179, 33, 243, 63, 125, 105, 244, 71, 78, 127, 127, 157, 73, 174, 96, 25, 244, 86, 245, 237, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 178, 233, 102, 5, 30, 5, 64, 198, 211, 147, 237, 52, 143, 145, 90, 254, 48, 251, 223, 245, 9, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 194, 160, 61, 149, 147, 116, 50, 179, 116, 248, 87, 64, 55, 167, 34, 116, 145, 91, 247, 142, 46, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 29, 125, 44, 141, 164, 22, 36, 245, 118, 197, 133, 254, 131, 82, 122, 246, 105, 204, 57, 148, 46, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 156, 154, 104, 126, 189, 84, 195, 3, 242, 255, 230, 170, 190, 35, 19, 172, 117, 224, 58, 19, 60, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 217, 111, 181, 109, 101, 204, 15, 81, 25, 72, 231, 32, 102, 157, 148, 72, 75, 197, 16, 191, 20, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 170, 36, 22, 144, 17, 217, 164, 57, 69, 251, 184, 41, 34, 220, 104, 117, 237, 137, 80, 83, 115, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 16, 173, 250, 100, 79, 85, 46, 34, 35, 217, 126, 116, 55, 189, 212, 28, 69, 45, 155, 64, 91, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 73, 43, 213, 252, 75, 222, 162, 219, 108, 46, 206, 72, 49, 234, 14, 122, 193, 162, 115, 176, 197, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 42, 112, 209, 70, 250, 135, 212, 222, 195, 132, 101, 223, 14, 92, 31, 235, 147, 61, 47, 13, 175, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 220, 167, 108, 88, 159, 207, 242, 17, 124, 104, 232, 80, 117, 3, 247, 191, 82, 129, 14, 144, 121, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 108, 144, 25, 119, 159, 160, 107, 253, 100, 55, 215, 82, 47, 119, 171, 236, 20, 64, 99, 243, 87, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 47, 251, 249, 33, 143, 243, 250, 205, 188, 21, 108, 213, 163, 142, 175, 40, 216, 206, 17, 234, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 203, 91, 156, 248, 199, 16, 124, 194, 67, 240, 106, 192, 37, 70, 138, 151, 36, 219, 94, 1, 96, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 30, 146, 135, 99, 232, 226, 135, 173, 5, 76, 38, 212, 0, 79, 244, 95, 94, 213, 62, 244, 24, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 166, 218, 131, 160, 233, 168, 4, 234, 60, 230, 222, 32, 217, 213, 186, 204, 73, 49, 194, 56, 111, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 177, 210, 27, 126, 42, 249, 13, 169, 158, 221, 76, 100, 174, 46, 120, 55, 99, 251, 174, 169, 250, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 168, 143, 35, 86, 22, 225, 246, 115, 200, 191, 247, 231, 150, 71, 4, 226, 198, 221, 83, 223, 212, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 249, 42, 55, 121, 79, 8, 174, 233, 186, 91, 226, 143, 163, 106, 205, 11, 69, 18, 69, 31, 174, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 77, 254, 49, 137, 67, 173, 29, 230, 102, 139, 239, 52, 51, 115, 154, 203, 142, 118, 71, 250, 201, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 159, 132, 79, 66, 216, 196, 229, 248, 36, 66, 252, 128, 155, 157, 85, 83, 214, 234, 162, 47, 220, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 147, 173, 224, 79, 27, 2, 118, 109, 251, 113, 67, 162, 163, 193, 233, 31, 182, 30, 47, 90, 219, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 116, 186, 5, 86, 52, 126, 203, 30, 13, 86, 141, 65, 75, 27, 252, 46, 92, 154, 247, 65, 5, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 193, 106, 16, 130, 246, 194, 198, 10, 223, 162, 144, 31, 34, 106, 188, 148, 226, 23, 254, 167, 149, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 123, 65, 52, 255, 81, 84, 113, 6, 231, 49, 126, 20, 17, 97, 225, 20, 210, 101, 30, 23, 23, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 39, 34, 176, 33, 192, 20, 70, 243, 31, 55, 241, 157, 228, 199, 33, 202, 0, 54, 208, 70, 7, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 181, 209, 125, 8, 200, 187, 31, 19, 120, 64, 255, 77, 209, 199, 116, 187, 154, 80, 69, 150, 102, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, 213, 43, 31, 82, 140, 194, 92, 93, 38, 9, 63, 237, 28, 223, 51, 86, 244, 178, 88, 94, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 20, 251, 120, 227, 44, 81, 111, 10, 238, 3, 81, 121, 98, 70, 13, 162, 71, 131, 46, 103, 98, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 10, 157, 95, 206, 143, 35, 162, 25, 129, 59, 54, 72, 193, 232, 226, 210, 196, 196, 41, 100, 34, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 9, 24, 75, 131, 234, 128, 79, 5, 117, 60, 138, 234, 90, 104, 210, 69, 204, 65, 255, 204, 167, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 201, 8, 128, 251, 92, 81, 68, 64, 63, 169, 238, 67, 142, 236, 122, 89, 163, 196, 201, 76, 225, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 171, 25, 79, 109, 104, 214, 41, 29, 136, 185, 4, 196, 111, 120, 245, 107, 147, 119, 13, 102, 65, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 164, 10, 7, 8, 95, 108, 125, 255, 124, 241, 247, 205, 157, 13, 119, 202, 81, 4, 170, 1, 20, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 113, 35, 109, 246, 65, 23, 45, 65, 116, 51, 39, 90, 143, 131, 34, 6, 141, 86, 174, 97, 134, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 17, 219, 112, 146, 102, 164, 109, 250, 237, 28, 67, 34, 122, 165, 112, 23, 159, 147, 126, 17, 110, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 166, 13, 213, 152, 15, 244, 21, 15, 216, 172, 198, 144, 147, 155, 130, 132, 250, 62, 135, 41, 211, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 122, 230, 189, 241, 100, 207, 33, 97, 250, 117, 32, 29, 205, 246, 22, 60, 207, 106, 246, 26, 6, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 15, 131, 64, 121, 47, 163, 18, 170, 84, 253, 221, 153, 52, 40, 51, 94, 208, 71, 136, 115, 214, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 211, 10, 50, 65, 83, 72, 67, 128, 24, 130, 253, 176, 7, 101, 238, 83, 244, 42, 12, 125, 52, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 142, 66, 230, 141, 29, 134, 213, 171, 121, 31, 148, 7, 204, 168, 63, 7, 108, 205, 32, 127, 166, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 175, 180, 23, 150, 138, 210, 61, 241, 170, 248, 43, 178, 57, 164, 206, 222, 235, 101, 133, 16, 64, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 217, 50, 135, 140, 18, 81, 49, 56, 168, 19, 77, 173, 63, 128, 170, 129, 62, 36, 64, 168, 94, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 110, 77, 80, 143, 224, 170, 140, 47, 160, 174, 228, 250, 110, 88, 193, 177, 0, 249, 97, 48, 85, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 24, 208, 66, 49, 81, 228, 15, 74, 159, 154, 45, 254, 30, 39, 168, 170, 195, 77, 146, 108, 54, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 182, 72, 29, 209, 253, 26, 238, 146, 20, 49, 239, 248, 241, 154, 53, 162, 46, 73, 231, 158, 61, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 193, 124, 164, 17, 25, 250, 8, 66, 12, 132, 48, 174, 46, 21, 1, 153, 89, 250, 124, 43, 187, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 254, 204, 223, 255, 248, 36, 147, 203, 139, 233, 166, 144, 167, 156, 217, 10, 230, 186, 154, 221, 138, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 157, 1, 82, 216, 240, 244, 171, 31, 43, 72, 139, 78, 109, 130, 199, 180, 29, 220, 152, 86, 41, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 118, 62, 180, 234, 142, 50, 253, 134, 112, 238, 1, 135, 172, 62, 137, 172, 101, 144, 80, 181, 118, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 248, 25, 23, 244, 216, 85, 10, 32, 5, 245, 76, 71, 163, 248, 171, 150, 22, 157, 42, 51, 83, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 120, 215, 253, 150, 149, 111, 192, 171, 225, 21, 37, 33, 213, 31, 199, 168, 148, 200, 59, 178, 210, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 33, 215, 218, 101, 231, 100, 1, 25, 227, 155, 64, 152, 197, 8, 65, 219, 201, 99, 174, 40, 9, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 147, 209, 159, 187, 1, 87, 223, 93, 64, 154, 44, 158, 152, 252, 15, 46, 181, 109, 69, 191, 253, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 36, 153, 72, 151, 36, 144, 73, 224, 171, 192, 77, 113, 30, 99, 86, 246, 112, 229, 79, 12, 234, 255, 255, 255, 255, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 64, 100, 56, 207, 172, 88, 237, 127, 243, 73, 172, 162, 140, 43, 101, 189, 0, 104, 48, 102, 2, 49, 0, 222, 33, 224, 165, 39, 217, 81, 217, 135, 23, 127, 61, 9, 89, 74, 102, 176, 204, 189, 109, 198, 10, 59, 246, 251, 25, 141, 88, 85, 215, 156, 106, 200, 198, 75, 45, 202, 77, 184, 217, 138, 222, 19, 71, 3, 205, 239, 248, 2, 49, 0, 253, 18, 129, 175, 193, 214, 6, 110, 200, 105, 144, 43, 103, 18, 156, 55, 81, 32, 190, 155, 152, 12, 243, 121, 56, 140, 114, 52, 104, 39, 162, 171, 97, 22, 203, 194, 15, 38, 206, 103, 80, 46, 7, 111, 74, 131, 237, 22]) +export function ciphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384() { + return new Uint8Array([ + 1, + 128, + 3, + 120, + 152, + 39, + 185, + 111, + 47, + 165, + 9, + 162, + 229, + 10, + 42, + 28, + 134, + 86, + 134, + 57, + 0, + 112, + 0, + 2, + 0, + 21, + 97, + 119, + 115, + 45, + 99, + 114, + 121, + 112, + 116, + 111, + 45, + 112, + 117, + 98, + 108, + 105, + 99, + 45, + 107, + 101, + 121, + 0, + 68, + 65, + 110, + 89, + 116, + 70, + 69, + 101, + 119, + 90, + 109, + 43, + 50, + 56, + 75, + 104, + 73, + 71, + 112, + 120, + 56, + 82, + 104, + 107, + 97, + 85, + 97, + 76, + 99, + 99, + 74, + 112, + 121, + 102, + 49, + 110, + 119, + 73, + 86, + 81, + 70, + 71, + 109, + 121, + 112, + 103, + 122, + 104, + 72, + 50, + 88, + 100, + 83, + 73, + 66, + 74, + 52, + 115, + 75, + 105, + 83, + 72, + 51, + 99, + 107, + 122, + 119, + 61, + 61, + 0, + 6, + 115, + 105, + 109, + 112, + 108, + 101, + 0, + 7, + 99, + 111, + 110, + 116, + 101, + 120, + 116, + 0, + 1, + 0, + 1, + 107, + 0, + 1, + 107, + 0, + 3, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26, + 145, + 102, + 170, + 98, + 142, + 150, + 6, + 52, + 206, + 143, + 212, + 191, + 251, + 240, + 5, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 34, + 13, + 100, + 212, + 135, + 138, + 87, + 224, + 143, + 81, + 80, + 103, + 165, + 73, + 32, + 201, + 85, + 20, + 102, + 94, + 240, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 57, + 122, + 63, + 111, + 60, + 86, + 216, + 227, + 41, + 135, + 153, + 3, + 185, + 146, + 121, + 226, + 96, + 140, + 133, + 7, + 108, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 187, + 57, + 143, + 182, + 231, + 34, + 100, + 85, + 193, + 111, + 48, + 197, + 231, + 237, + 92, + 237, + 200, + 232, + 110, + 33, + 10, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 27, + 168, + 206, + 28, + 12, + 247, + 55, + 12, + 177, + 129, + 72, + 230, + 229, + 113, + 77, + 48, + 28, + 126, + 216, + 32, + 175, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 132, + 109, + 27, + 21, + 79, + 80, + 166, + 225, + 107, + 189, + 218, + 203, + 249, + 24, + 174, + 153, + 124, + 14, + 184, + 164, + 218, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 232, + 179, + 33, + 243, + 63, + 125, + 105, + 244, + 71, + 78, + 127, + 127, + 157, + 73, + 174, + 96, + 25, + 244, + 86, + 245, + 237, + 0, + 0, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 178, + 233, + 102, + 5, + 30, + 5, + 64, + 198, + 211, + 147, + 237, + 52, + 143, + 145, + 90, + 254, + 48, + 251, + 223, + 245, + 9, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 194, + 160, + 61, + 149, + 147, + 116, + 50, + 179, + 116, + 248, + 87, + 64, + 55, + 167, + 34, + 116, + 145, + 91, + 247, + 142, + 46, + 0, + 0, + 0, + 9, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9, + 29, + 125, + 44, + 141, + 164, + 22, + 36, + 245, + 118, + 197, + 133, + 254, + 131, + 82, + 122, + 246, + 105, + 204, + 57, + 148, + 46, + 0, + 0, + 0, + 10, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 156, + 154, + 104, + 126, + 189, + 84, + 195, + 3, + 242, + 255, + 230, + 170, + 190, + 35, + 19, + 172, + 117, + 224, + 58, + 19, + 60, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11, + 217, + 111, + 181, + 109, + 101, + 204, + 15, + 81, + 25, + 72, + 231, + 32, + 102, + 157, + 148, + 72, + 75, + 197, + 16, + 191, + 20, + 0, + 0, + 0, + 12, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12, + 170, + 36, + 22, + 144, + 17, + 217, + 164, + 57, + 69, + 251, + 184, + 41, + 34, + 220, + 104, + 117, + 237, + 137, + 80, + 83, + 115, + 0, + 0, + 0, + 13, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13, + 16, + 173, + 250, + 100, + 79, + 85, + 46, + 34, + 35, + 217, + 126, + 116, + 55, + 189, + 212, + 28, + 69, + 45, + 155, + 64, + 91, + 0, + 0, + 0, + 14, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14, + 73, + 43, + 213, + 252, + 75, + 222, + 162, + 219, + 108, + 46, + 206, + 72, + 49, + 234, + 14, + 122, + 193, + 162, + 115, + 176, + 197, + 0, + 0, + 0, + 15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15, + 42, + 112, + 209, + 70, + 250, + 135, + 212, + 222, + 195, + 132, + 101, + 223, + 14, + 92, + 31, + 235, + 147, + 61, + 47, + 13, + 175, + 0, + 0, + 0, + 16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 220, + 167, + 108, + 88, + 159, + 207, + 242, + 17, + 124, + 104, + 232, + 80, + 117, + 3, + 247, + 191, + 82, + 129, + 14, + 144, + 121, + 0, + 0, + 0, + 17, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17, + 108, + 144, + 25, + 119, + 159, + 160, + 107, + 253, + 100, + 55, + 215, + 82, + 47, + 119, + 171, + 236, + 20, + 64, + 99, + 243, + 87, + 0, + 0, + 0, + 18, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + 3, + 47, + 251, + 249, + 33, + 143, + 243, + 250, + 205, + 188, + 21, + 108, + 213, + 163, + 142, + 175, + 40, + 216, + 206, + 17, + 234, + 0, + 0, + 0, + 19, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19, + 203, + 91, + 156, + 248, + 199, + 16, + 124, + 194, + 67, + 240, + 106, + 192, + 37, + 70, + 138, + 151, + 36, + 219, + 94, + 1, + 96, + 0, + 0, + 0, + 20, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20, + 30, + 146, + 135, + 99, + 232, + 226, + 135, + 173, + 5, + 76, + 38, + 212, + 0, + 79, + 244, + 95, + 94, + 213, + 62, + 244, + 24, + 0, + 0, + 0, + 21, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21, + 166, + 218, + 131, + 160, + 233, + 168, + 4, + 234, + 60, + 230, + 222, + 32, + 217, + 213, + 186, + 204, + 73, + 49, + 194, + 56, + 111, + 0, + 0, + 0, + 22, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22, + 177, + 210, + 27, + 126, + 42, + 249, + 13, + 169, + 158, + 221, + 76, + 100, + 174, + 46, + 120, + 55, + 99, + 251, + 174, + 169, + 250, + 0, + 0, + 0, + 23, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23, + 168, + 143, + 35, + 86, + 22, + 225, + 246, + 115, + 200, + 191, + 247, + 231, + 150, + 71, + 4, + 226, + 198, + 221, + 83, + 223, + 212, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24, + 249, + 42, + 55, + 121, + 79, + 8, + 174, + 233, + 186, + 91, + 226, + 143, + 163, + 106, + 205, + 11, + 69, + 18, + 69, + 31, + 174, + 0, + 0, + 0, + 25, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25, + 77, + 254, + 49, + 137, + 67, + 173, + 29, + 230, + 102, + 139, + 239, + 52, + 51, + 115, + 154, + 203, + 142, + 118, + 71, + 250, + 201, + 0, + 0, + 0, + 26, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26, + 159, + 132, + 79, + 66, + 216, + 196, + 229, + 248, + 36, + 66, + 252, + 128, + 155, + 157, + 85, + 83, + 214, + 234, + 162, + 47, + 220, + 0, + 0, + 0, + 27, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27, + 147, + 173, + 224, + 79, + 27, + 2, + 118, + 109, + 251, + 113, + 67, + 162, + 163, + 193, + 233, + 31, + 182, + 30, + 47, + 90, + 219, + 0, + 0, + 0, + 28, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28, + 116, + 186, + 5, + 86, + 52, + 126, + 203, + 30, + 13, + 86, + 141, + 65, + 75, + 27, + 252, + 46, + 92, + 154, + 247, + 65, + 5, + 0, + 0, + 0, + 29, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29, + 193, + 106, + 16, + 130, + 246, + 194, + 198, + 10, + 223, + 162, + 144, + 31, + 34, + 106, + 188, + 148, + 226, + 23, + 254, + 167, + 149, + 0, + 0, + 0, + 30, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30, + 123, + 65, + 52, + 255, + 81, + 84, + 113, + 6, + 231, + 49, + 126, + 20, + 17, + 97, + 225, + 20, + 210, + 101, + 30, + 23, + 23, + 0, + 0, + 0, + 31, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31, + 39, + 34, + 176, + 33, + 192, + 20, + 70, + 243, + 31, + 55, + 241, + 157, + 228, + 199, + 33, + 202, + 0, + 54, + 208, + 70, + 7, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 181, + 209, + 125, + 8, + 200, + 187, + 31, + 19, + 120, + 64, + 255, + 77, + 209, + 199, + 116, + 187, + 154, + 80, + 69, + 150, + 102, + 0, + 0, + 0, + 33, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 33, + 34, + 213, + 43, + 31, + 82, + 140, + 194, + 92, + 93, + 38, + 9, + 63, + 237, + 28, + 223, + 51, + 86, + 244, + 178, + 88, + 94, + 0, + 0, + 0, + 34, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 34, + 20, + 251, + 120, + 227, + 44, + 81, + 111, + 10, + 238, + 3, + 81, + 121, + 98, + 70, + 13, + 162, + 71, + 131, + 46, + 103, + 98, + 0, + 0, + 0, + 35, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 35, + 10, + 157, + 95, + 206, + 143, + 35, + 162, + 25, + 129, + 59, + 54, + 72, + 193, + 232, + 226, + 210, + 196, + 196, + 41, + 100, + 34, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 9, + 24, + 75, + 131, + 234, + 128, + 79, + 5, + 117, + 60, + 138, + 234, + 90, + 104, + 210, + 69, + 204, + 65, + 255, + 204, + 167, + 0, + 0, + 0, + 37, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 37, + 201, + 8, + 128, + 251, + 92, + 81, + 68, + 64, + 63, + 169, + 238, + 67, + 142, + 236, + 122, + 89, + 163, + 196, + 201, + 76, + 225, + 0, + 0, + 0, + 38, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 38, + 171, + 25, + 79, + 109, + 104, + 214, + 41, + 29, + 136, + 185, + 4, + 196, + 111, + 120, + 245, + 107, + 147, + 119, + 13, + 102, + 65, + 0, + 0, + 0, + 39, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 39, + 164, + 10, + 7, + 8, + 95, + 108, + 125, + 255, + 124, + 241, + 247, + 205, + 157, + 13, + 119, + 202, + 81, + 4, + 170, + 1, + 20, + 0, + 0, + 0, + 40, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 40, + 113, + 35, + 109, + 246, + 65, + 23, + 45, + 65, + 116, + 51, + 39, + 90, + 143, + 131, + 34, + 6, + 141, + 86, + 174, + 97, + 134, + 0, + 0, + 0, + 41, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 41, + 17, + 219, + 112, + 146, + 102, + 164, + 109, + 250, + 237, + 28, + 67, + 34, + 122, + 165, + 112, + 23, + 159, + 147, + 126, + 17, + 110, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 42, + 166, + 13, + 213, + 152, + 15, + 244, + 21, + 15, + 216, + 172, + 198, + 144, + 147, + 155, + 130, + 132, + 250, + 62, + 135, + 41, + 211, + 0, + 0, + 0, + 43, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 43, + 122, + 230, + 189, + 241, + 100, + 207, + 33, + 97, + 250, + 117, + 32, + 29, + 205, + 246, + 22, + 60, + 207, + 106, + 246, + 26, + 6, + 0, + 0, + 0, + 44, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 44, + 15, + 131, + 64, + 121, + 47, + 163, + 18, + 170, + 84, + 253, + 221, + 153, + 52, + 40, + 51, + 94, + 208, + 71, + 136, + 115, + 214, + 0, + 0, + 0, + 45, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 45, + 211, + 10, + 50, + 65, + 83, + 72, + 67, + 128, + 24, + 130, + 253, + 176, + 7, + 101, + 238, + 83, + 244, + 42, + 12, + 125, + 52, + 0, + 0, + 0, + 46, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 46, + 142, + 66, + 230, + 141, + 29, + 134, + 213, + 171, + 121, + 31, + 148, + 7, + 204, + 168, + 63, + 7, + 108, + 205, + 32, + 127, + 166, + 0, + 0, + 0, + 47, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 47, + 175, + 180, + 23, + 150, + 138, + 210, + 61, + 241, + 170, + 248, + 43, + 178, + 57, + 164, + 206, + 222, + 235, + 101, + 133, + 16, + 64, + 0, + 0, + 0, + 48, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 48, + 217, + 50, + 135, + 140, + 18, + 81, + 49, + 56, + 168, + 19, + 77, + 173, + 63, + 128, + 170, + 129, + 62, + 36, + 64, + 168, + 94, + 0, + 0, + 0, + 49, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 49, + 110, + 77, + 80, + 143, + 224, + 170, + 140, + 47, + 160, + 174, + 228, + 250, + 110, + 88, + 193, + 177, + 0, + 249, + 97, + 48, + 85, + 0, + 0, + 0, + 50, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 50, + 24, + 208, + 66, + 49, + 81, + 228, + 15, + 74, + 159, + 154, + 45, + 254, + 30, + 39, + 168, + 170, + 195, + 77, + 146, + 108, + 54, + 0, + 0, + 0, + 51, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 51, + 182, + 72, + 29, + 209, + 253, + 26, + 238, + 146, + 20, + 49, + 239, + 248, + 241, + 154, + 53, + 162, + 46, + 73, + 231, + 158, + 61, + 0, + 0, + 0, + 52, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 52, + 193, + 124, + 164, + 17, + 25, + 250, + 8, + 66, + 12, + 132, + 48, + 174, + 46, + 21, + 1, + 153, + 89, + 250, + 124, + 43, + 187, + 0, + 0, + 0, + 53, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 53, + 254, + 204, + 223, + 255, + 248, + 36, + 147, + 203, + 139, + 233, + 166, + 144, + 167, + 156, + 217, + 10, + 230, + 186, + 154, + 221, + 138, + 0, + 0, + 0, + 54, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 54, + 157, + 1, + 82, + 216, + 240, + 244, + 171, + 31, + 43, + 72, + 139, + 78, + 109, + 130, + 199, + 180, + 29, + 220, + 152, + 86, + 41, + 0, + 0, + 0, + 55, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 55, + 118, + 62, + 180, + 234, + 142, + 50, + 253, + 134, + 112, + 238, + 1, + 135, + 172, + 62, + 137, + 172, + 101, + 144, + 80, + 181, + 118, + 0, + 0, + 0, + 56, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 56, + 248, + 25, + 23, + 244, + 216, + 85, + 10, + 32, + 5, + 245, + 76, + 71, + 163, + 248, + 171, + 150, + 22, + 157, + 42, + 51, + 83, + 0, + 0, + 0, + 57, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 57, + 120, + 215, + 253, + 150, + 149, + 111, + 192, + 171, + 225, + 21, + 37, + 33, + 213, + 31, + 199, + 168, + 148, + 200, + 59, + 178, + 210, + 0, + 0, + 0, + 58, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 58, + 33, + 215, + 218, + 101, + 231, + 100, + 1, + 25, + 227, + 155, + 64, + 152, + 197, + 8, + 65, + 219, + 201, + 99, + 174, + 40, + 9, + 0, + 0, + 0, + 59, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 59, + 147, + 209, + 159, + 187, + 1, + 87, + 223, + 93, + 64, + 154, + 44, + 158, + 152, + 252, + 15, + 46, + 181, + 109, + 69, + 191, + 253, + 0, + 0, + 0, + 60, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 60, + 36, + 153, + 72, + 151, + 36, + 144, + 73, + 224, + 171, + 192, + 77, + 113, + 30, + 99, + 86, + 246, + 112, + 229, + 79, + 12, + 234, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 61, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 61, + 0, + 0, + 0, + 0, + 64, + 100, + 56, + 207, + 172, + 88, + 237, + 127, + 243, + 73, + 172, + 162, + 140, + 43, + 101, + 189, + 0, + 104, + 48, + 102, + 2, + 49, + 0, + 222, + 33, + 224, + 165, + 39, + 217, + 81, + 217, + 135, + 23, + 127, + 61, + 9, + 89, + 74, + 102, + 176, + 204, + 189, + 109, + 198, + 10, + 59, + 246, + 251, + 25, + 141, + 88, + 85, + 215, + 156, + 106, + 200, + 198, + 75, + 45, + 202, + 77, + 184, + 217, + 138, + 222, + 19, + 71, + 3, + 205, + 239, + 248, + 2, + 49, + 0, + 253, + 18, + 129, + 175, + 193, + 214, + 6, + 110, + 200, + 105, + 144, + 43, + 103, + 18, + 156, + 55, + 81, + 32, + 190, + 155, + 152, + 12, + 243, + 121, + 56, + 140, + 114, + 52, + 104, + 39, + 162, + 171, + 97, + 22, + 203, + 194, + 15, + 38, + 206, + 103, + 80, + 46, + 7, + 111, + 74, + 131, + 237, + 22, + ]) } -export function invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 () { - return new Uint8Array([1, 128, 3, 120, 152, 39, 185, 111, 47, 165, 9, 162, 229, 10, 42, 28, 134, 86, 134, 57, 0, 112, 0, 2, 0, 21, 97, 119, 115, 45, 99, 114, 121, 112, 116, 111, 45, 112, 117, 98, 108, 105, 99, 45, 107, 101, 121, 0, 68, 65, 110, 89, 116, 70, 69, 101, 119, 90, 109, 43, 50, 56, 75, 104, 73, 71, 112, 120, 56, 82, 104, 107, 97, 85, 97, 76, 99, 99, 74, 112, 121, 102, 49, 110, 119, 73, 86, 81, 70, 71, 109, 121, 112, 103, 122, 104, 72, 50, 88, 100, 83, 73, 66, 74, 52, 115, 75, 105, 83, 72, 51, 99, 107, 122, 119, 61, 61, 0, 6, 115, 105, 109, 112, 108, 101, 0, 7, 99, 111, 110, 116, 101, 120, 116, 0, 1, 0, 1, 107, 0, 1, 107, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 145, 102, 170, 98, 142, 150, 6, 52, 206, 143, 212, 191, 251, 240, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 34, 13, 100, 212, 135, 138, 87, 224, 143, 81, 80, 103, 165, 73, 32, 201, 85, 20, 102, 94, 240, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 57, 122, 63, 111, 60, 86, 216, 227, 41, 135, 153, 3, 185, 146, 121, 226, 96, 140, 133, 7, 108, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 187, 57, 143, 182, 231, 34, 100, 85, 193, 111, 48, 197, 231, 237, 92, 237, 200, 232, 110, 33, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 27, 168, 206, 28, 12, 247, 55, 12, 177, 129, 72, 230, 229, 113, 77, 48, 28, 126, 216, 32, 175, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 132, 109, 27, 21, 79, 80, 166, 225, 107, 189, 218, 203, 249, 24, 174, 153, 124, 14, 184, 164, 218, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 232, 179, 33, 243, 63, 125, 105, 244, 71, 78, 127, 127, 157, 73, 174, 96, 25, 244, 86, 245, 237, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 178, 233, 102, 5, 30, 5, 64, 198, 211, 147, 237, 52, 143, 145, 90, 254, 48, 251, 223, 245, 9, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 194, 160, 61, 149, 147, 116, 50, 179, 116, 248, 87, 64, 55, 167, 34, 116, 145, 91, 247, 142, 46, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 29, 125, 44, 141, 164, 22, 36, 245, 118, 197, 133, 254, 131, 82, 122, 246, 105, 204, 57, 148, 46, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 156, 154, 104, 126, 189, 84, 195, 3, 242, 255, 230, 170, 190, 35, 19, 172, 117, 224, 58, 19, 60, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 217, 111, 181, 109, 101, 204, 15, 81, 25, 72, 231, 32, 102, 157, 148, 72, 75, 197, 16, 191, 20, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 170, 36, 22, 144, 17, 217, 164, 57, 69, 251, 184, 41, 34, 220, 104, 117, 237, 137, 80, 83, 115, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 16, 173, 250, 100, 79, 85, 46, 34, 35, 217, 126, 116, 55, 189, 212, 28, 69, 45, 155, 64, 91, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 73, 43, 213, 252, 75, 222, 162, 219, 108, 46, 206, 72, 49, 234, 14, 122, 193, 162, 115, 176, 197, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 42, 112, 209, 70, 250, 135, 212, 222, 195, 132, 101, 223, 14, 92, 31, 235, 147, 61, 47, 13, 175, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 220, 167, 108, 88, 159, 207, 242, 17, 124, 104, 232, 80, 117, 3, 247, 191, 82, 129, 14, 144, 121, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 108, 144, 25, 119, 159, 160, 107, 253, 100, 55, 215, 82, 47, 119, 171, 236, 20, 64, 99, 243, 87, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 47, 251, 249, 33, 143, 243, 250, 205, 188, 21, 108, 213, 163, 142, 175, 40, 216, 206, 17, 234, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 203, 91, 156, 248, 199, 16, 124, 194, 67, 240, 106, 192, 37, 70, 138, 151, 36, 219, 94, 1, 96, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 30, 146, 135, 99, 232, 226, 135, 173, 5, 76, 38, 212, 0, 79, 244, 95, 94, 213, 62, 244, 24, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 166, 218, 131, 160, 233, 168, 4, 234, 60, 230, 222, 32, 217, 213, 186, 204, 73, 49, 194, 56, 111, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 177, 210, 27, 126, 42, 249, 13, 169, 158, 221, 76, 100, 174, 46, 120, 55, 99, 251, 174, 169, 250, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 168, 143, 35, 86, 22, 225, 246, 115, 200, 191, 247, 231, 150, 71, 4, 226, 198, 221, 83, 223, 212, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 249, 42, 55, 121, 79, 8, 174, 233, 186, 91, 226, 143, 163, 106, 205, 11, 69, 18, 69, 31, 174, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 77, 254, 49, 137, 67, 173, 29, 230, 102, 139, 239, 52, 51, 115, 154, 203, 142, 118, 71, 250, 201, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 159, 132, 79, 66, 216, 196, 229, 248, 36, 66, 252, 128, 155, 157, 85, 83, 214, 234, 162, 47, 220, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 147, 173, 224, 79, 27, 2, 118, 109, 251, 113, 67, 162, 163, 193, 233, 31, 182, 30, 47, 90, 219, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 116, 186, 5, 86, 52, 126, 203, 30, 13, 86, 141, 65, 75, 27, 252, 46, 92, 154, 247, 65, 5, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 193, 106, 16, 130, 246, 194, 198, 10, 223, 162, 144, 31, 34, 106, 188, 148, 226, 23, 254, 167, 149, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 123, 65, 52, 255, 81, 84, 113, 6, 231, 49, 126, 20, 17, 97, 225, 20, 210, 101, 30, 23, 23, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 39, 34, 176, 33, 192, 20, 70, 243, 31, 55, 241, 157, 228, 199, 33, 202, 0, 54, 208, 70, 7, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 181, 209, 125, 8, 200, 187, 31, 19, 120, 64, 255, 77, 209, 199, 116, 187, 154, 80, 69, 150, 102, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, 213, 43, 31, 82, 140, 194, 92, 93, 38, 9, 63, 237, 28, 223, 51, 86, 244, 178, 88, 94, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 20, 251, 120, 227, 44, 81, 111, 10, 238, 3, 81, 121, 98, 70, 13, 162, 71, 131, 46, 103, 98, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 10, 157, 95, 206, 143, 35, 162, 25, 129, 59, 54, 72, 193, 232, 226, 210, 196, 196, 41, 100, 34, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 9, 24, 75, 131, 234, 128, 79, 5, 117, 60, 138, 234, 90, 104, 210, 69, 204, 65, 255, 204, 167, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 201, 8, 128, 251, 92, 81, 68, 64, 63, 169, 238, 67, 142, 236, 122, 89, 163, 196, 201, 76, 225, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 171, 25, 79, 109, 104, 214, 41, 29, 136, 185, 4, 196, 111, 120, 245, 107, 147, 119, 13, 102, 65, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 164, 10, 7, 8, 95, 108, 125, 255, 124, 241, 247, 205, 157, 13, 119, 202, 81, 4, 170, 1, 20, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 113, 35, 109, 246, 65, 23, 45, 65, 116, 51, 39, 90, 143, 131, 34, 6, 141, 86, 174, 97, 134, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 17, 219, 112, 146, 102, 164, 109, 250, 237, 28, 67, 34, 122, 165, 112, 23, 159, 147, 126, 17, 110, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 166, 13, 213, 152, 15, 244, 21, 15, 216, 172, 198, 144, 147, 155, 130, 132, 250, 62, 135, 41, 211, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 122, 230, 189, 241, 100, 207, 33, 97, 250, 117, 32, 29, 205, 246, 22, 60, 207, 106, 246, 26, 6, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 15, 131, 64, 121, 47, 163, 18, 170, 84, 253, 221, 153, 52, 40, 51, 94, 208, 71, 136, 115, 214, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 211, 10, 50, 65, 83, 72, 67, 128, 24, 130, 253, 176, 7, 101, 238, 83, 244, 42, 12, 125, 52, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 142, 66, 230, 141, 29, 134, 213, 171, 121, 31, 148, 7, 204, 168, 63, 7, 108, 205, 32, 127, 166, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 175, 180, 23, 150, 138, 210, 61, 241, 170, 248, 43, 178, 57, 164, 206, 222, 235, 101, 133, 16, 64, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 217, 50, 135, 140, 18, 81, 49, 56, 168, 19, 77, 173, 63, 128, 170, 129, 62, 36, 64, 168, 94, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 110, 77, 80, 143, 224, 170, 140, 47, 160, 174, 228, 250, 110, 88, 193, 177, 0, 249, 97, 48, 85, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 24, 208, 66, 49, 81, 228, 15, 74, 159, 154, 45, 254, 30, 39, 168, 170, 195, 77, 146, 108, 54, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 182, 72, 29, 209, 253, 26, 238, 146, 20, 49, 239, 248, 241, 154, 53, 162, 46, 73, 231, 158, 61, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 193, 124, 164, 17, 25, 250, 8, 66, 12, 132, 48, 174, 46, 21, 1, 153, 89, 250, 124, 43, 187, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 254, 204, 223, 255, 248, 36, 147, 203, 139, 233, 166, 144, 167, 156, 217, 10, 230, 186, 154, 221, 138, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 157, 1, 82, 216, 240, 244, 171, 31, 43, 72, 139, 78, 109, 130, 199, 180, 29, 220, 152, 86, 41, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 118, 62, 180, 234, 142, 50, 253, 134, 112, 238, 1, 135, 172, 62, 137, 172, 101, 144, 80, 181, 118, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 248, 25, 23, 244, 216, 85, 10, 32, 5, 245, 76, 71, 163, 248, 171, 150, 22, 157, 42, 51, 83, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 120, 215, 253, 150, 149, 111, 192, 171, 225, 21, 37, 33, 213, 31, 199, 168, 148, 200, 59, 178, 210, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 33, 215, 218, 101, 231, 100, 1, 25, 227, 155, 64, 152, 197, 8, 65, 219, 201, 99, 174, 40, 9, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 147, 209, 159, 187, 1, 87, 223, 93, 64, 154, 44, 158, 152, 252, 15, 46, 181, 109, 69, 191, 253, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 36, 153, 72, 151, 36, 144, 73, 224, 171, 192, 77, 113, 30, 99, 86, 246, 112, 229, 79, 12, 234, 255, 255, 255, 255, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 64, 100, 56, 207, 172, 88, 237, 127, 243, 73, 172, 162, 140, 43, 101, 189, 0, 104, 48, 102, 2, 49, 0, 222, 33, 224, 165, 39, 217, 81, 217, 135, 23, 127, 61, 9, 89, 74, 102, 176, 204, 189, 109, 198, 10, 59, 246, 251, 25, 141, 88, 85, 215, 156, 106, 200, 198, 75, 45, 202, 77, 184, 217, 138, 222, 19, 71, 3, 205, 239, 248, 2, 49, 0, 253, 18, 129, 175, 193, 214, 6, 110, 200, 105, 144, 43, 103, 18, 156, 55, 81, 32, 190, 155, 152, 12, 243, 121, 56, 140, 114, 52, 104, 39, 162, 171, 97, 22, 203, 194, 15, 38, 206, 103, 80, 46, 7, 111, 74, 131, 0, 0]) +export function invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384() { + return new Uint8Array([ + 1, + 128, + 3, + 120, + 152, + 39, + 185, + 111, + 47, + 165, + 9, + 162, + 229, + 10, + 42, + 28, + 134, + 86, + 134, + 57, + 0, + 112, + 0, + 2, + 0, + 21, + 97, + 119, + 115, + 45, + 99, + 114, + 121, + 112, + 116, + 111, + 45, + 112, + 117, + 98, + 108, + 105, + 99, + 45, + 107, + 101, + 121, + 0, + 68, + 65, + 110, + 89, + 116, + 70, + 69, + 101, + 119, + 90, + 109, + 43, + 50, + 56, + 75, + 104, + 73, + 71, + 112, + 120, + 56, + 82, + 104, + 107, + 97, + 85, + 97, + 76, + 99, + 99, + 74, + 112, + 121, + 102, + 49, + 110, + 119, + 73, + 86, + 81, + 70, + 71, + 109, + 121, + 112, + 103, + 122, + 104, + 72, + 50, + 88, + 100, + 83, + 73, + 66, + 74, + 52, + 115, + 75, + 105, + 83, + 72, + 51, + 99, + 107, + 122, + 119, + 61, + 61, + 0, + 6, + 115, + 105, + 109, + 112, + 108, + 101, + 0, + 7, + 99, + 111, + 110, + 116, + 101, + 120, + 116, + 0, + 1, + 0, + 1, + 107, + 0, + 1, + 107, + 0, + 3, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26, + 145, + 102, + 170, + 98, + 142, + 150, + 6, + 52, + 206, + 143, + 212, + 191, + 251, + 240, + 5, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 34, + 13, + 100, + 212, + 135, + 138, + 87, + 224, + 143, + 81, + 80, + 103, + 165, + 73, + 32, + 201, + 85, + 20, + 102, + 94, + 240, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 57, + 122, + 63, + 111, + 60, + 86, + 216, + 227, + 41, + 135, + 153, + 3, + 185, + 146, + 121, + 226, + 96, + 140, + 133, + 7, + 108, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 187, + 57, + 143, + 182, + 231, + 34, + 100, + 85, + 193, + 111, + 48, + 197, + 231, + 237, + 92, + 237, + 200, + 232, + 110, + 33, + 10, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 27, + 168, + 206, + 28, + 12, + 247, + 55, + 12, + 177, + 129, + 72, + 230, + 229, + 113, + 77, + 48, + 28, + 126, + 216, + 32, + 175, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 132, + 109, + 27, + 21, + 79, + 80, + 166, + 225, + 107, + 189, + 218, + 203, + 249, + 24, + 174, + 153, + 124, + 14, + 184, + 164, + 218, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 232, + 179, + 33, + 243, + 63, + 125, + 105, + 244, + 71, + 78, + 127, + 127, + 157, + 73, + 174, + 96, + 25, + 244, + 86, + 245, + 237, + 0, + 0, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 178, + 233, + 102, + 5, + 30, + 5, + 64, + 198, + 211, + 147, + 237, + 52, + 143, + 145, + 90, + 254, + 48, + 251, + 223, + 245, + 9, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 194, + 160, + 61, + 149, + 147, + 116, + 50, + 179, + 116, + 248, + 87, + 64, + 55, + 167, + 34, + 116, + 145, + 91, + 247, + 142, + 46, + 0, + 0, + 0, + 9, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9, + 29, + 125, + 44, + 141, + 164, + 22, + 36, + 245, + 118, + 197, + 133, + 254, + 131, + 82, + 122, + 246, + 105, + 204, + 57, + 148, + 46, + 0, + 0, + 0, + 10, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 156, + 154, + 104, + 126, + 189, + 84, + 195, + 3, + 242, + 255, + 230, + 170, + 190, + 35, + 19, + 172, + 117, + 224, + 58, + 19, + 60, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 11, + 217, + 111, + 181, + 109, + 101, + 204, + 15, + 81, + 25, + 72, + 231, + 32, + 102, + 157, + 148, + 72, + 75, + 197, + 16, + 191, + 20, + 0, + 0, + 0, + 12, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12, + 170, + 36, + 22, + 144, + 17, + 217, + 164, + 57, + 69, + 251, + 184, + 41, + 34, + 220, + 104, + 117, + 237, + 137, + 80, + 83, + 115, + 0, + 0, + 0, + 13, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 13, + 16, + 173, + 250, + 100, + 79, + 85, + 46, + 34, + 35, + 217, + 126, + 116, + 55, + 189, + 212, + 28, + 69, + 45, + 155, + 64, + 91, + 0, + 0, + 0, + 14, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 14, + 73, + 43, + 213, + 252, + 75, + 222, + 162, + 219, + 108, + 46, + 206, + 72, + 49, + 234, + 14, + 122, + 193, + 162, + 115, + 176, + 197, + 0, + 0, + 0, + 15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 15, + 42, + 112, + 209, + 70, + 250, + 135, + 212, + 222, + 195, + 132, + 101, + 223, + 14, + 92, + 31, + 235, + 147, + 61, + 47, + 13, + 175, + 0, + 0, + 0, + 16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 220, + 167, + 108, + 88, + 159, + 207, + 242, + 17, + 124, + 104, + 232, + 80, + 117, + 3, + 247, + 191, + 82, + 129, + 14, + 144, + 121, + 0, + 0, + 0, + 17, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 17, + 108, + 144, + 25, + 119, + 159, + 160, + 107, + 253, + 100, + 55, + 215, + 82, + 47, + 119, + 171, + 236, + 20, + 64, + 99, + 243, + 87, + 0, + 0, + 0, + 18, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + 3, + 47, + 251, + 249, + 33, + 143, + 243, + 250, + 205, + 188, + 21, + 108, + 213, + 163, + 142, + 175, + 40, + 216, + 206, + 17, + 234, + 0, + 0, + 0, + 19, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 19, + 203, + 91, + 156, + 248, + 199, + 16, + 124, + 194, + 67, + 240, + 106, + 192, + 37, + 70, + 138, + 151, + 36, + 219, + 94, + 1, + 96, + 0, + 0, + 0, + 20, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 20, + 30, + 146, + 135, + 99, + 232, + 226, + 135, + 173, + 5, + 76, + 38, + 212, + 0, + 79, + 244, + 95, + 94, + 213, + 62, + 244, + 24, + 0, + 0, + 0, + 21, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21, + 166, + 218, + 131, + 160, + 233, + 168, + 4, + 234, + 60, + 230, + 222, + 32, + 217, + 213, + 186, + 204, + 73, + 49, + 194, + 56, + 111, + 0, + 0, + 0, + 22, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22, + 177, + 210, + 27, + 126, + 42, + 249, + 13, + 169, + 158, + 221, + 76, + 100, + 174, + 46, + 120, + 55, + 99, + 251, + 174, + 169, + 250, + 0, + 0, + 0, + 23, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 23, + 168, + 143, + 35, + 86, + 22, + 225, + 246, + 115, + 200, + 191, + 247, + 231, + 150, + 71, + 4, + 226, + 198, + 221, + 83, + 223, + 212, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24, + 249, + 42, + 55, + 121, + 79, + 8, + 174, + 233, + 186, + 91, + 226, + 143, + 163, + 106, + 205, + 11, + 69, + 18, + 69, + 31, + 174, + 0, + 0, + 0, + 25, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 25, + 77, + 254, + 49, + 137, + 67, + 173, + 29, + 230, + 102, + 139, + 239, + 52, + 51, + 115, + 154, + 203, + 142, + 118, + 71, + 250, + 201, + 0, + 0, + 0, + 26, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 26, + 159, + 132, + 79, + 66, + 216, + 196, + 229, + 248, + 36, + 66, + 252, + 128, + 155, + 157, + 85, + 83, + 214, + 234, + 162, + 47, + 220, + 0, + 0, + 0, + 27, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27, + 147, + 173, + 224, + 79, + 27, + 2, + 118, + 109, + 251, + 113, + 67, + 162, + 163, + 193, + 233, + 31, + 182, + 30, + 47, + 90, + 219, + 0, + 0, + 0, + 28, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28, + 116, + 186, + 5, + 86, + 52, + 126, + 203, + 30, + 13, + 86, + 141, + 65, + 75, + 27, + 252, + 46, + 92, + 154, + 247, + 65, + 5, + 0, + 0, + 0, + 29, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 29, + 193, + 106, + 16, + 130, + 246, + 194, + 198, + 10, + 223, + 162, + 144, + 31, + 34, + 106, + 188, + 148, + 226, + 23, + 254, + 167, + 149, + 0, + 0, + 0, + 30, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 30, + 123, + 65, + 52, + 255, + 81, + 84, + 113, + 6, + 231, + 49, + 126, + 20, + 17, + 97, + 225, + 20, + 210, + 101, + 30, + 23, + 23, + 0, + 0, + 0, + 31, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31, + 39, + 34, + 176, + 33, + 192, + 20, + 70, + 243, + 31, + 55, + 241, + 157, + 228, + 199, + 33, + 202, + 0, + 54, + 208, + 70, + 7, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 181, + 209, + 125, + 8, + 200, + 187, + 31, + 19, + 120, + 64, + 255, + 77, + 209, + 199, + 116, + 187, + 154, + 80, + 69, + 150, + 102, + 0, + 0, + 0, + 33, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 33, + 34, + 213, + 43, + 31, + 82, + 140, + 194, + 92, + 93, + 38, + 9, + 63, + 237, + 28, + 223, + 51, + 86, + 244, + 178, + 88, + 94, + 0, + 0, + 0, + 34, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 34, + 20, + 251, + 120, + 227, + 44, + 81, + 111, + 10, + 238, + 3, + 81, + 121, + 98, + 70, + 13, + 162, + 71, + 131, + 46, + 103, + 98, + 0, + 0, + 0, + 35, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 35, + 10, + 157, + 95, + 206, + 143, + 35, + 162, + 25, + 129, + 59, + 54, + 72, + 193, + 232, + 226, + 210, + 196, + 196, + 41, + 100, + 34, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 9, + 24, + 75, + 131, + 234, + 128, + 79, + 5, + 117, + 60, + 138, + 234, + 90, + 104, + 210, + 69, + 204, + 65, + 255, + 204, + 167, + 0, + 0, + 0, + 37, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 37, + 201, + 8, + 128, + 251, + 92, + 81, + 68, + 64, + 63, + 169, + 238, + 67, + 142, + 236, + 122, + 89, + 163, + 196, + 201, + 76, + 225, + 0, + 0, + 0, + 38, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 38, + 171, + 25, + 79, + 109, + 104, + 214, + 41, + 29, + 136, + 185, + 4, + 196, + 111, + 120, + 245, + 107, + 147, + 119, + 13, + 102, + 65, + 0, + 0, + 0, + 39, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 39, + 164, + 10, + 7, + 8, + 95, + 108, + 125, + 255, + 124, + 241, + 247, + 205, + 157, + 13, + 119, + 202, + 81, + 4, + 170, + 1, + 20, + 0, + 0, + 0, + 40, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 40, + 113, + 35, + 109, + 246, + 65, + 23, + 45, + 65, + 116, + 51, + 39, + 90, + 143, + 131, + 34, + 6, + 141, + 86, + 174, + 97, + 134, + 0, + 0, + 0, + 41, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 41, + 17, + 219, + 112, + 146, + 102, + 164, + 109, + 250, + 237, + 28, + 67, + 34, + 122, + 165, + 112, + 23, + 159, + 147, + 126, + 17, + 110, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 42, + 166, + 13, + 213, + 152, + 15, + 244, + 21, + 15, + 216, + 172, + 198, + 144, + 147, + 155, + 130, + 132, + 250, + 62, + 135, + 41, + 211, + 0, + 0, + 0, + 43, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 43, + 122, + 230, + 189, + 241, + 100, + 207, + 33, + 97, + 250, + 117, + 32, + 29, + 205, + 246, + 22, + 60, + 207, + 106, + 246, + 26, + 6, + 0, + 0, + 0, + 44, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 44, + 15, + 131, + 64, + 121, + 47, + 163, + 18, + 170, + 84, + 253, + 221, + 153, + 52, + 40, + 51, + 94, + 208, + 71, + 136, + 115, + 214, + 0, + 0, + 0, + 45, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 45, + 211, + 10, + 50, + 65, + 83, + 72, + 67, + 128, + 24, + 130, + 253, + 176, + 7, + 101, + 238, + 83, + 244, + 42, + 12, + 125, + 52, + 0, + 0, + 0, + 46, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 46, + 142, + 66, + 230, + 141, + 29, + 134, + 213, + 171, + 121, + 31, + 148, + 7, + 204, + 168, + 63, + 7, + 108, + 205, + 32, + 127, + 166, + 0, + 0, + 0, + 47, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 47, + 175, + 180, + 23, + 150, + 138, + 210, + 61, + 241, + 170, + 248, + 43, + 178, + 57, + 164, + 206, + 222, + 235, + 101, + 133, + 16, + 64, + 0, + 0, + 0, + 48, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 48, + 217, + 50, + 135, + 140, + 18, + 81, + 49, + 56, + 168, + 19, + 77, + 173, + 63, + 128, + 170, + 129, + 62, + 36, + 64, + 168, + 94, + 0, + 0, + 0, + 49, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 49, + 110, + 77, + 80, + 143, + 224, + 170, + 140, + 47, + 160, + 174, + 228, + 250, + 110, + 88, + 193, + 177, + 0, + 249, + 97, + 48, + 85, + 0, + 0, + 0, + 50, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 50, + 24, + 208, + 66, + 49, + 81, + 228, + 15, + 74, + 159, + 154, + 45, + 254, + 30, + 39, + 168, + 170, + 195, + 77, + 146, + 108, + 54, + 0, + 0, + 0, + 51, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 51, + 182, + 72, + 29, + 209, + 253, + 26, + 238, + 146, + 20, + 49, + 239, + 248, + 241, + 154, + 53, + 162, + 46, + 73, + 231, + 158, + 61, + 0, + 0, + 0, + 52, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 52, + 193, + 124, + 164, + 17, + 25, + 250, + 8, + 66, + 12, + 132, + 48, + 174, + 46, + 21, + 1, + 153, + 89, + 250, + 124, + 43, + 187, + 0, + 0, + 0, + 53, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 53, + 254, + 204, + 223, + 255, + 248, + 36, + 147, + 203, + 139, + 233, + 166, + 144, + 167, + 156, + 217, + 10, + 230, + 186, + 154, + 221, + 138, + 0, + 0, + 0, + 54, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 54, + 157, + 1, + 82, + 216, + 240, + 244, + 171, + 31, + 43, + 72, + 139, + 78, + 109, + 130, + 199, + 180, + 29, + 220, + 152, + 86, + 41, + 0, + 0, + 0, + 55, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 55, + 118, + 62, + 180, + 234, + 142, + 50, + 253, + 134, + 112, + 238, + 1, + 135, + 172, + 62, + 137, + 172, + 101, + 144, + 80, + 181, + 118, + 0, + 0, + 0, + 56, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 56, + 248, + 25, + 23, + 244, + 216, + 85, + 10, + 32, + 5, + 245, + 76, + 71, + 163, + 248, + 171, + 150, + 22, + 157, + 42, + 51, + 83, + 0, + 0, + 0, + 57, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 57, + 120, + 215, + 253, + 150, + 149, + 111, + 192, + 171, + 225, + 21, + 37, + 33, + 213, + 31, + 199, + 168, + 148, + 200, + 59, + 178, + 210, + 0, + 0, + 0, + 58, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 58, + 33, + 215, + 218, + 101, + 231, + 100, + 1, + 25, + 227, + 155, + 64, + 152, + 197, + 8, + 65, + 219, + 201, + 99, + 174, + 40, + 9, + 0, + 0, + 0, + 59, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 59, + 147, + 209, + 159, + 187, + 1, + 87, + 223, + 93, + 64, + 154, + 44, + 158, + 152, + 252, + 15, + 46, + 181, + 109, + 69, + 191, + 253, + 0, + 0, + 0, + 60, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 60, + 36, + 153, + 72, + 151, + 36, + 144, + 73, + 224, + 171, + 192, + 77, + 113, + 30, + 99, + 86, + 246, + 112, + 229, + 79, + 12, + 234, + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 61, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 61, + 0, + 0, + 0, + 0, + 64, + 100, + 56, + 207, + 172, + 88, + 237, + 127, + 243, + 73, + 172, + 162, + 140, + 43, + 101, + 189, + 0, + 104, + 48, + 102, + 2, + 49, + 0, + 222, + 33, + 224, + 165, + 39, + 217, + 81, + 217, + 135, + 23, + 127, + 61, + 9, + 89, + 74, + 102, + 176, + 204, + 189, + 109, + 198, + 10, + 59, + 246, + 251, + 25, + 141, + 88, + 85, + 215, + 156, + 106, + 200, + 198, + 75, + 45, + 202, + 77, + 184, + 217, + 138, + 222, + 19, + 71, + 3, + 205, + 239, + 248, + 2, + 49, + 0, + 253, + 18, + 129, + 175, + 193, + 214, + 6, + 110, + 200, + 105, + 144, + 43, + 103, + 18, + 156, + 55, + 81, + 32, + 190, + 155, + 152, + 12, + 243, + 121, + 56, + 140, + 114, + 52, + 104, + 39, + 162, + 171, + 97, + 22, + 203, + 194, + 15, + 38, + 206, + 103, + 80, + 46, + 7, + 111, + 74, + 131, + 0, + 0, + ]) } -export function plaintext () { - return new Uint8Array([221, 135, 180, 69, 84, 200, 141, 138, 125, 98, 248, 190, 243, 80, 243, 171, 216, 125, 128, 5, 5, 233, 169, 12, 214, 106, 147, 108, 242, 140, 134, 108, 32, 197, 53, 174, 143, 165, 165, 127, 197, 5, 80, 193, 187, 204, 2, 207, 14, 147, 123, 236, 73, 94, 49, 45, 221, 93, 67, 134, 150, 191, 231, 106, 89, 176, 94, 64, 108, 120, 74, 62, 67, 16, 137, 129, 234, 58, 88, 203, 129, 219, 20, 7, 102, 162, 83, 251, 72, 37, 51, 121, 156, 151, 97, 86, 194, 36, 3, 103, 209, 188, 225, 214, 14, 91, 82, 146, 13, 248, 178, 33, 39, 189, 173, 58, 128, 70, 93, 31, 152, 73, 195, 214, 128, 122, 206, 83, 248, 113, 136, 59, 248, 48, 211, 196, 227, 175, 195, 148, 103, 118, 136, 142, 5, 159, 166, 45, 182, 83, 246, 241, 211, 176, 153, 22, 7, 113, 224, 20, 237, 58, 116, 80, 45, 193, 40, 35, 80, 1, 26, 53, 99, 35, 147, 78, 47, 33, 63, 189, 72, 27, 234, 151, 167, 14, 147, 225, 139, 125, 71, 100, 31, 125, 220, 132, 217, 54, 219, 34, 143, 23, 101, 16, 235, 233, 111, 91, 70, 42, 24, 224, 200, 125, 48, 80, 95, 42, 79, 186, 226, 152, 92, 157, 211, 231, 205, 216, 197, 232, 138, 163, 27, 177, 100, 90, 85, 54, 72, 55, 210, 190, 92, 96, 243, 152, 186, 82, 13, 203, 230, 43, 89, 2, 27, 52, 84, 79, 245, 153, 52, 8, 217, 0, 39, 188, 236, 32, 200, 80, 240, 133, 199, 251, 49, 181, 109, 9, 176, 135, 84, 67, 25, 32, 31, 102, 25, 172, 71, 94, 59, 38, 200, 186, 170, 220, 189, 21, 239, 78]) +export function plaintext() { + return new Uint8Array([ + 221, + 135, + 180, + 69, + 84, + 200, + 141, + 138, + 125, + 98, + 248, + 190, + 243, + 80, + 243, + 171, + 216, + 125, + 128, + 5, + 5, + 233, + 169, + 12, + 214, + 106, + 147, + 108, + 242, + 140, + 134, + 108, + 32, + 197, + 53, + 174, + 143, + 165, + 165, + 127, + 197, + 5, + 80, + 193, + 187, + 204, + 2, + 207, + 14, + 147, + 123, + 236, + 73, + 94, + 49, + 45, + 221, + 93, + 67, + 134, + 150, + 191, + 231, + 106, + 89, + 176, + 94, + 64, + 108, + 120, + 74, + 62, + 67, + 16, + 137, + 129, + 234, + 58, + 88, + 203, + 129, + 219, + 20, + 7, + 102, + 162, + 83, + 251, + 72, + 37, + 51, + 121, + 156, + 151, + 97, + 86, + 194, + 36, + 3, + 103, + 209, + 188, + 225, + 214, + 14, + 91, + 82, + 146, + 13, + 248, + 178, + 33, + 39, + 189, + 173, + 58, + 128, + 70, + 93, + 31, + 152, + 73, + 195, + 214, + 128, + 122, + 206, + 83, + 248, + 113, + 136, + 59, + 248, + 48, + 211, + 196, + 227, + 175, + 195, + 148, + 103, + 118, + 136, + 142, + 5, + 159, + 166, + 45, + 182, + 83, + 246, + 241, + 211, + 176, + 153, + 22, + 7, + 113, + 224, + 20, + 237, + 58, + 116, + 80, + 45, + 193, + 40, + 35, + 80, + 1, + 26, + 53, + 99, + 35, + 147, + 78, + 47, + 33, + 63, + 189, + 72, + 27, + 234, + 151, + 167, + 14, + 147, + 225, + 139, + 125, + 71, + 100, + 31, + 125, + 220, + 132, + 217, + 54, + 219, + 34, + 143, + 23, + 101, + 16, + 235, + 233, + 111, + 91, + 70, + 42, + 24, + 224, + 200, + 125, + 48, + 80, + 95, + 42, + 79, + 186, + 226, + 152, + 92, + 157, + 211, + 231, + 205, + 216, + 197, + 232, + 138, + 163, + 27, + 177, + 100, + 90, + 85, + 54, + 72, + 55, + 210, + 190, + 92, + 96, + 243, + 152, + 186, + 82, + 13, + 203, + 230, + 43, + 89, + 2, + 27, + 52, + 84, + 79, + 245, + 153, + 52, + 8, + 217, + 0, + 39, + 188, + 236, + 32, + 200, + 80, + 240, + 133, + 199, + 251, + 49, + 181, + 109, + 9, + 176, + 135, + 84, + 67, + 25, + 32, + 31, + 102, + 25, + 172, + 71, + 94, + 59, + 38, + 200, + 186, + 170, + 220, + 189, + 21, + 239, + 78, + ]) } -export function encryptionContext () { +export function encryptionContext() { return { - 'aws-crypto-public-key': 'AnYtFEewZm+28KhIGpx8RhkaUaLccJpyf1nwIVQFGmypgzhH2XdSIBJ4sKiSH3ckzw==', - simple: 'context' + 'aws-crypto-public-key': + 'AnYtFEewZm+28KhIGpx8RhkaUaLccJpyf1nwIVQFGmypgzhH2XdSIBJ4sKiSH3ckzw==', + simple: 'context', } } -export function frameSequenceOutOfOrder () { +export function frameSequenceOutOfOrder() { /* This is the string 'asdf' encrypted with ALG_AES128_GCM_IV12_TAG16. * The data key is all zeros. * The frames have been reordered in order to test decryption failure. */ return new Uint8Array([ - 1, 128, 0, 20, 111, 198, 208, 129, 64, 41, 115, 91, 247, 27, 148, 148, 102, 70, 149, 210, 0, 0, 0, 1, 0, 1, 107, 0, 1, 107, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0, 0, 0, 1, // header - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 85, 20, 93, 96, 34, 206, 116, 216, 115, 183, 217, 192, 84, 155, 15, // header auth - 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 217, 75, 144, 128, 252, 7, 157, 174, 2, 89, 248, 206, 24, 122, 69, 226, 95, // f - 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 114, 251, 4, 157, 182, 94, 8, 230, 234, 185, 222, 120, 209, 235, 186, 207, 112, // d - 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 44, 171, 202, 172, 191, 0, 232, 145, 31, 77, 90, 8, 233, 45, 106, 60, 176, // s - 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 248, 112, 28, 63, 229, 61, 238, 146, 255, 228, 38, 170, 100, 42, 251, 21, 208 // a + 1, + 128, + 0, + 20, + 111, + 198, + 208, + 129, + 64, + 41, + 115, + 91, + 247, + 27, + 148, + 148, + 102, + 70, + 149, + 210, + 0, + 0, + 0, + 1, + 0, + 1, + 107, + 0, + 1, + 107, + 0, + 3, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 0, + 1, // header + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 178, + 85, + 20, + 93, + 96, + 34, + 206, + 116, + 216, + 115, + 183, + 217, + 192, + 84, + 155, + 15, // header auth + 0, + 0, + 0, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 71, + 217, + 75, + 144, + 128, + 252, + 7, + 157, + 174, + 2, + 89, + 248, + 206, + 24, + 122, + 69, + 226, + 95, // f + 0, + 0, + 0, + 48, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 62, + 114, + 251, + 4, + 157, + 182, + 94, + 8, + 230, + 234, + 185, + 222, + 120, + 209, + 235, + 186, + 207, + 112, // d + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 42, + 44, + 171, + 202, + 172, + 191, + 0, + 232, + 145, + 31, + 77, + 90, + 8, + 233, + 45, + 106, + 60, + 176, // s + 0, + 0, + 0, + 16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 248, + 112, + 28, + 63, + 229, + 61, + 238, + 146, + 255, + 228, + 38, + 170, + 100, + 42, + 251, + 21, + 208, // a ]) } class TestKeyring extends KeyringWebCrypto { - async _onEncrypt () : Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (material: WebCryptoDecryptionMaterial) { - const unencryptedDataKey = new Uint8Array(material.suite.keyLengthBytes).fill(0) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } - return importForWebCryptoDecryptionMaterial(material.setUnencryptedDataKey(unencryptedDataKey, trace)) + async _onDecrypt(material: WebCryptoDecryptionMaterial) { + const unencryptedDataKey = new Uint8Array( + material.suite.keyLengthBytes + ).fill(0) + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } + return importForWebCryptoDecryptionMaterial( + material.setUnencryptedDataKey(unencryptedDataKey, trace) + ) } } -export function decryptKeyring () { +export function decryptKeyring() { return new TestKeyring() } diff --git a/modules/decrypt-node/test/decipher_stream.test.ts b/modules/decrypt-node/test/decipher_stream.test.ts index ce9477e07..9fc655e61 100644 --- a/modules/decrypt-node/test/decipher_stream.test.ts +++ b/modules/decrypt-node/test/decipher_stream.test.ts @@ -30,17 +30,17 @@ describe('getDecipherStream', () => { contentType: ContentType.FRAMED_DATA, iv: Buffer.from(Array(12)), getDecipher: () => ({ - setAAD () { + setAAD() { // set decipher to a true-ish value for test return true - } - }) + }, + }), }) const bodyInfo = { contentLength: 123, iv: Buffer.from(Array(12)), sequenceNumber: 1, - isFinalFrame: false + isFinalFrame: false, } test._onBodyHeader(bodyInfo) @@ -51,7 +51,9 @@ describe('getDecipherStream', () => { it('Precondition: BodyHeader must be parsed before frame data.', () => { const test = getDecipherStream() - expect(() => test._transform(Buffer.from([1]), 'binary', () => {})).to.throw('Malformed State.') + expect(() => + test._transform(Buffer.from([1]), 'binary', () => {}) + ).to.throw('Malformed State.') }) it('Precondition: Only content should be transformed, so the lengths must always match.', () => { @@ -63,21 +65,23 @@ describe('getDecipherStream', () => { contentType: ContentType.FRAMED_DATA, iv: Buffer.from(Array(12)), getDecipher: () => ({ - setAAD () { + setAAD() { // set decipher to a true-ish value for test return true - } - }) + }, + }), }) const bodyInfo = { contentLength: 0, iv: Buffer.from(Array(12)), sequenceNumber: 1, - isFinalFrame: false + isFinalFrame: false, } test._onBodyHeader(bodyInfo) - expect(() => test._transform(Buffer.from([1]), 'binary', () => {})).to.throw('Lengths do not match') + expect(() => + test._transform(Buffer.from([1]), 'binary', () => {}) + ).to.throw('Lengths do not match') }) it('Precondition: _onAuthTag must be called only after a frame has been accumulated.', async () => { @@ -89,20 +93,23 @@ describe('getDecipherStream', () => { contentType: ContentType.FRAMED_DATA, iv: Buffer.from(Array(12)), getDecipher: () => ({ - setAAD () { + setAAD() { // set decipher to a true-ish value for test return true - } - }) + }, + }), }) const bodyInfo = { contentLength: 10, iv: Buffer.from(Array(12)), sequenceNumber: 1, - isFinalFrame: false + isFinalFrame: false, } test._onBodyHeader(bodyInfo) - await expect(test._onAuthTag(Buffer.from([]), () => {})).to.rejectedWith(Error, 'AuthTag before frame.') + await expect(test._onAuthTag(Buffer.from([]), () => {})).to.rejectedWith( + Error, + 'AuthTag before frame.' + ) }) }) diff --git a/modules/decrypt-node/test/decrypt.test.ts b/modules/decrypt-node/test/decrypt.test.ts index 5233e0b26..342824c42 100644 --- a/modules/decrypt-node/test/decrypt.test.ts +++ b/modules/decrypt-node/test/decrypt.test.ts @@ -11,30 +11,47 @@ import from from 'from2' describe('decrypt', () => { it('string with encoding', async () => { - const { plaintext: test, messageHeader } = await decrypt( + const { + plaintext: test, + messageHeader, + } = await decrypt( fixtures.decryptKeyring(), fixtures.base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), { encoding: 'base64' } ) - expect(messageHeader.suiteId).to.equal(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - expect(messageHeader.encryptionContext).to.deep.equal(fixtures.encryptionContext()) + expect(messageHeader.suiteId).to.equal( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + expect(messageHeader.encryptionContext).to.deep.equal( + fixtures.encryptionContext() + ) expect(test.toString('base64')).to.equal(fixtures.base64Plaintext()) }) it('buffer', async () => { const { plaintext: test, messageHeader } = await decrypt( fixtures.decryptKeyring(), - Buffer.from(fixtures.base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), 'base64') + Buffer.from( + fixtures.base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), + 'base64' + ) ) - expect(messageHeader.suiteId).to.equal(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - expect(messageHeader.encryptionContext).to.deep.equal(fixtures.encryptionContext()) + expect(messageHeader.suiteId).to.equal( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + expect(messageHeader.encryptionContext).to.deep.equal( + fixtures.encryptionContext() + ) expect(test.toString('base64')).to.equal(fixtures.base64Plaintext()) }) it('stream', async () => { - const ciphertext = Buffer.from(fixtures.base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), 'base64') + const ciphertext = Buffer.from( + fixtures.base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), + 'base64' + ) const i = ciphertext.values() const ciphertextStream = from((_: number, next: Function) => { /* Pushing 1 byte at time is the most annoying thing. @@ -50,25 +67,31 @@ describe('decrypt', () => { ciphertextStream ) - expect(messageHeader.suiteId).to.equal(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - expect(messageHeader.encryptionContext).to.deep.equal(fixtures.encryptionContext()) + expect(messageHeader.suiteId).to.equal( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + expect(messageHeader.encryptionContext).to.deep.equal( + fixtures.encryptionContext() + ) expect(test.toString('base64')).to.equal(fixtures.base64Plaintext()) }) it('Precondition: The sequence number is required to monotonically increase, starting from 1.', async () => { - return expect(decrypt( - fixtures.decryptKeyring(), - fixtures.frameSequenceOutOfOrder(), - { encoding: 'base64' } - )).to.rejectedWith(Error, 'Encrypted body sequence out of order.') + return expect( + decrypt(fixtures.decryptKeyring(), fixtures.frameSequenceOutOfOrder(), { + encoding: 'base64', + }) + ).to.rejectedWith(Error, 'Encrypted body sequence out of order.') }) it('Postcondition: The signature must be valid.', async () => { - await expect(decrypt( - fixtures.decryptKeyring(), - fixtures.invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), - { encoding: 'base64' } - )).to.rejectedWith(Error, 'Invalid Signature') + await expect( + decrypt( + fixtures.decryptKeyring(), + fixtures.invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384(), + { encoding: 'base64' } + ) + ).to.rejectedWith(Error, 'Invalid Signature') }) it('can decrypt maxBodySize message with a single final frame.', async () => { @@ -81,10 +104,12 @@ describe('decrypt', () => { }) it('will not decrypt data that exceeds maxBodySize.', async () => { - return expect(decrypt( - fixtures.decryptKeyring(), - fixtures.base64Ciphertext4BytesWith4KFrameLength(), - { encoding: 'base64', maxBodySize: 3 } - )).to.rejectedWith(Error, 'maxBodySize exceeded.') + return expect( + decrypt( + fixtures.decryptKeyring(), + fixtures.base64Ciphertext4BytesWith4KFrameLength(), + { encoding: 'base64', maxBodySize: 3 } + ) + ).to.rejectedWith(Error, 'maxBodySize exceeded.') }) }) diff --git a/modules/decrypt-node/test/fixtures.ts b/modules/decrypt-node/test/fixtures.ts index 501e0561f..118c3bfa7 100644 --- a/modules/decrypt-node/test/fixtures.ts +++ b/modules/decrypt-node/test/fixtures.ts @@ -4,60 +4,69 @@ /* eslint-env mocha */ import { - NodeDecryptionMaterial, // eslint-disable-line no-unused-vars - NodeEncryptionMaterial, // eslint-disable-line no-unused-vars + NodeDecryptionMaterial, + NodeEncryptionMaterial, KeyringNode, - KeyringTraceFlag + KeyringTraceFlag, } from '@aws-crypto/material-management-node' -export function base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 () { +export function base64CiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384() { return 'AYADeJgnuW8vpQmi5QoqHIZWhjkAcAACABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREFuWXRGRWV3Wm0rMjhLaElHcHg4UmhrYVVhTGNjSnB5ZjFud0lWUUZHbXlwZ3poSDJYZFNJQko0c0tpU0gzY2t6dz09AAZzaW1wbGUAB2NvbnRleHQAAQABawABawADAAAAAgAAAAAMAAAABQAAAAAAAAAAAAAAABqRZqpijpYGNM6P1L/78AUAAAABAAAAAAAAAAAAAAABIg1k1IeKV+CPUVBnpUkgyVUUZl7wAAAAAgAAAAAAAAAAAAAAAjl6P288VtjjKYeZA7mSeeJgjIUHbAAAAAMAAAAAAAAAAAAAAAO7OY+25yJkVcFvMMXn7VztyOhuIQoAAAAEAAAAAAAAAAAAAAAEG6jOHAz3NwyxgUjm5XFNMBx+2CCvAAAABQAAAAAAAAAAAAAABYRtGxVPUKbha73ay/kYrpl8Drik2gAAAAYAAAAAAAAAAAAAAAbosyHzP31p9EdOf3+dSa5gGfRW9e0AAAAHAAAAAAAAAAAAAAAHsulmBR4FQMbTk+00j5Fa/jD73/UJAAAACAAAAAAAAAAAAAAACMKgPZWTdDKzdPhXQDenInSRW/eOLgAAAAkAAAAAAAAAAAAAAAkdfSyNpBYk9XbFhf6DUnr2acw5lC4AAAAKAAAAAAAAAAAAAAAKnJpofr1UwwPy/+aqviMTrHXgOhM8AAAACwAAAAAAAAAAAAAAC9lvtW1lzA9RGUjnIGadlEhLxRC/FAAAAAwAAAAAAAAAAAAAAAyqJBaQEdmkOUX7uCki3Gh17YlQU3MAAAANAAAAAAAAAAAAAAANEK36ZE9VLiIj2X50N73UHEUtm0BbAAAADgAAAAAAAAAAAAAADkkr1fxL3qLbbC7OSDHqDnrBonOwxQAAAA8AAAAAAAAAAAAAAA8qcNFG+ofU3sOEZd8OXB/rkz0vDa8AAAAQAAAAAAAAAAAAAAAQ3KdsWJ/P8hF8aOhQdQP3v1KBDpB5AAAAEQAAAAAAAAAAAAAAEWyQGXefoGv9ZDfXUi93q+wUQGPzVwAAABIAAAAAAAAAAAAAABIDL/v5IY/z+s28FWzVo46vKNjOEeoAAAATAAAAAAAAAAAAAAATy1uc+McQfMJD8GrAJUaKlyTbXgFgAAAAFAAAAAAAAAAAAAAAFB6Sh2Po4oetBUwm1ABP9F9e1T70GAAAABUAAAAAAAAAAAAAABWm2oOg6agE6jzm3iDZ1brMSTHCOG8AAAAWAAAAAAAAAAAAAAAWsdIbfir5Dame3Uxkri54N2P7rqn6AAAAFwAAAAAAAAAAAAAAF6iPI1YW4fZzyL/355ZHBOLG3VPf1AAAABgAAAAAAAAAAAAAABj5Kjd5Twiu6bpb4o+jas0LRRJFH64AAAAZAAAAAAAAAAAAAAAZTf4xiUOtHeZmi+80M3Oay452R/rJAAAAGgAAAAAAAAAAAAAAGp+ET0LYxOX4JEL8gJudVVPW6qIv3AAAABsAAAAAAAAAAAAAABuTreBPGwJ2bftxQ6Kjwekfth4vWtsAAAAcAAAAAAAAAAAAAAAcdLoFVjR+yx4NVo1BSxv8Llya90EFAAAAHQAAAAAAAAAAAAAAHcFqEIL2wsYK36KQHyJqvJTiF/6nlQAAAB4AAAAAAAAAAAAAAB57QTT/UVRxBucxfhQRYeEU0mUeFxcAAAAfAAAAAAAAAAAAAAAfJyKwIcAURvMfN/Gd5MchygA20EYHAAAAIAAAAAAAAAAAAAAAILXRfQjIux8TeED/TdHHdLuaUEWWZgAAACEAAAAAAAAAAAAAACEi1SsfUozCXF0mCT/tHN8zVvSyWF4AAAAiAAAAAAAAAAAAAAAiFPt44yxRbwruA1F5YkYNokeDLmdiAAAAIwAAAAAAAAAAAAAAIwqdX86PI6IZgTs2SMHo4tLExClkIgAAACQAAAAAAAAAAAAAACQJGEuD6oBPBXU8iupaaNJFzEH/zKcAAAAlAAAAAAAAAAAAAAAlyQiA+1xRREA/qe5Djux6WaPEyUzhAAAAJgAAAAAAAAAAAAAAJqsZT21o1ikdiLkExG949WuTdw1mQQAAACcAAAAAAAAAAAAAACekCgcIX2x9/3zx982dDXfKUQSqARQAAAAoAAAAAAAAAAAAAAAocSNt9kEXLUF0Mydaj4MiBo1WrmGGAAAAKQAAAAAAAAAAAAAAKRHbcJJmpG367RxDInqlcBefk34RbgAAACoAAAAAAAAAAAAAACqmDdWYD/QVD9isxpCTm4KE+j6HKdMAAAArAAAAAAAAAAAAAAAreua98WTPIWH6dSAdzfYWPM9q9hoGAAAALAAAAAAAAAAAAAAALA+DQHkvoxKqVP3dmTQoM17QR4hz1gAAAC0AAAAAAAAAAAAAAC3TCjJBU0hDgBiC/bAHZe5T9CoMfTQAAAAuAAAAAAAAAAAAAAAujkLmjR2G1at5H5QHzKg/B2zNIH+mAAAALwAAAAAAAAAAAAAAL6+0F5aK0j3xqvgrsjmkzt7rZYUQQAAAADAAAAAAAAAAAAAAADDZMoeMElExOKgTTa0/gKqBPiRAqF4AAAAxAAAAAAAAAAAAAAAxbk1Qj+CqjC+gruT6bljBsQD5YTBVAAAAMgAAAAAAAAAAAAAAMhjQQjFR5A9Kn5ot/h4nqKrDTZJsNgAAADMAAAAAAAAAAAAAADO2SB3R/RrukhQx7/jxmjWiLknnnj0AAAA0AAAAAAAAAAAAAAA0wXykERn6CEIMhDCuLhUBmVn6fCu7AAAANQAAAAAAAAAAAAAANf7M3//4JJPLi+mmkKec2QrmuprdigAAADYAAAAAAAAAAAAAADadAVLY8PSrHytIi05tgse0HdyYVikAAAA3AAAAAAAAAAAAAAA3dj606o4y/YZw7gGHrD6JrGWQULV2AAAAOAAAAAAAAAAAAAAAOPgZF/TYVQogBfVMR6P4q5YWnSozUwAAADkAAAAAAAAAAAAAADl41/2WlW/Aq+EVJSHVH8eolMg7stIAAAA6AAAAAAAAAAAAAAA6IdfaZedkARnjm0CYxQhB28ljrigJAAAAOwAAAAAAAAAAAAAAO5PRn7sBV99dQJosnpj8Dy61bUW//QAAADwAAAAAAAAAAAAAADwkmUiXJJBJ4KvATXEeY1b2cOVPDOr/////AAAAPQAAAAAAAAAAAAAAPQAAAABAZDjPrFjtf/NJrKKMK2W9AGgwZgIxAN4h4KUn2VHZhxd/PQlZSmawzL1txgo79vsZjVhV15xqyMZLLcpNuNmK3hNHA83v+AIxAP0Sga/B1gZuyGmQK2cSnDdRIL6bmAzzeTiMcjRoJ6KrYRbLwg8mzmdQLgdvSoPtFg==' } -export function invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 () { +export function invalidSignatureCiphertextAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384() { return 'AYADeJgnuW8vpQmi5QoqHIZWhjkAcAACABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREFuWXRGRWV3Wm0rMjhLaElHcHg4UmhrYVVhTGNjSnB5ZjFud0lWUUZHbXlwZ3poSDJYZFNJQko0c0tpU0gzY2t6dz09AAZzaW1wbGUAB2NvbnRleHQAAQABawABawADAAAAAgAAAAAMAAAABQAAAAAAAAAAAAAAABqRZqpijpYGNM6P1L/78AUAAAABAAAAAAAAAAAAAAABIg1k1IeKV+CPUVBnpUkgyVUUZl7wAAAAAgAAAAAAAAAAAAAAAjl6P288VtjjKYeZA7mSeeJgjIUHbAAAAAMAAAAAAAAAAAAAAAO7OY+25yJkVcFvMMXn7VztyOhuIQoAAAAEAAAAAAAAAAAAAAAEG6jOHAz3NwyxgUjm5XFNMBx+2CCvAAAABQAAAAAAAAAAAAAABYRtGxVPUKbha73ay/kYrpl8Drik2gAAAAYAAAAAAAAAAAAAAAbosyHzP31p9EdOf3+dSa5gGfRW9e0AAAAHAAAAAAAAAAAAAAAHsulmBR4FQMbTk+00j5Fa/jD73/UJAAAACAAAAAAAAAAAAAAACMKgPZWTdDKzdPhXQDenInSRW/eOLgAAAAkAAAAAAAAAAAAAAAkdfSyNpBYk9XbFhf6DUnr2acw5lC4AAAAKAAAAAAAAAAAAAAAKnJpofr1UwwPy/+aqviMTrHXgOhM8AAAACwAAAAAAAAAAAAAAC9lvtW1lzA9RGUjnIGadlEhLxRC/FAAAAAwAAAAAAAAAAAAAAAyqJBaQEdmkOUX7uCki3Gh17YlQU3MAAAANAAAAAAAAAAAAAAANEK36ZE9VLiIj2X50N73UHEUtm0BbAAAADgAAAAAAAAAAAAAADkkr1fxL3qLbbC7OSDHqDnrBonOwxQAAAA8AAAAAAAAAAAAAAA8qcNFG+ofU3sOEZd8OXB/rkz0vDa8AAAAQAAAAAAAAAAAAAAAQ3KdsWJ/P8hF8aOhQdQP3v1KBDpB5AAAAEQAAAAAAAAAAAAAAEWyQGXefoGv9ZDfXUi93q+wUQGPzVwAAABIAAAAAAAAAAAAAABIDL/v5IY/z+s28FWzVo46vKNjOEeoAAAATAAAAAAAAAAAAAAATy1uc+McQfMJD8GrAJUaKlyTbXgFgAAAAFAAAAAAAAAAAAAAAFB6Sh2Po4oetBUwm1ABP9F9e1T70GAAAABUAAAAAAAAAAAAAABWm2oOg6agE6jzm3iDZ1brMSTHCOG8AAAAWAAAAAAAAAAAAAAAWsdIbfir5Dame3Uxkri54N2P7rqn6AAAAFwAAAAAAAAAAAAAAF6iPI1YW4fZzyL/355ZHBOLG3VPf1AAAABgAAAAAAAAAAAAAABj5Kjd5Twiu6bpb4o+jas0LRRJFH64AAAAZAAAAAAAAAAAAAAAZTf4xiUOtHeZmi+80M3Oay452R/rJAAAAGgAAAAAAAAAAAAAAGp+ET0LYxOX4JEL8gJudVVPW6qIv3AAAABsAAAAAAAAAAAAAABuTreBPGwJ2bftxQ6Kjwekfth4vWtsAAAAcAAAAAAAAAAAAAAAcdLoFVjR+yx4NVo1BSxv8Llya90EFAAAAHQAAAAAAAAAAAAAAHcFqEIL2wsYK36KQHyJqvJTiF/6nlQAAAB4AAAAAAAAAAAAAAB57QTT/UVRxBucxfhQRYeEU0mUeFxcAAAAfAAAAAAAAAAAAAAAfJyKwIcAURvMfN/Gd5MchygA20EYHAAAAIAAAAAAAAAAAAAAAILXRfQjIux8TeED/TdHHdLuaUEWWZgAAACEAAAAAAAAAAAAAACEi1SsfUozCXF0mCT/tHN8zVvSyWF4AAAAiAAAAAAAAAAAAAAAiFPt44yxRbwruA1F5YkYNokeDLmdiAAAAIwAAAAAAAAAAAAAAIwqdX86PI6IZgTs2SMHo4tLExClkIgAAACQAAAAAAAAAAAAAACQJGEuD6oBPBXU8iupaaNJFzEH/zKcAAAAlAAAAAAAAAAAAAAAlyQiA+1xRREA/qe5Djux6WaPEyUzhAAAAJgAAAAAAAAAAAAAAJqsZT21o1ikdiLkExG949WuTdw1mQQAAACcAAAAAAAAAAAAAACekCgcIX2x9/3zx982dDXfKUQSqARQAAAAoAAAAAAAAAAAAAAAocSNt9kEXLUF0Mydaj4MiBo1WrmGGAAAAKQAAAAAAAAAAAAAAKRHbcJJmpG367RxDInqlcBefk34RbgAAACoAAAAAAAAAAAAAACqmDdWYD/QVD9isxpCTm4KE+j6HKdMAAAArAAAAAAAAAAAAAAAreua98WTPIWH6dSAdzfYWPM9q9hoGAAAALAAAAAAAAAAAAAAALA+DQHkvoxKqVP3dmTQoM17QR4hz1gAAAC0AAAAAAAAAAAAAAC3TCjJBU0hDgBiC/bAHZe5T9CoMfTQAAAAuAAAAAAAAAAAAAAAujkLmjR2G1at5H5QHzKg/B2zNIH+mAAAALwAAAAAAAAAAAAAAL6+0F5aK0j3xqvgrsjmkzt7rZYUQQAAAADAAAAAAAAAAAAAAADDZMoeMElExOKgTTa0/gKqBPiRAqF4AAAAxAAAAAAAAAAAAAAAxbk1Qj+CqjC+gruT6bljBsQD5YTBVAAAAMgAAAAAAAAAAAAAAMhjQQjFR5A9Kn5ot/h4nqKrDTZJsNgAAADMAAAAAAAAAAAAAADO2SB3R/RrukhQx7/jxmjWiLknnnj0AAAA0AAAAAAAAAAAAAAA0wXykERn6CEIMhDCuLhUBmVn6fCu7AAAANQAAAAAAAAAAAAAANf7M3//4JJPLi+mmkKec2QrmuprdigAAADYAAAAAAAAAAAAAADadAVLY8PSrHytIi05tgse0HdyYVikAAAA3AAAAAAAAAAAAAAA3dj606o4y/YZw7gGHrD6JrGWQULV2AAAAOAAAAAAAAAAAAAAAOPgZF/TYVQogBfVMR6P4q5YWnSozUwAAADkAAAAAAAAAAAAAADl41/2WlW/Aq+EVJSHVH8eolMg7stIAAAA6AAAAAAAAAAAAAAA6IdfaZedkARnjm0CYxQhB28ljrigJAAAAOwAAAAAAAAAAAAAAO5PRn7sBV99dQJosnpj8Dy61bUW//QAAADwAAAAAAAAAAAAAADwkmUiXJJBJ4KvATXEeY1b2cOVPDOr/////AAAAPQAAAAAAAAAAAAAAPQAAAABAZDjPrFjtf/NJrKKMK2W9AGgwZgIxAN4h4KUn2VHZhxd/PQlZSmawzL1txgo79vsZjVhV15xqyMZLLcpNuNmK3hNHA83v+AIxAP0Sga/B1gZuyGmQK2cSnDdRIL6bmAzzeTiMcjRoJ6KrYRbLwg8mzmdQLgdvSoPt00==' } -export function base64Ciphertext4BytesWith4KFrameLength () { +export function base64Ciphertext4BytesWith4KFrameLength() { return 'AYADeEpqVoZzS6rBmbCKSa4acg4AXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREE4blREMk5rYzRDRXhoQTNlR0E3M1kyWWY2N2c4TDQySjlwL2UzNHo5RjdUR1hlT2pJZGR4TjEyeitUemk4Wmpxdz09AAEAAWsAAWsAAwAAAAIAAAAADAAAEAAAAAAAAAAAAAAAAABggOHpalFEq+ovk6c4Ugaj/////wAAAAEAAAAAAAAAAAAAAAEAAAAEDyVA5PCXHZo4sqQuqprmzWXwXUsAZzBlAjAY3vK9flPg8WEnoxIjPuhbj4o+bKUsJzbZgtDBaqIaBZYo8yt7JQB4vFyzb/PwucoCMQCz2fzhOQBAM63n56vBdIjBVqbNPyszIy0QjE8OJ/X8mV48VNi5wCF4u7I4MmK91N0=' } -export function base64Plaintext () { +export function base64Plaintext() { return '3Ye0RVTIjYp9Yvi+81Dzq9h9gAUF6akM1mqTbPKMhmwgxTWuj6Wlf8UFUMG7zALPDpN77EleMS3dXUOGlr/nalmwXkBseEo+QxCJgeo6WMuB2xQHZqJT+0glM3mcl2FWwiQDZ9G84dYOW1KSDfiyISe9rTqARl0fmEnD1oB6zlP4cYg7+DDTxOOvw5RndoiOBZ+mLbZT9vHTsJkWB3HgFO06dFAtwSgjUAEaNWMjk04vIT+9SBvql6cOk+GLfUdkH33chNk22yKPF2UQ6+lvW0YqGODIfTBQXypPuuKYXJ3T583YxeiKoxuxZFpVNkg30r5cYPOYulINy+YrWQIbNFRP9Zk0CNkAJ7zsIMhQ8IXH+zG1bQmwh1RDGSAfZhmsR147Jsi6qty9Fe9O' } -export function encryptionContext () { +export function encryptionContext() { return { - 'aws-crypto-public-key': 'AnYtFEewZm+28KhIGpx8RhkaUaLccJpyf1nwIVQFGmypgzhH2XdSIBJ4sKiSH3ckzw==', - simple: 'context' + 'aws-crypto-public-key': + 'AnYtFEewZm+28KhIGpx8RhkaUaLccJpyf1nwIVQFGmypgzhH2XdSIBJ4sKiSH3ckzw==', + simple: 'context', } } -export function basicFrameHeader () { +export function basicFrameHeader() { return Buffer.from([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) } -export function frameSequenceOutOfOrder () { +export function frameSequenceOutOfOrder() { /* This is the string 'asdf' encrypted with ALG_AES128_GCM_IV12_TAG16. * The data key is all zeros. * The frames have been reordered in order to test decryption failure. */ - return 'AYAAFG/G0IFAKXNb9xuUlGZGldIAAAABAAFrAAFrAAMAAAACAAAAAAwAAAAB' + // header - 'AAAAAAAAAAAAAAAAslUUXWAiznTYc7fZwFSbDw' + // header auth - 'AAAAQAAAAAAAAAAAAAAAR9lLkID8B52uAln4zhh6ReJf' + // f - 'AAAAMAAAAAAAAAAAAAAAPnL7BJ22Xgjm6rneeNHrus9w' + // d - 'AAAAIAAAAAAAAAAAAAAAKiyryqy/AOiRH01aCOktajyw' + // s - 'AAAAEAAAAAAAAAAAAAAAEPhwHD/lPe6S/+QmqmQq+xXQ' // a + return ( + 'AYAAFG/G0IFAKXNb9xuUlGZGldIAAAABAAFrAAFrAAMAAAACAAAAAAwAAAAB' + // header + 'AAAAAAAAAAAAAAAAslUUXWAiznTYc7fZwFSbDw' + // header auth + 'AAAAQAAAAAAAAAAAAAAAR9lLkID8B52uAln4zhh6ReJf' + // f + 'AAAAMAAAAAAAAAAAAAAAPnL7BJ22Xgjm6rneeNHrus9w' + // d + 'AAAAIAAAAAAAAAAAAAAAKiyryqy/AOiRH01aCOktajyw' + // s + 'AAAAEAAAAAAAAAAAAAAAEPhwHD/lPe6S/+QmqmQq+xXQ' + ) // a } -export function decryptKeyring () { +export function decryptKeyring() { class TestKeyring extends KeyringNode { - async _onEncrypt () : Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (material: NodeDecryptionMaterial) { - const unencryptedDataKey = new Uint8Array(material.suite.keyLengthBytes).fill(0) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + async _onDecrypt(material: NodeDecryptionMaterial) { + const unencryptedDataKey = new Uint8Array( + material.suite.keyLengthBytes + ).fill(0) + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } return material.setUnencryptedDataKey(unencryptedDataKey, trace) } } diff --git a/modules/decrypt-node/test/verify_stream.test.ts b/modules/decrypt-node/test/verify_stream.test.ts index 0377ee043..320c45d96 100644 --- a/modules/decrypt-node/test/verify_stream.test.ts +++ b/modules/decrypt-node/test/verify_stream.test.ts @@ -9,7 +9,10 @@ import { ParseHeaderStream } from '../src/parse_header_stream' import * as fixtures from './fixtures' import from from 'from2' import { ContentType } from '@aws-crypto/serialize' -import { NodeAlgorithmSuite, AlgorithmSuiteIdentifier } from '@aws-crypto/material-management-node' +import { + NodeAlgorithmSuite, + AlgorithmSuiteIdentifier, +} from '@aws-crypto/material-management-node' describe('VerifyStream', () => { it('can be created', () => { @@ -18,7 +21,9 @@ describe('VerifyStream', () => { }) it('Precondition: VerifyStream requires maxBodySize must be falsey or a number.', () => { - expect(() => new VerifyStream({ maxBodySize: true } as any)).to.throw('Unsupported MaxBodySize.') + expect(() => new VerifyStream({ maxBodySize: true } as any)).to.throw( + 'Unsupported MaxBodySize.' + ) }) it('Precondition: The source must a ParseHeaderStream emit the required events.', () => { @@ -34,25 +39,33 @@ describe('VerifyStream', () => { // this is _just_ enough data to pass.... source.emit('VerifyInfo', { headerInfo: { - algorithmSuite: new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16), + algorithmSuite: new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ), messageHeader: { messageId: Buffer.from('asdf'), contentType: ContentType.FRAMED_DATA, - frameLength: 2 - } - } + frameLength: 2, + }, + }, }) const buffer = Buffer.concat([ fixtures.basicFrameHeader(), - Buffer.from([1]) + Buffer.from([1]), ]) - expect(() => test._transform(buffer, 'binary', () => {})).to.throw('maxBodySize exceeded.') + expect(() => test._transform(buffer, 'binary', () => {})).to.throw( + 'maxBodySize exceeded.' + ) }) it('Precondition: VerifyInfo must have initialized the stream.', () => { const test = new VerifyStream({}) - expect(() => test._transform(Buffer.from([1]), 'binary', () => {})).to.throw('VerifyStream not configured, VerifyInfo event not yet received.') + expect(() => + test._transform(Buffer.from([1]), 'binary', () => {}) + ).to.throw( + 'VerifyStream not configured, VerifyInfo event not yet received.' + ) }) it('Check for early return (Postcondition): If there is no verify stream do not attempt to verify.', () => { diff --git a/modules/encrypt-browser/test/encrypt.test.ts b/modules/encrypt-browser/test/encrypt.test.ts index 44c2676fb..2a50d584a 100644 --- a/modules/encrypt-browser/test/encrypt.test.ts +++ b/modules/encrypt-browser/test/encrypt.test.ts @@ -6,16 +6,18 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { - WebCryptoDecryptionMaterial, // eslint-disable-line no-unused-vars - WebCryptoEncryptionMaterial, // eslint-disable-line no-unused-vars - KeyringWebCrypto, EncryptedDataKey, - KeyringTraceFlag, WebCryptoAlgorithmSuite, - importForWebCryptoEncryptionMaterial + WebCryptoDecryptionMaterial, + WebCryptoEncryptionMaterial, + KeyringWebCrypto, + EncryptedDataKey, + KeyringTraceFlag, + WebCryptoAlgorithmSuite, + importForWebCryptoEncryptionMaterial, } from '@aws-crypto/material-management-browser' import { deserializeFactory, decodeBodyHeader, - deserializeSignature + deserializeSignature, } from '@aws-crypto/serialize' import { encrypt } from '../src/index' import { toUtf8, fromUtf8 } from '@aws-sdk/util-utf8-browser' @@ -23,7 +25,10 @@ import { toUtf8, fromUtf8 } from '@aws-sdk/util-utf8-browser' chai.use(chaiAsPromised) const { expect } = chai -const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) +const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite +) /* These tests only check structure. * see decrypt-node for actual cryptographic tests @@ -38,18 +43,27 @@ describe('encrypt structural testing', () => { * This way deep equal will pass nicely. * 107 is 'k' in ASCII */ - rawInfo: new Uint8Array([107]) + rawInfo: new Uint8Array([107]), }) class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (material: WebCryptoEncryptionMaterial) { - const unencryptedDataKey = new Uint8Array(material.suite.keyLengthBytes).fill(0) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + async _onEncrypt(material: WebCryptoEncryptionMaterial) { + const unencryptedDataKey = new Uint8Array( + material.suite.keyLengthBytes + ).fill(0) + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material .setUnencryptedDataKey(unencryptedDataKey, trace) - .addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) return importForWebCryptoEncryptionMaterial(material) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -60,12 +74,16 @@ describe('encrypt structural testing', () => { const encryptionContext = { simple: 'context' } const plaintext = fromUtf8('asdf') - const { result, messageHeader } = await encrypt(keyRing, plaintext, { encryptionContext }) + const { result, messageHeader } = await encrypt(keyRing, plaintext, { + encryptionContext, + }) /* The default algorithm suite will add a signature key to the context. * So I only check that the passed context elements exist. */ - expect(messageHeader.encryptionContext).to.haveOwnProperty('simple').and.to.equal('context') + expect(messageHeader.encryptionContext) + .to.haveOwnProperty('simple') + .and.to.equal('context') expect(messageHeader.encryptedDataKeys).lengthOf(1) expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk) @@ -77,7 +95,9 @@ describe('encrypt structural testing', () => { it('Precondition: The frameLength must be less than the maximum frame size for browser encryption.', async () => { const frameLength = 0 - expect(encrypt(keyRing, fromUtf8('asdf'), { frameLength })).to.rejectedWith(Error) + await expect( + encrypt(keyRing, fromUtf8('asdf'), { frameLength }) + ).to.rejectedWith(Error) }) it('can fully parse a framed message', async () => { @@ -89,7 +109,8 @@ describe('encrypt structural testing', () => { if (!headerInfo) throw new Error('this should never happen') const tagLength = headerInfo.algorithmSuite.tagLength / 8 - let readPos = headerInfo.headerLength + headerInfo.algorithmSuite.ivLength + tagLength + let readPos = + headerInfo.headerLength + headerInfo.algorithmSuite.ivLength + tagLength let i = 0 let bodyHeader: any // for every frame... diff --git a/modules/encrypt-node/test/encrypt.test.ts b/modules/encrypt-node/test/encrypt.test.ts index adfae9884..95ba2ae25 100644 --- a/modules/encrypt-node/test/encrypt.test.ts +++ b/modules/encrypt-node/test/encrypt.test.ts @@ -6,16 +6,19 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { - NodeDecryptionMaterial, // eslint-disable-line no-unused-vars - NodeEncryptionMaterial, // eslint-disable-line no-unused-vars - KeyringNode, EncryptedDataKey, - KeyringTraceFlag, AlgorithmSuiteIdentifier, NodeAlgorithmSuite + NodeDecryptionMaterial, + NodeEncryptionMaterial, + KeyringNode, + EncryptedDataKey, + KeyringTraceFlag, + AlgorithmSuiteIdentifier, + NodeAlgorithmSuite, } from '@aws-crypto/material-management-node' import { deserializeFactory, decodeBodyHeader, deserializeSignature, - MessageHeader // eslint-disable-line no-unused-vars + MessageHeader, } from '@aws-crypto/serialize' import { encrypt, encryptStream } from '../src/index' import from from 'from2' @@ -26,10 +29,12 @@ import { randomBytes } from 'crypto' chai.use(chaiAsPromised) const { expect } = chai -const toUtf8 = (input: Uint8Array) => Buffer - .from(input.buffer, input.byteOffset, input.byteLength) - .toString('utf8') -const { deserializeMessageHeader } = deserializeFactory(toUtf8, NodeAlgorithmSuite) +const toUtf8 = (input: Uint8Array) => + Buffer.from(input.buffer, input.byteOffset, input.byteLength).toString('utf8') +const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + NodeAlgorithmSuite +) /* These tests only check structure. * see decrypt-node for actual cryptographic tests @@ -44,17 +49,26 @@ describe('encrypt structural testing', () => { * This way deep equal will pass nicely. * 107 is 'k' in ASCII */ - rawInfo: new Uint8Array([107]) + rawInfo: new Uint8Array([107]), }) class TestKeyring extends KeyringNode { - async _onEncrypt (material: NodeEncryptionMaterial) { - const unencryptedDataKey = new Uint8Array(material.suite.keyLengthBytes).fill(0) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + async _onEncrypt(material: NodeEncryptionMaterial) { + const unencryptedDataKey = new Uint8Array( + material.suite.keyLengthBytes + ).fill(0) + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } return material .setUnencryptedDataKey(unencryptedDataKey, trace) - .addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -65,7 +79,9 @@ describe('encrypt structural testing', () => { const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 const plaintext = 'asdf' - const { result, messageHeader } = await encrypt(keyRing, plaintext, { suiteId }) + const { result, messageHeader } = await encrypt(keyRing, plaintext, { + suiteId, + }) expect(messageHeader.suiteId).to.equal(suiteId) expect(messageHeader.encryptionContext).to.deep.equal({}) @@ -82,12 +98,16 @@ describe('encrypt structural testing', () => { const encryptionContext = { simple: 'context' } const plaintext = Buffer.from('asdf') - const { result, messageHeader } = await encrypt(keyRing, plaintext, { encryptionContext }) + const { result, messageHeader } = await encrypt(keyRing, plaintext, { + encryptionContext, + }) /* The default algorithm suite will add a signature key to the context. * So I only check that the passed context elements exist. */ - expect(messageHeader.encryptionContext).to.haveOwnProperty('simple').and.to.equal('context') + expect(messageHeader.encryptionContext) + .to.haveOwnProperty('simple') + .and.to.equal('context') expect(messageHeader.encryptedDataKeys).lengthOf(1) expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk) @@ -107,12 +127,16 @@ describe('encrypt structural testing', () => { next(null, 'asdf') }) - const { result, messageHeader } = await encrypt(keyRing, plaintext, { encryptionContext }) + const { result, messageHeader } = await encrypt(keyRing, plaintext, { + encryptionContext, + }) /* The default algorithm suite will add a signature key to the context. * So I only check that the passed context elements exist. */ - expect(messageHeader.encryptionContext).to.haveOwnProperty('simple').and.to.equal('context') + expect(messageHeader.encryptionContext) + .to.haveOwnProperty('simple') + .and.to.equal('context') expect(messageHeader.encryptedDataKeys).lengthOf(1) expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk) @@ -124,7 +148,7 @@ describe('encrypt structural testing', () => { it('Unsupported plaintext', async () => { const plaintext = {} as any - expect(encrypt(keyRing, plaintext)).to.rejectedWith(Error) + await expect(encrypt(keyRing, plaintext)).to.rejectedWith(Error) }) it('encryptStream', async () => { @@ -164,7 +188,9 @@ describe('encrypt structural testing', () => { /* The default algorithm suite will add a signature key to the context. * So I only check that the passed context elements exist. */ - expect(messageHeader.encryptionContext).to.haveOwnProperty('simple').and.to.equal('context') + expect(messageHeader.encryptionContext) + .to.haveOwnProperty('simple') + .and.to.equal('context') expect(messageHeader.encryptedDataKeys).lengthOf(1) expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk) @@ -176,7 +202,9 @@ describe('encrypt structural testing', () => { it('Precondition: The frameLength must be less than the maximum frame size Node.js stream.', async () => { const frameLength = 0 - expect(encrypt(keyRing, 'asdf', { frameLength })).to.rejectedWith(Error) + await expect(encrypt(keyRing, 'asdf', { frameLength })).to.rejectedWith( + Error + ) }) it('can fully parse a framed message', async () => { @@ -188,7 +216,8 @@ describe('encrypt structural testing', () => { if (!headerInfo) throw new Error('this should never happen') const tagLength = headerInfo.algorithmSuite.tagLength / 8 - let readPos = headerInfo.headerLength + headerInfo.algorithmSuite.ivLength + tagLength + let readPos = + headerInfo.headerLength + headerInfo.algorithmSuite.ivLength + tagLength let i = 0 let bodyHeader: any // for every frame... @@ -209,8 +238,8 @@ describe('encrypt structural testing', () => { }) }) -function finishedAsync (stream: any) { +async function finishedAsync(stream: any) { return new Promise((resolve, reject) => { - finished(stream, (err: Error) => err ? reject(err) : resolve()) + finished(stream, (err: Error) => (err ? reject(err) : resolve())) }) } diff --git a/modules/encrypt-node/test/framed_encrypt_stream.test.ts b/modules/encrypt-node/test/framed_encrypt_stream.test.ts index e5be25d21..8535bd5f2 100644 --- a/modules/encrypt-node/test/framed_encrypt_stream.test.ts +++ b/modules/encrypt-node/test/framed_encrypt_stream.test.ts @@ -5,7 +5,10 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { getFramedEncryptStream, getEncryptFrame } from '../src/framed_encrypt_stream' +import { + getFramedEncryptStream, + getEncryptFrame, +} from '../src/framed_encrypt_stream' chai.use(chaiAsPromised) const { expect } = chai @@ -19,26 +22,48 @@ describe('getFramedEncryptStream', () => { it('Precondition: plaintextLength must be within bounds.', () => { const getCipher: any = () => {} - expect(() => getFramedEncryptStream(getCipher, {} as any, () => {}, -1)).to.throw(Error, 'plaintextLength out of bounds.') - expect(() => getFramedEncryptStream(getCipher, {} as any, () => {}, Number.MAX_SAFE_INTEGER + 1)).to.throw(Error, 'plaintextLength out of bounds.') + expect(() => + getFramedEncryptStream(getCipher, {} as any, () => {}, -1) + ).to.throw(Error, 'plaintextLength out of bounds.') + expect(() => + getFramedEncryptStream( + getCipher, + {} as any, + () => {}, + Number.MAX_SAFE_INTEGER + 1 + ) + ).to.throw(Error, 'plaintextLength out of bounds.') /* Math is hard. * I want to make sure that I don't have an errant off by 1 error. */ - expect(() => getFramedEncryptStream(getCipher, {} as any, () => {}, Number.MAX_SAFE_INTEGER)).to.not.throw(Error) + expect(() => + getFramedEncryptStream( + getCipher, + {} as any, + () => {}, + Number.MAX_SAFE_INTEGER + ) + ).to.not.throw(Error) }) it('Precondition: Must not process more than plaintextLength.', () => { const getCipher: any = () => {} - const test = getFramedEncryptStream(getCipher, { } as any, () => {}, 8) + const test = getFramedEncryptStream(getCipher, {} as any, () => {}, 8) - expect(() => test._transform(Buffer.from(Array(9)), 'binary', () => {})).to.throw(Error, 'Encrypted data exceeded plaintextLength.') + expect(() => + test._transform(Buffer.from(Array(9)), 'binary', () => {}) + ).to.throw(Error, 'Encrypted data exceeded plaintextLength.') }) it('Check for early return (Postcondition): Have not accumulated a frame.', () => { const getCipher: any = () => {} const frameLength = 10 - const test = getFramedEncryptStream(getCipher, { frameLength } as any, () => {}) + const test = getFramedEncryptStream( + getCipher, + { frameLength } as any, + () => {} + ) let called = false test._transform(Buffer.from(Array(9)), 'binary', () => { @@ -55,10 +80,10 @@ describe('getEncryptFrame', () => { pendingFrame: { content: [Buffer.from([1, 2, 3, 4, 5])], contentLength: 5, - sequenceNumber: 1 + sequenceNumber: 1, }, isFinalFrame: false, - getCipher: () => ({ setAAD: () => {} }) as any, + getCipher: () => ({ setAAD: () => {} } as any), messageHeader: { frameLength: 5, contentType: 2, @@ -68,8 +93,8 @@ describe('getEncryptFrame', () => { type: 12, suiteId: 1, encryptionContext: {}, - encryptedDataKeys: [] - } + encryptedDataKeys: [], + }, } const test1 = getEncryptFrame(input) expect(test1.content).to.equal(input.pendingFrame.content) @@ -88,10 +113,10 @@ describe('getEncryptFrame', () => { content: [Buffer.from([1, 2, 3, 4, 5, 6])], // This exceeds the frameLength below contentLength: 6, - sequenceNumber: 1 + sequenceNumber: 1, }, isFinalFrame: true, - getCipher: () => ({ setAAD: () => {} }) as any, + getCipher: () => ({ setAAD: () => {} } as any), messageHeader: { frameLength: 5, contentType: 2, @@ -101,20 +126,22 @@ describe('getEncryptFrame', () => { type: 12, suiteId: 1, encryptionContext: {}, - encryptedDataKeys: [] - } + encryptedDataKeys: [], + }, } - expect(() => getEncryptFrame(inputFinalFrameToLarge)).to.throw('Malformed frame length and content length:') + expect(() => getEncryptFrame(inputFinalFrameToLarge)).to.throw( + 'Malformed frame length and content length:' + ) const inputFrame = { pendingFrame: { content: [Buffer.from([1, 2, 3, 4, 5])], contentLength: 5, - sequenceNumber: 1 + sequenceNumber: 1, }, isFinalFrame: false, - getCipher: () => ({ setAAD: () => {} }) as any, + getCipher: () => ({ setAAD: () => {} } as any), messageHeader: { frameLength: 5, contentType: 2, @@ -124,14 +151,18 @@ describe('getEncryptFrame', () => { type: 12, suiteId: 1, encryptionContext: {}, - encryptedDataKeys: [] - } + encryptedDataKeys: [], + }, } // Make sure that it must be equal as long as we are here... inputFrame.pendingFrame.contentLength = 4 - expect(() => getEncryptFrame(inputFrame)).to.throw('Malformed frame length and content length:') + expect(() => getEncryptFrame(inputFrame)).to.throw( + 'Malformed frame length and content length:' + ) inputFrame.pendingFrame.contentLength = 6 - expect(() => getEncryptFrame(inputFrame)).to.throw('Malformed frame length and content length:') + expect(() => getEncryptFrame(inputFrame)).to.throw( + 'Malformed frame length and content length:' + ) }) }) diff --git a/modules/hkdf-node/test/fixtures.ts b/modules/hkdf-node/test/fixtures.ts index 9abd4e7bb..6cdd3a4aa 100644 --- a/modules/hkdf-node/test/fixtures.ts +++ b/modules/hkdf-node/test/fixtures.ts @@ -5,607 +5,9288 @@ // See: https://github.com/aws/aws-encryption-sdk-c/blob/master/tests/unit/t_hkdf.c -export const tv0Ikm = new Uint8Array([ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b ]) +export const tv0Ikm = new Uint8Array([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, +]) -export const tv0Salt = new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c ]) +export const tv0Salt = new Uint8Array([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, +]) -export const tv0Info = new Uint8Array([ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 ]) +export const tv0Info = new Uint8Array([ + 0xf0, + 0xf1, + 0xf2, + 0xf3, + 0xf4, + 0xf5, + 0xf6, + 0xf7, + 0xf8, + 0xf9, +]) -export const tv0OkmDesired = new Uint8Array([ 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, - 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, - 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, - 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 ]) +export const tv0OkmDesired = new Uint8Array([ + 0x3c, + 0xb2, + 0x5f, + 0x25, + 0xfa, + 0xac, + 0xd5, + 0x7a, + 0x90, + 0x43, + 0x4f, + 0x64, + 0xd0, + 0x36, + 0x2f, + 0x2a, + 0x2d, + 0x2d, + 0x0a, + 0x90, + 0xcf, + 0x1a, + 0x5a, + 0x4c, + 0x5d, + 0xb0, + 0x2d, + 0x56, + 0xec, + 0xc4, + 0xc5, + 0xbf, + 0x34, + 0x00, + 0x72, + 0x08, + 0xd5, + 0xb8, + 0x87, + 0x18, + 0x58, + 0x65, +]) // Test vector 1: Test with SHA-256 and longer inputs/outputs -export const tv1Ikm = new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f ]) - -export const tv1Salt = new Uint8Array([ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, - 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, - 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x82, 0x56, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf ]) - -export const tv1Info = new Uint8Array([ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, - 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, - 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff ]) - -export const tv1OkmDesired = new Uint8Array([ 0x56, 0xa0, 0x54, 0x34, 0x1d, 0x0d, 0x47, 0xfa, 0x0b, 0x49, 0xd0, 0x1d, - 0x01, 0x35, 0x2d, 0xc2, 0x11, 0x0c, 0xfd, 0x75, 0x10, 0xfb, 0x06, 0x7c, - 0x9b, 0x5a, 0xe9, 0x69, 0x94, 0x56, 0x29, 0x63, 0x43, 0xc7, 0xfd, 0xd5, - 0xa9, 0xfe, 0xe2, 0x68, 0xd7, 0x9e, 0xea, 0xfa, 0x86, 0x3c, 0xf1, 0x17, - 0x58, 0xda, 0x18, 0xb0, 0x47, 0x88, 0xa0, 0xd2, 0xc5, 0x9f, 0x3b, 0x03, - 0x42, 0xa3, 0x82, 0x2e, 0xd7, 0xa6, 0xdf, 0xf1, 0x6c, 0x3b, 0x61, 0x3b, - 0x58, 0x9e, 0xcf, 0x0f, 0x71, 0x0b, 0xdf, 0x2b, 0x15, 0x39 ]) +export const tv1Ikm = new Uint8Array([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3a, + 0x3b, + 0x3c, + 0x3d, + 0x3e, + 0x3f, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f, +]) + +export const tv1Salt = new Uint8Array([ + 0x60, + 0x61, + 0x62, + 0x63, + 0x64, + 0x65, + 0x66, + 0x67, + 0x68, + 0x69, + 0x6a, + 0x6b, + 0x6c, + 0x6d, + 0x6e, + 0x6f, + 0x70, + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, + 0x76, + 0x77, + 0x78, + 0x79, + 0x7a, + 0x7b, + 0x7c, + 0x7d, + 0x7e, + 0x7f, + 0x80, + 0x81, + 0x82, + 0x82, + 0x56, + 0x85, + 0x86, + 0x87, + 0x88, + 0x89, + 0x8a, + 0x8b, + 0x8c, + 0x8d, + 0x8e, + 0x8f, + 0x90, + 0x91, + 0x92, + 0x93, + 0x94, + 0x95, + 0x96, + 0x97, + 0x98, + 0x99, + 0x9a, + 0x9b, + 0x9c, + 0x9d, + 0x9e, + 0x9f, + 0xa0, + 0xa1, + 0xa2, + 0xa3, + 0xa4, + 0xa5, + 0xa6, + 0xa7, + 0xa8, + 0xa9, + 0xaa, + 0xab, + 0xac, + 0xad, + 0xae, + 0xaf, +]) + +export const tv1Info = new Uint8Array([ + 0xb0, + 0xb1, + 0xb2, + 0xb3, + 0xb4, + 0xb5, + 0xb6, + 0xb7, + 0xb8, + 0xb9, + 0xba, + 0xbb, + 0xbc, + 0xbd, + 0xbe, + 0xbf, + 0xc0, + 0xc1, + 0xc2, + 0xc3, + 0xc4, + 0xc5, + 0xc6, + 0xc7, + 0xc8, + 0xc9, + 0xca, + 0xcb, + 0xcc, + 0xcd, + 0xce, + 0xcf, + 0xd0, + 0xd1, + 0xd2, + 0xd3, + 0xd4, + 0xd5, + 0xd6, + 0xd7, + 0xd8, + 0xd9, + 0xda, + 0xdb, + 0xdc, + 0xdd, + 0xde, + 0xdf, + 0xe0, + 0xe1, + 0xe2, + 0xe3, + 0xe4, + 0xe5, + 0xe6, + 0xe7, + 0xe8, + 0xe9, + 0xea, + 0xeb, + 0xec, + 0xed, + 0xee, + 0xef, + 0xf0, + 0xf1, + 0xf2, + 0xf3, + 0xf4, + 0xf5, + 0xf6, + 0xf7, + 0xf8, + 0xf9, + 0xfa, + 0xfb, + 0xfc, + 0xfd, + 0xfe, + 0xff, +]) + +export const tv1OkmDesired = new Uint8Array([ + 0x56, + 0xa0, + 0x54, + 0x34, + 0x1d, + 0x0d, + 0x47, + 0xfa, + 0x0b, + 0x49, + 0xd0, + 0x1d, + 0x01, + 0x35, + 0x2d, + 0xc2, + 0x11, + 0x0c, + 0xfd, + 0x75, + 0x10, + 0xfb, + 0x06, + 0x7c, + 0x9b, + 0x5a, + 0xe9, + 0x69, + 0x94, + 0x56, + 0x29, + 0x63, + 0x43, + 0xc7, + 0xfd, + 0xd5, + 0xa9, + 0xfe, + 0xe2, + 0x68, + 0xd7, + 0x9e, + 0xea, + 0xfa, + 0x86, + 0x3c, + 0xf1, + 0x17, + 0x58, + 0xda, + 0x18, + 0xb0, + 0x47, + 0x88, + 0xa0, + 0xd2, + 0xc5, + 0x9f, + 0x3b, + 0x03, + 0x42, + 0xa3, + 0x82, + 0x2e, + 0xd7, + 0xa6, + 0xdf, + 0xf1, + 0x6c, + 0x3b, + 0x61, + 0x3b, + 0x58, + 0x9e, + 0xcf, + 0x0f, + 0x71, + 0x0b, + 0xdf, + 0x2b, + 0x15, + 0x39, +]) // Test vector 2: Test with SHA-256 and zero-length salt/info -export const tv2Ikm = new Uint8Array([ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b ]) +export const tv2Ikm = new Uint8Array([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, +]) -export const tv2OkmDesired = new Uint8Array([ 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, - 0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, - 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, - 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8 ]) +export const tv2OkmDesired = new Uint8Array([ + 0x8d, + 0xa4, + 0xe7, + 0x75, + 0xa5, + 0x63, + 0xc1, + 0x8f, + 0x71, + 0x5f, + 0x80, + 0x2a, + 0x06, + 0x3c, + 0x5a, + 0x31, + 0xb8, + 0xa1, + 0x1f, + 0x5c, + 0x5e, + 0xe1, + 0x87, + 0x9e, + 0xc3, + 0x45, + 0x4e, + 0x5f, + 0x3c, + 0x73, + 0x8d, + 0x2d, + 0x9d, + 0x20, + 0x13, + 0x95, + 0xfa, + 0xa4, + 0xb6, + 0x1a, + 0x96, + 0xc8, +]) // Test vector 3: Basic test case with SHA-384 -export const tv3Ikm = new Uint8Array([ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b ]) +export const tv3Ikm = new Uint8Array([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, +]) -export const tv3Salt = new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c ]) +export const tv3Salt = new Uint8Array([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, +]) -export const tv3Info = new Uint8Array([ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 ]) +export const tv3Info = new Uint8Array([ + 0xf0, + 0xf1, + 0xf2, + 0xf3, + 0xf4, + 0xf5, + 0xf6, + 0xf7, + 0xf8, + 0xf9, +]) -export const tv3OkmDesired = new Uint8Array([ 0x9b, 0x50, 0x97, 0xa8, 0x60, 0x38, 0xb8, 0x05, 0x30, 0x90, 0x76, - 0xa4, 0x4b, 0x3a, 0x9f, 0x38, 0x06, 0x3e, 0x25, 0xb5, 0x16, 0xdc, - 0xbf, 0x36, 0x9f, 0x39, 0x4c, 0xfa, 0xb4, 0x36, 0x85, 0xf7, 0x48, - 0xb6, 0x45, 0x77, 0x63, 0xe4, 0xf0, 0x20, 0x4f, 0xc5 ]) +export const tv3OkmDesired = new Uint8Array([ + 0x9b, + 0x50, + 0x97, + 0xa8, + 0x60, + 0x38, + 0xb8, + 0x05, + 0x30, + 0x90, + 0x76, + 0xa4, + 0x4b, + 0x3a, + 0x9f, + 0x38, + 0x06, + 0x3e, + 0x25, + 0xb5, + 0x16, + 0xdc, + 0xbf, + 0x36, + 0x9f, + 0x39, + 0x4c, + 0xfa, + 0xb4, + 0x36, + 0x85, + 0xf7, + 0x48, + 0xb6, + 0x45, + 0x77, + 0x63, + 0xe4, + 0xf0, + 0x20, + 0x4f, + 0xc5, +]) // Test vector 4: Test with SHA-384 and longer inputs/outputs -export const tv4Ikm = new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f ]) - -export const tv4Salt = new Uint8Array([ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, - 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, - 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf ]) - -export const tv4Info = new Uint8Array([ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, - 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, - 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff ]) - -export const tv4OkmDesired = new Uint8Array([ 0x48, 0x4c, 0xa0, 0x52, 0xb8, 0xcc, 0x72, 0x4f, 0xd1, 0xc4, 0xec, 0x64, - 0xd5, 0x7b, 0x4e, 0x81, 0x8c, 0x7e, 0x25, 0xa8, 0xe0, 0xf4, 0x56, 0x9e, - 0xd7, 0x2a, 0x6a, 0x05, 0xfe, 0x06, 0x49, 0xee, 0xbf, 0x69, 0xf8, 0xd5, - 0xc8, 0x32, 0x85, 0x6b, 0xf4, 0xe4, 0xfb, 0xc1, 0x79, 0x67, 0xd5, 0x49, - 0x75, 0x32, 0x4a, 0x94, 0x98, 0x7f, 0x7f, 0x41, 0x83, 0x58, 0x17, 0xd8, - 0x99, 0x4f, 0xdb, 0xd6, 0xf4, 0xc0, 0x9c, 0x55, 0x00, 0xdc, 0xa2, 0x4a, - 0x56, 0x22, 0x2f, 0xea, 0x53, 0xd8, 0x96, 0x7a, 0x8b, 0x2e ]) +export const tv4Ikm = new Uint8Array([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3a, + 0x3b, + 0x3c, + 0x3d, + 0x3e, + 0x3f, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4a, + 0x4b, + 0x4c, + 0x4d, + 0x4e, + 0x4f, +]) + +export const tv4Salt = new Uint8Array([ + 0x60, + 0x61, + 0x62, + 0x63, + 0x64, + 0x65, + 0x66, + 0x67, + 0x68, + 0x69, + 0x6a, + 0x6b, + 0x6c, + 0x6d, + 0x6e, + 0x6f, + 0x70, + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, + 0x76, + 0x77, + 0x78, + 0x79, + 0x7a, + 0x7b, + 0x7c, + 0x7d, + 0x7e, + 0x7f, + 0x80, + 0x81, + 0x82, + 0x83, + 0x84, + 0x85, + 0x86, + 0x87, + 0x88, + 0x89, + 0x8a, + 0x8b, + 0x8c, + 0x8d, + 0x8e, + 0x8f, + 0x90, + 0x91, + 0x92, + 0x93, + 0x94, + 0x95, + 0x96, + 0x97, + 0x98, + 0x99, + 0x9a, + 0x9b, + 0x9c, + 0x9d, + 0x9e, + 0x9f, + 0xa0, + 0xa1, + 0xa2, + 0xa3, + 0xa4, + 0xa5, + 0xa6, + 0xa7, + 0xa8, + 0xa9, + 0xaa, + 0xab, + 0xac, + 0xad, + 0xae, + 0xaf, +]) + +export const tv4Info = new Uint8Array([ + 0xb0, + 0xb1, + 0xb2, + 0xb3, + 0xb4, + 0xb5, + 0xb6, + 0xb7, + 0xb8, + 0xb9, + 0xba, + 0xbb, + 0xbc, + 0xbd, + 0xbe, + 0xbf, + 0xc0, + 0xc1, + 0xc2, + 0xc3, + 0xc4, + 0xc5, + 0xc6, + 0xc7, + 0xc8, + 0xc9, + 0xca, + 0xcb, + 0xcc, + 0xcd, + 0xce, + 0xcf, + 0xd0, + 0xd1, + 0xd2, + 0xd3, + 0xd4, + 0xd5, + 0xd6, + 0xd7, + 0xd8, + 0xd9, + 0xda, + 0xdb, + 0xdc, + 0xdd, + 0xde, + 0xdf, + 0xe0, + 0xe1, + 0xe2, + 0xe3, + 0xe4, + 0xe5, + 0xe6, + 0xe7, + 0xe8, + 0xe9, + 0xea, + 0xeb, + 0xec, + 0xed, + 0xee, + 0xef, + 0xf0, + 0xf1, + 0xf2, + 0xf3, + 0xf4, + 0xf5, + 0xf6, + 0xf7, + 0xf8, + 0xf9, + 0xfa, + 0xfb, + 0xfc, + 0xfd, + 0xfe, + 0xff, +]) + +export const tv4OkmDesired = new Uint8Array([ + 0x48, + 0x4c, + 0xa0, + 0x52, + 0xb8, + 0xcc, + 0x72, + 0x4f, + 0xd1, + 0xc4, + 0xec, + 0x64, + 0xd5, + 0x7b, + 0x4e, + 0x81, + 0x8c, + 0x7e, + 0x25, + 0xa8, + 0xe0, + 0xf4, + 0x56, + 0x9e, + 0xd7, + 0x2a, + 0x6a, + 0x05, + 0xfe, + 0x06, + 0x49, + 0xee, + 0xbf, + 0x69, + 0xf8, + 0xd5, + 0xc8, + 0x32, + 0x85, + 0x6b, + 0xf4, + 0xe4, + 0xfb, + 0xc1, + 0x79, + 0x67, + 0xd5, + 0x49, + 0x75, + 0x32, + 0x4a, + 0x94, + 0x98, + 0x7f, + 0x7f, + 0x41, + 0x83, + 0x58, + 0x17, + 0xd8, + 0x99, + 0x4f, + 0xdb, + 0xd6, + 0xf4, + 0xc0, + 0x9c, + 0x55, + 0x00, + 0xdc, + 0xa2, + 0x4a, + 0x56, + 0x22, + 0x2f, + 0xea, + 0x53, + 0xd8, + 0x96, + 0x7a, + 0x8b, + 0x2e, +]) // Test vector 5: Test with SHA-384 and zero-length salt/info -export const tv5Ikm = new Uint8Array([ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b ]) +export const tv5Ikm = new Uint8Array([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, +]) -export const tv5OkmDesired = new Uint8Array([ 0xc8, 0xc9, 0x6e, 0x71, 0x0f, 0x89, 0xb0, 0xd7, 0x99, 0x0b, 0xca, - 0x68, 0xbc, 0xde, 0xc8, 0xcf, 0x85, 0x40, 0x62, 0xe5, 0x4c, 0x73, - 0xa7, 0xab, 0xc7, 0x43, 0xfa, 0xde, 0x9b, 0x24, 0x2d, 0xaa, 0xcc, - 0x1c, 0xea, 0x56, 0x70, 0x41, 0x5b, 0x52, 0x84, 0x9c ]) +export const tv5OkmDesired = new Uint8Array([ + 0xc8, + 0xc9, + 0x6e, + 0x71, + 0x0f, + 0x89, + 0xb0, + 0xd7, + 0x99, + 0x0b, + 0xca, + 0x68, + 0xbc, + 0xde, + 0xc8, + 0xcf, + 0x85, + 0x40, + 0x62, + 0xe5, + 0x4c, + 0x73, + 0xa7, + 0xab, + 0xc7, + 0x43, + 0xfa, + 0xde, + 0x9b, + 0x24, + 0x2d, + 0xaa, + 0xcc, + 0x1c, + 0xea, + 0x56, + 0x70, + 0x41, + 0x5b, + 0x52, + 0x84, + 0x9c, +]) // Test vector 6: Test with NOSHA -export const tv6Ikm = new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 ]) +export const tv6Ikm = new Uint8Array([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, +]) // Test vector 7: Test with SHA-256 for N = ceil(L/HashLen) = 255 -export const tv7Ikm = new Uint8Array([ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b ]) +export const tv7Ikm = new Uint8Array([ + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, + 0x0b, +]) -export const tv7Salt = new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c ]) +export const tv7Salt = new Uint8Array([ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, +]) -export const tv7Info = new Uint8Array([ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 ]) +export const tv7Info = new Uint8Array([ + 0xf0, + 0xf1, + 0xf2, + 0xf3, + 0xf4, + 0xf5, + 0xf6, + 0xf7, + 0xf8, + 0xf9, +]) export const tv7OkmDesired = new Uint8Array([ - 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, - 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, - 0x87, 0x18, 0x58, 0x65, 0xb4, 0xb0, 0xa8, 0x5a, 0x99, 0x3b, 0x89, 0xb9, 0xb6, 0x56, 0x83, 0xd6, 0x0f, 0x01, 0x06, - 0xd2, 0x8f, 0xff, 0x03, 0x9d, 0x0b, 0x6f, 0x34, 0x08, 0x90, 0x0c, 0x0f, 0x2a, 0x9d, 0x44, 0x63, 0xde, 0x83, 0x62, - 0x20, 0x56, 0xbe, 0x50, 0xa8, 0x81, 0xbe, 0xbf, 0x2b, 0x98, 0x3a, 0xb4, 0x3e, 0x06, 0x99, 0x12, 0xf0, 0xa5, 0x75, - 0x82, 0xfc, 0xb1, 0x8c, 0xa7, 0xa7, 0xfe, 0x40, 0xa3, 0x3c, 0x76, 0x6c, 0x82, 0x98, 0x12, 0xaf, 0x32, 0x7c, 0x32, - 0xe1, 0x26, 0x58, 0x9d, 0x3c, 0x64, 0xf4, 0x19, 0xdd, 0xff, 0xf9, 0xd8, 0xc7, 0x87, 0xf6, 0x95, 0xcf, 0xea, 0x76, - 0x96, 0x81, 0x67, 0x25, 0xe3, 0x92, 0xc6, 0x3b, 0x53, 0x7e, 0x66, 0x5a, 0x6b, 0x15, 0xe1, 0xe4, 0x5a, 0x2d, 0xf8, - 0x0e, 0x62, 0x54, 0xa7, 0xa3, 0xed, 0xc8, 0x43, 0xde, 0x19, 0xe5, 0xb0, 0xd8, 0x97, 0xe8, 0x04, 0x82, 0x9e, 0xf3, - 0xed, 0xed, 0xa2, 0x0b, 0xbc, 0xda, 0x7c, 0xf1, 0x31, 0x62, 0x16, 0x2a, 0x1d, 0xa8, 0x86, 0x95, 0xf3, 0xe3, 0xa1, - 0xb5, 0xf5, 0x24, 0xe5, 0xbb, 0x98, 0x5f, 0x73, 0xc6, 0x6d, 0x66, 0xdf, 0x92, 0x70, 0x57, 0x4f, 0x90, 0xb7, 0x34, - 0x8e, 0xc9, 0x65, 0xfd, 0x51, 0x45, 0x75, 0x28, 0xfd, 0x72, 0xac, 0x47, 0x58, 0xbe, 0x57, 0x3c, 0x6d, 0x8d, 0x02, - 0x94, 0xe1, 0x7b, 0xc9, 0xf2, 0x67, 0xbf, 0x9f, 0x1c, 0xaa, 0x8d, 0x38, 0x48, 0x67, 0x7c, 0xb9, 0xb0, 0xfa, 0xed, - 0x8a, 0x51, 0xf2, 0x41, 0x50, 0xfd, 0xc8, 0x60, 0x3a, 0xfa, 0x82, 0xe8, 0xd5, 0xd5, 0x82, 0x4a, 0x71, 0x6e, 0x3f, - 0xb9, 0x5b, 0x0a, 0xcc, 0xe9, 0xa7, 0x56, 0x06, 0xd0, 0x6f, 0xe3, 0x58, 0x89, 0xef, 0xaa, 0x6d, 0x4e, 0x0c, 0x4b, - 0x3d, 0xd2, 0xdf, 0xde, 0x00, 0xed, 0x9b, 0x12, 0xd3, 0xe1, 0xf3, 0x40, 0xa7, 0xae, 0x4e, 0x49, 0x51, 0xbd, 0x67, - 0xff, 0xfb, 0x2d, 0xb3, 0x93, 0xa0, 0x3e, 0x3e, 0xf9, 0x2c, 0x90, 0xbf, 0xdf, 0xde, 0xb3, 0x10, 0xb7, 0x52, 0xbb, - 0x86, 0x38, 0x1a, 0xd9, 0x02, 0x1e, 0xee, 0x15, 0x15, 0x5e, 0xbb, 0x3e, 0xbf, 0x54, 0x66, 0x44, 0x2e, 0x67, 0xdf, - 0xb4, 0x7e, 0xf1, 0xf3, 0xb8, 0x2f, 0x59, 0x0e, 0xc2, 0xca, 0x99, 0x68, 0xc2, 0xd3, 0x5a, 0x32, 0x5f, 0x27, 0xb7, - 0x61, 0x72, 0x56, 0x03, 0xf7, 0x40, 0xc9, 0xcd, 0x10, 0x96, 0x15, 0x88, 0xf1, 0x88, 0x9c, 0xd2, 0x6c, 0xa6, 0xca, - 0xac, 0x70, 0x33, 0x57, 0xf9, 0x89, 0xbc, 0x4f, 0x5b, 0x48, 0x3b, 0x53, 0x8e, 0xae, 0x52, 0xbf, 0x88, 0x88, 0xdc, - 0xe1, 0xc4, 0x13, 0xb5, 0x9c, 0x24, 0xa2, 0x8b, 0xc1, 0xfc, 0x85, 0x39, 0x79, 0xdb, 0x54, 0xdd, 0x8a, 0xc0, 0xcf, - 0xae, 0x72, 0x9d, 0x9b, 0xd3, 0xa8, 0xe9, 0xa1, 0xc0, 0x6f, 0x07, 0xf6, 0xf1, 0xc2, 0xb9, 0xd7, 0x7a, 0x6d, 0x0f, - 0x21, 0x2b, 0x24, 0xa4, 0x3c, 0xc8, 0x10, 0x99, 0xc0, 0xc0, 0x65, 0x8f, 0x9e, 0x24, 0x67, 0xa7, 0x0e, 0x46, 0x3d, - 0x9e, 0xf7, 0x6c, 0xef, 0x0e, 0x6b, 0xf2, 0xca, 0xe3, 0xd7, 0x84, 0x71, 0x54, 0x73, 0xdb, 0x41, 0x27, 0x62, 0xd1, - 0x09, 0x87, 0x24, 0x85, 0xf9, 0x9b, 0x2c, 0x90, 0x14, 0x61, 0x0e, 0xd6, 0x12, 0xe6, 0x5f, 0x0f, 0x15, 0x63, 0x5e, - 0x00, 0x0b, 0x3e, 0x15, 0x3d, 0x88, 0x00, 0xba, 0x09, 0x27, 0x31, 0x9b, 0x95, 0x47, 0x3d, 0x2e, 0xdf, 0x96, 0xc7, - 0x39, 0x3a, 0x61, 0xa2, 0xa6, 0xb7, 0x7c, 0xd9, 0x35, 0x1c, 0x6f, 0x80, 0x4d, 0x89, 0x8d, 0xe8, 0x62, 0xfb, 0x5e, - 0x9b, 0x30, 0x1f, 0xf3, 0x63, 0xf5, 0xa1, 0x8f, 0x8e, 0xa2, 0xea, 0x23, 0x1f, 0xf4, 0x84, 0x77, 0x31, 0x14, 0xd7, - 0x38, 0xca, 0xab, 0xb7, 0x7d, 0xe6, 0x0b, 0x38, 0x22, 0xbc, 0x88, 0xb9, 0x8f, 0x31, 0xdf, 0xa4, 0xe5, 0xcb, 0x9a, - 0xb1, 0xeb, 0x09, 0xb4, 0xd1, 0xd4, 0xfa, 0xee, 0x63, 0x3f, 0xbb, 0x57, 0x4d, 0x3a, 0xb2, 0xfd, 0xb8, 0xa1, 0xa1, - 0x5b, 0x01, 0x37, 0x73, 0xb5, 0x03, 0xc7, 0xfa, 0x99, 0x9d, 0xed, 0x73, 0x81, 0x8c, 0x72, 0xb4, 0x67, 0x33, 0xbd, - 0xa3, 0x75, 0x9d, 0xd5, 0xb8, 0x70, 0xd1, 0xc5, 0xdb, 0x6e, 0x73, 0xd1, 0x12, 0xe8, 0x54, 0x89, 0xce, 0x87, 0x6b, - 0xb3, 0xa3, 0xe1, 0x14, 0xa7, 0xcc, 0x07, 0xf9, 0xd4, 0x9a, 0xb5, 0xe3, 0x33, 0x20, 0xb5, 0xaa, 0x45, 0x89, 0xa0, - 0xbf, 0x5f, 0x74, 0x32, 0x02, 0x25, 0x90, 0xa0, 0x26, 0x19, 0xce, 0xac, 0xee, 0x97, 0x55, 0x66, 0x79, 0xfa, 0xd3, - 0xc9, 0xfc, 0xdc, 0xc9, 0x97, 0x44, 0xdd, 0x0b, 0xb6, 0x82, 0x2b, 0xbf, 0x83, 0x7c, 0xb6, 0x8a, 0x0b, 0xe3, 0x2f, - 0x42, 0x07, 0xbd, 0xf0, 0x97, 0x65, 0x16, 0xda, 0x46, 0x58, 0x27, 0x3f, 0x73, 0xc2, 0x5d, 0x3d, 0x42, 0x0e, 0x7e, - 0x72, 0x8e, 0x8e, 0xa4, 0x85, 0x16, 0x02, 0x80, 0xe6, 0x51, 0x01, 0xe4, 0x15, 0x12, 0x4c, 0xf9, 0xd3, 0x85, 0x2f, - 0x9e, 0x6c, 0x22, 0xa6, 0xda, 0x8a, 0x5b, 0x30, 0xfb, 0xc1, 0xde, 0x62, 0x5a, 0xa2, 0x52, 0xc6, 0xb4, 0x07, 0x87, - 0x09, 0x66, 0x9a, 0x14, 0x76, 0xf6, 0x55, 0x01, 0xac, 0xd8, 0x61, 0xff, 0xba, 0x6c, 0xd0, 0xc3, 0x9e, 0x06, 0x4d, - 0xe9, 0xdd, 0xcb, 0xf2, 0x52, 0x9c, 0xb0, 0x42, 0x81, 0xd3, 0x22, 0xda, 0xdc, 0xa6, 0xb5, 0x7a, 0x65, 0xbf, 0xa9, - 0xd4, 0x3e, 0x7f, 0x7e, 0x84, 0x6f, 0x6f, 0xe2, 0x03, 0x93, 0xeb, 0xd8, 0x3d, 0x98, 0x77, 0xff, 0x22, 0x74, 0xb0, - 0xf7, 0x75, 0x31, 0x13, 0x21, 0x5c, 0xf5, 0xb4, 0x4a, 0xe6, 0xaa, 0x96, 0x1f, 0x94, 0x19, 0x6c, 0x4d, 0x7d, 0x44, - 0x6b, 0x19, 0x92, 0x31, 0xcf, 0x6d, 0x9f, 0xa3, 0xa8, 0x1d, 0x27, 0xdc, 0xd5, 0x3b, 0x17, 0x01, 0x7b, 0xf9, 0x4f, - 0xbb, 0xbe, 0xb4, 0xb3, 0x35, 0x3c, 0x8e, 0xfb, 0x67, 0x5c, 0x39, 0x30, 0x6e, 0xdd, 0x8f, 0xcd, 0x7e, 0x02, 0xc0, - 0xa3, 0xd2, 0x4f, 0x79, 0x52, 0xaf, 0xbb, 0x3f, 0x38, 0x06, 0xc9, 0x2a, 0xf0, 0x1a, 0xc2, 0xa3, 0xb7, 0x85, 0x58, - 0x26, 0x97, 0xf6, 0x64, 0xc2, 0xd4, 0xde, 0x12, 0x07, 0xa8, 0x01, 0x9b, 0x49, 0x3b, 0x9b, 0xff, 0x0a, 0xd3, 0x66, - 0x74, 0xc8, 0x59, 0xf7, 0x7f, 0xe6, 0x3b, 0xca, 0xee, 0xf3, 0xb3, 0x87, 0xe6, 0xf5, 0x42, 0x08, 0x88, 0xc8, 0x35, - 0x03, 0xf9, 0x67, 0x07, 0xd4, 0x41, 0x5f, 0xab, 0x76, 0x33, 0x51, 0x5a, 0xe7, 0x5b, 0xbd, 0x3c, 0x37, 0x71, 0x77, - 0x06, 0x9f, 0x3b, 0x8e, 0x6c, 0xe3, 0xc0, 0xd0, 0x7a, 0xfb, 0x49, 0xc7, 0x6b, 0xc2, 0xca, 0x11, 0x5e, 0x54, 0x9b, - 0x14, 0x0d, 0xdf, 0x2b, 0xa3, 0x4b, 0xc1, 0xf7, 0x04, 0x6d, 0xab, 0x2e, 0xaa, 0x56, 0x01, 0xa6, 0xd3, 0xcb, 0x16, - 0x9e, 0x21, 0xaa, 0xa1, 0xab, 0x45, 0x95, 0x95, 0x91, 0x9a, 0x09, 0x26, 0x1f, 0x84, 0xab, 0xd3, 0xaa, 0x69, 0x99, - 0xd1, 0x60, 0x87, 0xf3, 0x36, 0x12, 0x91, 0x7f, 0x49, 0x66, 0xe6, 0x4a, 0x35, 0xbb, 0xe3, 0x41, 0x95, 0x51, 0x1f, - 0x6e, 0x2b, 0x4a, 0x49, 0x61, 0x16, 0xe7, 0x77, 0xd4, 0x9a, 0x40, 0xf7, 0xdd, 0xff, 0xdb, 0xd0, 0x41, 0x4f, 0xbc, - 0x78, 0xba, 0x08, 0x2b, 0x52, 0xe8, 0x67, 0x75, 0x0b, 0xa3, 0x89, 0xae, 0xac, 0x7c, 0xbc, 0x26, 0x68, 0xa6, 0xab, - 0x92, 0x81, 0x6b, 0xd4, 0xed, 0x0b, 0x71, 0xbe, 0x0c, 0x42, 0xdf, 0xea, 0x61, 0x62, 0x11, 0x20, 0x6a, 0x06, 0xe4, - 0x56, 0x19, 0xa4, 0x52, 0x52, 0x43, 0x97, 0x95, 0x41, 0xac, 0x1a, 0x90, 0x45, 0x8e, 0xd6, 0xf0, 0x54, 0x90, 0xa3, - 0xab, 0xea, 0xc0, 0x5a, 0xf8, 0x14, 0xc4, 0x8b, 0x6c, 0x44, 0xf6, 0x7e, 0xba, 0x58, 0x37, 0x8a, 0xf8, 0x0a, 0x26, - 0x49, 0x54, 0xe6, 0x90, 0xa9, 0xf3, 0x6a, 0xdc, 0xc9, 0x43, 0x93, 0x9c, 0xfc, 0x8c, 0x6f, 0x7f, 0xb9, 0x6b, 0x09, - 0x1e, 0xfe, 0xba, 0xc7, 0xe9, 0xca, 0x41, 0x13, 0xbb, 0x67, 0x9d, 0x76, 0xe0, 0x93, 0xce, 0xdd, 0xd8, 0x81, 0x66, - 0xc7, 0x32, 0x9c, 0x1c, 0xc4, 0x31, 0x59, 0x81, 0xa0, 0xc7, 0x61, 0x1e, 0x5d, 0x64, 0xe6, 0x14, 0x81, 0xd7, 0x42, - 0x88, 0x3a, 0xc0, 0x11, 0xc7, 0xa8, 0xa9, 0x9a, 0xd9, 0x3f, 0x21, 0x41, 0xdc, 0x2b, 0x45, 0x0a, 0xf6, 0xa2, 0xb7, - 0xb6, 0x05, 0x52, 0x61, 0x7b, 0x86, 0xd0, 0x08, 0x73, 0x68, 0x6d, 0x18, 0xd9, 0xf2, 0x81, 0x7d, 0x12, 0x08, 0x74, - 0x4d, 0x2d, 0x9a, 0xf5, 0xc9, 0x4d, 0x47, 0xb5, 0x48, 0x4f, 0x14, 0x4d, 0xb2, 0x86, 0xba, 0x9f, 0xa7, 0xed, 0x20, - 0x32, 0x7c, 0xcd, 0xec, 0x70, 0x5c, 0xf4, 0xa4, 0xef, 0x1f, 0x6d, 0x21, 0xdf, 0x5d, 0x16, 0xde, 0xa6, 0x3e, 0x1e, - 0xd6, 0x84, 0xce, 0x97, 0x35, 0xb2, 0xfa, 0xd0, 0x34, 0x42, 0x99, 0xf8, 0x3f, 0x02, 0x0c, 0xb2, 0x75, 0xf1, 0x18, - 0x71, 0x2f, 0x22, 0xeb, 0x95, 0x28, 0x42, 0xe5, 0x7f, 0xcc, 0x1d, 0xa3, 0x5a, 0x23, 0x97, 0xf4, 0x1c, 0xf9, 0x46, - 0x5b, 0x4a, 0xcd, 0x2e, 0xeb, 0x64, 0xc2, 0xbc, 0x61, 0x33, 0xa4, 0xf1, 0x23, 0xb0, 0x08, 0x5b, 0x43, 0xcc, 0x33, - 0x85, 0x9d, 0x1c, 0xed, 0xea, 0x87, 0x8c, 0x44, 0xf8, 0xc3, 0xa8, 0x30, 0x98, 0x56, 0x29, 0xb0, 0x35, 0x27, 0xc7, - 0x63, 0x7a, 0x56, 0x46, 0xe1, 0x57, 0xe1, 0x8b, 0x39, 0x5d, 0x5d, 0xa1, 0xe4, 0xba, 0xc0, 0x54, 0xe5, 0xb9, 0x03, - 0x49, 0xc4, 0x85, 0x89, 0xd7, 0xc0, 0x29, 0x1e, 0x54, 0xa0, 0x4b, 0xce, 0x04, 0xf5, 0x35, 0x34, 0x20, 0xb6, 0x8d, - 0x42, 0x32, 0xee, 0x5a, 0x51, 0x32, 0x37, 0x84, 0x03, 0xee, 0x44, 0xcf, 0x90, 0x0f, 0x0c, 0x7f, 0xc3, 0x55, 0x12, - 0x43, 0x37, 0x04, 0xf9, 0xe8, 0xaa, 0xbd, 0xcd, 0xc5, 0xa9, 0x80, 0x9c, 0x67, 0xdd, 0xac, 0xd5, 0x2e, 0x8f, 0xda, - 0x6b, 0xfd, 0x4d, 0x4c, 0xbe, 0x3f, 0x97, 0x2c, 0x39, 0x25, 0xe1, 0x87, 0x7d, 0x15, 0xd9, 0x00, 0x3e, 0x53, 0x32, - 0x33, 0x02, 0xb0, 0xa0, 0xa1, 0x52, 0x70, 0xc6, 0x80, 0xeb, 0x28, 0x65, 0x97, 0xbd, 0x56, 0x2e, 0xce, 0xca, 0x5a, - 0xe5, 0xbc, 0x6c, 0xeb, 0xf5, 0x34, 0x16, 0x30, 0xbd, 0x58, 0xc0, 0x5f, 0x99, 0x6d, 0x5c, 0x4a, 0x92, 0x87, 0x2c, - 0x82, 0xdd, 0x5b, 0x11, 0x2e, 0x31, 0x18, 0x61, 0xdd, 0x16, 0xae, 0x20, 0x0c, 0xbd, 0x34, 0xfc, 0xcc, 0x85, 0x13, - 0x7a, 0xf2, 0x1a, 0x6a, 0xe9, 0xda, 0xb0, 0x58, 0x47, 0xa9, 0x4c, 0x4d, 0x47, 0x20, 0xeb, 0x00, 0xcc, 0x25, 0x47, - 0x12, 0xaf, 0x63, 0xca, 0x8d, 0x5f, 0x49, 0x51, 0x66, 0xe0, 0x53, 0x61, 0x79, 0x29, 0x38, 0x04, 0xa8, 0x19, 0xa1, - 0xb5, 0x6d, 0x6d, 0x20, 0x77, 0x32, 0xef, 0x9d, 0x4c, 0x57, 0x83, 0x31, 0xc2, 0x8f, 0x3c, 0xfc, 0xcc, 0x97, 0x54, - 0x8a, 0xe3, 0xa1, 0x19, 0xe0, 0xb9, 0x0b, 0xf4, 0xf3, 0x47, 0x64, 0x3a, 0xbb, 0x64, 0x0a, 0x72, 0x09, 0x96, 0x31, - 0x37, 0x58, 0x32, 0xec, 0x36, 0x86, 0x75, 0xe1, 0x8a, 0x70, 0x36, 0xe7, 0x0a, 0xac, 0xde, 0x28, 0x86, 0xf7, 0xdf, - 0x16, 0x7f, 0xae, 0xd9, 0x59, 0xe4, 0x79, 0xd5, 0xab, 0x75, 0x26, 0x73, 0xb8, 0x97, 0x41, 0x74, 0x50, 0xb4, 0x06, - 0x2c, 0x44, 0x64, 0x67, 0x3e, 0x2d, 0xa1, 0x69, 0x5b, 0xcd, 0xa3, 0xaa, 0xc2, 0x45, 0x07, 0x6e, 0x55, 0x09, 0x01, - 0x4b, 0x8a, 0x5d, 0x3f, 0xdf, 0xe0, 0x23, 0x29, 0x57, 0x56, 0xa2, 0xfb, 0xde, 0x60, 0x74, 0x90, 0xe2, 0xcb, 0xdc, - 0x35, 0x3a, 0xad, 0xbd, 0xfb, 0x42, 0x30, 0x46, 0xb3, 0x7c, 0x2b, 0xc7, 0x61, 0x8c, 0x11, 0x48, 0x5f, 0x9c, 0x56, - 0x31, 0x79, 0x65, 0xab, 0xbf, 0xef, 0x83, 0x58, 0x52, 0x57, 0x05, 0x89, 0x84, 0x5e, 0x32, 0xaa, 0x9a, 0x97, 0x5c, - 0x8c, 0x55, 0x2e, 0x3d, 0x99, 0xde, 0xe7, 0xbd, 0x8d, 0x6d, 0x01, 0xd6, 0xcc, 0xc3, 0xde, 0xbd, 0x7d, 0xa1, 0x7b, - 0x86, 0xa1, 0x51, 0xe1, 0xa5, 0xf4, 0x3a, 0x66, 0x27, 0xab, 0xb7, 0xe9, 0x42, 0xc2, 0xd2, 0x08, 0x5a, 0x73, 0xca, - 0xc6, 0x44, 0x3b, 0xf7, 0x88, 0x15, 0x3e, 0x22, 0xa6, 0x95, 0x7d, 0x02, 0xd4, 0x22, 0x73, 0xef, 0x91, 0x19, 0xde, - 0xdc, 0xfb, 0x75, 0xc8, 0x58, 0x99, 0x04, 0x14, 0x6e, 0xe7, 0xa8, 0xed, 0x66, 0x07, 0x85, 0x33, 0x06, 0xfc, 0xb5, - 0x43, 0x53, 0x09, 0xf3, 0x4f, 0xe6, 0xcc, 0x3a, 0x19, 0x25, 0x22, 0xa5, 0x91, 0x4c, 0x38, 0xdc, 0x44, 0xb4, 0x1c, - 0x3c, 0x39, 0x6e, 0x94, 0xe1, 0x25, 0xc9, 0xc9, 0xba, 0x5d, 0xe0, 0xbf, 0xc5, 0x30, 0xac, 0x90, 0x76, 0x67, 0xce, - 0x47, 0x67, 0xf5, 0xcb, 0x26, 0x62, 0x43, 0xfd, 0x50, 0x30, 0xf1, 0x18, 0xe7, 0x1a, 0xc6, 0x96, 0x68, 0xbc, 0x21, - 0x55, 0x49, 0xe1, 0x17, 0x2c, 0xda, 0x83, 0x82, 0xde, 0x94, 0x23, 0xb5, 0x43, 0x86, 0x6f, 0x11, 0x6c, 0x39, 0x6d, - 0x11, 0x2c, 0x36, 0xea, 0xaf, 0xe6, 0x08, 0x54, 0x02, 0x6a, 0x13, 0x47, 0x48, 0x16, 0xea, 0x76, 0x5b, 0x80, 0xeb, - 0x92, 0x1d, 0xf4, 0xca, 0xed, 0x6d, 0xe6, 0xdf, 0x2b, 0x2b, 0xbb, 0x26, 0x89, 0xb3, 0xe3, 0xbb, 0x68, 0x99, 0x4d, - 0x84, 0x7e, 0xa2, 0x97, 0xf5, 0xf8, 0x94, 0x08, 0xe7, 0xc6, 0xbf, 0x83, 0x60, 0x9d, 0x1d, 0xda, 0xb7, 0x25, 0x45, - 0x3d, 0x39, 0xe3, 0x53, 0xed, 0x8e, 0x2e, 0x2a, 0xc6, 0x8e, 0x9e, 0xd8, 0xd9, 0x35, 0xba, 0xfa, 0x35, 0x7b, 0x40, - 0x0b, 0x6a, 0x82, 0x9c, 0xc2, 0xd9, 0xd1, 0x38, 0xd0, 0x50, 0xb6, 0xa2, 0x8a, 0xec, 0x97, 0x91, 0x11, 0x7d, 0x8c, - 0xfb, 0xf4, 0xac, 0xdf, 0xe2, 0xaf, 0x1a, 0x74, 0xfb, 0x3a, 0xc2, 0xf8, 0xe4, 0x7a, 0x50, 0xf7, 0x11, 0x25, 0xa8, - 0xf8, 0x99, 0x38, 0x94, 0x0c, 0x72, 0xdc, 0xea, 0x4a, 0x50, 0x05, 0xd0, 0xee, 0xa4, 0xd0, 0x6c, 0xc6, 0x5c, 0x37, - 0x2e, 0x14, 0x6f, 0x3a, 0x20, 0x11, 0x0b, 0x2b, 0xd9, 0xf1, 0x77, 0x5a, 0x57, 0xe1, 0x88, 0x3b, 0x7f, 0x66, 0x9e, - 0x45, 0x00, 0x95, 0xe2, 0x6a, 0x59, 0xdf, 0x86, 0xa5, 0x22, 0x29, 0x10, 0x3b, 0xda, 0xbc, 0x18, 0x95, 0x91, 0x02, - 0x79, 0x42, 0x80, 0xba, 0xfc, 0xa8, 0xe9, 0x66, 0xf8, 0x66, 0x7e, 0x31, 0x5a, 0xd4, 0x66, 0xca, 0x74, 0x61, 0x93, - 0x5e, 0x27, 0xf5, 0xe9, 0x22, 0x4d, 0x07, 0x71, 0xed, 0x59, 0x0e, 0xf6, 0x9c, 0x3d, 0x1e, 0xad, 0xa3, 0x53, 0xa4, - 0x0d, 0x0b, 0xbe, 0x34, 0x0b, 0xa5, 0x23, 0x46, 0xd9, 0x13, 0x97, 0x70, 0x40, 0xbe, 0xd6, 0x8e, 0x84, 0x30, 0x14, - 0x33, 0x0f, 0xf2, 0x23, 0x1b, 0xaf, 0x6a, 0xde, 0xa5, 0x99, 0xe7, 0x77, 0x47, 0x9b, 0x4b, 0x4b, 0x7c, 0x6a, 0xe1, - 0x8e, 0xf7, 0x07, 0x16, 0xf5, 0xd5, 0x66, 0x56, 0x3e, 0xa2, 0xdf, 0x66, 0xac, 0xd7, 0x16, 0xca, 0xb9, 0x23, 0xa3, - 0x54, 0x9a, 0xbc, 0x2e, 0xcb, 0xe6, 0xac, 0x88, 0x82, 0x5f, 0x56, 0x46, 0x80, 0xe8, 0x1a, 0x69, 0x14, 0x6c, 0x22, - 0x81, 0x24, 0x4a, 0x27, 0xb8, 0x57, 0x6e, 0xcc, 0xd1, 0xcd, 0xc1, 0xe5, 0x19, 0x8e, 0xa0, 0xff, 0x22, 0xd9, 0x5f, - 0xe4, 0x8c, 0x79, 0x7e, 0x16, 0x79, 0x75, 0x73, 0xe9, 0x23, 0x4d, 0xce, 0x5c, 0x77, 0xf2, 0xe5, 0xcc, 0x22, 0x9b, - 0x26, 0xd4, 0x32, 0x30, 0xf9, 0xbf, 0x91, 0x32, 0xbf, 0x96, 0xbe, 0x5d, 0x5b, 0x1d, 0xa3, 0x7a, 0x55, 0xfe, 0x5d, - 0x0e, 0xd5, 0x81, 0x18, 0x9e, 0x85, 0xb9, 0xb1, 0x6e, 0xdc, 0x6d, 0x21, 0x2d, 0xf3, 0x19, 0xe0, 0x83, 0x1b, 0x6e, - 0x40, 0x97, 0x80, 0x12, 0x07, 0x67, 0x2d, 0xf5, 0xb6, 0xab, 0xe1, 0xec, 0x15, 0x62, 0xff, 0x89, 0x2c, 0x28, 0x44, - 0x7c, 0x0c, 0x15, 0xa0, 0xe6, 0x55, 0x53, 0x14, 0x02, 0xa1, 0xdb, 0x84, 0x96, 0x1f, 0x8c, 0xf4, 0x67, 0x4c, 0x90, - 0xb6, 0x46, 0x4c, 0xbf, 0x10, 0xf2, 0xfe, 0x09, 0x27, 0x2e, 0x04, 0x9c, 0xf3, 0x06, 0x28, 0x77, 0x09, 0xca, 0xae, - 0x37, 0x9f, 0xe1, 0x84, 0x4e, 0xa0, 0x35, 0xbd, 0x4d, 0xaa, 0xb9, 0x60, 0xa9, 0xf7, 0x7a, 0x9f, 0xc3, 0xe2, 0xff, - 0xbf, 0x8e, 0x19, 0xa8, 0xa2, 0x4f, 0x8b, 0xa4, 0xa7, 0x0b, 0x40, 0x85, 0x37, 0xe3, 0xb4, 0xc0, 0x0b, 0xa6, 0xff, - 0x41, 0x8d, 0x6e, 0x26, 0x5e, 0x01, 0x2b, 0xb1, 0x19, 0xfd, 0xc7, 0xaf, 0xf7, 0x05, 0x23, 0x6d, 0xb1, 0x89, 0xa2, - 0x0a, 0xb1, 0xc7, 0xca, 0x70, 0x83, 0x67, 0xf8, 0xdd, 0xe8, 0x0e, 0xbd, 0x94, 0x96, 0x3d, 0x6b, 0x85, 0x04, 0x97, - 0xaf, 0x78, 0x38, 0x88, 0x87, 0xc9, 0x5e, 0x8d, 0x2a, 0x67, 0x96, 0x43, 0x48, 0xc8, 0x51, 0x3d, 0x07, 0x68, 0xf8, - 0x41, 0x63, 0xb3, 0x39, 0xb0, 0xf6, 0xab, 0xa5, 0xc7, 0x02, 0xff, 0xf4, 0x9c, 0x55, 0x50, 0x3b, 0x4a, 0x6d, 0x88, - 0x76, 0xac, 0xfe, 0xa5, 0xe7, 0x73, 0xf5, 0x39, 0xe3, 0x90, 0x03, 0xb5, 0xf7, 0x59, 0x06, 0xbe, 0x0a, 0xf4, 0x7b, - 0x74, 0x90, 0x06, 0x21, 0xfe, 0x8b, 0x1e, 0x73, 0x76, 0x48, 0xe1, 0x96, 0x24, 0xcb, 0x31, 0xdb, 0x19, 0xfe, 0xf6, - 0x3b, 0x4e, 0x47, 0xde, 0x9d, 0xaa, 0x3f, 0xaf, 0xaa, 0x81, 0xec, 0x46, 0x9b, 0xf2, 0x6f, 0x28, 0x86, 0x8b, 0x94, - 0xc6, 0x31, 0x84, 0x45, 0x84, 0x91, 0x87, 0x77, 0x4d, 0x6d, 0xc6, 0xd0, 0x24, 0xe2, 0xb4, 0x24, 0xe8, 0xd0, 0x08, - 0x5e, 0x15, 0x9b, 0xb3, 0xae, 0x2a, 0x85, 0xd0, 0xfb, 0x93, 0x1a, 0x07, 0xdc, 0x94, 0x3d, 0x8d, 0xe4, 0xb4, 0xe8, - 0x38, 0x1c, 0xa9, 0x23, 0x9e, 0x4f, 0xc0, 0x1a, 0x11, 0x5a, 0x92, 0xbb, 0xfd, 0x78, 0x86, 0x56, 0x43, 0x90, 0x6c, - 0x46, 0x36, 0x30, 0x8a, 0x0d, 0x32, 0xb3, 0x01, 0x92, 0x7b, 0xeb, 0xf0, 0xf8, 0x6d, 0xad, 0x8f, 0x22, 0xb6, 0x51, - 0x2e, 0x30, 0xf2, 0x3c, 0xb6, 0xe6, 0x4e, 0xa9, 0x62, 0x26, 0x0b, 0x35, 0x1a, 0x51, 0xa8, 0x42, 0xe9, 0x5f, 0x5a, - 0xa1, 0x7f, 0xba, 0x68, 0x9f, 0xa1, 0xb6, 0xb2, 0xed, 0x0c, 0xe6, 0xa9, 0xb3, 0x2e, 0xd6, 0x5b, 0x9a, 0x60, 0xd4, - 0x14, 0xd4, 0xe3, 0xa1, 0xbb, 0xb5, 0x29, 0xc9, 0x12, 0x95, 0xd4, 0xd8, 0x0b, 0x98, 0x09, 0xd9, 0x86, 0xdf, 0xe5, - 0xc3, 0x53, 0x04, 0x8d, 0xbc, 0xdc, 0xb1, 0x70, 0xa1, 0x40, 0x7f, 0xdf, 0xad, 0xcc, 0x74, 0x60, 0x1a, 0xb6, 0xcc, - 0x80, 0x92, 0xf1, 0xd4, 0x09, 0xea, 0x65, 0x2a, 0xe9, 0x55, 0xdc, 0xb9, 0x7e, 0x19, 0xaf, 0x48, 0xa5, 0xef, 0xf1, - 0x7c, 0x4a, 0x0a, 0x98, 0xda, 0x01, 0x24, 0xa1, 0xfb, 0x62, 0x94, 0x2a, 0x26, 0x4d, 0x67, 0xeb, 0x96, 0xc8, 0xb6, - 0xcf, 0x96, 0x12, 0xcf, 0xd0, 0xc7, 0xb1, 0xac, 0xcc, 0x09, 0x5d, 0x5d, 0x66, 0x14, 0xc1, 0xeb, 0xf7, 0x08, 0x4c, - 0x54, 0xb1, 0xc7, 0x92, 0x88, 0x6d, 0xee, 0x8c, 0xb4, 0xd8, 0x47, 0x41, 0x4c, 0x3f, 0x50, 0xc1, 0xa2, 0xbb, 0x5c, - 0x24, 0x25, 0xd2, 0xb1, 0xd4, 0xe4, 0x15, 0xcc, 0xcc, 0xef, 0xe1, 0x40, 0xc8, 0x76, 0xaf, 0xa6, 0xb8, 0x2b, 0xf7, - 0xb1, 0xdb, 0x63, 0x58, 0x45, 0xdc, 0x8f, 0x7e, 0x90, 0x22, 0xf5, 0xed, 0x2e, 0xca, 0x92, 0xd3, 0x92, 0xa0, 0xe8, - 0xab, 0x12, 0xaf, 0x96, 0xec, 0xa9, 0x2a, 0x47, 0x9a, 0x97, 0x65, 0x94, 0x65, 0x66, 0xe0, 0xc5, 0x2d, 0xdf, 0xf3, - 0x61, 0xcd, 0x1d, 0x6b, 0x48, 0x00, 0x5e, 0x8d, 0x91, 0xf1, 0x1e, 0xa6, 0x61, 0x3d, 0xde, 0x31, 0x02, 0x69, 0x81, - 0x2b, 0x2b, 0x30, 0x2e, 0x9e, 0xb0, 0xd0, 0x47, 0x0e, 0x53, 0xea, 0x03, 0x57, 0xc1, 0x94, 0x62, 0x3d, 0xce, 0x64, - 0x03, 0x20, 0x93, 0x55, 0x2f, 0xd1, 0xc9, 0xfb, 0x96, 0xc7, 0x39, 0x61, 0xdc, 0x12, 0x87, 0xbe, 0x1e, 0xcb, 0xea, - 0xbb, 0x87, 0x30, 0x3d, 0x35, 0x14, 0xac, 0x3f, 0x64, 0x8a, 0xcf, 0xcd, 0x8d, 0xe9, 0xb9, 0xbf, 0xbf, 0xc7, 0x70, - 0xd0, 0xe0, 0x6f, 0x8a, 0x5b, 0xc9, 0xc7, 0x5a, 0xce, 0x8b, 0x30, 0xa1, 0xf5, 0xa0, 0xfd, 0x4b, 0x24, 0x0c, 0xf3, - 0xb6, 0xfc, 0xfe, 0xb9, 0xdf, 0xbb, 0xfe, 0x21, 0x63, 0xb9, 0x6f, 0xe9, 0x65, 0x0f, 0x8c, 0x3e, 0xac, 0x2d, 0x26, - 0xcc, 0xc8, 0x68, 0x6f, 0x32, 0x40, 0x91, 0x33, 0x1b, 0xcb, 0xf0, 0x7a, 0x11, 0x46, 0x78, 0x01, 0xc0, 0xa1, 0xf6, - 0x78, 0xdd, 0x38, 0x66, 0xe2, 0xf3, 0x97, 0x2f, 0xfc, 0xdd, 0x7a, 0xd8, 0x26, 0x54, 0xbd, 0xb5, 0xa3, 0x94, 0xe4, - 0x08, 0x5e, 0x65, 0xc6, 0x58, 0x62, 0x53, 0xcb, 0x46, 0x9a, 0x36, 0xd1, 0xf6, 0x43, 0xf9, 0x39, 0x10, 0xc9, 0x33, - 0x7c, 0x1a, 0x31, 0x91, 0x42, 0xdf, 0xf8, 0x48, 0xaf, 0xa5, 0x86, 0x4a, 0x5c, 0x48, 0x30, 0x62, 0x72, 0x23, 0x55, - 0x69, 0x94, 0x9c, 0x67, 0x61, 0xa9, 0x99, 0xeb, 0xef, 0xbf, 0xe7, 0xe1, 0x7e, 0x24, 0x62, 0x38, 0xa8, 0x86, 0xd7, - 0x3a, 0xa0, 0x95, 0x23, 0x82, 0x7c, 0xf0, 0x5c, 0x6b, 0xa7, 0x90, 0x2f, 0x81, 0x04, 0x52, 0xaa, 0x22, 0xe2, 0xab, - 0x07, 0x7b, 0x22, 0x80, 0xec, 0xa2, 0x75, 0x6c, 0x53, 0x64, 0xb4, 0xe2, 0x28, 0xfb, 0xe3, 0xad, 0xab, 0xc4, 0x51, - 0x52, 0xf2, 0x94, 0xc1, 0x0a, 0xb7, 0x33, 0x8e, 0x52, 0x4c, 0x70, 0x50, 0xce, 0x09, 0xed, 0xe3, 0x0a, 0x73, 0xb6, - 0x4c, 0x59, 0xe0, 0xb8, 0x5e, 0x0d, 0xd2, 0xdb, 0x88, 0x74, 0xdd, 0x3b, 0xc3, 0x4c, 0x90, 0x2e, 0x95, 0x3b, 0x37, - 0xf3, 0x81, 0xc7, 0x2e, 0xb4, 0xa4, 0x15, 0x00, 0x30, 0x38, 0xc9, 0x43, 0x1e, 0xbe, 0x91, 0xa1, 0x82, 0x7c, 0xf8, - 0x1d, 0x67, 0x6f, 0x0e, 0x71, 0x10, 0x36, 0xf6, 0x3c, 0x01, 0xca, 0x8f, 0x43, 0xfd, 0xb7, 0x8d, 0xf7, 0x52, 0x54, - 0x21, 0x9b, 0xb1, 0x5f, 0x40, 0x84, 0xbb, 0xd2, 0xa7, 0x1a, 0xd3, 0xaa, 0xee, 0xb6, 0xef, 0x40, 0xbf, 0x1f, 0x47, - 0x3d, 0xba, 0x91, 0xa8, 0x85, 0x2a, 0x13, 0x14, 0xf2, 0xdc, 0x84, 0x9f, 0xeb, 0xca, 0x97, 0xe6, 0xdb, 0x3e, 0x39, - 0x14, 0xe6, 0x99, 0xe5, 0x80, 0x14, 0x20, 0xe4, 0x0b, 0xb3, 0x32, 0x5a, 0x9e, 0x69, 0xa7, 0x4c, 0x8c, 0xb7, 0x1f, - 0x9f, 0xb7, 0x2c, 0x82, 0x20, 0x92, 0xf0, 0x0d, 0x39, 0x97, 0x41, 0x3c, 0xb4, 0xa1, 0x60, 0x67, 0x08, 0x44, 0xcc, - 0x9c, 0xca, 0x0b, 0x44, 0xb6, 0xb1, 0x35, 0x49, 0xcc, 0xa7, 0xaf, 0xc1, 0x14, 0x01, 0xaa, 0x6f, 0xf9, 0x1d, 0x8e, - 0xc6, 0x1e, 0x93, 0x19, 0xf1, 0x03, 0x16, 0x93, 0x48, 0x7b, 0xf5, 0x6d, 0xb5, 0x43, 0xa2, 0xa4, 0x9a, 0x47, 0x1c, - 0x30, 0x0b, 0xcc, 0x02, 0x8f, 0x96, 0x06, 0x48, 0x09, 0x6c, 0xbb, 0x10, 0xd1, 0xb8, 0x01, 0xb7, 0x83, 0xdb, 0x76, - 0x01, 0x3d, 0x0c, 0x3c, 0xbb, 0x2f, 0x1e, 0x01, 0x9a, 0xea, 0x7f, 0x17, 0xc2, 0xc7, 0xc2, 0xcc, 0xe2, 0x7c, 0xde, - 0xa6, 0xf9, 0x58, 0x36, 0xbf, 0x76, 0xdd, 0x1b, 0xee, 0x3d, 0x86, 0x17, 0xaf, 0xda, 0xc5, 0x2a, 0xd2, 0x2b, 0xb3, - 0xfa, 0x00, 0xf5, 0x66, 0xde, 0xc4, 0x5f, 0xfa, 0x3e, 0x98, 0x31, 0x83, 0xb5, 0x79, 0x4d, 0x17, 0x32, 0xf4, 0x6a, - 0xcd, 0xe3, 0xa3, 0xdd, 0xfa, 0xe8, 0x6a, 0xe6, 0x3e, 0x86, 0xeb, 0x79, 0xe1, 0xfd, 0xd2, 0x7b, 0xcc, 0x39, 0xda, - 0x06, 0xe4, 0x80, 0x09, 0x0d, 0xf5, 0x62, 0xda, 0x9e, 0xe5, 0x89, 0xee, 0xe7, 0x0d, 0xc5, 0xb9, 0xd6, 0x88, 0xf9, - 0xad, 0x6c, 0xec, 0x7a, 0x00, 0x46, 0x9a, 0xd8, 0x49, 0xc3, 0x40, 0xc3, 0x4b, 0xcc, 0x21, 0xbc, 0x31, 0xf4, 0xee, - 0xcb, 0x64, 0x89, 0x09, 0x66, 0x41, 0x6d, 0x38, 0xd3, 0x9f, 0xcc, 0x50, 0x6d, 0xed, 0x6a, 0xcb, 0x29, 0x72, 0x32, - 0x50, 0x41, 0xbd, 0x34, 0x8f, 0x61, 0x7e, 0x3d, 0xd3, 0x63, 0xcf, 0x52, 0x96, 0x5b, 0x0a, 0x23, 0xf8, 0x0a, 0x1a, - 0xbf, 0x9a, 0xb1, 0xa6, 0x9c, 0x19, 0x7f, 0x87, 0xc1, 0xe9, 0x0f, 0xad, 0xd0, 0x49, 0x0b, 0x96, 0x19, 0x1a, 0x1d, - 0x49, 0x8d, 0x8e, 0x93, 0xa5, 0x6d, 0x1e, 0x3a, 0xe2, 0xe2, 0x72, 0x80, 0x92, 0x3b, 0xa8, 0x06, 0xa6, 0x5e, 0xad, - 0x35, 0xb6, 0xb2, 0xd9, 0xee, 0xed, 0x00, 0xb5, 0xa1, 0xe2, 0x0f, 0x06, 0xe1, 0xe7, 0xb4, 0x2d, 0x3e, 0x29, 0xba, - 0xae, 0x1d, 0x3a, 0x59, 0x5d, 0xef, 0xeb, 0xd2, 0xb8, 0x14, 0xac, 0x52, 0x1c, 0x5a, 0xbd, 0xe8, 0x88, 0x48, 0xc7, - 0xde, 0x49, 0xca, 0xe2, 0x0b, 0x36, 0x7f, 0xb4, 0xa9, 0xab, 0x46, 0xf1, 0x7f, 0x36, 0x0a, 0xbc, 0x12, 0x34, 0xb3, - 0xae, 0x29, 0xf0, 0xd6, 0x0f, 0x03, 0xca, 0x90, 0x2f, 0xaa, 0x08, 0xe6, 0x4c, 0xca, 0xdc, 0x97, 0xc8, 0x9b, 0xc2, - 0xd3, 0x4e, 0x04, 0x4f, 0x6b, 0x87, 0x0a, 0x72, 0xc3, 0x61, 0x50, 0x9e, 0xa0, 0x27, 0x9f, 0xbf, 0x0c, 0xcb, 0x08, - 0x90, 0x00, 0x41, 0x41, 0xc7, 0xbb, 0xef, 0x99, 0x8e, 0x16, 0xbd, 0x18, 0x1d, 0x0e, 0x40, 0x81, 0x0c, 0x91, 0x91, - 0x81, 0x31, 0x28, 0xf0, 0xdf, 0x80, 0xc9, 0x1a, 0xb6, 0x3d, 0xae, 0xe1, 0x01, 0xdf, 0xab, 0x3b, 0x9f, 0xc9, 0x4a, - 0x0b, 0xcc, 0xc0, 0x5d, 0xaf, 0x6d, 0x59, 0xba, 0x4a, 0x94, 0x13, 0xcf, 0xd7, 0x3c, 0x5e, 0xbc, 0xb8, 0x57, 0x1f, - 0xaa, 0xaa, 0xc8, 0x2b, 0xc1, 0xe7, 0x74, 0xa6, 0x02, 0x54, 0x4d, 0x88, 0xb1, 0xc4, 0x13, 0xe7, 0xa9, 0x25, 0x8b, - 0xea, 0x67, 0xc4, 0x2f, 0xc9, 0x8c, 0x13, 0x50, 0xd9, 0xca, 0xd4, 0x13, 0x71, 0xd0, 0xfa, 0x31, 0x9b, 0x2f, 0x3e, - 0x77, 0x56, 0x24, 0xce, 0x8b, 0x63, 0x12, 0xe1, 0x29, 0x0b, 0x25, 0xe7, 0xdc, 0x03, 0xbd, 0xf8, 0xc6, 0xbb, 0x7b, - 0x2e, 0x07, 0x1a, 0xa0, 0x7a, 0xe3, 0x0b, 0x47, 0xa9, 0xd2, 0x52, 0x3e, 0x28, 0x85, 0x02, 0x3a, 0x58, 0xb1, 0xf5, - 0x54, 0x4a, 0x21, 0x46, 0x92, 0xd1, 0x43, 0xaa, 0x26, 0xf8, 0x86, 0x85, 0x89, 0x6f, 0x52, 0xbd, 0xcd, 0x77, 0x25, - 0x8a, 0xad, 0x61, 0xdc, 0x6e, 0x83, 0x27, 0x33, 0xb3, 0x50, 0xee, 0x6f, 0x29, 0x2f, 0x64, 0x52, 0x66, 0xe2, 0xbf, - 0xf4, 0x6a, 0x1a, 0x15, 0x51, 0xcb, 0x36, 0xb6, 0x58, 0x70, 0x99, 0xc3, 0x52, 0x1d, 0xb6, 0xb5, 0x38, 0x66, 0xe6, - 0xff, 0xf5, 0x25, 0x91, 0xc7, 0x3e, 0x54, 0xc9, 0x9b, 0x13, 0xba, 0x4b, 0xda, 0x39, 0xd2, 0xd2, 0x5b, 0xa3, 0x14, - 0x85, 0x08, 0x78, 0x96, 0x14, 0x8e, 0x04, 0x7d, 0xe9, 0x2a, 0xf8, 0x74, 0x75, 0x5e, 0x85, 0x46, 0x07, 0x3f, 0x72, - 0xc5, 0x43, 0x27, 0xde, 0x7a, 0xea, 0x68, 0x7d, 0xe8, 0x7a, 0x8f, 0xc3, 0x2d, 0x9d, 0x72, 0xb0, 0x52, 0xe5, 0x36, - 0xfa, 0x87, 0x01, 0x34, 0x37, 0x12, 0x8a, 0x74, 0x86, 0x1f, 0x4a, 0x40, 0x2b, 0xd1, 0xfe, 0x22, 0x6f, 0x5c, 0xc8, - 0x0a, 0x8c, 0x31, 0x43, 0x12, 0x72, 0x64, 0xbd, 0x6b, 0xe7, 0x17, 0x72, 0xe3, 0xfd, 0x7f, 0xf6, 0x81, 0x76, 0xa9, - 0x43, 0xdd, 0x52, 0x5d, 0xbc, 0x3b, 0xf7, 0xa0, 0x94, 0xce, 0xd6, 0xc0, 0xdc, 0xb1, 0xa0, 0xde, 0x82, 0xe5, 0xa5, - 0x27, 0x31, 0x03, 0xad, 0x64, 0x94, 0x77, 0x7c, 0xd3, 0xdf, 0x8a, 0x8e, 0x95, 0x20, 0xd9, 0x87, 0xad, 0x27, 0x44, - 0xc4, 0x61, 0xb2, 0x32, 0x41, 0x0b, 0xa7, 0x30, 0x28, 0xd4, 0x5d, 0xe4, 0xdb, 0xd2, 0xad, 0xbc, 0x2d, 0x6c, 0x1d, - 0xd6, 0xb1, 0xf9, 0xc2, 0x39, 0x91, 0x55, 0x02, 0xec, 0x9b, 0x60, 0xba, 0x07, 0xdb, 0x3f, 0x1a, 0x46, 0x6d, 0x02, - 0xf7, 0xd8, 0x6e, 0x1f, 0x7a, 0x58, 0xa0, 0x26, 0xf0, 0x5f, 0xf1, 0x4c, 0x12, 0xc5, 0x6c, 0xf1, 0x85, 0x38, 0x77, - 0x9c, 0x54, 0x6d, 0x8d, 0x2d, 0x27, 0x62, 0x0c, 0x75, 0x82, 0xef, 0xb3, 0xfd, 0x18, 0x91, 0x68, 0xef, 0xe1, 0xa8, - 0x69, 0x92, 0xbf, 0x14, 0xc4, 0x09, 0x2c, 0x88, 0xee, 0x51, 0x87, 0xfb, 0xb7, 0x81, 0x2b, 0x4c, 0x69, 0xde, 0x88, - 0x0c, 0xb7, 0xbe, 0x2e, 0xc2, 0xa6, 0xb1, 0xe6, 0xda, 0xd1, 0x3e, 0x4f, 0xb3, 0x55, 0xd0, 0xbb, 0xa9, 0xe3, 0x62, - 0xfb, 0x48, 0xb3, 0x5e, 0x6d, 0x0a, 0xd1, 0xd7, 0x4e, 0x89, 0x01, 0xdf, 0xd3, 0x7d, 0x39, 0x3b, 0x02, 0xff, 0x79, - 0x05, 0x65, 0x8a, 0xdf, 0xc8, 0x8d, 0x4b, 0x11, 0x69, 0x30, 0xa8, 0x8a, 0x76, 0x1a, 0xca, 0xf4, 0xa4, 0xf6, 0xbf, - 0x53, 0x1a, 0xbb, 0x05, 0xfa, 0xa0, 0xb4, 0x1a, 0x85, 0x3e, 0x59, 0xfd, 0xf3, 0xaf, 0x79, 0xdb, 0x13, 0xcb, 0x20, - 0x95, 0x86, 0x07, 0xde, 0xb7, 0x03, 0x6f, 0xdb, 0xc5, 0x63, 0x9a, 0x7f, 0xe3, 0xc5, 0x0d, 0x89, 0x09, 0xb0, 0x3a, - 0x5b, 0x83, 0x37, 0x10, 0x66, 0xf1, 0xb1, 0x11, 0xfd, 0xd5, 0x15, 0x12, 0x88, 0x83, 0x34, 0xf1, 0xba, 0xdb, 0xc9, - 0xd7, 0x2a, 0xda, 0x7f, 0x6e, 0x6d, 0xc5, 0xe6, 0x04, 0x20, 0x23, 0x88, 0x41, 0xef, 0x0d, 0xba, 0x0b, 0xc1, 0x7f, - 0x62, 0xd3, 0xe9, 0x91, 0x9f, 0xc2, 0x1a, 0xbc, 0x7a, 0xd3, 0x8a, 0xea, 0xae, 0xfd, 0x3e, 0x71, 0xdb, 0xa0, 0x7f, - 0x2d, 0x79, 0xee, 0x83, 0x69, 0xcd, 0xb4, 0x33, 0x0f, 0x83, 0xd0, 0xa7, 0x87, 0x76, 0x5a, 0x9c, 0xe4, 0xce, 0xe6, - 0xec, 0xfb, 0x81, 0x3a, 0xa9, 0x31, 0x8c, 0x40, 0xe0, 0x20, 0x6c, 0x01, 0x03, 0x29, 0x05, 0xe1, 0x21, 0x67, 0xcd, - 0x3f, 0x00, 0xa5, 0x36, 0x22, 0x33, 0x74, 0x7d, 0xed, 0x9d, 0xc9, 0xfa, 0xe2, 0xda, 0x16, 0x22, 0x5c, 0xa8, 0x44, - 0xa6, 0x6a, 0x4b, 0x79, 0x42, 0xb7, 0xd6, 0x1d, 0x27, 0x13, 0xe2, 0x7d, 0x2e, 0x5b, 0x30, 0x9d, 0x0a, 0x1a, 0xcd, - 0x37, 0x8b, 0x4c, 0x81, 0xc4, 0x21, 0x31, 0x20, 0xc9, 0xdb, 0xb1, 0xed, 0x90, 0x49, 0x7d, 0xe4, 0x65, 0xf5, 0x67, - 0x11, 0x7d, 0x13, 0x5d, 0xa1, 0xb2, 0xf3, 0x6e, 0x28, 0x88, 0x02, 0x5e, 0xf4, 0xdc, 0x50, 0x08, 0x0e, 0xd9, 0xee, - 0x14, 0x7e, 0x93, 0x8e, 0x6a, 0x44, 0x5c, 0xcf, 0x4d, 0xe5, 0xc6, 0xe1, 0xf1, 0xc3, 0x98, 0x2e, 0x32, 0x4c, 0x18, - 0xaf, 0x4a, 0x1c, 0x37, 0x2c, 0x6e, 0x6c, 0x8e, 0xcf, 0x9f, 0xcf, 0xe5, 0x08, 0xf5, 0x42, 0xa5, 0x1c, 0x90, 0x32, - 0x20, 0xe1, 0xb1, 0xe5, 0x60, 0x32, 0xd9, 0x53, 0xd7, 0x11, 0xbe, 0xb0, 0x33, 0x80, 0x27, 0x7a, 0x87, 0x47, 0x59, - 0x11, 0x55, 0x50, 0xf0, 0xa5, 0x06, 0x83, 0xfa, 0x06, 0x85, 0x99, 0x00, 0x0e, 0x72, 0x2c, 0x2b, 0x14, 0xaa, 0xfe, - 0x4d, 0xe2, 0x5a, 0x17, 0x22, 0xdb, 0xf4, 0x54, 0x0a, 0x7f, 0xae, 0xd3, 0x3a, 0xe1, 0xb9, 0xd9, 0x71, 0xbb, 0x1c, - 0x52, 0x89, 0xac, 0x36, 0xe5, 0xcd, 0x41, 0x36, 0xff, 0x6b, 0xe6, 0xd2, 0xa3, 0x84, 0x8b, 0xbc, 0xb1, 0x8b, 0x48, - 0xa3, 0x58, 0xa9, 0x90, 0x5f, 0xea, 0xd3, 0x31, 0x2d, 0x9a, 0x43, 0xbe, 0xa1, 0x78, 0x3f, 0xd4, 0x51, 0xfc, 0x3b, - 0xd2, 0xa6, 0xc3, 0x8b, 0xe8, 0x3a, 0x8d, 0x24, 0x99, 0x84, 0x6d, 0x33, 0x3c, 0xc3, 0xd2, 0xaf, 0x19, 0xb7, 0xcd, - 0x23, 0x5c, 0x55, 0x28, 0x2f, 0x06, 0x09, 0x4a, 0xf2, 0x1b, 0xc0, 0x94, 0x81, 0x82, 0xee, 0x8c, 0x30, 0x9e, 0x8a, - 0x8a, 0x63, 0x14, 0xe4, 0x72, 0x77, 0x95, 0x81, 0x55, 0x9d, 0x36, 0x67, 0xbb, 0xee, 0xd5, 0x77, 0x93, 0x2e, 0xcd, - 0x65, 0x18, 0x9a, 0x1c, 0x0b, 0x4c, 0xed, 0x2c, 0x57, 0x76, 0x08, 0x54, 0x39, 0x1c, 0xd5, 0xed, 0x5f, 0xf3, 0x96, - 0xc8, 0x44, 0x29, 0xa8, 0x74, 0x26, 0xb8, 0x98, 0x8c, 0x53, 0xbf, 0x9b, 0xca, 0x27, 0xdc, 0xb7, 0xb3, 0xe5, 0xe3, - 0x6f, 0x5e, 0x16, 0xe8, 0x71, 0x71, 0x15, 0xd5, 0x6d, 0x81, 0x14, 0x6f, 0x53, 0xa3, 0xd2, 0xc3, 0x0f, 0x4b, 0xaa, - 0xc5, 0x1c, 0x80, 0xc9, 0xc4, 0x54, 0x3c, 0x80, 0xfd, 0x84, 0x16, 0xd3, 0x64, 0xbe, 0x81, 0x89, 0xae, 0xb0, 0xdd, - 0x1c, 0x7e, 0xa6, 0x30, 0x98, 0x72, 0xe9, 0x66, 0x6e, 0x59, 0x76, 0x3b, 0x2b, 0x1f, 0xc3, 0x38, 0x83, 0xbb, 0x56, - 0x71, 0x7f, 0xdb, 0x7d, 0xfb, 0x19, 0xa2, 0x6c, 0xbe, 0xfe, 0x14, 0xa0, 0x12, 0x34, 0x51, 0x54, 0xfc, 0x2b, 0x45, - 0x65, 0x73, 0xff, 0xc5, 0x51, 0x64, 0x2a, 0xf2, 0x9e, 0x05, 0x30, 0x04, 0x13, 0xf1, 0x01, 0x25, 0x04, 0xd3, 0x1c, - 0x09, 0xe8, 0xc8, 0x95, 0x40, 0x1c, 0xda, 0x4d, 0x86, 0x6f, 0xc9, 0x8b, 0xab, 0x36, 0xbe, 0x40, 0xf6, 0x59, 0x1a, - 0xf6, 0x8c, 0xc1, 0x85, 0xb1, 0x4d, 0x55, 0x7d, 0xc8, 0x77, 0x2f, 0x26, 0x90, 0x26, 0xd6, 0x62, 0x96, 0x5a, 0xcc, - 0xcd, 0x67, 0x72, 0x06, 0xd5, 0x76, 0x24, 0x91, 0x6d, 0xbf, 0x8b, 0x9a, 0xb3, 0x0c, 0xd2, 0xe6, 0x15, 0x8a, 0xcc, - 0xfc, 0xc0, 0x89, 0x61, 0x90, 0xfa, 0xf8, 0xc1, 0x4b, 0x9c, 0x38, 0x72, 0xda, 0x7f, 0x76, 0x24, 0x6e, 0x67, 0x55, - 0xbf, 0xe5, 0xc5, 0x29, 0xfa, 0x1c, 0xdc, 0xb1, 0xe3, 0x9c, 0x32, 0x64, 0xdb, 0x2e, 0x7e, 0x50, 0x6b, 0x11, 0x9d, - 0x00, 0x8c, 0xad, 0x2e, 0x93, 0x24, 0xfb, 0x9b, 0xff, 0x7b, 0x33, 0x88, 0x1b, 0x78, 0xf2, 0x27, 0x75, 0xf1, 0x1a, - 0xa1, 0x43, 0xd5, 0x03, 0x65, 0xc0, 0x81, 0x89, 0xa5, 0xa0, 0x7c, 0x5e, 0xd6, 0x04, 0xd7, 0x70, 0xbb, 0x4b, 0xbd, - 0x9e, 0x58, 0x74, 0xaa, 0x87, 0x81, 0xa4, 0xbf, 0x41, 0x47, 0xee, 0xc9, 0x57, 0xcf, 0x94, 0xf6, 0x86, 0xaf, 0xcb, - 0x7a, 0x33, 0xc1, 0x23, 0x32, 0x45, 0xcb, 0xd6, 0x2c, 0x91, 0x79, 0x50, 0x19, 0x0e, 0xf9, 0x29, 0xf6, 0x59, 0xf5, - 0x65, 0x2e, 0x62, 0x5d, 0x6a, 0xc1, 0xf0, 0x2a, 0xa4, 0x70, 0xe9, 0xc6, 0x02, 0xa2, 0x8a, 0xcf, 0x10, 0x56, 0xbf, - 0x53, 0x49, 0x20, 0xe5, 0x4d, 0xb5, 0x45, 0x64, 0x9e, 0xcf, 0x1a, 0x09, 0xbe, 0x8b, 0xdf, 0xc3, 0x11, 0x73, 0x16, - 0x36, 0x96, 0xdc, 0x1c, 0x8d, 0x6e, 0x7b, 0x50, 0xca, 0x82, 0x6c, 0x56, 0xcd, 0x3c, 0x30, 0x4b, 0xce, 0x26, 0x71, - 0x2c, 0xed, 0xf5, 0x45, 0x15, 0xff, 0x55, 0xa2, 0x89, 0xc5, 0x6b, 0xc4, 0x67, 0xa4, 0x44, 0xf8, 0x2e, 0x09, 0xb2, - 0xb7, 0xe7, 0x93, 0x61, 0x54, 0x38, 0xf5, 0x4b, 0x3f, 0x18, 0x99, 0xa9, 0x51, 0x67, 0xa7, 0x4a, 0xef, 0x13, 0x19, - 0x97, 0x07, 0x11, 0x8d, 0xb9, 0xb4, 0xfb, 0x84, 0xd3, 0x9a, 0x9c, 0x25, 0x03, 0x3d, 0x6d, 0x9b, 0x0c, 0x25, 0x84, - 0x9c, 0xc3, 0x61, 0x96, 0x8b, 0xaf, 0xbd, 0xc7, 0x6a, 0x4a, 0x26, 0xd4, 0x4f, 0x40, 0xeb, 0xc0, 0x4e, 0x87, 0xd5, - 0xd9, 0xb0, 0xac, 0x49, 0xb6, 0x3d, 0x56, 0x99, 0xe3, 0xbe, 0xae, 0xd4, 0xef, 0x4c, 0x47, 0x6d, 0xb1, 0x8d, 0xc1, - 0x9c, 0xa1, 0x49, 0xb6, 0x96, 0x1d, 0xdf, 0x56, 0x3b, 0xaa, 0xf1, 0xd1, 0x15, 0xbc, 0x54, 0x17, 0xed, 0xe9, 0xb4, - 0x5c, 0x45, 0x48, 0x17, 0xfd, 0xaf, 0xb4, 0x8d, 0x78, 0x01, 0x94, 0xd5, 0xa8, 0x94, 0x3e, 0xee, 0xf3, 0x3c, 0x71, - 0x6e, 0xf4, 0x66, 0x3e, 0x23, 0x7a, 0x88, 0xb3, 0xcf, 0xf0, 0xbc, 0x43, 0x89, 0x1c, 0x5b, 0x4a, 0xc9, 0xf0, 0xca, - 0xb2, 0x5f, 0xe0, 0xe6, 0xe8, 0xdd, 0x0e, 0xd1, 0xae, 0xdd, 0x6f, 0x77, 0x7a, 0xfd, 0xed, 0x83, 0x68, 0x4e, 0xc8, - 0x93, 0xf7, 0xa1, 0xc5, 0x60, 0x10, 0x1a, 0xf9, 0x00, 0x7d, 0xcd, 0xf7, 0xfc, 0x9f, 0xae, 0xbd, 0x81, 0xb0, 0x42, - 0xd4, 0xbb, 0x0d, 0x11, 0xae, 0xcf, 0xed, 0xcf, 0x1c, 0xa4, 0xa8, 0xea, 0x34, 0xc8, 0xfd, 0x99, 0xed, 0x75, 0x6f, - 0x91, 0x42, 0x32, 0xf5, 0x3b, 0x5a, 0x49, 0xea, 0x12, 0xbc, 0x51, 0xd4, 0xbe, 0x1a, 0x1f, 0x6b, 0x62, 0x25, 0x27, - 0x62, 0xf4, 0xbf, 0xbf, 0xb2, 0xc7, 0x10, 0xd6, 0x55, 0x0f, 0x05, 0xd3, 0x17, 0xe5, 0x90, 0x62, 0x5a, 0xd1, 0x3b, - 0xc6, 0xd7, 0x36, 0xc3, 0x27, 0x7c, 0xb1, 0x30, 0x3c, 0x7b, 0x8f, 0x25, 0xbe, 0xb0, 0x69, 0x0d, 0x13, 0x61, 0x41, - 0x1f, 0x00, 0x9c, 0x1b, 0xea, 0x24, 0xef, 0x44, 0xdf, 0xd1, 0xd3, 0xf4, 0xf4, 0x45, 0xdc, 0xbe, 0x75, 0x6b, 0x30, - 0x58, 0x16, 0x99, 0xff, 0x46, 0x10, 0x0d, 0x4a, 0x80, 0xd8, 0xf1, 0xe6, 0x2b, 0xa6, 0x35, 0x45, 0x30, 0x69, 0x0b, - 0x2e, 0xc0, 0x6c, 0xb8, 0x75, 0x31, 0x8a, 0x05, 0x60, 0x96, 0x33, 0x69, 0x1a, 0xa7, 0x1d, 0xbd, 0x5f, 0x77, 0x34, - 0xf7, 0x00, 0xf6, 0xe3, 0xa8, 0xec, 0xe2, 0x73, 0xaa, 0xc4, 0x72, 0x3e, 0x32, 0xf9, 0xe0, 0xf7, 0x2d, 0xee, 0x62, - 0xa3, 0xc0, 0xe6, 0xf4, 0xde, 0xae, 0xbc, 0xfc, 0x59, 0x0f, 0x53, 0x7e, 0xe1, 0x86, 0xe3, 0x59, 0xfd, 0xd2, 0x68, - 0xab, 0x99, 0x5c, 0x66, 0xf7, 0x16, 0xd1, 0xec, 0xcb, 0x07, 0xee, 0x41, 0x13, 0x08, 0xbd, 0xba, 0x1c, 0x78, 0xbf, - 0x6c, 0xf5, 0x77, 0xa3, 0xbd, 0x55, 0xaf, 0x26, 0x92, 0xa2, 0x3c, 0x90, 0x00, 0xcf, 0x99, 0x60, 0x81, 0xc4, 0xcf, - 0xd1, 0xba, 0x9f, 0x62, 0xb7, 0x8b, 0x14, 0x49, 0x4f, 0xa7, 0x6c, 0x3c, 0xc8, 0x99, 0xac, 0x6a, 0x69, 0x36, 0x5e, - 0x31, 0x6c, 0x58, 0xc3, 0xbf, 0x48, 0x47, 0xce, 0x5b, 0x1a, 0x0b, 0xb5, 0x0b, 0xf0, 0x11, 0x67, 0x85, 0x1b, 0x10, - 0x33, 0x45, 0x39, 0xc1, 0x41, 0xef, 0xa6, 0xa4, 0x15, 0x03, 0xb6, 0xec, 0x09, 0x3d, 0x5f, 0x22, 0xa9, 0x70, 0x83, - 0xa1, 0x73, 0xe6, 0xeb, 0xfb, 0xa3, 0x92, 0xf5, 0x21, 0xbd, 0x03, 0x19, 0x15, 0xb1, 0x73, 0xc2, 0xe6, 0x44, 0xb9, - 0x30, 0x0e, 0x39, 0xce, 0xe7, 0x07, 0x49, 0x7b, 0x6d, 0x7b, 0x02, 0x74, 0xa7, 0xbd, 0x38, 0x35, 0xb3, 0x59, 0x3a, - 0x10, 0x6b, 0xf4, 0xf2, 0xba, 0xd4, 0xb5, 0xbf, 0xe1, 0x1e, 0x00, 0xed, 0x33, 0x2f, 0xc7, 0xf3, 0x45, 0x46, 0xaf, - 0xb9, 0xf2, 0xe2, 0x07, 0x4a, 0xf1, 0xce, 0xa6, 0x87, 0x2f, 0xeb, 0x58, 0x33, 0xc2, 0x53, 0xb2, 0xd2, 0x5e, 0x5d, - 0x85, 0x95, 0xa6, 0xcc, 0x4e, 0x39, 0x63, 0x66, 0xa4, 0xb2, 0x7b, 0xbe, 0x81, 0x85, 0xe1, 0xaf, 0xb0, 0x62, 0x9f, - 0x71, 0xe1, 0x7a, 0xd1, 0xa7, 0xb9, 0xb4, 0x8c, 0x10, 0xaf, 0x68, 0xd6, 0xb1, 0xc9, 0x83, 0x0a, 0xce, 0x75, 0x73, - 0xb7, 0x18, 0x19, 0x91, 0xe4, 0x2b, 0x51, 0x2d, 0x7b, 0xa2, 0x6f, 0xfb, 0x06, 0x66, 0xc6, 0xaf, 0x9c, 0xbb, 0x7a, - 0xc9, 0x31, 0x09, 0xec, 0x0b, 0x2c, 0x57, 0x53, 0xec, 0xd7, 0x83, 0x68, 0xb1, 0xd3, 0x3a, 0x57, 0xff, 0xe4, 0x57, - 0x03, 0xa1, 0xe3, 0x55, 0x0a, 0xe2, 0x0c, 0xb9, 0x79, 0x86, 0x7b, 0xf6, 0xf8, 0x82, 0x0d, 0xb8, 0x44, 0xb6, 0x4b, - 0x3d, 0x1e, 0x2b, 0xa4, 0xa8, 0xbf, 0xe8, 0x45, 0xc4, 0xdd, 0xcb, 0xee, 0x00, 0xfa, 0x2b, 0xa7, 0xe2, 0xd7, 0xa7, - 0xef, 0x7e, 0x90, 0x80, 0x7f, 0x59, 0x2a, 0x99, 0xfd, 0x51, 0xe1, 0xed, 0x04, 0xa4, 0xfe, 0x3d, 0x27, 0x96, 0xe9, - 0xb4, 0xed, 0xef, 0x70, 0x23, 0x60, 0x5e, 0x43, 0x2c, 0x7e, 0xb1, 0xfb, 0xa5, 0x1f, 0x5d, 0x30, 0xd2, 0x6a, 0x47, - 0x16, 0x11, 0x38, 0x07, 0x3c, 0x01, 0x0c, 0x5e, 0x10, 0x13, 0x95, 0x55, 0x85, 0xea, 0x14, 0xf8, 0xda, 0x90, 0x11, - 0xb4, 0x2a, 0x63, 0x89, 0x09, 0x13, 0x1c, 0x90, 0x4d, 0x22, 0x39, 0x80, 0xdf, 0xa8, 0xcd, 0x95, 0x73, 0x91, 0xaf, - 0x61, 0xb1, 0xc1, 0xcb, 0x67, 0x0f, 0xde, 0xd3, 0xb8, 0xff, 0x77, 0x14, 0x0a, 0x2d, 0xb3, 0x5f, 0x8d, 0xc6, 0x44, - 0x93, 0x4f, 0x86, 0x57, 0x6c, 0xa2, 0xa5, 0x05, 0x3d, 0x03, 0xd2, 0x4f, 0x85, 0x44, 0x4f, 0x51, 0x55, 0x25, 0xfd, - 0xb8, 0x69, 0x1c, 0x72, 0x99, 0x0d, 0xb4, 0x25, 0x42, 0xd9, 0x13, 0x0c, 0x56, 0x50, 0x8d, 0x6f, 0x7e, 0xca, 0xa8, - 0x20, 0xd1, 0xf1, 0x9f, 0xbb, 0xc2, 0x13, 0xfa, 0x2b, 0x46, 0x01, 0xf3, 0xe7, 0x2a, 0x25, 0x60, 0xf6, 0xb2, 0xb5, - 0x9c, 0x82, 0x40, 0xc2, 0xdc, 0x3c, 0x54, 0x38, 0x7a, 0x7e, 0xa5, 0x3d, 0xd1, 0xf5, 0x65, 0x7c, 0x3e, 0x92, 0x18, - 0xa4, 0xe7, 0x2b, 0x78, 0x94, 0xa5, 0x1f, 0x49, 0x61, 0x52, 0x43, 0xe4, 0x22, 0x2e, 0x81, 0xa7, 0x1d, 0x25, 0x8c, - 0xf0, 0xbf, 0xec, 0xf0, 0xa0, 0xa3, 0x70, 0xd7, 0x92, 0x2f, 0xb1, 0x65, 0x75, 0xe4, 0x19, 0x25, 0xb9, 0x38, 0xde, - 0xc2, 0x64, 0x64, 0x39, 0x44, 0x93, 0xc0, 0x8b, 0x63, 0xa2, 0xd7, 0x6b, 0x4e, 0x75, 0xf7, 0x8d, 0x3f, 0xa8, 0x47, - 0x3a, 0xbd, 0x28, 0xc8, 0xf3, 0x84, 0x60, 0xa9, 0xd0, 0x75, 0x06, 0x3e, 0xad, 0x34, 0x56, 0xca, 0xdf, 0x8c, 0x18, - 0x2d, 0x6f, 0xc6, 0xa5, 0x8b, 0x98, 0x0a, 0x57, 0x7e, 0x1c, 0x72, 0xb9, 0xfe, 0xc1, 0x64, 0x15, 0x90, 0x8e, 0x08, - 0xe9, 0xc1, 0x57, 0x6e, 0x4f, 0x3c, 0xaa, 0xa0, 0x5c, 0xd4, 0x0a, 0xa3, 0x87, 0x22, 0xf7, 0x80, 0xe8, 0xd4, 0xeb, - 0x8e, 0x2e, 0x0e, 0xf7, 0x0f, 0x56, 0x45, 0x58, 0x07, 0x1c, 0x58, 0xbc, 0xc8, 0xd8, 0xd1, 0xe3, 0x41, 0xea, 0x27, - 0xf1, 0x53, 0xeb, 0x9a, 0xd4, 0x76, 0xdf, 0x0d, 0x70, 0xd9, 0x12, 0xf0, 0xb3, 0x61, 0xce, 0xf9, 0x00, 0xe4, 0x24, - 0x1e, 0x7c, 0xd3, 0x9b, 0xe4, 0xa5, 0xe5, 0xf0, 0x5d, 0x02, 0x5b, 0x52, 0xdf, 0xd8, 0x12, 0xbd, 0xec, 0xd9, 0x67, - 0x94, 0xb6, 0x65, 0x31, 0x3a, 0xbe, 0xf3, 0xba, 0x85, 0xc6, 0x8d, 0x5a, 0x00, 0x3e, 0xe7, 0xe3, 0x91, 0x60, 0x03, - 0xf8, 0xe8, 0x78, 0x8e, 0x21, 0xfc, 0x5e, 0x3c, 0x56, 0x89, 0xd6, 0x27, 0x7a, 0xb9, 0xb9, 0xa0, 0x29, 0x7b, 0x93, - 0x79, 0x16, 0x8d, 0xe3, 0x8e, 0x8f, 0x28, 0xb1, 0x10, 0xda, 0x34, 0xb9, 0xc9, 0xcd, 0x8e, 0x66, 0x57, 0x65, 0x77, - 0x2d, 0x44, 0x16, 0x83, 0xa0, 0x74, 0x57, 0x25, 0x60, 0x38, 0x3a, 0xf1, 0x9f, 0x89, 0x2b, 0xd1, 0x16, 0xd4, 0x02, - 0xa2, 0x75, 0x9a, 0x4e, 0xe4, 0x4c, 0xa9, 0x35, 0x56, 0xeb, 0xa4, 0xf4, 0xa3, 0x2c, 0x0d, 0xa5, 0xec, 0x58, 0x45, - 0xe5, 0x98, 0xbb, 0x1d, 0xf5, 0x9b, 0xa6, 0x6a, 0x2a, 0x9e, 0x15, 0xd5, 0x09, 0x9e, 0x56, 0xfc, 0xae, 0x0c, 0x4d, - 0xb0, 0x9e, 0x04, 0x1c, 0xb7, 0xd2, 0x3d, 0xe8, 0x8d, 0xe9, 0x47, 0x03, 0x12, 0x23, 0xd9, 0xab, 0x51, 0xf0, 0x42, - 0xca, 0x23, 0x19, 0x85, 0xc0, 0x34, 0xd7, 0xe8, 0x0b, 0xf5, 0x2d, 0xe4, 0xcd, 0xdb, 0x6d, 0x8a, 0x67, 0x7f, 0xcd, - 0xae, 0x58, 0x48, 0x55, 0xef, 0x35, 0xb6, 0xc0, 0x2f, 0x5c, 0xc3, 0xeb, 0xd3, 0xae, 0xf3, 0x38, 0x37, 0x47, 0x0c, - 0xa4, 0x10, 0xb2, 0xc4, 0x80, 0xab, 0x93, 0x6c, 0x0a, 0x70, 0xac, 0x09, 0xdf, 0x34, 0xc7, 0x78, 0x85, 0x33, 0xae, - 0xf2, 0x89, 0xa1, 0xf3, 0xea, 0xd5, 0x80, 0x50, 0x8c, 0x79, 0xe0, 0x92, 0xd9, 0x46, 0x14, 0xcb, 0x5a, 0x0d, 0xd4, - 0xdb, 0x8b, 0xa7, 0x47, 0x03, 0xb6, 0x8c, 0xd1, 0x91, 0xe0, 0xd7, 0x3f, 0x73, 0xa9, 0x01, 0xa2, 0xe1, 0x6c, 0x86, - 0xe1, 0xc5, 0xf5, 0x99, 0x74, 0x99, 0x87, 0x48, 0xd0, 0xeb, 0x9a, 0xe6, 0x44, 0xd4, 0x58, 0x6f, 0xb5, 0x2b, 0xa7, - 0x5b, 0xaa, 0xcb, 0xde, 0xc3, 0x09, 0xb8, 0xf6, 0x52, 0xae, 0xf7, 0x54, 0xc4, 0x06, 0x2e, 0x78, 0xee, 0xdf, 0x94, - 0x85, 0xa7, 0x50, 0x07, 0x66, 0xe9, 0x16, 0x85, 0x6b, 0xdd, 0x95, 0xc3, 0xd0, 0x5e, 0xbc, 0xb9, 0x3e, 0xc7, 0x47, - 0x29, 0xfa, 0x39, 0xb2, 0xcb, 0x49, 0xdd, 0xb7, 0xcb, 0x77, 0xb4, 0x22, 0xcf, 0x3c, 0x8d, 0x8e, 0x1c, 0x6b, 0x72, - 0xc3, 0xa1, 0x08, 0x9c, 0x45, 0x7b, 0x61, 0xcd, 0x61, 0x5f, 0xc4, 0xc4, 0xc9, 0xf9, 0x41, 0x99, 0x1e, 0x54, 0x5d, - 0xa4, 0xce, 0x53, 0x3e, 0x38, 0x0e, 0xa7, 0xff, 0x0c, 0x49, 0x7b, 0x8d, 0x48, 0x26, 0xba, 0x47, 0xcd, 0x61, 0xf0, - 0x5b, 0xff, 0x4f, 0x77, 0x73, 0xf8, 0x91, 0xa3, 0x28, 0x3a, 0x6c, 0xb9, 0xbb, 0xce, 0x8f, 0x2e, 0x03, 0xff, 0x10, - 0x04, 0x3a, 0x8e, 0x4d, 0xd4, 0x86, 0x34, 0xea, 0x8e, 0x54, 0xbf, 0x81, 0xe2, 0xd2, 0x65, 0x74, 0x9b, 0x39, 0x01, - 0x83, 0xd0, 0xce, 0x40, 0x0b, 0x95, 0x10, 0xae, 0xc2, 0x6b, 0xbb, 0x3d, 0xb8, 0xce, 0x1d, 0xde, 0xbd, 0x78, 0xed, - 0x38, 0xd9, 0xcf, 0x37, 0x74, 0xf6, 0x7a, 0xf1, 0x36, 0xeb, 0xd6, 0x76, 0x48, 0xc3, 0x9d, 0x0d, 0x4d, 0xe7, 0x5c, - 0x1d, 0x29, 0x69, 0x5d, 0xdf, 0xaa, 0xa5, 0x33, 0x11, 0x5c, 0x27, 0xb3, 0x41, 0xf8, 0x14, 0x88, 0x5d, 0x10, 0x3d, - 0x76, 0x9e, 0x9d, 0x31, 0x83, 0x29, 0x8e, 0xfc, 0x57, 0xd8, 0x42, 0x6d, 0xba, 0x28, 0x89, 0xeb, 0xf8, 0x78, 0xd5, - 0xe0, 0x14, 0x60, 0xec, 0x96, 0x1d, 0x25, 0x34, 0x8c, 0xa8, 0x9c, 0xc5, 0x38, 0xe3, 0xa8, 0xde, 0x80, 0x2b, 0x95, - 0x99, 0x1a, 0x5f, 0x99, 0x10, 0xb6, 0x17, 0x67, 0x9c, 0x5d, 0x1e, 0x4b, 0x91, 0x1a, 0x74, 0x2e, 0x73, 0x3f, 0xd5, - 0x7c, 0xc1, 0x2a, 0xaf, 0xb4, 0xa0, 0x18, 0xdc, 0xbd, 0x46, 0x17, 0x8d, 0xfa, 0x68, 0x54, 0x29, 0x27, 0xa7, 0xf2, - 0x3f, 0x46, 0xcd, 0x73, 0x40, 0xee, 0xb9, 0xe5, 0xc1, 0x1a, 0xb2, 0xcb, 0xd5, 0xe5, 0x91, 0x53, 0x28, 0xea, 0x4b, - 0xd9, 0x73, 0x54, 0x6e, 0xe4, 0x72, 0x96, 0xfb, 0x74, 0x45, 0xc4, 0xfc, 0x63, 0x12, 0xf7, 0x9c, 0x16, 0x68, 0x95, - 0x39, 0x85, 0xff, 0xbe, 0xfb, 0x3b, 0x20, 0x6c, 0x0c, 0x20, 0xd3, 0x61, 0xfa, 0x77, 0x5a, 0x0d, 0x50, 0x38, 0xa4, - 0x2c, 0x8c, 0x31, 0xef, 0x61, 0x3b, 0x89, 0x42, 0xee, 0xc0, 0xe3, 0xad, 0x99, 0xd8, 0xdd, 0xac, 0x96, 0x09, 0xdd, - 0x1e, 0x36, 0x08, 0x76, 0x60, 0x83, 0xf4, 0xa3, 0x38, 0xe9, 0x4a, 0x9d, 0x0a, 0x40, 0x2f, 0xf1, 0xb6, 0x1c, 0x7b, - 0x6c, 0xcb, 0xf0, 0xba, 0x79, 0x52, 0xc8, 0x2d, 0xe3, 0x3e, 0xa1, 0x82, 0x93, 0x03, 0xd3, 0x08, 0x56, 0x02, 0x8d, - 0x1d, 0xfe, 0x88, 0x27, 0xcd, 0x4d, 0x33, 0x4a, 0x59, 0xb7, 0x89, 0xed, 0xd7, 0x8a, 0x9d, 0x69, 0xb8, 0xf8, 0x92, - 0xf2, 0x32, 0x62, 0x2e, 0x08, 0x59, 0x28, 0x3e, 0xff, 0x9e, 0x2a, 0xfd, 0x92, 0xa4, 0x7e, 0x62, 0x17, 0xee, 0xa2, - 0xa3, 0x4c, 0x94, 0xef, 0x62, 0x28, 0x3d, 0x30, 0xa4, 0xcf, 0x13, 0x27, 0xee, 0x4c, 0xc7, 0x0b, 0x72, 0x42, 0x50, - 0xc6, 0x6e, 0x43, 0x0a, 0xf6, 0x9f, 0x2e, 0x3d, 0x6f, 0xb9, 0x26, 0xb2, 0x56, 0x99, 0xc4, 0x75, 0x33, 0x60, 0x18, - 0xf7, 0x79, 0x47, 0x06, 0xdc, 0x62, 0xe2, 0xe1, 0x45, 0xd9, 0xa6, 0xaf, 0x62, 0x3e, 0x32, 0xfe, 0xf8, 0xc1, 0xb1, - 0x1e, 0xb7, 0xee, 0x5f, 0xe2, 0x52, 0xd6, 0x80, 0x36, 0x93, 0x7a, 0x78, 0x63, 0x09, 0xdb, 0x71, 0x1e, 0x68, 0x85, - 0x0c, 0xed, 0x87, 0x63, 0x1f, 0x79, 0x5b, 0x6a, 0x00, 0xa1, 0x61, 0xa7, 0xee, 0x56, 0x75, 0xeb, 0x57, 0xaf, 0x1b, - 0x12, 0xae, 0x24, 0xdc, 0xa7, 0x87, 0xc6, 0x9d, 0x52, 0x3f, 0x6c, 0x93, 0x95, 0xc5, 0x61, 0x59, 0x4c, 0x1a, 0x67, - 0x10, 0x23, 0xbc, 0x5a, 0x91, 0xfe, 0xe6, 0x38, 0xe9, 0xe6, 0x4a, 0x60, 0xee, 0xff, 0x1a, 0x94, 0x14, 0xd3, 0x32, - 0x30, 0x16, 0xbe, 0x4f, 0x37, 0xca, 0x33, 0xdc, 0x0c, 0x03, 0xde, 0x5b, 0x01, 0x56, 0x61, 0xd8, 0x5a, 0x03, 0xd1, - 0x58, 0x28, 0x44, 0xd1, 0x47, 0xe9, 0xef, 0x36, 0x15, 0xab, 0x0b, 0x5f, 0x02, 0xb4, 0x5f, 0x4a, 0x0d, 0x85, 0x86, - 0x20, 0xe3, 0x27, 0xf7, 0x71, 0x2e, 0xf7, 0xb1, 0x59, 0x2e, 0x03, 0xa6, 0xe3, 0x17, 0x7b, 0x9b, 0x39, 0x2c, 0x8e, - 0x25, 0x50, 0x03, 0xf7, 0x1e, 0xc4, 0x7f, 0x9e, 0x15, 0x49, 0xb1, 0x5a, 0xf1, 0xcc, 0x01, 0xe0, 0x54, 0xe1, 0xc1, - 0xd5, 0xf9, 0xa7, 0xee, 0x30, 0x6c, 0xbd, 0xf8, 0x7b, 0x60, 0x73, 0xe8, 0xed, 0x67, 0x4e, 0xa7, 0xde, 0x4d, 0x60, - 0x0a, 0x38, 0x1f, 0xd6, 0x9f, 0xec, 0x33, 0x86, 0x35, 0xb9, 0xaf, 0x8b, 0xb1, 0x28, 0x91, 0x0f, 0xc4, 0x26, 0xcd, - 0xde, 0xf2, 0xc6, 0x17, 0x71, 0x3e, 0x74, 0x66, 0x47, 0xa6, 0x5c, 0xad, 0x32, 0x40, 0xa7, 0x3a, 0xff, 0x27, 0x05, - 0x92, 0x5b, 0x3a, 0x0f, 0xc3, 0xf4, 0x33, 0xfb, 0x04, 0xb0, 0x0a, 0xde, 0x06, 0x82, 0x01, 0xff, 0x2e, 0x82, 0x04, - 0xe0, 0xc8, 0x86, 0xe3, 0xaf, 0x49, 0x98, 0x50, 0x73, 0x8a, 0x8b, 0x98, 0xff, 0x0d, 0x10, 0x22, 0x14, 0xec, 0x7b, - 0xb4, 0xc5, 0xdd, 0x85, 0x34, 0x84, 0x19, 0x50, 0xfb, 0x7f, 0x84, 0xc7, 0x92, 0x42, 0x94, 0x2f, 0x18, 0x43, 0x3e, - 0xa5, 0xba, 0xd4, 0xbb, 0xe0, 0x3e, 0x01, 0xbb, 0x76, 0xe5, 0xd6, 0x45, 0xde, 0xdf, 0x43, 0x51, 0xee, 0x8f, 0x04, - 0xf6, 0x3c, 0x41, 0x43, 0x2b, 0x5a, 0xb8, 0x6e, 0x49, 0xe7, 0xff, 0x5d, 0x73, 0x83, 0x57, 0x0f, 0x9f, 0x82, 0xdc, - 0x03, 0x22, 0x33, 0x65, 0x9a, 0xdb, 0x03, 0xfa, 0x51, 0x69, 0xc0, 0x0a, 0x20, 0x10, 0xc8, 0xd0, 0xc4, 0x61, 0x48, - 0xbd, 0x87, 0xbf, 0x2a, 0x19, 0x34, 0x77, 0x45, 0x0f, 0xe6, 0xc5, 0x8f, 0x33, 0xf3, 0x64, 0x82, 0xab, 0xb0, 0x61, - 0xc0, 0x7d, 0xa8, 0x23, 0x7f, 0xb4, 0xdf, 0xd0, 0x33, 0x7f, 0x45, 0x8e, 0x5d, 0xbc, 0xcd, 0xdf, 0xac, 0x60, 0xb2, - 0xec, 0x17, 0x3b, 0xcf, 0x77, 0x6d, 0xa2, 0xfd, 0x05, 0xe2, 0x98, 0xef, 0xe4, 0x6d, 0x92, 0xa8, 0x93, 0x38, 0x07, - 0xa6, 0x76, 0x83, 0x82, 0xcf, 0x73, 0x18, 0xce, 0xd7, 0x68, 0xf4, 0x6d, 0xe6, 0x84, 0x4f, 0xbc, 0x59, 0xd2, 0x5b, - 0xd2, 0x1c, 0xcc, 0x60, 0xad, 0x68, 0x79, 0x70, 0x74, 0x59, 0x06, 0xbf, 0xac, 0x43, 0x99, 0x62, 0xec, 0x76, 0x97, - 0x11, 0x9a, 0x85, 0xd4, 0xed, 0xf6, 0x20, 0x2e, 0x3c, 0x92, 0x5d, 0x62, 0x22, 0x44, 0xbd, 0xb2, 0x3b, 0x64, 0x82, - 0x63, 0xe1, 0x39, 0xc6, 0x69, 0x0b, 0x64, 0xc9, 0x70, 0xcb, 0x02, 0x89, 0xe5, 0x6d, 0xb1, 0x2d, 0x51, 0x2d, 0xdd, - 0xe4, 0x49, 0x52, 0xbd, 0x9c, 0xa5, 0xec, 0xa2, 0xa4, 0x72, 0x39, 0x8e, 0xe2, 0xbf, 0xbc, 0x47, 0xbe, 0x8f, 0x86, - 0x8a, 0xad, 0xe0, 0x46, 0x57, 0xb7, 0x80, 0xad, 0x8e, 0x44, 0x32, 0x02, 0x7f, 0x80, 0x70, 0xdd, 0xfe, 0x71, 0xd4, - 0x27, 0x3e, 0x87, 0x46, 0x20, 0x44, 0x61, 0xc0, 0x51, 0x19, 0x54, 0xb9, 0x60, 0x56, 0x30, 0xe3, 0xfa, 0x03, 0x38, - 0xd4, 0x07, 0xc3, 0x22, 0xf3, 0x58, 0x8e, 0x1d, 0x21, 0xda, 0x4f, 0x98, 0xf5, 0x79, 0xe3, 0xd7, 0x45, 0x48, 0x11, - 0x8b, 0x34, 0xce, 0xcc, 0xea, 0xfc, 0x24, 0xfb, 0x11, 0xf4, 0xf5, 0xfa, 0x05, 0x24, 0xc7, 0x5d, 0x7e, 0x3a, 0x65, - 0x45, 0xfa, 0x90, 0xe7, 0xbe, 0x02, 0x95, 0xbf, 0xcc, 0xe1, 0xd9, 0x87, 0x42, 0xff, 0x50, 0x87, 0x5f, 0x70, 0x14, - 0xce, 0xbe, 0xb7, 0x77, 0xfb, 0xc3, 0xc4, 0x89, 0x4b, 0xda, 0x3b, 0x75, 0x37, 0xb6, 0x94, 0x14, 0xd7, 0x1f, 0xe4, - 0xb1, 0xc0, 0x45, 0xb0, 0xcf, 0x79, 0x2f, 0x23, 0x7d, 0x81, 0xf9, 0x4f, 0x36, 0xe0, 0x46, 0xf0, 0x4e, 0xfb, 0xfa, - 0x95, 0x38, 0xfe, 0xf7, 0xcf, 0x3f, 0x92, 0xc0, 0xaf, 0x56, 0x14, 0x31, 0xe2, 0x2a, 0x71, 0x62, 0x8e, 0x34, 0xc6, - 0x08, 0x0f, 0xa4, 0x3a, 0x03, 0x1a, 0xfd, 0x42, 0xa8, 0xb9, 0x51, 0xe6, 0x8f, 0x35, 0x08, 0x26, 0x3d, 0xf5, 0x63, - 0xf2, 0x18, 0x38, 0xa9, 0x21, 0x6c, 0xf0, 0x39, 0x22, 0x8d, 0x3e, 0xa9, 0xd4, 0x87, 0x66, 0xf6, 0xb7, 0x72, 0x6f, - 0xab, 0xc8, 0x0a, 0x2a, 0x6c, 0x79, 0x5b, 0x02, 0x8a, 0x2c, 0xb5, 0x36, 0x77, 0x09, 0xb7, 0x61, 0xca, 0x89, 0x58, - 0xc8, 0xbd, 0xa2, 0x21, 0x2b, 0xfe, 0x16, 0x0c, 0x24, 0x6d, 0xe1, 0x70, 0x78, 0x6a, 0xd5, 0x62, 0x7a, 0xfe, 0x5f, - 0x63, 0x55, 0xdf, 0xd4, 0xd1, 0x32, 0x46, 0x83, 0x9c, 0xda, 0xb4, 0x6a, 0x71, 0xb8, 0xc6, 0xe6, 0xce, 0x00, 0xbd, - 0x1a, 0x00, 0x77, 0x8a, 0x3c, 0x58, 0xcb, 0x17, 0x91, 0xe9, 0x08, 0x48, 0x11, 0x5e, 0xe3, 0x2a, 0xf7, 0xfb, 0x87, - 0xd9, 0x8e, 0xe8, 0xf0, 0x0c, 0x13, 0xdb, 0x16, 0xb4, 0x6b, 0xae, 0xb2, 0xec, 0x28, 0x5e, 0x79, 0x8c, 0x8c, 0xbf, - 0x3b, 0xe0, 0x75, 0x9c, 0xa7, 0x71, 0x83, 0x46, 0xd8, 0xff, 0x2d, 0x24, 0x10, 0xb8, 0x8a, 0x1e, 0x95, 0x3a, 0xf0, - 0xdc, 0xe3, 0xf8, 0x0c, 0xa7, 0x83, 0x41, 0xed, 0x4e, 0xe3, 0xf5, 0x3e, 0x07, 0xb3, 0xbd, 0x8a, 0xdb, 0x73, 0x41, - 0xf3, 0xb4, 0xf5, 0xfb, 0x18, 0x43, 0x77, 0x80, 0x30, 0x0b, 0x51, 0x0b, 0xe2, 0xf1, 0x0d, 0x10, 0x48, 0xab, 0x7d, - 0x36, 0x0f, 0x98, 0xa2, 0x42, 0xef, 0xce, 0x0c, 0x8d, 0xe8, 0xa7, 0xfb, 0x38, 0xb4, 0x84, 0x6d, 0x41, 0xfe, 0xb1, - 0x8a, 0x90, 0xf1, 0x48, 0xf8, 0x48, 0x46, 0x9a, 0x55, 0x37, 0xec, 0x3d, 0xea, 0x76, 0x43, 0xaf, 0x22, 0xbf, 0x5b, - 0x2b, 0x7b, 0x1a, 0x7d, 0xce, 0xff, 0x89, 0xf7, 0xbc, 0x6f, 0x86, 0x4d, 0xae, 0x6c, 0x15, 0x5b, 0x03, 0xd5, 0xfc, - 0x9c, 0x85, 0x0b, 0xd0, 0x28, 0xb4, 0xfc, 0x3c, 0xc0, 0x96, 0xaf, 0x4d, 0xb3, 0x7c, 0xea, 0xa7, 0x72, 0x54, 0x73, - 0x42, 0x41, 0xaa, 0x6c, 0x24, 0x1f, 0xc0, 0x0d, 0xec, 0xa9, 0xb0, 0x3e, 0x9c, 0x59, 0x3b, 0x59, 0x96, 0x9b, 0x85, - 0x05, 0x6c, 0xaf, 0xfe, 0xa4, 0x38, 0x2d, 0xc9, 0xad, 0x65, 0x81, 0x49, 0x40, 0xe9, 0xd0, 0x40, 0x0f, 0x15, 0xcb, - 0x68, 0xcc, 0x88, 0x8f, 0xaf, 0x6b, 0x30, 0x2b, 0x29, 0x37, 0xcf, 0xc4, 0x4e, 0x42, 0xfb, 0xb2, 0x61, 0x91, 0x6e, - 0xc3, 0x2b, 0xd5, 0x6d, 0x8d, 0x7e, 0x78, 0x3f, 0x81, 0xd4, 0xaf, 0x89, 0xaf, 0x2f, 0xe6, 0x7a, 0x31, 0x49, 0x99, - 0xe5, 0x7e, 0x4c, 0x1a, 0x0e, 0xa2, 0x1a, 0x3e, 0xca, 0xec, 0x4d, 0xf7, 0x64, 0xd4, 0x45, 0xe4, 0x2f, 0xd5, 0xf4, - 0xe1, 0x29, 0xe7, 0x74, 0x5d, 0x54, 0xb7, 0x3e, 0x33, 0x27, 0x79, 0xeb, 0x9e, 0x93, 0xe0, 0x7e, 0xfe, 0x9c, 0x84, - 0xbf, 0x9b, 0x6a, 0xfc, 0xa4, 0xdd, 0x63, 0x84, 0xea, 0x99, 0x3f, 0x17, 0xd8, 0xb0, 0xf6, 0xdb, 0x16, 0x32, 0x57, - 0xf0, 0x7d, 0xcc, 0x03, 0xd2, 0x07, 0xe1, 0x60, 0x01, 0xf1, 0xea, 0xe1, 0xd8, 0x0a, 0xb9, 0x12, 0xb4, 0xdc, 0xf5, - 0x80, 0x0b, 0x89, 0x76, 0x5d, 0x83, 0xd1, 0xcb, 0xe8, 0x9c, 0xd5, 0xf3, 0x1e, 0x5c, 0x7e, 0x3c, 0xb0, 0xd2, 0xe3, - 0x49, 0xb9, 0x14, 0xa5, 0x31, 0xb6, 0x14, 0x68, 0xdf, 0x75, 0x74, 0x9e, 0xd3, 0x49, 0xc6, 0x2e, 0x45, 0x96, 0xb6, - 0xae, 0xdb, 0x36, 0x27, 0xdf, 0xbb, 0x4e, 0x3f, 0x14, 0xd1, 0x0e, 0x25, 0xd1, 0x6b, 0x07, 0x93, 0xc3, 0xc3, 0xf7, - 0xe7, 0x7a, 0x6c, 0x59, 0xdb, 0xcd, 0xe6, 0xba, 0x01, 0x08, 0xc4, 0xc2, 0xf4, 0xce, 0xb0, 0x49, 0x37, 0xa3, 0xd5, - 0x4e, 0xff, 0xe8, 0x51, 0x94, 0x6a, 0x32, 0x8d, 0xa0, 0x86, 0x1b, 0xdf, 0x0f, 0x57, 0x42, 0x64, 0xd2, 0xd7, 0x2b, - 0x71, 0x03, 0xda, 0xb6, 0xe8, 0xcb, 0xc0, 0xe1, 0x8b, 0xa3, 0xd5, 0x31, 0x37, 0x72, 0x69, 0xec, 0xd7, 0xa5, 0xfb, - 0x96, 0xab, 0x11, 0x7c, 0x8f, 0x9e, 0xce, 0x6d, 0x96, 0x2b, 0xe5, 0xec, 0x23, 0xaa, 0x0e, 0x51, 0x0a, 0x1b, 0xf9, - 0xdc, 0x86, 0x80, 0xff, 0x47, 0x0c, 0x23, 0xfa, 0x29, 0x48, 0x8f, 0x22, 0xcb, 0x00, 0x15, 0xa9, 0x2a, 0xd2, 0x1f, - 0x17, 0x56, 0x30, 0x7d, 0xa4, 0xf8, 0x4d, 0xec, 0x19, 0xf8, 0xe9, 0x48, 0xc4, 0x40, 0x14, 0x68, 0x61, 0xf9, 0x4b, - 0xa8, 0x44, 0x94, 0x66, 0x37, 0xd9, 0xf2, 0x3f, 0xdb, 0x66, 0x2d, 0x5a, 0x70, 0x37, 0x60, 0xe6, 0x9b, 0x09, 0x40, - 0x60, 0x11, 0x14, 0x40, 0x81, 0xb7, 0x2e, 0x29, 0x02, 0xab, 0x8d, 0x4e, 0x5b, 0xbe, 0x55, 0x1a, 0xfe, 0x6f, 0xdd, - 0xb4, 0x0b, 0x98, 0xd4, 0x41, 0xa6, 0xb0, 0x50, 0x6b, 0x3a, 0x59, 0xb4, 0xcf, 0x7b, 0x14, 0x26, 0x1e, 0x0e, 0x53, - 0xd7, 0x4b, 0x29, 0x81, 0x37, 0x68, 0xbb, 0x9d, 0x48, 0x8e, 0xa7, 0xf6, 0x7f, 0x26, 0x99, 0x3a, 0x93, 0xbe, 0x3b, - 0x5f, 0xb7, 0xbc, 0xf6, 0x22, 0x22, 0x0c, 0x05, 0xdb, 0x6e, 0x09, 0x0e, 0x7d, 0x4b, 0x8c, 0x2e, 0xff, 0xcd, 0x4d, - 0x5b, 0xfd, 0xee, 0x6a, 0xc6, 0x37, 0xea, 0xf7, 0xc0, 0x8b, 0x59, 0xed, 0xc1, 0xa4, 0x5a, 0x7f, 0xc3, 0x81, 0x29, - 0x49, 0x7b, 0xf8, 0x35, 0x04, 0x54, 0x11, 0x3b, 0x19, 0x18, 0x76, 0x7f, 0xce, 0x06, 0xc2, 0x95, 0xe0, 0x2e, 0xa6, - 0xe4, 0xc2, 0x57, 0xfc, 0x97, 0x6f, 0xb6, 0x87, 0xcf, 0x90, 0x25, 0xef, 0xb8, 0x1f, 0xc6, 0xdc, 0x8d, 0xcd, 0x21, - 0x33, 0xa7, 0x7e, 0xa3, 0x9a, 0x43, 0x10, 0x38, 0xc5, 0x90, 0x28, 0xd6, 0x3e, 0x7a, 0x14, 0xce, 0x5e, 0x02, 0xd2, - 0x7f, 0xe6, 0x13, 0x2f, 0xfb, 0x32, 0x8c, 0xd1, 0xec, 0xeb, 0xd9, 0x03, 0x22, 0x31, 0x8c, 0xa6, 0xcc, 0xc3, 0x12, - 0x87, 0x12, 0x24, 0x6b, 0x73, 0x79, 0x15, 0xc7, 0x93, 0x04, 0xd5, 0x50, 0x37, 0x8b, 0xa9, 0xdf, 0xcc, 0x21, 0xb4, - 0xba, 0xca, 0xd1, 0xde, 0x86, 0x4e, 0x1d, 0x20, 0xee, 0xa2, 0x1b, 0x5a, 0xc5, 0x2a, 0x7c, 0x63, 0xd2, 0xda, 0xba, - 0xe3, 0xa7, 0xd5, 0x37, 0x5b, 0xef, 0x73, 0xc8, 0x18, 0x0d, 0x17, 0xef, 0x53, 0xbc, 0xcd, 0x32, 0xfd, 0xc1, 0xbc, - 0xa7, 0xd6, 0xa8, 0xdc, 0xb8, 0x98, 0xa8, 0xf7, 0x6e, 0x56, 0x86, 0x2d, 0x26, 0x42, 0x46, 0x25, 0x16, 0x43, 0x36, - 0xbf, 0xfc, 0x78, 0xdc, 0x7b, 0x35, 0xc9, 0xe2, 0x48, 0x35, 0xd8, 0x52, 0xc9, 0x75, 0xec, 0x4f, 0xac, 0x93, 0xb9, - 0x1d, 0x6c, 0xde, 0xa1, 0x21, 0xda, 0x0f, 0x3c, 0x49, 0x78, 0x80, 0xec, 0xa1, 0xa3, 0x41, 0x22, 0xe7, 0x8a, 0xce, - 0xbb, 0xb6, 0xef, 0x62, 0x82, 0xd9, 0x96, 0x66, 0xe1, 0x6f, 0xa0, 0x07, 0xc0, 0x1c, 0x61, 0xd4, 0x53, 0x23, 0x09, - 0xd4, 0x34, 0xbe, 0x3a, 0xa9, 0x5f, 0x52, 0xa2, 0x7d, 0xbd, 0xc2, 0xcb, 0x71, 0xaa, 0xa6, 0xca, 0x1a, 0x9e, 0x74, - 0xf4, 0x84, 0x02, 0xfc, 0x0f, 0xb0, 0x4f, 0x9d, 0x3c, 0x35, 0x82, 0x04, 0xe0, 0x88, 0x24, 0x93, 0x29, 0x96, 0x7a, - 0xb8, 0xb7, 0xe9, 0xec, 0x87, 0xbe, 0x75, 0x61, 0x56, 0x80, 0xdd, 0x54, 0x80, 0xde, 0x40, 0xe2, 0x63, 0x62, 0x4b, - 0x5a, 0x63, 0x07, 0x77, 0xba, 0x0b, 0x90, 0x77, 0xa8, 0xc6, 0x24, 0x8d, 0xd0, 0x82, 0xcd, 0xec, 0x11, 0xf8, 0xba, - 0xd6, 0x6c, 0xf1, 0x1a, 0x90, 0xa7, 0xfd, 0xff, 0x61, 0xcd, 0x48, 0x93, 0x83, 0xec, 0x2e, 0x52, 0x3f, 0xcb, 0x0a, - 0x06, 0xfe, 0x46, 0x5f, 0xe5, 0x88, 0xbb, 0xc7, 0x27, 0x16, 0xef, 0x92, 0xb4, 0x1e, 0x66, 0x67, 0x42, 0xe1, 0xd3, - 0x15, 0xf1, 0x58, 0x8d, 0x8e, 0x42, 0xdb, 0x35, 0xea, 0xcd, 0x40, 0x59, 0x3a, 0xb3, 0x9a, 0xc9, 0x1e, 0x4f, 0x59, - 0x20, 0x03, 0xdf, 0xed, 0x3e, 0xd7, 0xbb, 0x0f, 0x0b, 0xbb, 0xf0, 0xa2, 0x9f, 0xad, 0x8e, 0x64, 0x1c, 0x44, 0x9f, - 0x13, 0x1e, 0xa7, 0xd3, 0x8c, 0x7a, 0xd6, 0xfd, 0x9f, 0xa2, 0xf0, 0x61, 0xfe, 0x29, 0xd8, 0x84, 0x56, 0x96, 0xda, - 0xa9, 0x82, 0x15, 0xf6, 0x79, 0xf8, 0xe6, 0xd5, 0xdc, 0xe0, 0xfd, 0x77, 0x4b, 0x1a, 0x3c, 0x7e, 0x61, 0x3e, 0x1f, - 0xf3, 0x05, 0xfc, 0xac, 0x34, 0x2b, 0xf0, 0x95, 0x47, 0x31, 0x63, 0xe9, 0x9f, 0x4b, 0x9d, 0xc2, 0x44, 0xd4, 0xc3, - 0xbb, 0x65, 0xc3, 0x9f, 0xcf, 0x3e, 0xe3, 0x99, 0x89, 0x33, 0x61, 0x46, 0xdc, 0xb7, 0xba, 0x76 + 0x3c, + 0xb2, + 0x5f, + 0x25, + 0xfa, + 0xac, + 0xd5, + 0x7a, + 0x90, + 0x43, + 0x4f, + 0x64, + 0xd0, + 0x36, + 0x2f, + 0x2a, + 0x2d, + 0x2d, + 0x0a, + 0x90, + 0xcf, + 0x1a, + 0x5a, + 0x4c, + 0x5d, + 0xb0, + 0x2d, + 0x56, + 0xec, + 0xc4, + 0xc5, + 0xbf, + 0x34, + 0x00, + 0x72, + 0x08, + 0xd5, + 0xb8, + 0x87, + 0x18, + 0x58, + 0x65, + 0xb4, + 0xb0, + 0xa8, + 0x5a, + 0x99, + 0x3b, + 0x89, + 0xb9, + 0xb6, + 0x56, + 0x83, + 0xd6, + 0x0f, + 0x01, + 0x06, + 0xd2, + 0x8f, + 0xff, + 0x03, + 0x9d, + 0x0b, + 0x6f, + 0x34, + 0x08, + 0x90, + 0x0c, + 0x0f, + 0x2a, + 0x9d, + 0x44, + 0x63, + 0xde, + 0x83, + 0x62, + 0x20, + 0x56, + 0xbe, + 0x50, + 0xa8, + 0x81, + 0xbe, + 0xbf, + 0x2b, + 0x98, + 0x3a, + 0xb4, + 0x3e, + 0x06, + 0x99, + 0x12, + 0xf0, + 0xa5, + 0x75, + 0x82, + 0xfc, + 0xb1, + 0x8c, + 0xa7, + 0xa7, + 0xfe, + 0x40, + 0xa3, + 0x3c, + 0x76, + 0x6c, + 0x82, + 0x98, + 0x12, + 0xaf, + 0x32, + 0x7c, + 0x32, + 0xe1, + 0x26, + 0x58, + 0x9d, + 0x3c, + 0x64, + 0xf4, + 0x19, + 0xdd, + 0xff, + 0xf9, + 0xd8, + 0xc7, + 0x87, + 0xf6, + 0x95, + 0xcf, + 0xea, + 0x76, + 0x96, + 0x81, + 0x67, + 0x25, + 0xe3, + 0x92, + 0xc6, + 0x3b, + 0x53, + 0x7e, + 0x66, + 0x5a, + 0x6b, + 0x15, + 0xe1, + 0xe4, + 0x5a, + 0x2d, + 0xf8, + 0x0e, + 0x62, + 0x54, + 0xa7, + 0xa3, + 0xed, + 0xc8, + 0x43, + 0xde, + 0x19, + 0xe5, + 0xb0, + 0xd8, + 0x97, + 0xe8, + 0x04, + 0x82, + 0x9e, + 0xf3, + 0xed, + 0xed, + 0xa2, + 0x0b, + 0xbc, + 0xda, + 0x7c, + 0xf1, + 0x31, + 0x62, + 0x16, + 0x2a, + 0x1d, + 0xa8, + 0x86, + 0x95, + 0xf3, + 0xe3, + 0xa1, + 0xb5, + 0xf5, + 0x24, + 0xe5, + 0xbb, + 0x98, + 0x5f, + 0x73, + 0xc6, + 0x6d, + 0x66, + 0xdf, + 0x92, + 0x70, + 0x57, + 0x4f, + 0x90, + 0xb7, + 0x34, + 0x8e, + 0xc9, + 0x65, + 0xfd, + 0x51, + 0x45, + 0x75, + 0x28, + 0xfd, + 0x72, + 0xac, + 0x47, + 0x58, + 0xbe, + 0x57, + 0x3c, + 0x6d, + 0x8d, + 0x02, + 0x94, + 0xe1, + 0x7b, + 0xc9, + 0xf2, + 0x67, + 0xbf, + 0x9f, + 0x1c, + 0xaa, + 0x8d, + 0x38, + 0x48, + 0x67, + 0x7c, + 0xb9, + 0xb0, + 0xfa, + 0xed, + 0x8a, + 0x51, + 0xf2, + 0x41, + 0x50, + 0xfd, + 0xc8, + 0x60, + 0x3a, + 0xfa, + 0x82, + 0xe8, + 0xd5, + 0xd5, + 0x82, + 0x4a, + 0x71, + 0x6e, + 0x3f, + 0xb9, + 0x5b, + 0x0a, + 0xcc, + 0xe9, + 0xa7, + 0x56, + 0x06, + 0xd0, + 0x6f, + 0xe3, + 0x58, + 0x89, + 0xef, + 0xaa, + 0x6d, + 0x4e, + 0x0c, + 0x4b, + 0x3d, + 0xd2, + 0xdf, + 0xde, + 0x00, + 0xed, + 0x9b, + 0x12, + 0xd3, + 0xe1, + 0xf3, + 0x40, + 0xa7, + 0xae, + 0x4e, + 0x49, + 0x51, + 0xbd, + 0x67, + 0xff, + 0xfb, + 0x2d, + 0xb3, + 0x93, + 0xa0, + 0x3e, + 0x3e, + 0xf9, + 0x2c, + 0x90, + 0xbf, + 0xdf, + 0xde, + 0xb3, + 0x10, + 0xb7, + 0x52, + 0xbb, + 0x86, + 0x38, + 0x1a, + 0xd9, + 0x02, + 0x1e, + 0xee, + 0x15, + 0x15, + 0x5e, + 0xbb, + 0x3e, + 0xbf, + 0x54, + 0x66, + 0x44, + 0x2e, + 0x67, + 0xdf, + 0xb4, + 0x7e, + 0xf1, + 0xf3, + 0xb8, + 0x2f, + 0x59, + 0x0e, + 0xc2, + 0xca, + 0x99, + 0x68, + 0xc2, + 0xd3, + 0x5a, + 0x32, + 0x5f, + 0x27, + 0xb7, + 0x61, + 0x72, + 0x56, + 0x03, + 0xf7, + 0x40, + 0xc9, + 0xcd, + 0x10, + 0x96, + 0x15, + 0x88, + 0xf1, + 0x88, + 0x9c, + 0xd2, + 0x6c, + 0xa6, + 0xca, + 0xac, + 0x70, + 0x33, + 0x57, + 0xf9, + 0x89, + 0xbc, + 0x4f, + 0x5b, + 0x48, + 0x3b, + 0x53, + 0x8e, + 0xae, + 0x52, + 0xbf, + 0x88, + 0x88, + 0xdc, + 0xe1, + 0xc4, + 0x13, + 0xb5, + 0x9c, + 0x24, + 0xa2, + 0x8b, + 0xc1, + 0xfc, + 0x85, + 0x39, + 0x79, + 0xdb, + 0x54, + 0xdd, + 0x8a, + 0xc0, + 0xcf, + 0xae, + 0x72, + 0x9d, + 0x9b, + 0xd3, + 0xa8, + 0xe9, + 0xa1, + 0xc0, + 0x6f, + 0x07, + 0xf6, + 0xf1, + 0xc2, + 0xb9, + 0xd7, + 0x7a, + 0x6d, + 0x0f, + 0x21, + 0x2b, + 0x24, + 0xa4, + 0x3c, + 0xc8, + 0x10, + 0x99, + 0xc0, + 0xc0, + 0x65, + 0x8f, + 0x9e, + 0x24, + 0x67, + 0xa7, + 0x0e, + 0x46, + 0x3d, + 0x9e, + 0xf7, + 0x6c, + 0xef, + 0x0e, + 0x6b, + 0xf2, + 0xca, + 0xe3, + 0xd7, + 0x84, + 0x71, + 0x54, + 0x73, + 0xdb, + 0x41, + 0x27, + 0x62, + 0xd1, + 0x09, + 0x87, + 0x24, + 0x85, + 0xf9, + 0x9b, + 0x2c, + 0x90, + 0x14, + 0x61, + 0x0e, + 0xd6, + 0x12, + 0xe6, + 0x5f, + 0x0f, + 0x15, + 0x63, + 0x5e, + 0x00, + 0x0b, + 0x3e, + 0x15, + 0x3d, + 0x88, + 0x00, + 0xba, + 0x09, + 0x27, + 0x31, + 0x9b, + 0x95, + 0x47, + 0x3d, + 0x2e, + 0xdf, + 0x96, + 0xc7, + 0x39, + 0x3a, + 0x61, + 0xa2, + 0xa6, + 0xb7, + 0x7c, + 0xd9, + 0x35, + 0x1c, + 0x6f, + 0x80, + 0x4d, + 0x89, + 0x8d, + 0xe8, + 0x62, + 0xfb, + 0x5e, + 0x9b, + 0x30, + 0x1f, + 0xf3, + 0x63, + 0xf5, + 0xa1, + 0x8f, + 0x8e, + 0xa2, + 0xea, + 0x23, + 0x1f, + 0xf4, + 0x84, + 0x77, + 0x31, + 0x14, + 0xd7, + 0x38, + 0xca, + 0xab, + 0xb7, + 0x7d, + 0xe6, + 0x0b, + 0x38, + 0x22, + 0xbc, + 0x88, + 0xb9, + 0x8f, + 0x31, + 0xdf, + 0xa4, + 0xe5, + 0xcb, + 0x9a, + 0xb1, + 0xeb, + 0x09, + 0xb4, + 0xd1, + 0xd4, + 0xfa, + 0xee, + 0x63, + 0x3f, + 0xbb, + 0x57, + 0x4d, + 0x3a, + 0xb2, + 0xfd, + 0xb8, + 0xa1, + 0xa1, + 0x5b, + 0x01, + 0x37, + 0x73, + 0xb5, + 0x03, + 0xc7, + 0xfa, + 0x99, + 0x9d, + 0xed, + 0x73, + 0x81, + 0x8c, + 0x72, + 0xb4, + 0x67, + 0x33, + 0xbd, + 0xa3, + 0x75, + 0x9d, + 0xd5, + 0xb8, + 0x70, + 0xd1, + 0xc5, + 0xdb, + 0x6e, + 0x73, + 0xd1, + 0x12, + 0xe8, + 0x54, + 0x89, + 0xce, + 0x87, + 0x6b, + 0xb3, + 0xa3, + 0xe1, + 0x14, + 0xa7, + 0xcc, + 0x07, + 0xf9, + 0xd4, + 0x9a, + 0xb5, + 0xe3, + 0x33, + 0x20, + 0xb5, + 0xaa, + 0x45, + 0x89, + 0xa0, + 0xbf, + 0x5f, + 0x74, + 0x32, + 0x02, + 0x25, + 0x90, + 0xa0, + 0x26, + 0x19, + 0xce, + 0xac, + 0xee, + 0x97, + 0x55, + 0x66, + 0x79, + 0xfa, + 0xd3, + 0xc9, + 0xfc, + 0xdc, + 0xc9, + 0x97, + 0x44, + 0xdd, + 0x0b, + 0xb6, + 0x82, + 0x2b, + 0xbf, + 0x83, + 0x7c, + 0xb6, + 0x8a, + 0x0b, + 0xe3, + 0x2f, + 0x42, + 0x07, + 0xbd, + 0xf0, + 0x97, + 0x65, + 0x16, + 0xda, + 0x46, + 0x58, + 0x27, + 0x3f, + 0x73, + 0xc2, + 0x5d, + 0x3d, + 0x42, + 0x0e, + 0x7e, + 0x72, + 0x8e, + 0x8e, + 0xa4, + 0x85, + 0x16, + 0x02, + 0x80, + 0xe6, + 0x51, + 0x01, + 0xe4, + 0x15, + 0x12, + 0x4c, + 0xf9, + 0xd3, + 0x85, + 0x2f, + 0x9e, + 0x6c, + 0x22, + 0xa6, + 0xda, + 0x8a, + 0x5b, + 0x30, + 0xfb, + 0xc1, + 0xde, + 0x62, + 0x5a, + 0xa2, + 0x52, + 0xc6, + 0xb4, + 0x07, + 0x87, + 0x09, + 0x66, + 0x9a, + 0x14, + 0x76, + 0xf6, + 0x55, + 0x01, + 0xac, + 0xd8, + 0x61, + 0xff, + 0xba, + 0x6c, + 0xd0, + 0xc3, + 0x9e, + 0x06, + 0x4d, + 0xe9, + 0xdd, + 0xcb, + 0xf2, + 0x52, + 0x9c, + 0xb0, + 0x42, + 0x81, + 0xd3, + 0x22, + 0xda, + 0xdc, + 0xa6, + 0xb5, + 0x7a, + 0x65, + 0xbf, + 0xa9, + 0xd4, + 0x3e, + 0x7f, + 0x7e, + 0x84, + 0x6f, + 0x6f, + 0xe2, + 0x03, + 0x93, + 0xeb, + 0xd8, + 0x3d, + 0x98, + 0x77, + 0xff, + 0x22, + 0x74, + 0xb0, + 0xf7, + 0x75, + 0x31, + 0x13, + 0x21, + 0x5c, + 0xf5, + 0xb4, + 0x4a, + 0xe6, + 0xaa, + 0x96, + 0x1f, + 0x94, + 0x19, + 0x6c, + 0x4d, + 0x7d, + 0x44, + 0x6b, + 0x19, + 0x92, + 0x31, + 0xcf, + 0x6d, + 0x9f, + 0xa3, + 0xa8, + 0x1d, + 0x27, + 0xdc, + 0xd5, + 0x3b, + 0x17, + 0x01, + 0x7b, + 0xf9, + 0x4f, + 0xbb, + 0xbe, + 0xb4, + 0xb3, + 0x35, + 0x3c, + 0x8e, + 0xfb, + 0x67, + 0x5c, + 0x39, + 0x30, + 0x6e, + 0xdd, + 0x8f, + 0xcd, + 0x7e, + 0x02, + 0xc0, + 0xa3, + 0xd2, + 0x4f, + 0x79, + 0x52, + 0xaf, + 0xbb, + 0x3f, + 0x38, + 0x06, + 0xc9, + 0x2a, + 0xf0, + 0x1a, + 0xc2, + 0xa3, + 0xb7, + 0x85, + 0x58, + 0x26, + 0x97, + 0xf6, + 0x64, + 0xc2, + 0xd4, + 0xde, + 0x12, + 0x07, + 0xa8, + 0x01, + 0x9b, + 0x49, + 0x3b, + 0x9b, + 0xff, + 0x0a, + 0xd3, + 0x66, + 0x74, + 0xc8, + 0x59, + 0xf7, + 0x7f, + 0xe6, + 0x3b, + 0xca, + 0xee, + 0xf3, + 0xb3, + 0x87, + 0xe6, + 0xf5, + 0x42, + 0x08, + 0x88, + 0xc8, + 0x35, + 0x03, + 0xf9, + 0x67, + 0x07, + 0xd4, + 0x41, + 0x5f, + 0xab, + 0x76, + 0x33, + 0x51, + 0x5a, + 0xe7, + 0x5b, + 0xbd, + 0x3c, + 0x37, + 0x71, + 0x77, + 0x06, + 0x9f, + 0x3b, + 0x8e, + 0x6c, + 0xe3, + 0xc0, + 0xd0, + 0x7a, + 0xfb, + 0x49, + 0xc7, + 0x6b, + 0xc2, + 0xca, + 0x11, + 0x5e, + 0x54, + 0x9b, + 0x14, + 0x0d, + 0xdf, + 0x2b, + 0xa3, + 0x4b, + 0xc1, + 0xf7, + 0x04, + 0x6d, + 0xab, + 0x2e, + 0xaa, + 0x56, + 0x01, + 0xa6, + 0xd3, + 0xcb, + 0x16, + 0x9e, + 0x21, + 0xaa, + 0xa1, + 0xab, + 0x45, + 0x95, + 0x95, + 0x91, + 0x9a, + 0x09, + 0x26, + 0x1f, + 0x84, + 0xab, + 0xd3, + 0xaa, + 0x69, + 0x99, + 0xd1, + 0x60, + 0x87, + 0xf3, + 0x36, + 0x12, + 0x91, + 0x7f, + 0x49, + 0x66, + 0xe6, + 0x4a, + 0x35, + 0xbb, + 0xe3, + 0x41, + 0x95, + 0x51, + 0x1f, + 0x6e, + 0x2b, + 0x4a, + 0x49, + 0x61, + 0x16, + 0xe7, + 0x77, + 0xd4, + 0x9a, + 0x40, + 0xf7, + 0xdd, + 0xff, + 0xdb, + 0xd0, + 0x41, + 0x4f, + 0xbc, + 0x78, + 0xba, + 0x08, + 0x2b, + 0x52, + 0xe8, + 0x67, + 0x75, + 0x0b, + 0xa3, + 0x89, + 0xae, + 0xac, + 0x7c, + 0xbc, + 0x26, + 0x68, + 0xa6, + 0xab, + 0x92, + 0x81, + 0x6b, + 0xd4, + 0xed, + 0x0b, + 0x71, + 0xbe, + 0x0c, + 0x42, + 0xdf, + 0xea, + 0x61, + 0x62, + 0x11, + 0x20, + 0x6a, + 0x06, + 0xe4, + 0x56, + 0x19, + 0xa4, + 0x52, + 0x52, + 0x43, + 0x97, + 0x95, + 0x41, + 0xac, + 0x1a, + 0x90, + 0x45, + 0x8e, + 0xd6, + 0xf0, + 0x54, + 0x90, + 0xa3, + 0xab, + 0xea, + 0xc0, + 0x5a, + 0xf8, + 0x14, + 0xc4, + 0x8b, + 0x6c, + 0x44, + 0xf6, + 0x7e, + 0xba, + 0x58, + 0x37, + 0x8a, + 0xf8, + 0x0a, + 0x26, + 0x49, + 0x54, + 0xe6, + 0x90, + 0xa9, + 0xf3, + 0x6a, + 0xdc, + 0xc9, + 0x43, + 0x93, + 0x9c, + 0xfc, + 0x8c, + 0x6f, + 0x7f, + 0xb9, + 0x6b, + 0x09, + 0x1e, + 0xfe, + 0xba, + 0xc7, + 0xe9, + 0xca, + 0x41, + 0x13, + 0xbb, + 0x67, + 0x9d, + 0x76, + 0xe0, + 0x93, + 0xce, + 0xdd, + 0xd8, + 0x81, + 0x66, + 0xc7, + 0x32, + 0x9c, + 0x1c, + 0xc4, + 0x31, + 0x59, + 0x81, + 0xa0, + 0xc7, + 0x61, + 0x1e, + 0x5d, + 0x64, + 0xe6, + 0x14, + 0x81, + 0xd7, + 0x42, + 0x88, + 0x3a, + 0xc0, + 0x11, + 0xc7, + 0xa8, + 0xa9, + 0x9a, + 0xd9, + 0x3f, + 0x21, + 0x41, + 0xdc, + 0x2b, + 0x45, + 0x0a, + 0xf6, + 0xa2, + 0xb7, + 0xb6, + 0x05, + 0x52, + 0x61, + 0x7b, + 0x86, + 0xd0, + 0x08, + 0x73, + 0x68, + 0x6d, + 0x18, + 0xd9, + 0xf2, + 0x81, + 0x7d, + 0x12, + 0x08, + 0x74, + 0x4d, + 0x2d, + 0x9a, + 0xf5, + 0xc9, + 0x4d, + 0x47, + 0xb5, + 0x48, + 0x4f, + 0x14, + 0x4d, + 0xb2, + 0x86, + 0xba, + 0x9f, + 0xa7, + 0xed, + 0x20, + 0x32, + 0x7c, + 0xcd, + 0xec, + 0x70, + 0x5c, + 0xf4, + 0xa4, + 0xef, + 0x1f, + 0x6d, + 0x21, + 0xdf, + 0x5d, + 0x16, + 0xde, + 0xa6, + 0x3e, + 0x1e, + 0xd6, + 0x84, + 0xce, + 0x97, + 0x35, + 0xb2, + 0xfa, + 0xd0, + 0x34, + 0x42, + 0x99, + 0xf8, + 0x3f, + 0x02, + 0x0c, + 0xb2, + 0x75, + 0xf1, + 0x18, + 0x71, + 0x2f, + 0x22, + 0xeb, + 0x95, + 0x28, + 0x42, + 0xe5, + 0x7f, + 0xcc, + 0x1d, + 0xa3, + 0x5a, + 0x23, + 0x97, + 0xf4, + 0x1c, + 0xf9, + 0x46, + 0x5b, + 0x4a, + 0xcd, + 0x2e, + 0xeb, + 0x64, + 0xc2, + 0xbc, + 0x61, + 0x33, + 0xa4, + 0xf1, + 0x23, + 0xb0, + 0x08, + 0x5b, + 0x43, + 0xcc, + 0x33, + 0x85, + 0x9d, + 0x1c, + 0xed, + 0xea, + 0x87, + 0x8c, + 0x44, + 0xf8, + 0xc3, + 0xa8, + 0x30, + 0x98, + 0x56, + 0x29, + 0xb0, + 0x35, + 0x27, + 0xc7, + 0x63, + 0x7a, + 0x56, + 0x46, + 0xe1, + 0x57, + 0xe1, + 0x8b, + 0x39, + 0x5d, + 0x5d, + 0xa1, + 0xe4, + 0xba, + 0xc0, + 0x54, + 0xe5, + 0xb9, + 0x03, + 0x49, + 0xc4, + 0x85, + 0x89, + 0xd7, + 0xc0, + 0x29, + 0x1e, + 0x54, + 0xa0, + 0x4b, + 0xce, + 0x04, + 0xf5, + 0x35, + 0x34, + 0x20, + 0xb6, + 0x8d, + 0x42, + 0x32, + 0xee, + 0x5a, + 0x51, + 0x32, + 0x37, + 0x84, + 0x03, + 0xee, + 0x44, + 0xcf, + 0x90, + 0x0f, + 0x0c, + 0x7f, + 0xc3, + 0x55, + 0x12, + 0x43, + 0x37, + 0x04, + 0xf9, + 0xe8, + 0xaa, + 0xbd, + 0xcd, + 0xc5, + 0xa9, + 0x80, + 0x9c, + 0x67, + 0xdd, + 0xac, + 0xd5, + 0x2e, + 0x8f, + 0xda, + 0x6b, + 0xfd, + 0x4d, + 0x4c, + 0xbe, + 0x3f, + 0x97, + 0x2c, + 0x39, + 0x25, + 0xe1, + 0x87, + 0x7d, + 0x15, + 0xd9, + 0x00, + 0x3e, + 0x53, + 0x32, + 0x33, + 0x02, + 0xb0, + 0xa0, + 0xa1, + 0x52, + 0x70, + 0xc6, + 0x80, + 0xeb, + 0x28, + 0x65, + 0x97, + 0xbd, + 0x56, + 0x2e, + 0xce, + 0xca, + 0x5a, + 0xe5, + 0xbc, + 0x6c, + 0xeb, + 0xf5, + 0x34, + 0x16, + 0x30, + 0xbd, + 0x58, + 0xc0, + 0x5f, + 0x99, + 0x6d, + 0x5c, + 0x4a, + 0x92, + 0x87, + 0x2c, + 0x82, + 0xdd, + 0x5b, + 0x11, + 0x2e, + 0x31, + 0x18, + 0x61, + 0xdd, + 0x16, + 0xae, + 0x20, + 0x0c, + 0xbd, + 0x34, + 0xfc, + 0xcc, + 0x85, + 0x13, + 0x7a, + 0xf2, + 0x1a, + 0x6a, + 0xe9, + 0xda, + 0xb0, + 0x58, + 0x47, + 0xa9, + 0x4c, + 0x4d, + 0x47, + 0x20, + 0xeb, + 0x00, + 0xcc, + 0x25, + 0x47, + 0x12, + 0xaf, + 0x63, + 0xca, + 0x8d, + 0x5f, + 0x49, + 0x51, + 0x66, + 0xe0, + 0x53, + 0x61, + 0x79, + 0x29, + 0x38, + 0x04, + 0xa8, + 0x19, + 0xa1, + 0xb5, + 0x6d, + 0x6d, + 0x20, + 0x77, + 0x32, + 0xef, + 0x9d, + 0x4c, + 0x57, + 0x83, + 0x31, + 0xc2, + 0x8f, + 0x3c, + 0xfc, + 0xcc, + 0x97, + 0x54, + 0x8a, + 0xe3, + 0xa1, + 0x19, + 0xe0, + 0xb9, + 0x0b, + 0xf4, + 0xf3, + 0x47, + 0x64, + 0x3a, + 0xbb, + 0x64, + 0x0a, + 0x72, + 0x09, + 0x96, + 0x31, + 0x37, + 0x58, + 0x32, + 0xec, + 0x36, + 0x86, + 0x75, + 0xe1, + 0x8a, + 0x70, + 0x36, + 0xe7, + 0x0a, + 0xac, + 0xde, + 0x28, + 0x86, + 0xf7, + 0xdf, + 0x16, + 0x7f, + 0xae, + 0xd9, + 0x59, + 0xe4, + 0x79, + 0xd5, + 0xab, + 0x75, + 0x26, + 0x73, + 0xb8, + 0x97, + 0x41, + 0x74, + 0x50, + 0xb4, + 0x06, + 0x2c, + 0x44, + 0x64, + 0x67, + 0x3e, + 0x2d, + 0xa1, + 0x69, + 0x5b, + 0xcd, + 0xa3, + 0xaa, + 0xc2, + 0x45, + 0x07, + 0x6e, + 0x55, + 0x09, + 0x01, + 0x4b, + 0x8a, + 0x5d, + 0x3f, + 0xdf, + 0xe0, + 0x23, + 0x29, + 0x57, + 0x56, + 0xa2, + 0xfb, + 0xde, + 0x60, + 0x74, + 0x90, + 0xe2, + 0xcb, + 0xdc, + 0x35, + 0x3a, + 0xad, + 0xbd, + 0xfb, + 0x42, + 0x30, + 0x46, + 0xb3, + 0x7c, + 0x2b, + 0xc7, + 0x61, + 0x8c, + 0x11, + 0x48, + 0x5f, + 0x9c, + 0x56, + 0x31, + 0x79, + 0x65, + 0xab, + 0xbf, + 0xef, + 0x83, + 0x58, + 0x52, + 0x57, + 0x05, + 0x89, + 0x84, + 0x5e, + 0x32, + 0xaa, + 0x9a, + 0x97, + 0x5c, + 0x8c, + 0x55, + 0x2e, + 0x3d, + 0x99, + 0xde, + 0xe7, + 0xbd, + 0x8d, + 0x6d, + 0x01, + 0xd6, + 0xcc, + 0xc3, + 0xde, + 0xbd, + 0x7d, + 0xa1, + 0x7b, + 0x86, + 0xa1, + 0x51, + 0xe1, + 0xa5, + 0xf4, + 0x3a, + 0x66, + 0x27, + 0xab, + 0xb7, + 0xe9, + 0x42, + 0xc2, + 0xd2, + 0x08, + 0x5a, + 0x73, + 0xca, + 0xc6, + 0x44, + 0x3b, + 0xf7, + 0x88, + 0x15, + 0x3e, + 0x22, + 0xa6, + 0x95, + 0x7d, + 0x02, + 0xd4, + 0x22, + 0x73, + 0xef, + 0x91, + 0x19, + 0xde, + 0xdc, + 0xfb, + 0x75, + 0xc8, + 0x58, + 0x99, + 0x04, + 0x14, + 0x6e, + 0xe7, + 0xa8, + 0xed, + 0x66, + 0x07, + 0x85, + 0x33, + 0x06, + 0xfc, + 0xb5, + 0x43, + 0x53, + 0x09, + 0xf3, + 0x4f, + 0xe6, + 0xcc, + 0x3a, + 0x19, + 0x25, + 0x22, + 0xa5, + 0x91, + 0x4c, + 0x38, + 0xdc, + 0x44, + 0xb4, + 0x1c, + 0x3c, + 0x39, + 0x6e, + 0x94, + 0xe1, + 0x25, + 0xc9, + 0xc9, + 0xba, + 0x5d, + 0xe0, + 0xbf, + 0xc5, + 0x30, + 0xac, + 0x90, + 0x76, + 0x67, + 0xce, + 0x47, + 0x67, + 0xf5, + 0xcb, + 0x26, + 0x62, + 0x43, + 0xfd, + 0x50, + 0x30, + 0xf1, + 0x18, + 0xe7, + 0x1a, + 0xc6, + 0x96, + 0x68, + 0xbc, + 0x21, + 0x55, + 0x49, + 0xe1, + 0x17, + 0x2c, + 0xda, + 0x83, + 0x82, + 0xde, + 0x94, + 0x23, + 0xb5, + 0x43, + 0x86, + 0x6f, + 0x11, + 0x6c, + 0x39, + 0x6d, + 0x11, + 0x2c, + 0x36, + 0xea, + 0xaf, + 0xe6, + 0x08, + 0x54, + 0x02, + 0x6a, + 0x13, + 0x47, + 0x48, + 0x16, + 0xea, + 0x76, + 0x5b, + 0x80, + 0xeb, + 0x92, + 0x1d, + 0xf4, + 0xca, + 0xed, + 0x6d, + 0xe6, + 0xdf, + 0x2b, + 0x2b, + 0xbb, + 0x26, + 0x89, + 0xb3, + 0xe3, + 0xbb, + 0x68, + 0x99, + 0x4d, + 0x84, + 0x7e, + 0xa2, + 0x97, + 0xf5, + 0xf8, + 0x94, + 0x08, + 0xe7, + 0xc6, + 0xbf, + 0x83, + 0x60, + 0x9d, + 0x1d, + 0xda, + 0xb7, + 0x25, + 0x45, + 0x3d, + 0x39, + 0xe3, + 0x53, + 0xed, + 0x8e, + 0x2e, + 0x2a, + 0xc6, + 0x8e, + 0x9e, + 0xd8, + 0xd9, + 0x35, + 0xba, + 0xfa, + 0x35, + 0x7b, + 0x40, + 0x0b, + 0x6a, + 0x82, + 0x9c, + 0xc2, + 0xd9, + 0xd1, + 0x38, + 0xd0, + 0x50, + 0xb6, + 0xa2, + 0x8a, + 0xec, + 0x97, + 0x91, + 0x11, + 0x7d, + 0x8c, + 0xfb, + 0xf4, + 0xac, + 0xdf, + 0xe2, + 0xaf, + 0x1a, + 0x74, + 0xfb, + 0x3a, + 0xc2, + 0xf8, + 0xe4, + 0x7a, + 0x50, + 0xf7, + 0x11, + 0x25, + 0xa8, + 0xf8, + 0x99, + 0x38, + 0x94, + 0x0c, + 0x72, + 0xdc, + 0xea, + 0x4a, + 0x50, + 0x05, + 0xd0, + 0xee, + 0xa4, + 0xd0, + 0x6c, + 0xc6, + 0x5c, + 0x37, + 0x2e, + 0x14, + 0x6f, + 0x3a, + 0x20, + 0x11, + 0x0b, + 0x2b, + 0xd9, + 0xf1, + 0x77, + 0x5a, + 0x57, + 0xe1, + 0x88, + 0x3b, + 0x7f, + 0x66, + 0x9e, + 0x45, + 0x00, + 0x95, + 0xe2, + 0x6a, + 0x59, + 0xdf, + 0x86, + 0xa5, + 0x22, + 0x29, + 0x10, + 0x3b, + 0xda, + 0xbc, + 0x18, + 0x95, + 0x91, + 0x02, + 0x79, + 0x42, + 0x80, + 0xba, + 0xfc, + 0xa8, + 0xe9, + 0x66, + 0xf8, + 0x66, + 0x7e, + 0x31, + 0x5a, + 0xd4, + 0x66, + 0xca, + 0x74, + 0x61, + 0x93, + 0x5e, + 0x27, + 0xf5, + 0xe9, + 0x22, + 0x4d, + 0x07, + 0x71, + 0xed, + 0x59, + 0x0e, + 0xf6, + 0x9c, + 0x3d, + 0x1e, + 0xad, + 0xa3, + 0x53, + 0xa4, + 0x0d, + 0x0b, + 0xbe, + 0x34, + 0x0b, + 0xa5, + 0x23, + 0x46, + 0xd9, + 0x13, + 0x97, + 0x70, + 0x40, + 0xbe, + 0xd6, + 0x8e, + 0x84, + 0x30, + 0x14, + 0x33, + 0x0f, + 0xf2, + 0x23, + 0x1b, + 0xaf, + 0x6a, + 0xde, + 0xa5, + 0x99, + 0xe7, + 0x77, + 0x47, + 0x9b, + 0x4b, + 0x4b, + 0x7c, + 0x6a, + 0xe1, + 0x8e, + 0xf7, + 0x07, + 0x16, + 0xf5, + 0xd5, + 0x66, + 0x56, + 0x3e, + 0xa2, + 0xdf, + 0x66, + 0xac, + 0xd7, + 0x16, + 0xca, + 0xb9, + 0x23, + 0xa3, + 0x54, + 0x9a, + 0xbc, + 0x2e, + 0xcb, + 0xe6, + 0xac, + 0x88, + 0x82, + 0x5f, + 0x56, + 0x46, + 0x80, + 0xe8, + 0x1a, + 0x69, + 0x14, + 0x6c, + 0x22, + 0x81, + 0x24, + 0x4a, + 0x27, + 0xb8, + 0x57, + 0x6e, + 0xcc, + 0xd1, + 0xcd, + 0xc1, + 0xe5, + 0x19, + 0x8e, + 0xa0, + 0xff, + 0x22, + 0xd9, + 0x5f, + 0xe4, + 0x8c, + 0x79, + 0x7e, + 0x16, + 0x79, + 0x75, + 0x73, + 0xe9, + 0x23, + 0x4d, + 0xce, + 0x5c, + 0x77, + 0xf2, + 0xe5, + 0xcc, + 0x22, + 0x9b, + 0x26, + 0xd4, + 0x32, + 0x30, + 0xf9, + 0xbf, + 0x91, + 0x32, + 0xbf, + 0x96, + 0xbe, + 0x5d, + 0x5b, + 0x1d, + 0xa3, + 0x7a, + 0x55, + 0xfe, + 0x5d, + 0x0e, + 0xd5, + 0x81, + 0x18, + 0x9e, + 0x85, + 0xb9, + 0xb1, + 0x6e, + 0xdc, + 0x6d, + 0x21, + 0x2d, + 0xf3, + 0x19, + 0xe0, + 0x83, + 0x1b, + 0x6e, + 0x40, + 0x97, + 0x80, + 0x12, + 0x07, + 0x67, + 0x2d, + 0xf5, + 0xb6, + 0xab, + 0xe1, + 0xec, + 0x15, + 0x62, + 0xff, + 0x89, + 0x2c, + 0x28, + 0x44, + 0x7c, + 0x0c, + 0x15, + 0xa0, + 0xe6, + 0x55, + 0x53, + 0x14, + 0x02, + 0xa1, + 0xdb, + 0x84, + 0x96, + 0x1f, + 0x8c, + 0xf4, + 0x67, + 0x4c, + 0x90, + 0xb6, + 0x46, + 0x4c, + 0xbf, + 0x10, + 0xf2, + 0xfe, + 0x09, + 0x27, + 0x2e, + 0x04, + 0x9c, + 0xf3, + 0x06, + 0x28, + 0x77, + 0x09, + 0xca, + 0xae, + 0x37, + 0x9f, + 0xe1, + 0x84, + 0x4e, + 0xa0, + 0x35, + 0xbd, + 0x4d, + 0xaa, + 0xb9, + 0x60, + 0xa9, + 0xf7, + 0x7a, + 0x9f, + 0xc3, + 0xe2, + 0xff, + 0xbf, + 0x8e, + 0x19, + 0xa8, + 0xa2, + 0x4f, + 0x8b, + 0xa4, + 0xa7, + 0x0b, + 0x40, + 0x85, + 0x37, + 0xe3, + 0xb4, + 0xc0, + 0x0b, + 0xa6, + 0xff, + 0x41, + 0x8d, + 0x6e, + 0x26, + 0x5e, + 0x01, + 0x2b, + 0xb1, + 0x19, + 0xfd, + 0xc7, + 0xaf, + 0xf7, + 0x05, + 0x23, + 0x6d, + 0xb1, + 0x89, + 0xa2, + 0x0a, + 0xb1, + 0xc7, + 0xca, + 0x70, + 0x83, + 0x67, + 0xf8, + 0xdd, + 0xe8, + 0x0e, + 0xbd, + 0x94, + 0x96, + 0x3d, + 0x6b, + 0x85, + 0x04, + 0x97, + 0xaf, + 0x78, + 0x38, + 0x88, + 0x87, + 0xc9, + 0x5e, + 0x8d, + 0x2a, + 0x67, + 0x96, + 0x43, + 0x48, + 0xc8, + 0x51, + 0x3d, + 0x07, + 0x68, + 0xf8, + 0x41, + 0x63, + 0xb3, + 0x39, + 0xb0, + 0xf6, + 0xab, + 0xa5, + 0xc7, + 0x02, + 0xff, + 0xf4, + 0x9c, + 0x55, + 0x50, + 0x3b, + 0x4a, + 0x6d, + 0x88, + 0x76, + 0xac, + 0xfe, + 0xa5, + 0xe7, + 0x73, + 0xf5, + 0x39, + 0xe3, + 0x90, + 0x03, + 0xb5, + 0xf7, + 0x59, + 0x06, + 0xbe, + 0x0a, + 0xf4, + 0x7b, + 0x74, + 0x90, + 0x06, + 0x21, + 0xfe, + 0x8b, + 0x1e, + 0x73, + 0x76, + 0x48, + 0xe1, + 0x96, + 0x24, + 0xcb, + 0x31, + 0xdb, + 0x19, + 0xfe, + 0xf6, + 0x3b, + 0x4e, + 0x47, + 0xde, + 0x9d, + 0xaa, + 0x3f, + 0xaf, + 0xaa, + 0x81, + 0xec, + 0x46, + 0x9b, + 0xf2, + 0x6f, + 0x28, + 0x86, + 0x8b, + 0x94, + 0xc6, + 0x31, + 0x84, + 0x45, + 0x84, + 0x91, + 0x87, + 0x77, + 0x4d, + 0x6d, + 0xc6, + 0xd0, + 0x24, + 0xe2, + 0xb4, + 0x24, + 0xe8, + 0xd0, + 0x08, + 0x5e, + 0x15, + 0x9b, + 0xb3, + 0xae, + 0x2a, + 0x85, + 0xd0, + 0xfb, + 0x93, + 0x1a, + 0x07, + 0xdc, + 0x94, + 0x3d, + 0x8d, + 0xe4, + 0xb4, + 0xe8, + 0x38, + 0x1c, + 0xa9, + 0x23, + 0x9e, + 0x4f, + 0xc0, + 0x1a, + 0x11, + 0x5a, + 0x92, + 0xbb, + 0xfd, + 0x78, + 0x86, + 0x56, + 0x43, + 0x90, + 0x6c, + 0x46, + 0x36, + 0x30, + 0x8a, + 0x0d, + 0x32, + 0xb3, + 0x01, + 0x92, + 0x7b, + 0xeb, + 0xf0, + 0xf8, + 0x6d, + 0xad, + 0x8f, + 0x22, + 0xb6, + 0x51, + 0x2e, + 0x30, + 0xf2, + 0x3c, + 0xb6, + 0xe6, + 0x4e, + 0xa9, + 0x62, + 0x26, + 0x0b, + 0x35, + 0x1a, + 0x51, + 0xa8, + 0x42, + 0xe9, + 0x5f, + 0x5a, + 0xa1, + 0x7f, + 0xba, + 0x68, + 0x9f, + 0xa1, + 0xb6, + 0xb2, + 0xed, + 0x0c, + 0xe6, + 0xa9, + 0xb3, + 0x2e, + 0xd6, + 0x5b, + 0x9a, + 0x60, + 0xd4, + 0x14, + 0xd4, + 0xe3, + 0xa1, + 0xbb, + 0xb5, + 0x29, + 0xc9, + 0x12, + 0x95, + 0xd4, + 0xd8, + 0x0b, + 0x98, + 0x09, + 0xd9, + 0x86, + 0xdf, + 0xe5, + 0xc3, + 0x53, + 0x04, + 0x8d, + 0xbc, + 0xdc, + 0xb1, + 0x70, + 0xa1, + 0x40, + 0x7f, + 0xdf, + 0xad, + 0xcc, + 0x74, + 0x60, + 0x1a, + 0xb6, + 0xcc, + 0x80, + 0x92, + 0xf1, + 0xd4, + 0x09, + 0xea, + 0x65, + 0x2a, + 0xe9, + 0x55, + 0xdc, + 0xb9, + 0x7e, + 0x19, + 0xaf, + 0x48, + 0xa5, + 0xef, + 0xf1, + 0x7c, + 0x4a, + 0x0a, + 0x98, + 0xda, + 0x01, + 0x24, + 0xa1, + 0xfb, + 0x62, + 0x94, + 0x2a, + 0x26, + 0x4d, + 0x67, + 0xeb, + 0x96, + 0xc8, + 0xb6, + 0xcf, + 0x96, + 0x12, + 0xcf, + 0xd0, + 0xc7, + 0xb1, + 0xac, + 0xcc, + 0x09, + 0x5d, + 0x5d, + 0x66, + 0x14, + 0xc1, + 0xeb, + 0xf7, + 0x08, + 0x4c, + 0x54, + 0xb1, + 0xc7, + 0x92, + 0x88, + 0x6d, + 0xee, + 0x8c, + 0xb4, + 0xd8, + 0x47, + 0x41, + 0x4c, + 0x3f, + 0x50, + 0xc1, + 0xa2, + 0xbb, + 0x5c, + 0x24, + 0x25, + 0xd2, + 0xb1, + 0xd4, + 0xe4, + 0x15, + 0xcc, + 0xcc, + 0xef, + 0xe1, + 0x40, + 0xc8, + 0x76, + 0xaf, + 0xa6, + 0xb8, + 0x2b, + 0xf7, + 0xb1, + 0xdb, + 0x63, + 0x58, + 0x45, + 0xdc, + 0x8f, + 0x7e, + 0x90, + 0x22, + 0xf5, + 0xed, + 0x2e, + 0xca, + 0x92, + 0xd3, + 0x92, + 0xa0, + 0xe8, + 0xab, + 0x12, + 0xaf, + 0x96, + 0xec, + 0xa9, + 0x2a, + 0x47, + 0x9a, + 0x97, + 0x65, + 0x94, + 0x65, + 0x66, + 0xe0, + 0xc5, + 0x2d, + 0xdf, + 0xf3, + 0x61, + 0xcd, + 0x1d, + 0x6b, + 0x48, + 0x00, + 0x5e, + 0x8d, + 0x91, + 0xf1, + 0x1e, + 0xa6, + 0x61, + 0x3d, + 0xde, + 0x31, + 0x02, + 0x69, + 0x81, + 0x2b, + 0x2b, + 0x30, + 0x2e, + 0x9e, + 0xb0, + 0xd0, + 0x47, + 0x0e, + 0x53, + 0xea, + 0x03, + 0x57, + 0xc1, + 0x94, + 0x62, + 0x3d, + 0xce, + 0x64, + 0x03, + 0x20, + 0x93, + 0x55, + 0x2f, + 0xd1, + 0xc9, + 0xfb, + 0x96, + 0xc7, + 0x39, + 0x61, + 0xdc, + 0x12, + 0x87, + 0xbe, + 0x1e, + 0xcb, + 0xea, + 0xbb, + 0x87, + 0x30, + 0x3d, + 0x35, + 0x14, + 0xac, + 0x3f, + 0x64, + 0x8a, + 0xcf, + 0xcd, + 0x8d, + 0xe9, + 0xb9, + 0xbf, + 0xbf, + 0xc7, + 0x70, + 0xd0, + 0xe0, + 0x6f, + 0x8a, + 0x5b, + 0xc9, + 0xc7, + 0x5a, + 0xce, + 0x8b, + 0x30, + 0xa1, + 0xf5, + 0xa0, + 0xfd, + 0x4b, + 0x24, + 0x0c, + 0xf3, + 0xb6, + 0xfc, + 0xfe, + 0xb9, + 0xdf, + 0xbb, + 0xfe, + 0x21, + 0x63, + 0xb9, + 0x6f, + 0xe9, + 0x65, + 0x0f, + 0x8c, + 0x3e, + 0xac, + 0x2d, + 0x26, + 0xcc, + 0xc8, + 0x68, + 0x6f, + 0x32, + 0x40, + 0x91, + 0x33, + 0x1b, + 0xcb, + 0xf0, + 0x7a, + 0x11, + 0x46, + 0x78, + 0x01, + 0xc0, + 0xa1, + 0xf6, + 0x78, + 0xdd, + 0x38, + 0x66, + 0xe2, + 0xf3, + 0x97, + 0x2f, + 0xfc, + 0xdd, + 0x7a, + 0xd8, + 0x26, + 0x54, + 0xbd, + 0xb5, + 0xa3, + 0x94, + 0xe4, + 0x08, + 0x5e, + 0x65, + 0xc6, + 0x58, + 0x62, + 0x53, + 0xcb, + 0x46, + 0x9a, + 0x36, + 0xd1, + 0xf6, + 0x43, + 0xf9, + 0x39, + 0x10, + 0xc9, + 0x33, + 0x7c, + 0x1a, + 0x31, + 0x91, + 0x42, + 0xdf, + 0xf8, + 0x48, + 0xaf, + 0xa5, + 0x86, + 0x4a, + 0x5c, + 0x48, + 0x30, + 0x62, + 0x72, + 0x23, + 0x55, + 0x69, + 0x94, + 0x9c, + 0x67, + 0x61, + 0xa9, + 0x99, + 0xeb, + 0xef, + 0xbf, + 0xe7, + 0xe1, + 0x7e, + 0x24, + 0x62, + 0x38, + 0xa8, + 0x86, + 0xd7, + 0x3a, + 0xa0, + 0x95, + 0x23, + 0x82, + 0x7c, + 0xf0, + 0x5c, + 0x6b, + 0xa7, + 0x90, + 0x2f, + 0x81, + 0x04, + 0x52, + 0xaa, + 0x22, + 0xe2, + 0xab, + 0x07, + 0x7b, + 0x22, + 0x80, + 0xec, + 0xa2, + 0x75, + 0x6c, + 0x53, + 0x64, + 0xb4, + 0xe2, + 0x28, + 0xfb, + 0xe3, + 0xad, + 0xab, + 0xc4, + 0x51, + 0x52, + 0xf2, + 0x94, + 0xc1, + 0x0a, + 0xb7, + 0x33, + 0x8e, + 0x52, + 0x4c, + 0x70, + 0x50, + 0xce, + 0x09, + 0xed, + 0xe3, + 0x0a, + 0x73, + 0xb6, + 0x4c, + 0x59, + 0xe0, + 0xb8, + 0x5e, + 0x0d, + 0xd2, + 0xdb, + 0x88, + 0x74, + 0xdd, + 0x3b, + 0xc3, + 0x4c, + 0x90, + 0x2e, + 0x95, + 0x3b, + 0x37, + 0xf3, + 0x81, + 0xc7, + 0x2e, + 0xb4, + 0xa4, + 0x15, + 0x00, + 0x30, + 0x38, + 0xc9, + 0x43, + 0x1e, + 0xbe, + 0x91, + 0xa1, + 0x82, + 0x7c, + 0xf8, + 0x1d, + 0x67, + 0x6f, + 0x0e, + 0x71, + 0x10, + 0x36, + 0xf6, + 0x3c, + 0x01, + 0xca, + 0x8f, + 0x43, + 0xfd, + 0xb7, + 0x8d, + 0xf7, + 0x52, + 0x54, + 0x21, + 0x9b, + 0xb1, + 0x5f, + 0x40, + 0x84, + 0xbb, + 0xd2, + 0xa7, + 0x1a, + 0xd3, + 0xaa, + 0xee, + 0xb6, + 0xef, + 0x40, + 0xbf, + 0x1f, + 0x47, + 0x3d, + 0xba, + 0x91, + 0xa8, + 0x85, + 0x2a, + 0x13, + 0x14, + 0xf2, + 0xdc, + 0x84, + 0x9f, + 0xeb, + 0xca, + 0x97, + 0xe6, + 0xdb, + 0x3e, + 0x39, + 0x14, + 0xe6, + 0x99, + 0xe5, + 0x80, + 0x14, + 0x20, + 0xe4, + 0x0b, + 0xb3, + 0x32, + 0x5a, + 0x9e, + 0x69, + 0xa7, + 0x4c, + 0x8c, + 0xb7, + 0x1f, + 0x9f, + 0xb7, + 0x2c, + 0x82, + 0x20, + 0x92, + 0xf0, + 0x0d, + 0x39, + 0x97, + 0x41, + 0x3c, + 0xb4, + 0xa1, + 0x60, + 0x67, + 0x08, + 0x44, + 0xcc, + 0x9c, + 0xca, + 0x0b, + 0x44, + 0xb6, + 0xb1, + 0x35, + 0x49, + 0xcc, + 0xa7, + 0xaf, + 0xc1, + 0x14, + 0x01, + 0xaa, + 0x6f, + 0xf9, + 0x1d, + 0x8e, + 0xc6, + 0x1e, + 0x93, + 0x19, + 0xf1, + 0x03, + 0x16, + 0x93, + 0x48, + 0x7b, + 0xf5, + 0x6d, + 0xb5, + 0x43, + 0xa2, + 0xa4, + 0x9a, + 0x47, + 0x1c, + 0x30, + 0x0b, + 0xcc, + 0x02, + 0x8f, + 0x96, + 0x06, + 0x48, + 0x09, + 0x6c, + 0xbb, + 0x10, + 0xd1, + 0xb8, + 0x01, + 0xb7, + 0x83, + 0xdb, + 0x76, + 0x01, + 0x3d, + 0x0c, + 0x3c, + 0xbb, + 0x2f, + 0x1e, + 0x01, + 0x9a, + 0xea, + 0x7f, + 0x17, + 0xc2, + 0xc7, + 0xc2, + 0xcc, + 0xe2, + 0x7c, + 0xde, + 0xa6, + 0xf9, + 0x58, + 0x36, + 0xbf, + 0x76, + 0xdd, + 0x1b, + 0xee, + 0x3d, + 0x86, + 0x17, + 0xaf, + 0xda, + 0xc5, + 0x2a, + 0xd2, + 0x2b, + 0xb3, + 0xfa, + 0x00, + 0xf5, + 0x66, + 0xde, + 0xc4, + 0x5f, + 0xfa, + 0x3e, + 0x98, + 0x31, + 0x83, + 0xb5, + 0x79, + 0x4d, + 0x17, + 0x32, + 0xf4, + 0x6a, + 0xcd, + 0xe3, + 0xa3, + 0xdd, + 0xfa, + 0xe8, + 0x6a, + 0xe6, + 0x3e, + 0x86, + 0xeb, + 0x79, + 0xe1, + 0xfd, + 0xd2, + 0x7b, + 0xcc, + 0x39, + 0xda, + 0x06, + 0xe4, + 0x80, + 0x09, + 0x0d, + 0xf5, + 0x62, + 0xda, + 0x9e, + 0xe5, + 0x89, + 0xee, + 0xe7, + 0x0d, + 0xc5, + 0xb9, + 0xd6, + 0x88, + 0xf9, + 0xad, + 0x6c, + 0xec, + 0x7a, + 0x00, + 0x46, + 0x9a, + 0xd8, + 0x49, + 0xc3, + 0x40, + 0xc3, + 0x4b, + 0xcc, + 0x21, + 0xbc, + 0x31, + 0xf4, + 0xee, + 0xcb, + 0x64, + 0x89, + 0x09, + 0x66, + 0x41, + 0x6d, + 0x38, + 0xd3, + 0x9f, + 0xcc, + 0x50, + 0x6d, + 0xed, + 0x6a, + 0xcb, + 0x29, + 0x72, + 0x32, + 0x50, + 0x41, + 0xbd, + 0x34, + 0x8f, + 0x61, + 0x7e, + 0x3d, + 0xd3, + 0x63, + 0xcf, + 0x52, + 0x96, + 0x5b, + 0x0a, + 0x23, + 0xf8, + 0x0a, + 0x1a, + 0xbf, + 0x9a, + 0xb1, + 0xa6, + 0x9c, + 0x19, + 0x7f, + 0x87, + 0xc1, + 0xe9, + 0x0f, + 0xad, + 0xd0, + 0x49, + 0x0b, + 0x96, + 0x19, + 0x1a, + 0x1d, + 0x49, + 0x8d, + 0x8e, + 0x93, + 0xa5, + 0x6d, + 0x1e, + 0x3a, + 0xe2, + 0xe2, + 0x72, + 0x80, + 0x92, + 0x3b, + 0xa8, + 0x06, + 0xa6, + 0x5e, + 0xad, + 0x35, + 0xb6, + 0xb2, + 0xd9, + 0xee, + 0xed, + 0x00, + 0xb5, + 0xa1, + 0xe2, + 0x0f, + 0x06, + 0xe1, + 0xe7, + 0xb4, + 0x2d, + 0x3e, + 0x29, + 0xba, + 0xae, + 0x1d, + 0x3a, + 0x59, + 0x5d, + 0xef, + 0xeb, + 0xd2, + 0xb8, + 0x14, + 0xac, + 0x52, + 0x1c, + 0x5a, + 0xbd, + 0xe8, + 0x88, + 0x48, + 0xc7, + 0xde, + 0x49, + 0xca, + 0xe2, + 0x0b, + 0x36, + 0x7f, + 0xb4, + 0xa9, + 0xab, + 0x46, + 0xf1, + 0x7f, + 0x36, + 0x0a, + 0xbc, + 0x12, + 0x34, + 0xb3, + 0xae, + 0x29, + 0xf0, + 0xd6, + 0x0f, + 0x03, + 0xca, + 0x90, + 0x2f, + 0xaa, + 0x08, + 0xe6, + 0x4c, + 0xca, + 0xdc, + 0x97, + 0xc8, + 0x9b, + 0xc2, + 0xd3, + 0x4e, + 0x04, + 0x4f, + 0x6b, + 0x87, + 0x0a, + 0x72, + 0xc3, + 0x61, + 0x50, + 0x9e, + 0xa0, + 0x27, + 0x9f, + 0xbf, + 0x0c, + 0xcb, + 0x08, + 0x90, + 0x00, + 0x41, + 0x41, + 0xc7, + 0xbb, + 0xef, + 0x99, + 0x8e, + 0x16, + 0xbd, + 0x18, + 0x1d, + 0x0e, + 0x40, + 0x81, + 0x0c, + 0x91, + 0x91, + 0x81, + 0x31, + 0x28, + 0xf0, + 0xdf, + 0x80, + 0xc9, + 0x1a, + 0xb6, + 0x3d, + 0xae, + 0xe1, + 0x01, + 0xdf, + 0xab, + 0x3b, + 0x9f, + 0xc9, + 0x4a, + 0x0b, + 0xcc, + 0xc0, + 0x5d, + 0xaf, + 0x6d, + 0x59, + 0xba, + 0x4a, + 0x94, + 0x13, + 0xcf, + 0xd7, + 0x3c, + 0x5e, + 0xbc, + 0xb8, + 0x57, + 0x1f, + 0xaa, + 0xaa, + 0xc8, + 0x2b, + 0xc1, + 0xe7, + 0x74, + 0xa6, + 0x02, + 0x54, + 0x4d, + 0x88, + 0xb1, + 0xc4, + 0x13, + 0xe7, + 0xa9, + 0x25, + 0x8b, + 0xea, + 0x67, + 0xc4, + 0x2f, + 0xc9, + 0x8c, + 0x13, + 0x50, + 0xd9, + 0xca, + 0xd4, + 0x13, + 0x71, + 0xd0, + 0xfa, + 0x31, + 0x9b, + 0x2f, + 0x3e, + 0x77, + 0x56, + 0x24, + 0xce, + 0x8b, + 0x63, + 0x12, + 0xe1, + 0x29, + 0x0b, + 0x25, + 0xe7, + 0xdc, + 0x03, + 0xbd, + 0xf8, + 0xc6, + 0xbb, + 0x7b, + 0x2e, + 0x07, + 0x1a, + 0xa0, + 0x7a, + 0xe3, + 0x0b, + 0x47, + 0xa9, + 0xd2, + 0x52, + 0x3e, + 0x28, + 0x85, + 0x02, + 0x3a, + 0x58, + 0xb1, + 0xf5, + 0x54, + 0x4a, + 0x21, + 0x46, + 0x92, + 0xd1, + 0x43, + 0xaa, + 0x26, + 0xf8, + 0x86, + 0x85, + 0x89, + 0x6f, + 0x52, + 0xbd, + 0xcd, + 0x77, + 0x25, + 0x8a, + 0xad, + 0x61, + 0xdc, + 0x6e, + 0x83, + 0x27, + 0x33, + 0xb3, + 0x50, + 0xee, + 0x6f, + 0x29, + 0x2f, + 0x64, + 0x52, + 0x66, + 0xe2, + 0xbf, + 0xf4, + 0x6a, + 0x1a, + 0x15, + 0x51, + 0xcb, + 0x36, + 0xb6, + 0x58, + 0x70, + 0x99, + 0xc3, + 0x52, + 0x1d, + 0xb6, + 0xb5, + 0x38, + 0x66, + 0xe6, + 0xff, + 0xf5, + 0x25, + 0x91, + 0xc7, + 0x3e, + 0x54, + 0xc9, + 0x9b, + 0x13, + 0xba, + 0x4b, + 0xda, + 0x39, + 0xd2, + 0xd2, + 0x5b, + 0xa3, + 0x14, + 0x85, + 0x08, + 0x78, + 0x96, + 0x14, + 0x8e, + 0x04, + 0x7d, + 0xe9, + 0x2a, + 0xf8, + 0x74, + 0x75, + 0x5e, + 0x85, + 0x46, + 0x07, + 0x3f, + 0x72, + 0xc5, + 0x43, + 0x27, + 0xde, + 0x7a, + 0xea, + 0x68, + 0x7d, + 0xe8, + 0x7a, + 0x8f, + 0xc3, + 0x2d, + 0x9d, + 0x72, + 0xb0, + 0x52, + 0xe5, + 0x36, + 0xfa, + 0x87, + 0x01, + 0x34, + 0x37, + 0x12, + 0x8a, + 0x74, + 0x86, + 0x1f, + 0x4a, + 0x40, + 0x2b, + 0xd1, + 0xfe, + 0x22, + 0x6f, + 0x5c, + 0xc8, + 0x0a, + 0x8c, + 0x31, + 0x43, + 0x12, + 0x72, + 0x64, + 0xbd, + 0x6b, + 0xe7, + 0x17, + 0x72, + 0xe3, + 0xfd, + 0x7f, + 0xf6, + 0x81, + 0x76, + 0xa9, + 0x43, + 0xdd, + 0x52, + 0x5d, + 0xbc, + 0x3b, + 0xf7, + 0xa0, + 0x94, + 0xce, + 0xd6, + 0xc0, + 0xdc, + 0xb1, + 0xa0, + 0xde, + 0x82, + 0xe5, + 0xa5, + 0x27, + 0x31, + 0x03, + 0xad, + 0x64, + 0x94, + 0x77, + 0x7c, + 0xd3, + 0xdf, + 0x8a, + 0x8e, + 0x95, + 0x20, + 0xd9, + 0x87, + 0xad, + 0x27, + 0x44, + 0xc4, + 0x61, + 0xb2, + 0x32, + 0x41, + 0x0b, + 0xa7, + 0x30, + 0x28, + 0xd4, + 0x5d, + 0xe4, + 0xdb, + 0xd2, + 0xad, + 0xbc, + 0x2d, + 0x6c, + 0x1d, + 0xd6, + 0xb1, + 0xf9, + 0xc2, + 0x39, + 0x91, + 0x55, + 0x02, + 0xec, + 0x9b, + 0x60, + 0xba, + 0x07, + 0xdb, + 0x3f, + 0x1a, + 0x46, + 0x6d, + 0x02, + 0xf7, + 0xd8, + 0x6e, + 0x1f, + 0x7a, + 0x58, + 0xa0, + 0x26, + 0xf0, + 0x5f, + 0xf1, + 0x4c, + 0x12, + 0xc5, + 0x6c, + 0xf1, + 0x85, + 0x38, + 0x77, + 0x9c, + 0x54, + 0x6d, + 0x8d, + 0x2d, + 0x27, + 0x62, + 0x0c, + 0x75, + 0x82, + 0xef, + 0xb3, + 0xfd, + 0x18, + 0x91, + 0x68, + 0xef, + 0xe1, + 0xa8, + 0x69, + 0x92, + 0xbf, + 0x14, + 0xc4, + 0x09, + 0x2c, + 0x88, + 0xee, + 0x51, + 0x87, + 0xfb, + 0xb7, + 0x81, + 0x2b, + 0x4c, + 0x69, + 0xde, + 0x88, + 0x0c, + 0xb7, + 0xbe, + 0x2e, + 0xc2, + 0xa6, + 0xb1, + 0xe6, + 0xda, + 0xd1, + 0x3e, + 0x4f, + 0xb3, + 0x55, + 0xd0, + 0xbb, + 0xa9, + 0xe3, + 0x62, + 0xfb, + 0x48, + 0xb3, + 0x5e, + 0x6d, + 0x0a, + 0xd1, + 0xd7, + 0x4e, + 0x89, + 0x01, + 0xdf, + 0xd3, + 0x7d, + 0x39, + 0x3b, + 0x02, + 0xff, + 0x79, + 0x05, + 0x65, + 0x8a, + 0xdf, + 0xc8, + 0x8d, + 0x4b, + 0x11, + 0x69, + 0x30, + 0xa8, + 0x8a, + 0x76, + 0x1a, + 0xca, + 0xf4, + 0xa4, + 0xf6, + 0xbf, + 0x53, + 0x1a, + 0xbb, + 0x05, + 0xfa, + 0xa0, + 0xb4, + 0x1a, + 0x85, + 0x3e, + 0x59, + 0xfd, + 0xf3, + 0xaf, + 0x79, + 0xdb, + 0x13, + 0xcb, + 0x20, + 0x95, + 0x86, + 0x07, + 0xde, + 0xb7, + 0x03, + 0x6f, + 0xdb, + 0xc5, + 0x63, + 0x9a, + 0x7f, + 0xe3, + 0xc5, + 0x0d, + 0x89, + 0x09, + 0xb0, + 0x3a, + 0x5b, + 0x83, + 0x37, + 0x10, + 0x66, + 0xf1, + 0xb1, + 0x11, + 0xfd, + 0xd5, + 0x15, + 0x12, + 0x88, + 0x83, + 0x34, + 0xf1, + 0xba, + 0xdb, + 0xc9, + 0xd7, + 0x2a, + 0xda, + 0x7f, + 0x6e, + 0x6d, + 0xc5, + 0xe6, + 0x04, + 0x20, + 0x23, + 0x88, + 0x41, + 0xef, + 0x0d, + 0xba, + 0x0b, + 0xc1, + 0x7f, + 0x62, + 0xd3, + 0xe9, + 0x91, + 0x9f, + 0xc2, + 0x1a, + 0xbc, + 0x7a, + 0xd3, + 0x8a, + 0xea, + 0xae, + 0xfd, + 0x3e, + 0x71, + 0xdb, + 0xa0, + 0x7f, + 0x2d, + 0x79, + 0xee, + 0x83, + 0x69, + 0xcd, + 0xb4, + 0x33, + 0x0f, + 0x83, + 0xd0, + 0xa7, + 0x87, + 0x76, + 0x5a, + 0x9c, + 0xe4, + 0xce, + 0xe6, + 0xec, + 0xfb, + 0x81, + 0x3a, + 0xa9, + 0x31, + 0x8c, + 0x40, + 0xe0, + 0x20, + 0x6c, + 0x01, + 0x03, + 0x29, + 0x05, + 0xe1, + 0x21, + 0x67, + 0xcd, + 0x3f, + 0x00, + 0xa5, + 0x36, + 0x22, + 0x33, + 0x74, + 0x7d, + 0xed, + 0x9d, + 0xc9, + 0xfa, + 0xe2, + 0xda, + 0x16, + 0x22, + 0x5c, + 0xa8, + 0x44, + 0xa6, + 0x6a, + 0x4b, + 0x79, + 0x42, + 0xb7, + 0xd6, + 0x1d, + 0x27, + 0x13, + 0xe2, + 0x7d, + 0x2e, + 0x5b, + 0x30, + 0x9d, + 0x0a, + 0x1a, + 0xcd, + 0x37, + 0x8b, + 0x4c, + 0x81, + 0xc4, + 0x21, + 0x31, + 0x20, + 0xc9, + 0xdb, + 0xb1, + 0xed, + 0x90, + 0x49, + 0x7d, + 0xe4, + 0x65, + 0xf5, + 0x67, + 0x11, + 0x7d, + 0x13, + 0x5d, + 0xa1, + 0xb2, + 0xf3, + 0x6e, + 0x28, + 0x88, + 0x02, + 0x5e, + 0xf4, + 0xdc, + 0x50, + 0x08, + 0x0e, + 0xd9, + 0xee, + 0x14, + 0x7e, + 0x93, + 0x8e, + 0x6a, + 0x44, + 0x5c, + 0xcf, + 0x4d, + 0xe5, + 0xc6, + 0xe1, + 0xf1, + 0xc3, + 0x98, + 0x2e, + 0x32, + 0x4c, + 0x18, + 0xaf, + 0x4a, + 0x1c, + 0x37, + 0x2c, + 0x6e, + 0x6c, + 0x8e, + 0xcf, + 0x9f, + 0xcf, + 0xe5, + 0x08, + 0xf5, + 0x42, + 0xa5, + 0x1c, + 0x90, + 0x32, + 0x20, + 0xe1, + 0xb1, + 0xe5, + 0x60, + 0x32, + 0xd9, + 0x53, + 0xd7, + 0x11, + 0xbe, + 0xb0, + 0x33, + 0x80, + 0x27, + 0x7a, + 0x87, + 0x47, + 0x59, + 0x11, + 0x55, + 0x50, + 0xf0, + 0xa5, + 0x06, + 0x83, + 0xfa, + 0x06, + 0x85, + 0x99, + 0x00, + 0x0e, + 0x72, + 0x2c, + 0x2b, + 0x14, + 0xaa, + 0xfe, + 0x4d, + 0xe2, + 0x5a, + 0x17, + 0x22, + 0xdb, + 0xf4, + 0x54, + 0x0a, + 0x7f, + 0xae, + 0xd3, + 0x3a, + 0xe1, + 0xb9, + 0xd9, + 0x71, + 0xbb, + 0x1c, + 0x52, + 0x89, + 0xac, + 0x36, + 0xe5, + 0xcd, + 0x41, + 0x36, + 0xff, + 0x6b, + 0xe6, + 0xd2, + 0xa3, + 0x84, + 0x8b, + 0xbc, + 0xb1, + 0x8b, + 0x48, + 0xa3, + 0x58, + 0xa9, + 0x90, + 0x5f, + 0xea, + 0xd3, + 0x31, + 0x2d, + 0x9a, + 0x43, + 0xbe, + 0xa1, + 0x78, + 0x3f, + 0xd4, + 0x51, + 0xfc, + 0x3b, + 0xd2, + 0xa6, + 0xc3, + 0x8b, + 0xe8, + 0x3a, + 0x8d, + 0x24, + 0x99, + 0x84, + 0x6d, + 0x33, + 0x3c, + 0xc3, + 0xd2, + 0xaf, + 0x19, + 0xb7, + 0xcd, + 0x23, + 0x5c, + 0x55, + 0x28, + 0x2f, + 0x06, + 0x09, + 0x4a, + 0xf2, + 0x1b, + 0xc0, + 0x94, + 0x81, + 0x82, + 0xee, + 0x8c, + 0x30, + 0x9e, + 0x8a, + 0x8a, + 0x63, + 0x14, + 0xe4, + 0x72, + 0x77, + 0x95, + 0x81, + 0x55, + 0x9d, + 0x36, + 0x67, + 0xbb, + 0xee, + 0xd5, + 0x77, + 0x93, + 0x2e, + 0xcd, + 0x65, + 0x18, + 0x9a, + 0x1c, + 0x0b, + 0x4c, + 0xed, + 0x2c, + 0x57, + 0x76, + 0x08, + 0x54, + 0x39, + 0x1c, + 0xd5, + 0xed, + 0x5f, + 0xf3, + 0x96, + 0xc8, + 0x44, + 0x29, + 0xa8, + 0x74, + 0x26, + 0xb8, + 0x98, + 0x8c, + 0x53, + 0xbf, + 0x9b, + 0xca, + 0x27, + 0xdc, + 0xb7, + 0xb3, + 0xe5, + 0xe3, + 0x6f, + 0x5e, + 0x16, + 0xe8, + 0x71, + 0x71, + 0x15, + 0xd5, + 0x6d, + 0x81, + 0x14, + 0x6f, + 0x53, + 0xa3, + 0xd2, + 0xc3, + 0x0f, + 0x4b, + 0xaa, + 0xc5, + 0x1c, + 0x80, + 0xc9, + 0xc4, + 0x54, + 0x3c, + 0x80, + 0xfd, + 0x84, + 0x16, + 0xd3, + 0x64, + 0xbe, + 0x81, + 0x89, + 0xae, + 0xb0, + 0xdd, + 0x1c, + 0x7e, + 0xa6, + 0x30, + 0x98, + 0x72, + 0xe9, + 0x66, + 0x6e, + 0x59, + 0x76, + 0x3b, + 0x2b, + 0x1f, + 0xc3, + 0x38, + 0x83, + 0xbb, + 0x56, + 0x71, + 0x7f, + 0xdb, + 0x7d, + 0xfb, + 0x19, + 0xa2, + 0x6c, + 0xbe, + 0xfe, + 0x14, + 0xa0, + 0x12, + 0x34, + 0x51, + 0x54, + 0xfc, + 0x2b, + 0x45, + 0x65, + 0x73, + 0xff, + 0xc5, + 0x51, + 0x64, + 0x2a, + 0xf2, + 0x9e, + 0x05, + 0x30, + 0x04, + 0x13, + 0xf1, + 0x01, + 0x25, + 0x04, + 0xd3, + 0x1c, + 0x09, + 0xe8, + 0xc8, + 0x95, + 0x40, + 0x1c, + 0xda, + 0x4d, + 0x86, + 0x6f, + 0xc9, + 0x8b, + 0xab, + 0x36, + 0xbe, + 0x40, + 0xf6, + 0x59, + 0x1a, + 0xf6, + 0x8c, + 0xc1, + 0x85, + 0xb1, + 0x4d, + 0x55, + 0x7d, + 0xc8, + 0x77, + 0x2f, + 0x26, + 0x90, + 0x26, + 0xd6, + 0x62, + 0x96, + 0x5a, + 0xcc, + 0xcd, + 0x67, + 0x72, + 0x06, + 0xd5, + 0x76, + 0x24, + 0x91, + 0x6d, + 0xbf, + 0x8b, + 0x9a, + 0xb3, + 0x0c, + 0xd2, + 0xe6, + 0x15, + 0x8a, + 0xcc, + 0xfc, + 0xc0, + 0x89, + 0x61, + 0x90, + 0xfa, + 0xf8, + 0xc1, + 0x4b, + 0x9c, + 0x38, + 0x72, + 0xda, + 0x7f, + 0x76, + 0x24, + 0x6e, + 0x67, + 0x55, + 0xbf, + 0xe5, + 0xc5, + 0x29, + 0xfa, + 0x1c, + 0xdc, + 0xb1, + 0xe3, + 0x9c, + 0x32, + 0x64, + 0xdb, + 0x2e, + 0x7e, + 0x50, + 0x6b, + 0x11, + 0x9d, + 0x00, + 0x8c, + 0xad, + 0x2e, + 0x93, + 0x24, + 0xfb, + 0x9b, + 0xff, + 0x7b, + 0x33, + 0x88, + 0x1b, + 0x78, + 0xf2, + 0x27, + 0x75, + 0xf1, + 0x1a, + 0xa1, + 0x43, + 0xd5, + 0x03, + 0x65, + 0xc0, + 0x81, + 0x89, + 0xa5, + 0xa0, + 0x7c, + 0x5e, + 0xd6, + 0x04, + 0xd7, + 0x70, + 0xbb, + 0x4b, + 0xbd, + 0x9e, + 0x58, + 0x74, + 0xaa, + 0x87, + 0x81, + 0xa4, + 0xbf, + 0x41, + 0x47, + 0xee, + 0xc9, + 0x57, + 0xcf, + 0x94, + 0xf6, + 0x86, + 0xaf, + 0xcb, + 0x7a, + 0x33, + 0xc1, + 0x23, + 0x32, + 0x45, + 0xcb, + 0xd6, + 0x2c, + 0x91, + 0x79, + 0x50, + 0x19, + 0x0e, + 0xf9, + 0x29, + 0xf6, + 0x59, + 0xf5, + 0x65, + 0x2e, + 0x62, + 0x5d, + 0x6a, + 0xc1, + 0xf0, + 0x2a, + 0xa4, + 0x70, + 0xe9, + 0xc6, + 0x02, + 0xa2, + 0x8a, + 0xcf, + 0x10, + 0x56, + 0xbf, + 0x53, + 0x49, + 0x20, + 0xe5, + 0x4d, + 0xb5, + 0x45, + 0x64, + 0x9e, + 0xcf, + 0x1a, + 0x09, + 0xbe, + 0x8b, + 0xdf, + 0xc3, + 0x11, + 0x73, + 0x16, + 0x36, + 0x96, + 0xdc, + 0x1c, + 0x8d, + 0x6e, + 0x7b, + 0x50, + 0xca, + 0x82, + 0x6c, + 0x56, + 0xcd, + 0x3c, + 0x30, + 0x4b, + 0xce, + 0x26, + 0x71, + 0x2c, + 0xed, + 0xf5, + 0x45, + 0x15, + 0xff, + 0x55, + 0xa2, + 0x89, + 0xc5, + 0x6b, + 0xc4, + 0x67, + 0xa4, + 0x44, + 0xf8, + 0x2e, + 0x09, + 0xb2, + 0xb7, + 0xe7, + 0x93, + 0x61, + 0x54, + 0x38, + 0xf5, + 0x4b, + 0x3f, + 0x18, + 0x99, + 0xa9, + 0x51, + 0x67, + 0xa7, + 0x4a, + 0xef, + 0x13, + 0x19, + 0x97, + 0x07, + 0x11, + 0x8d, + 0xb9, + 0xb4, + 0xfb, + 0x84, + 0xd3, + 0x9a, + 0x9c, + 0x25, + 0x03, + 0x3d, + 0x6d, + 0x9b, + 0x0c, + 0x25, + 0x84, + 0x9c, + 0xc3, + 0x61, + 0x96, + 0x8b, + 0xaf, + 0xbd, + 0xc7, + 0x6a, + 0x4a, + 0x26, + 0xd4, + 0x4f, + 0x40, + 0xeb, + 0xc0, + 0x4e, + 0x87, + 0xd5, + 0xd9, + 0xb0, + 0xac, + 0x49, + 0xb6, + 0x3d, + 0x56, + 0x99, + 0xe3, + 0xbe, + 0xae, + 0xd4, + 0xef, + 0x4c, + 0x47, + 0x6d, + 0xb1, + 0x8d, + 0xc1, + 0x9c, + 0xa1, + 0x49, + 0xb6, + 0x96, + 0x1d, + 0xdf, + 0x56, + 0x3b, + 0xaa, + 0xf1, + 0xd1, + 0x15, + 0xbc, + 0x54, + 0x17, + 0xed, + 0xe9, + 0xb4, + 0x5c, + 0x45, + 0x48, + 0x17, + 0xfd, + 0xaf, + 0xb4, + 0x8d, + 0x78, + 0x01, + 0x94, + 0xd5, + 0xa8, + 0x94, + 0x3e, + 0xee, + 0xf3, + 0x3c, + 0x71, + 0x6e, + 0xf4, + 0x66, + 0x3e, + 0x23, + 0x7a, + 0x88, + 0xb3, + 0xcf, + 0xf0, + 0xbc, + 0x43, + 0x89, + 0x1c, + 0x5b, + 0x4a, + 0xc9, + 0xf0, + 0xca, + 0xb2, + 0x5f, + 0xe0, + 0xe6, + 0xe8, + 0xdd, + 0x0e, + 0xd1, + 0xae, + 0xdd, + 0x6f, + 0x77, + 0x7a, + 0xfd, + 0xed, + 0x83, + 0x68, + 0x4e, + 0xc8, + 0x93, + 0xf7, + 0xa1, + 0xc5, + 0x60, + 0x10, + 0x1a, + 0xf9, + 0x00, + 0x7d, + 0xcd, + 0xf7, + 0xfc, + 0x9f, + 0xae, + 0xbd, + 0x81, + 0xb0, + 0x42, + 0xd4, + 0xbb, + 0x0d, + 0x11, + 0xae, + 0xcf, + 0xed, + 0xcf, + 0x1c, + 0xa4, + 0xa8, + 0xea, + 0x34, + 0xc8, + 0xfd, + 0x99, + 0xed, + 0x75, + 0x6f, + 0x91, + 0x42, + 0x32, + 0xf5, + 0x3b, + 0x5a, + 0x49, + 0xea, + 0x12, + 0xbc, + 0x51, + 0xd4, + 0xbe, + 0x1a, + 0x1f, + 0x6b, + 0x62, + 0x25, + 0x27, + 0x62, + 0xf4, + 0xbf, + 0xbf, + 0xb2, + 0xc7, + 0x10, + 0xd6, + 0x55, + 0x0f, + 0x05, + 0xd3, + 0x17, + 0xe5, + 0x90, + 0x62, + 0x5a, + 0xd1, + 0x3b, + 0xc6, + 0xd7, + 0x36, + 0xc3, + 0x27, + 0x7c, + 0xb1, + 0x30, + 0x3c, + 0x7b, + 0x8f, + 0x25, + 0xbe, + 0xb0, + 0x69, + 0x0d, + 0x13, + 0x61, + 0x41, + 0x1f, + 0x00, + 0x9c, + 0x1b, + 0xea, + 0x24, + 0xef, + 0x44, + 0xdf, + 0xd1, + 0xd3, + 0xf4, + 0xf4, + 0x45, + 0xdc, + 0xbe, + 0x75, + 0x6b, + 0x30, + 0x58, + 0x16, + 0x99, + 0xff, + 0x46, + 0x10, + 0x0d, + 0x4a, + 0x80, + 0xd8, + 0xf1, + 0xe6, + 0x2b, + 0xa6, + 0x35, + 0x45, + 0x30, + 0x69, + 0x0b, + 0x2e, + 0xc0, + 0x6c, + 0xb8, + 0x75, + 0x31, + 0x8a, + 0x05, + 0x60, + 0x96, + 0x33, + 0x69, + 0x1a, + 0xa7, + 0x1d, + 0xbd, + 0x5f, + 0x77, + 0x34, + 0xf7, + 0x00, + 0xf6, + 0xe3, + 0xa8, + 0xec, + 0xe2, + 0x73, + 0xaa, + 0xc4, + 0x72, + 0x3e, + 0x32, + 0xf9, + 0xe0, + 0xf7, + 0x2d, + 0xee, + 0x62, + 0xa3, + 0xc0, + 0xe6, + 0xf4, + 0xde, + 0xae, + 0xbc, + 0xfc, + 0x59, + 0x0f, + 0x53, + 0x7e, + 0xe1, + 0x86, + 0xe3, + 0x59, + 0xfd, + 0xd2, + 0x68, + 0xab, + 0x99, + 0x5c, + 0x66, + 0xf7, + 0x16, + 0xd1, + 0xec, + 0xcb, + 0x07, + 0xee, + 0x41, + 0x13, + 0x08, + 0xbd, + 0xba, + 0x1c, + 0x78, + 0xbf, + 0x6c, + 0xf5, + 0x77, + 0xa3, + 0xbd, + 0x55, + 0xaf, + 0x26, + 0x92, + 0xa2, + 0x3c, + 0x90, + 0x00, + 0xcf, + 0x99, + 0x60, + 0x81, + 0xc4, + 0xcf, + 0xd1, + 0xba, + 0x9f, + 0x62, + 0xb7, + 0x8b, + 0x14, + 0x49, + 0x4f, + 0xa7, + 0x6c, + 0x3c, + 0xc8, + 0x99, + 0xac, + 0x6a, + 0x69, + 0x36, + 0x5e, + 0x31, + 0x6c, + 0x58, + 0xc3, + 0xbf, + 0x48, + 0x47, + 0xce, + 0x5b, + 0x1a, + 0x0b, + 0xb5, + 0x0b, + 0xf0, + 0x11, + 0x67, + 0x85, + 0x1b, + 0x10, + 0x33, + 0x45, + 0x39, + 0xc1, + 0x41, + 0xef, + 0xa6, + 0xa4, + 0x15, + 0x03, + 0xb6, + 0xec, + 0x09, + 0x3d, + 0x5f, + 0x22, + 0xa9, + 0x70, + 0x83, + 0xa1, + 0x73, + 0xe6, + 0xeb, + 0xfb, + 0xa3, + 0x92, + 0xf5, + 0x21, + 0xbd, + 0x03, + 0x19, + 0x15, + 0xb1, + 0x73, + 0xc2, + 0xe6, + 0x44, + 0xb9, + 0x30, + 0x0e, + 0x39, + 0xce, + 0xe7, + 0x07, + 0x49, + 0x7b, + 0x6d, + 0x7b, + 0x02, + 0x74, + 0xa7, + 0xbd, + 0x38, + 0x35, + 0xb3, + 0x59, + 0x3a, + 0x10, + 0x6b, + 0xf4, + 0xf2, + 0xba, + 0xd4, + 0xb5, + 0xbf, + 0xe1, + 0x1e, + 0x00, + 0xed, + 0x33, + 0x2f, + 0xc7, + 0xf3, + 0x45, + 0x46, + 0xaf, + 0xb9, + 0xf2, + 0xe2, + 0x07, + 0x4a, + 0xf1, + 0xce, + 0xa6, + 0x87, + 0x2f, + 0xeb, + 0x58, + 0x33, + 0xc2, + 0x53, + 0xb2, + 0xd2, + 0x5e, + 0x5d, + 0x85, + 0x95, + 0xa6, + 0xcc, + 0x4e, + 0x39, + 0x63, + 0x66, + 0xa4, + 0xb2, + 0x7b, + 0xbe, + 0x81, + 0x85, + 0xe1, + 0xaf, + 0xb0, + 0x62, + 0x9f, + 0x71, + 0xe1, + 0x7a, + 0xd1, + 0xa7, + 0xb9, + 0xb4, + 0x8c, + 0x10, + 0xaf, + 0x68, + 0xd6, + 0xb1, + 0xc9, + 0x83, + 0x0a, + 0xce, + 0x75, + 0x73, + 0xb7, + 0x18, + 0x19, + 0x91, + 0xe4, + 0x2b, + 0x51, + 0x2d, + 0x7b, + 0xa2, + 0x6f, + 0xfb, + 0x06, + 0x66, + 0xc6, + 0xaf, + 0x9c, + 0xbb, + 0x7a, + 0xc9, + 0x31, + 0x09, + 0xec, + 0x0b, + 0x2c, + 0x57, + 0x53, + 0xec, + 0xd7, + 0x83, + 0x68, + 0xb1, + 0xd3, + 0x3a, + 0x57, + 0xff, + 0xe4, + 0x57, + 0x03, + 0xa1, + 0xe3, + 0x55, + 0x0a, + 0xe2, + 0x0c, + 0xb9, + 0x79, + 0x86, + 0x7b, + 0xf6, + 0xf8, + 0x82, + 0x0d, + 0xb8, + 0x44, + 0xb6, + 0x4b, + 0x3d, + 0x1e, + 0x2b, + 0xa4, + 0xa8, + 0xbf, + 0xe8, + 0x45, + 0xc4, + 0xdd, + 0xcb, + 0xee, + 0x00, + 0xfa, + 0x2b, + 0xa7, + 0xe2, + 0xd7, + 0xa7, + 0xef, + 0x7e, + 0x90, + 0x80, + 0x7f, + 0x59, + 0x2a, + 0x99, + 0xfd, + 0x51, + 0xe1, + 0xed, + 0x04, + 0xa4, + 0xfe, + 0x3d, + 0x27, + 0x96, + 0xe9, + 0xb4, + 0xed, + 0xef, + 0x70, + 0x23, + 0x60, + 0x5e, + 0x43, + 0x2c, + 0x7e, + 0xb1, + 0xfb, + 0xa5, + 0x1f, + 0x5d, + 0x30, + 0xd2, + 0x6a, + 0x47, + 0x16, + 0x11, + 0x38, + 0x07, + 0x3c, + 0x01, + 0x0c, + 0x5e, + 0x10, + 0x13, + 0x95, + 0x55, + 0x85, + 0xea, + 0x14, + 0xf8, + 0xda, + 0x90, + 0x11, + 0xb4, + 0x2a, + 0x63, + 0x89, + 0x09, + 0x13, + 0x1c, + 0x90, + 0x4d, + 0x22, + 0x39, + 0x80, + 0xdf, + 0xa8, + 0xcd, + 0x95, + 0x73, + 0x91, + 0xaf, + 0x61, + 0xb1, + 0xc1, + 0xcb, + 0x67, + 0x0f, + 0xde, + 0xd3, + 0xb8, + 0xff, + 0x77, + 0x14, + 0x0a, + 0x2d, + 0xb3, + 0x5f, + 0x8d, + 0xc6, + 0x44, + 0x93, + 0x4f, + 0x86, + 0x57, + 0x6c, + 0xa2, + 0xa5, + 0x05, + 0x3d, + 0x03, + 0xd2, + 0x4f, + 0x85, + 0x44, + 0x4f, + 0x51, + 0x55, + 0x25, + 0xfd, + 0xb8, + 0x69, + 0x1c, + 0x72, + 0x99, + 0x0d, + 0xb4, + 0x25, + 0x42, + 0xd9, + 0x13, + 0x0c, + 0x56, + 0x50, + 0x8d, + 0x6f, + 0x7e, + 0xca, + 0xa8, + 0x20, + 0xd1, + 0xf1, + 0x9f, + 0xbb, + 0xc2, + 0x13, + 0xfa, + 0x2b, + 0x46, + 0x01, + 0xf3, + 0xe7, + 0x2a, + 0x25, + 0x60, + 0xf6, + 0xb2, + 0xb5, + 0x9c, + 0x82, + 0x40, + 0xc2, + 0xdc, + 0x3c, + 0x54, + 0x38, + 0x7a, + 0x7e, + 0xa5, + 0x3d, + 0xd1, + 0xf5, + 0x65, + 0x7c, + 0x3e, + 0x92, + 0x18, + 0xa4, + 0xe7, + 0x2b, + 0x78, + 0x94, + 0xa5, + 0x1f, + 0x49, + 0x61, + 0x52, + 0x43, + 0xe4, + 0x22, + 0x2e, + 0x81, + 0xa7, + 0x1d, + 0x25, + 0x8c, + 0xf0, + 0xbf, + 0xec, + 0xf0, + 0xa0, + 0xa3, + 0x70, + 0xd7, + 0x92, + 0x2f, + 0xb1, + 0x65, + 0x75, + 0xe4, + 0x19, + 0x25, + 0xb9, + 0x38, + 0xde, + 0xc2, + 0x64, + 0x64, + 0x39, + 0x44, + 0x93, + 0xc0, + 0x8b, + 0x63, + 0xa2, + 0xd7, + 0x6b, + 0x4e, + 0x75, + 0xf7, + 0x8d, + 0x3f, + 0xa8, + 0x47, + 0x3a, + 0xbd, + 0x28, + 0xc8, + 0xf3, + 0x84, + 0x60, + 0xa9, + 0xd0, + 0x75, + 0x06, + 0x3e, + 0xad, + 0x34, + 0x56, + 0xca, + 0xdf, + 0x8c, + 0x18, + 0x2d, + 0x6f, + 0xc6, + 0xa5, + 0x8b, + 0x98, + 0x0a, + 0x57, + 0x7e, + 0x1c, + 0x72, + 0xb9, + 0xfe, + 0xc1, + 0x64, + 0x15, + 0x90, + 0x8e, + 0x08, + 0xe9, + 0xc1, + 0x57, + 0x6e, + 0x4f, + 0x3c, + 0xaa, + 0xa0, + 0x5c, + 0xd4, + 0x0a, + 0xa3, + 0x87, + 0x22, + 0xf7, + 0x80, + 0xe8, + 0xd4, + 0xeb, + 0x8e, + 0x2e, + 0x0e, + 0xf7, + 0x0f, + 0x56, + 0x45, + 0x58, + 0x07, + 0x1c, + 0x58, + 0xbc, + 0xc8, + 0xd8, + 0xd1, + 0xe3, + 0x41, + 0xea, + 0x27, + 0xf1, + 0x53, + 0xeb, + 0x9a, + 0xd4, + 0x76, + 0xdf, + 0x0d, + 0x70, + 0xd9, + 0x12, + 0xf0, + 0xb3, + 0x61, + 0xce, + 0xf9, + 0x00, + 0xe4, + 0x24, + 0x1e, + 0x7c, + 0xd3, + 0x9b, + 0xe4, + 0xa5, + 0xe5, + 0xf0, + 0x5d, + 0x02, + 0x5b, + 0x52, + 0xdf, + 0xd8, + 0x12, + 0xbd, + 0xec, + 0xd9, + 0x67, + 0x94, + 0xb6, + 0x65, + 0x31, + 0x3a, + 0xbe, + 0xf3, + 0xba, + 0x85, + 0xc6, + 0x8d, + 0x5a, + 0x00, + 0x3e, + 0xe7, + 0xe3, + 0x91, + 0x60, + 0x03, + 0xf8, + 0xe8, + 0x78, + 0x8e, + 0x21, + 0xfc, + 0x5e, + 0x3c, + 0x56, + 0x89, + 0xd6, + 0x27, + 0x7a, + 0xb9, + 0xb9, + 0xa0, + 0x29, + 0x7b, + 0x93, + 0x79, + 0x16, + 0x8d, + 0xe3, + 0x8e, + 0x8f, + 0x28, + 0xb1, + 0x10, + 0xda, + 0x34, + 0xb9, + 0xc9, + 0xcd, + 0x8e, + 0x66, + 0x57, + 0x65, + 0x77, + 0x2d, + 0x44, + 0x16, + 0x83, + 0xa0, + 0x74, + 0x57, + 0x25, + 0x60, + 0x38, + 0x3a, + 0xf1, + 0x9f, + 0x89, + 0x2b, + 0xd1, + 0x16, + 0xd4, + 0x02, + 0xa2, + 0x75, + 0x9a, + 0x4e, + 0xe4, + 0x4c, + 0xa9, + 0x35, + 0x56, + 0xeb, + 0xa4, + 0xf4, + 0xa3, + 0x2c, + 0x0d, + 0xa5, + 0xec, + 0x58, + 0x45, + 0xe5, + 0x98, + 0xbb, + 0x1d, + 0xf5, + 0x9b, + 0xa6, + 0x6a, + 0x2a, + 0x9e, + 0x15, + 0xd5, + 0x09, + 0x9e, + 0x56, + 0xfc, + 0xae, + 0x0c, + 0x4d, + 0xb0, + 0x9e, + 0x04, + 0x1c, + 0xb7, + 0xd2, + 0x3d, + 0xe8, + 0x8d, + 0xe9, + 0x47, + 0x03, + 0x12, + 0x23, + 0xd9, + 0xab, + 0x51, + 0xf0, + 0x42, + 0xca, + 0x23, + 0x19, + 0x85, + 0xc0, + 0x34, + 0xd7, + 0xe8, + 0x0b, + 0xf5, + 0x2d, + 0xe4, + 0xcd, + 0xdb, + 0x6d, + 0x8a, + 0x67, + 0x7f, + 0xcd, + 0xae, + 0x58, + 0x48, + 0x55, + 0xef, + 0x35, + 0xb6, + 0xc0, + 0x2f, + 0x5c, + 0xc3, + 0xeb, + 0xd3, + 0xae, + 0xf3, + 0x38, + 0x37, + 0x47, + 0x0c, + 0xa4, + 0x10, + 0xb2, + 0xc4, + 0x80, + 0xab, + 0x93, + 0x6c, + 0x0a, + 0x70, + 0xac, + 0x09, + 0xdf, + 0x34, + 0xc7, + 0x78, + 0x85, + 0x33, + 0xae, + 0xf2, + 0x89, + 0xa1, + 0xf3, + 0xea, + 0xd5, + 0x80, + 0x50, + 0x8c, + 0x79, + 0xe0, + 0x92, + 0xd9, + 0x46, + 0x14, + 0xcb, + 0x5a, + 0x0d, + 0xd4, + 0xdb, + 0x8b, + 0xa7, + 0x47, + 0x03, + 0xb6, + 0x8c, + 0xd1, + 0x91, + 0xe0, + 0xd7, + 0x3f, + 0x73, + 0xa9, + 0x01, + 0xa2, + 0xe1, + 0x6c, + 0x86, + 0xe1, + 0xc5, + 0xf5, + 0x99, + 0x74, + 0x99, + 0x87, + 0x48, + 0xd0, + 0xeb, + 0x9a, + 0xe6, + 0x44, + 0xd4, + 0x58, + 0x6f, + 0xb5, + 0x2b, + 0xa7, + 0x5b, + 0xaa, + 0xcb, + 0xde, + 0xc3, + 0x09, + 0xb8, + 0xf6, + 0x52, + 0xae, + 0xf7, + 0x54, + 0xc4, + 0x06, + 0x2e, + 0x78, + 0xee, + 0xdf, + 0x94, + 0x85, + 0xa7, + 0x50, + 0x07, + 0x66, + 0xe9, + 0x16, + 0x85, + 0x6b, + 0xdd, + 0x95, + 0xc3, + 0xd0, + 0x5e, + 0xbc, + 0xb9, + 0x3e, + 0xc7, + 0x47, + 0x29, + 0xfa, + 0x39, + 0xb2, + 0xcb, + 0x49, + 0xdd, + 0xb7, + 0xcb, + 0x77, + 0xb4, + 0x22, + 0xcf, + 0x3c, + 0x8d, + 0x8e, + 0x1c, + 0x6b, + 0x72, + 0xc3, + 0xa1, + 0x08, + 0x9c, + 0x45, + 0x7b, + 0x61, + 0xcd, + 0x61, + 0x5f, + 0xc4, + 0xc4, + 0xc9, + 0xf9, + 0x41, + 0x99, + 0x1e, + 0x54, + 0x5d, + 0xa4, + 0xce, + 0x53, + 0x3e, + 0x38, + 0x0e, + 0xa7, + 0xff, + 0x0c, + 0x49, + 0x7b, + 0x8d, + 0x48, + 0x26, + 0xba, + 0x47, + 0xcd, + 0x61, + 0xf0, + 0x5b, + 0xff, + 0x4f, + 0x77, + 0x73, + 0xf8, + 0x91, + 0xa3, + 0x28, + 0x3a, + 0x6c, + 0xb9, + 0xbb, + 0xce, + 0x8f, + 0x2e, + 0x03, + 0xff, + 0x10, + 0x04, + 0x3a, + 0x8e, + 0x4d, + 0xd4, + 0x86, + 0x34, + 0xea, + 0x8e, + 0x54, + 0xbf, + 0x81, + 0xe2, + 0xd2, + 0x65, + 0x74, + 0x9b, + 0x39, + 0x01, + 0x83, + 0xd0, + 0xce, + 0x40, + 0x0b, + 0x95, + 0x10, + 0xae, + 0xc2, + 0x6b, + 0xbb, + 0x3d, + 0xb8, + 0xce, + 0x1d, + 0xde, + 0xbd, + 0x78, + 0xed, + 0x38, + 0xd9, + 0xcf, + 0x37, + 0x74, + 0xf6, + 0x7a, + 0xf1, + 0x36, + 0xeb, + 0xd6, + 0x76, + 0x48, + 0xc3, + 0x9d, + 0x0d, + 0x4d, + 0xe7, + 0x5c, + 0x1d, + 0x29, + 0x69, + 0x5d, + 0xdf, + 0xaa, + 0xa5, + 0x33, + 0x11, + 0x5c, + 0x27, + 0xb3, + 0x41, + 0xf8, + 0x14, + 0x88, + 0x5d, + 0x10, + 0x3d, + 0x76, + 0x9e, + 0x9d, + 0x31, + 0x83, + 0x29, + 0x8e, + 0xfc, + 0x57, + 0xd8, + 0x42, + 0x6d, + 0xba, + 0x28, + 0x89, + 0xeb, + 0xf8, + 0x78, + 0xd5, + 0xe0, + 0x14, + 0x60, + 0xec, + 0x96, + 0x1d, + 0x25, + 0x34, + 0x8c, + 0xa8, + 0x9c, + 0xc5, + 0x38, + 0xe3, + 0xa8, + 0xde, + 0x80, + 0x2b, + 0x95, + 0x99, + 0x1a, + 0x5f, + 0x99, + 0x10, + 0xb6, + 0x17, + 0x67, + 0x9c, + 0x5d, + 0x1e, + 0x4b, + 0x91, + 0x1a, + 0x74, + 0x2e, + 0x73, + 0x3f, + 0xd5, + 0x7c, + 0xc1, + 0x2a, + 0xaf, + 0xb4, + 0xa0, + 0x18, + 0xdc, + 0xbd, + 0x46, + 0x17, + 0x8d, + 0xfa, + 0x68, + 0x54, + 0x29, + 0x27, + 0xa7, + 0xf2, + 0x3f, + 0x46, + 0xcd, + 0x73, + 0x40, + 0xee, + 0xb9, + 0xe5, + 0xc1, + 0x1a, + 0xb2, + 0xcb, + 0xd5, + 0xe5, + 0x91, + 0x53, + 0x28, + 0xea, + 0x4b, + 0xd9, + 0x73, + 0x54, + 0x6e, + 0xe4, + 0x72, + 0x96, + 0xfb, + 0x74, + 0x45, + 0xc4, + 0xfc, + 0x63, + 0x12, + 0xf7, + 0x9c, + 0x16, + 0x68, + 0x95, + 0x39, + 0x85, + 0xff, + 0xbe, + 0xfb, + 0x3b, + 0x20, + 0x6c, + 0x0c, + 0x20, + 0xd3, + 0x61, + 0xfa, + 0x77, + 0x5a, + 0x0d, + 0x50, + 0x38, + 0xa4, + 0x2c, + 0x8c, + 0x31, + 0xef, + 0x61, + 0x3b, + 0x89, + 0x42, + 0xee, + 0xc0, + 0xe3, + 0xad, + 0x99, + 0xd8, + 0xdd, + 0xac, + 0x96, + 0x09, + 0xdd, + 0x1e, + 0x36, + 0x08, + 0x76, + 0x60, + 0x83, + 0xf4, + 0xa3, + 0x38, + 0xe9, + 0x4a, + 0x9d, + 0x0a, + 0x40, + 0x2f, + 0xf1, + 0xb6, + 0x1c, + 0x7b, + 0x6c, + 0xcb, + 0xf0, + 0xba, + 0x79, + 0x52, + 0xc8, + 0x2d, + 0xe3, + 0x3e, + 0xa1, + 0x82, + 0x93, + 0x03, + 0xd3, + 0x08, + 0x56, + 0x02, + 0x8d, + 0x1d, + 0xfe, + 0x88, + 0x27, + 0xcd, + 0x4d, + 0x33, + 0x4a, + 0x59, + 0xb7, + 0x89, + 0xed, + 0xd7, + 0x8a, + 0x9d, + 0x69, + 0xb8, + 0xf8, + 0x92, + 0xf2, + 0x32, + 0x62, + 0x2e, + 0x08, + 0x59, + 0x28, + 0x3e, + 0xff, + 0x9e, + 0x2a, + 0xfd, + 0x92, + 0xa4, + 0x7e, + 0x62, + 0x17, + 0xee, + 0xa2, + 0xa3, + 0x4c, + 0x94, + 0xef, + 0x62, + 0x28, + 0x3d, + 0x30, + 0xa4, + 0xcf, + 0x13, + 0x27, + 0xee, + 0x4c, + 0xc7, + 0x0b, + 0x72, + 0x42, + 0x50, + 0xc6, + 0x6e, + 0x43, + 0x0a, + 0xf6, + 0x9f, + 0x2e, + 0x3d, + 0x6f, + 0xb9, + 0x26, + 0xb2, + 0x56, + 0x99, + 0xc4, + 0x75, + 0x33, + 0x60, + 0x18, + 0xf7, + 0x79, + 0x47, + 0x06, + 0xdc, + 0x62, + 0xe2, + 0xe1, + 0x45, + 0xd9, + 0xa6, + 0xaf, + 0x62, + 0x3e, + 0x32, + 0xfe, + 0xf8, + 0xc1, + 0xb1, + 0x1e, + 0xb7, + 0xee, + 0x5f, + 0xe2, + 0x52, + 0xd6, + 0x80, + 0x36, + 0x93, + 0x7a, + 0x78, + 0x63, + 0x09, + 0xdb, + 0x71, + 0x1e, + 0x68, + 0x85, + 0x0c, + 0xed, + 0x87, + 0x63, + 0x1f, + 0x79, + 0x5b, + 0x6a, + 0x00, + 0xa1, + 0x61, + 0xa7, + 0xee, + 0x56, + 0x75, + 0xeb, + 0x57, + 0xaf, + 0x1b, + 0x12, + 0xae, + 0x24, + 0xdc, + 0xa7, + 0x87, + 0xc6, + 0x9d, + 0x52, + 0x3f, + 0x6c, + 0x93, + 0x95, + 0xc5, + 0x61, + 0x59, + 0x4c, + 0x1a, + 0x67, + 0x10, + 0x23, + 0xbc, + 0x5a, + 0x91, + 0xfe, + 0xe6, + 0x38, + 0xe9, + 0xe6, + 0x4a, + 0x60, + 0xee, + 0xff, + 0x1a, + 0x94, + 0x14, + 0xd3, + 0x32, + 0x30, + 0x16, + 0xbe, + 0x4f, + 0x37, + 0xca, + 0x33, + 0xdc, + 0x0c, + 0x03, + 0xde, + 0x5b, + 0x01, + 0x56, + 0x61, + 0xd8, + 0x5a, + 0x03, + 0xd1, + 0x58, + 0x28, + 0x44, + 0xd1, + 0x47, + 0xe9, + 0xef, + 0x36, + 0x15, + 0xab, + 0x0b, + 0x5f, + 0x02, + 0xb4, + 0x5f, + 0x4a, + 0x0d, + 0x85, + 0x86, + 0x20, + 0xe3, + 0x27, + 0xf7, + 0x71, + 0x2e, + 0xf7, + 0xb1, + 0x59, + 0x2e, + 0x03, + 0xa6, + 0xe3, + 0x17, + 0x7b, + 0x9b, + 0x39, + 0x2c, + 0x8e, + 0x25, + 0x50, + 0x03, + 0xf7, + 0x1e, + 0xc4, + 0x7f, + 0x9e, + 0x15, + 0x49, + 0xb1, + 0x5a, + 0xf1, + 0xcc, + 0x01, + 0xe0, + 0x54, + 0xe1, + 0xc1, + 0xd5, + 0xf9, + 0xa7, + 0xee, + 0x30, + 0x6c, + 0xbd, + 0xf8, + 0x7b, + 0x60, + 0x73, + 0xe8, + 0xed, + 0x67, + 0x4e, + 0xa7, + 0xde, + 0x4d, + 0x60, + 0x0a, + 0x38, + 0x1f, + 0xd6, + 0x9f, + 0xec, + 0x33, + 0x86, + 0x35, + 0xb9, + 0xaf, + 0x8b, + 0xb1, + 0x28, + 0x91, + 0x0f, + 0xc4, + 0x26, + 0xcd, + 0xde, + 0xf2, + 0xc6, + 0x17, + 0x71, + 0x3e, + 0x74, + 0x66, + 0x47, + 0xa6, + 0x5c, + 0xad, + 0x32, + 0x40, + 0xa7, + 0x3a, + 0xff, + 0x27, + 0x05, + 0x92, + 0x5b, + 0x3a, + 0x0f, + 0xc3, + 0xf4, + 0x33, + 0xfb, + 0x04, + 0xb0, + 0x0a, + 0xde, + 0x06, + 0x82, + 0x01, + 0xff, + 0x2e, + 0x82, + 0x04, + 0xe0, + 0xc8, + 0x86, + 0xe3, + 0xaf, + 0x49, + 0x98, + 0x50, + 0x73, + 0x8a, + 0x8b, + 0x98, + 0xff, + 0x0d, + 0x10, + 0x22, + 0x14, + 0xec, + 0x7b, + 0xb4, + 0xc5, + 0xdd, + 0x85, + 0x34, + 0x84, + 0x19, + 0x50, + 0xfb, + 0x7f, + 0x84, + 0xc7, + 0x92, + 0x42, + 0x94, + 0x2f, + 0x18, + 0x43, + 0x3e, + 0xa5, + 0xba, + 0xd4, + 0xbb, + 0xe0, + 0x3e, + 0x01, + 0xbb, + 0x76, + 0xe5, + 0xd6, + 0x45, + 0xde, + 0xdf, + 0x43, + 0x51, + 0xee, + 0x8f, + 0x04, + 0xf6, + 0x3c, + 0x41, + 0x43, + 0x2b, + 0x5a, + 0xb8, + 0x6e, + 0x49, + 0xe7, + 0xff, + 0x5d, + 0x73, + 0x83, + 0x57, + 0x0f, + 0x9f, + 0x82, + 0xdc, + 0x03, + 0x22, + 0x33, + 0x65, + 0x9a, + 0xdb, + 0x03, + 0xfa, + 0x51, + 0x69, + 0xc0, + 0x0a, + 0x20, + 0x10, + 0xc8, + 0xd0, + 0xc4, + 0x61, + 0x48, + 0xbd, + 0x87, + 0xbf, + 0x2a, + 0x19, + 0x34, + 0x77, + 0x45, + 0x0f, + 0xe6, + 0xc5, + 0x8f, + 0x33, + 0xf3, + 0x64, + 0x82, + 0xab, + 0xb0, + 0x61, + 0xc0, + 0x7d, + 0xa8, + 0x23, + 0x7f, + 0xb4, + 0xdf, + 0xd0, + 0x33, + 0x7f, + 0x45, + 0x8e, + 0x5d, + 0xbc, + 0xcd, + 0xdf, + 0xac, + 0x60, + 0xb2, + 0xec, + 0x17, + 0x3b, + 0xcf, + 0x77, + 0x6d, + 0xa2, + 0xfd, + 0x05, + 0xe2, + 0x98, + 0xef, + 0xe4, + 0x6d, + 0x92, + 0xa8, + 0x93, + 0x38, + 0x07, + 0xa6, + 0x76, + 0x83, + 0x82, + 0xcf, + 0x73, + 0x18, + 0xce, + 0xd7, + 0x68, + 0xf4, + 0x6d, + 0xe6, + 0x84, + 0x4f, + 0xbc, + 0x59, + 0xd2, + 0x5b, + 0xd2, + 0x1c, + 0xcc, + 0x60, + 0xad, + 0x68, + 0x79, + 0x70, + 0x74, + 0x59, + 0x06, + 0xbf, + 0xac, + 0x43, + 0x99, + 0x62, + 0xec, + 0x76, + 0x97, + 0x11, + 0x9a, + 0x85, + 0xd4, + 0xed, + 0xf6, + 0x20, + 0x2e, + 0x3c, + 0x92, + 0x5d, + 0x62, + 0x22, + 0x44, + 0xbd, + 0xb2, + 0x3b, + 0x64, + 0x82, + 0x63, + 0xe1, + 0x39, + 0xc6, + 0x69, + 0x0b, + 0x64, + 0xc9, + 0x70, + 0xcb, + 0x02, + 0x89, + 0xe5, + 0x6d, + 0xb1, + 0x2d, + 0x51, + 0x2d, + 0xdd, + 0xe4, + 0x49, + 0x52, + 0xbd, + 0x9c, + 0xa5, + 0xec, + 0xa2, + 0xa4, + 0x72, + 0x39, + 0x8e, + 0xe2, + 0xbf, + 0xbc, + 0x47, + 0xbe, + 0x8f, + 0x86, + 0x8a, + 0xad, + 0xe0, + 0x46, + 0x57, + 0xb7, + 0x80, + 0xad, + 0x8e, + 0x44, + 0x32, + 0x02, + 0x7f, + 0x80, + 0x70, + 0xdd, + 0xfe, + 0x71, + 0xd4, + 0x27, + 0x3e, + 0x87, + 0x46, + 0x20, + 0x44, + 0x61, + 0xc0, + 0x51, + 0x19, + 0x54, + 0xb9, + 0x60, + 0x56, + 0x30, + 0xe3, + 0xfa, + 0x03, + 0x38, + 0xd4, + 0x07, + 0xc3, + 0x22, + 0xf3, + 0x58, + 0x8e, + 0x1d, + 0x21, + 0xda, + 0x4f, + 0x98, + 0xf5, + 0x79, + 0xe3, + 0xd7, + 0x45, + 0x48, + 0x11, + 0x8b, + 0x34, + 0xce, + 0xcc, + 0xea, + 0xfc, + 0x24, + 0xfb, + 0x11, + 0xf4, + 0xf5, + 0xfa, + 0x05, + 0x24, + 0xc7, + 0x5d, + 0x7e, + 0x3a, + 0x65, + 0x45, + 0xfa, + 0x90, + 0xe7, + 0xbe, + 0x02, + 0x95, + 0xbf, + 0xcc, + 0xe1, + 0xd9, + 0x87, + 0x42, + 0xff, + 0x50, + 0x87, + 0x5f, + 0x70, + 0x14, + 0xce, + 0xbe, + 0xb7, + 0x77, + 0xfb, + 0xc3, + 0xc4, + 0x89, + 0x4b, + 0xda, + 0x3b, + 0x75, + 0x37, + 0xb6, + 0x94, + 0x14, + 0xd7, + 0x1f, + 0xe4, + 0xb1, + 0xc0, + 0x45, + 0xb0, + 0xcf, + 0x79, + 0x2f, + 0x23, + 0x7d, + 0x81, + 0xf9, + 0x4f, + 0x36, + 0xe0, + 0x46, + 0xf0, + 0x4e, + 0xfb, + 0xfa, + 0x95, + 0x38, + 0xfe, + 0xf7, + 0xcf, + 0x3f, + 0x92, + 0xc0, + 0xaf, + 0x56, + 0x14, + 0x31, + 0xe2, + 0x2a, + 0x71, + 0x62, + 0x8e, + 0x34, + 0xc6, + 0x08, + 0x0f, + 0xa4, + 0x3a, + 0x03, + 0x1a, + 0xfd, + 0x42, + 0xa8, + 0xb9, + 0x51, + 0xe6, + 0x8f, + 0x35, + 0x08, + 0x26, + 0x3d, + 0xf5, + 0x63, + 0xf2, + 0x18, + 0x38, + 0xa9, + 0x21, + 0x6c, + 0xf0, + 0x39, + 0x22, + 0x8d, + 0x3e, + 0xa9, + 0xd4, + 0x87, + 0x66, + 0xf6, + 0xb7, + 0x72, + 0x6f, + 0xab, + 0xc8, + 0x0a, + 0x2a, + 0x6c, + 0x79, + 0x5b, + 0x02, + 0x8a, + 0x2c, + 0xb5, + 0x36, + 0x77, + 0x09, + 0xb7, + 0x61, + 0xca, + 0x89, + 0x58, + 0xc8, + 0xbd, + 0xa2, + 0x21, + 0x2b, + 0xfe, + 0x16, + 0x0c, + 0x24, + 0x6d, + 0xe1, + 0x70, + 0x78, + 0x6a, + 0xd5, + 0x62, + 0x7a, + 0xfe, + 0x5f, + 0x63, + 0x55, + 0xdf, + 0xd4, + 0xd1, + 0x32, + 0x46, + 0x83, + 0x9c, + 0xda, + 0xb4, + 0x6a, + 0x71, + 0xb8, + 0xc6, + 0xe6, + 0xce, + 0x00, + 0xbd, + 0x1a, + 0x00, + 0x77, + 0x8a, + 0x3c, + 0x58, + 0xcb, + 0x17, + 0x91, + 0xe9, + 0x08, + 0x48, + 0x11, + 0x5e, + 0xe3, + 0x2a, + 0xf7, + 0xfb, + 0x87, + 0xd9, + 0x8e, + 0xe8, + 0xf0, + 0x0c, + 0x13, + 0xdb, + 0x16, + 0xb4, + 0x6b, + 0xae, + 0xb2, + 0xec, + 0x28, + 0x5e, + 0x79, + 0x8c, + 0x8c, + 0xbf, + 0x3b, + 0xe0, + 0x75, + 0x9c, + 0xa7, + 0x71, + 0x83, + 0x46, + 0xd8, + 0xff, + 0x2d, + 0x24, + 0x10, + 0xb8, + 0x8a, + 0x1e, + 0x95, + 0x3a, + 0xf0, + 0xdc, + 0xe3, + 0xf8, + 0x0c, + 0xa7, + 0x83, + 0x41, + 0xed, + 0x4e, + 0xe3, + 0xf5, + 0x3e, + 0x07, + 0xb3, + 0xbd, + 0x8a, + 0xdb, + 0x73, + 0x41, + 0xf3, + 0xb4, + 0xf5, + 0xfb, + 0x18, + 0x43, + 0x77, + 0x80, + 0x30, + 0x0b, + 0x51, + 0x0b, + 0xe2, + 0xf1, + 0x0d, + 0x10, + 0x48, + 0xab, + 0x7d, + 0x36, + 0x0f, + 0x98, + 0xa2, + 0x42, + 0xef, + 0xce, + 0x0c, + 0x8d, + 0xe8, + 0xa7, + 0xfb, + 0x38, + 0xb4, + 0x84, + 0x6d, + 0x41, + 0xfe, + 0xb1, + 0x8a, + 0x90, + 0xf1, + 0x48, + 0xf8, + 0x48, + 0x46, + 0x9a, + 0x55, + 0x37, + 0xec, + 0x3d, + 0xea, + 0x76, + 0x43, + 0xaf, + 0x22, + 0xbf, + 0x5b, + 0x2b, + 0x7b, + 0x1a, + 0x7d, + 0xce, + 0xff, + 0x89, + 0xf7, + 0xbc, + 0x6f, + 0x86, + 0x4d, + 0xae, + 0x6c, + 0x15, + 0x5b, + 0x03, + 0xd5, + 0xfc, + 0x9c, + 0x85, + 0x0b, + 0xd0, + 0x28, + 0xb4, + 0xfc, + 0x3c, + 0xc0, + 0x96, + 0xaf, + 0x4d, + 0xb3, + 0x7c, + 0xea, + 0xa7, + 0x72, + 0x54, + 0x73, + 0x42, + 0x41, + 0xaa, + 0x6c, + 0x24, + 0x1f, + 0xc0, + 0x0d, + 0xec, + 0xa9, + 0xb0, + 0x3e, + 0x9c, + 0x59, + 0x3b, + 0x59, + 0x96, + 0x9b, + 0x85, + 0x05, + 0x6c, + 0xaf, + 0xfe, + 0xa4, + 0x38, + 0x2d, + 0xc9, + 0xad, + 0x65, + 0x81, + 0x49, + 0x40, + 0xe9, + 0xd0, + 0x40, + 0x0f, + 0x15, + 0xcb, + 0x68, + 0xcc, + 0x88, + 0x8f, + 0xaf, + 0x6b, + 0x30, + 0x2b, + 0x29, + 0x37, + 0xcf, + 0xc4, + 0x4e, + 0x42, + 0xfb, + 0xb2, + 0x61, + 0x91, + 0x6e, + 0xc3, + 0x2b, + 0xd5, + 0x6d, + 0x8d, + 0x7e, + 0x78, + 0x3f, + 0x81, + 0xd4, + 0xaf, + 0x89, + 0xaf, + 0x2f, + 0xe6, + 0x7a, + 0x31, + 0x49, + 0x99, + 0xe5, + 0x7e, + 0x4c, + 0x1a, + 0x0e, + 0xa2, + 0x1a, + 0x3e, + 0xca, + 0xec, + 0x4d, + 0xf7, + 0x64, + 0xd4, + 0x45, + 0xe4, + 0x2f, + 0xd5, + 0xf4, + 0xe1, + 0x29, + 0xe7, + 0x74, + 0x5d, + 0x54, + 0xb7, + 0x3e, + 0x33, + 0x27, + 0x79, + 0xeb, + 0x9e, + 0x93, + 0xe0, + 0x7e, + 0xfe, + 0x9c, + 0x84, + 0xbf, + 0x9b, + 0x6a, + 0xfc, + 0xa4, + 0xdd, + 0x63, + 0x84, + 0xea, + 0x99, + 0x3f, + 0x17, + 0xd8, + 0xb0, + 0xf6, + 0xdb, + 0x16, + 0x32, + 0x57, + 0xf0, + 0x7d, + 0xcc, + 0x03, + 0xd2, + 0x07, + 0xe1, + 0x60, + 0x01, + 0xf1, + 0xea, + 0xe1, + 0xd8, + 0x0a, + 0xb9, + 0x12, + 0xb4, + 0xdc, + 0xf5, + 0x80, + 0x0b, + 0x89, + 0x76, + 0x5d, + 0x83, + 0xd1, + 0xcb, + 0xe8, + 0x9c, + 0xd5, + 0xf3, + 0x1e, + 0x5c, + 0x7e, + 0x3c, + 0xb0, + 0xd2, + 0xe3, + 0x49, + 0xb9, + 0x14, + 0xa5, + 0x31, + 0xb6, + 0x14, + 0x68, + 0xdf, + 0x75, + 0x74, + 0x9e, + 0xd3, + 0x49, + 0xc6, + 0x2e, + 0x45, + 0x96, + 0xb6, + 0xae, + 0xdb, + 0x36, + 0x27, + 0xdf, + 0xbb, + 0x4e, + 0x3f, + 0x14, + 0xd1, + 0x0e, + 0x25, + 0xd1, + 0x6b, + 0x07, + 0x93, + 0xc3, + 0xc3, + 0xf7, + 0xe7, + 0x7a, + 0x6c, + 0x59, + 0xdb, + 0xcd, + 0xe6, + 0xba, + 0x01, + 0x08, + 0xc4, + 0xc2, + 0xf4, + 0xce, + 0xb0, + 0x49, + 0x37, + 0xa3, + 0xd5, + 0x4e, + 0xff, + 0xe8, + 0x51, + 0x94, + 0x6a, + 0x32, + 0x8d, + 0xa0, + 0x86, + 0x1b, + 0xdf, + 0x0f, + 0x57, + 0x42, + 0x64, + 0xd2, + 0xd7, + 0x2b, + 0x71, + 0x03, + 0xda, + 0xb6, + 0xe8, + 0xcb, + 0xc0, + 0xe1, + 0x8b, + 0xa3, + 0xd5, + 0x31, + 0x37, + 0x72, + 0x69, + 0xec, + 0xd7, + 0xa5, + 0xfb, + 0x96, + 0xab, + 0x11, + 0x7c, + 0x8f, + 0x9e, + 0xce, + 0x6d, + 0x96, + 0x2b, + 0xe5, + 0xec, + 0x23, + 0xaa, + 0x0e, + 0x51, + 0x0a, + 0x1b, + 0xf9, + 0xdc, + 0x86, + 0x80, + 0xff, + 0x47, + 0x0c, + 0x23, + 0xfa, + 0x29, + 0x48, + 0x8f, + 0x22, + 0xcb, + 0x00, + 0x15, + 0xa9, + 0x2a, + 0xd2, + 0x1f, + 0x17, + 0x56, + 0x30, + 0x7d, + 0xa4, + 0xf8, + 0x4d, + 0xec, + 0x19, + 0xf8, + 0xe9, + 0x48, + 0xc4, + 0x40, + 0x14, + 0x68, + 0x61, + 0xf9, + 0x4b, + 0xa8, + 0x44, + 0x94, + 0x66, + 0x37, + 0xd9, + 0xf2, + 0x3f, + 0xdb, + 0x66, + 0x2d, + 0x5a, + 0x70, + 0x37, + 0x60, + 0xe6, + 0x9b, + 0x09, + 0x40, + 0x60, + 0x11, + 0x14, + 0x40, + 0x81, + 0xb7, + 0x2e, + 0x29, + 0x02, + 0xab, + 0x8d, + 0x4e, + 0x5b, + 0xbe, + 0x55, + 0x1a, + 0xfe, + 0x6f, + 0xdd, + 0xb4, + 0x0b, + 0x98, + 0xd4, + 0x41, + 0xa6, + 0xb0, + 0x50, + 0x6b, + 0x3a, + 0x59, + 0xb4, + 0xcf, + 0x7b, + 0x14, + 0x26, + 0x1e, + 0x0e, + 0x53, + 0xd7, + 0x4b, + 0x29, + 0x81, + 0x37, + 0x68, + 0xbb, + 0x9d, + 0x48, + 0x8e, + 0xa7, + 0xf6, + 0x7f, + 0x26, + 0x99, + 0x3a, + 0x93, + 0xbe, + 0x3b, + 0x5f, + 0xb7, + 0xbc, + 0xf6, + 0x22, + 0x22, + 0x0c, + 0x05, + 0xdb, + 0x6e, + 0x09, + 0x0e, + 0x7d, + 0x4b, + 0x8c, + 0x2e, + 0xff, + 0xcd, + 0x4d, + 0x5b, + 0xfd, + 0xee, + 0x6a, + 0xc6, + 0x37, + 0xea, + 0xf7, + 0xc0, + 0x8b, + 0x59, + 0xed, + 0xc1, + 0xa4, + 0x5a, + 0x7f, + 0xc3, + 0x81, + 0x29, + 0x49, + 0x7b, + 0xf8, + 0x35, + 0x04, + 0x54, + 0x11, + 0x3b, + 0x19, + 0x18, + 0x76, + 0x7f, + 0xce, + 0x06, + 0xc2, + 0x95, + 0xe0, + 0x2e, + 0xa6, + 0xe4, + 0xc2, + 0x57, + 0xfc, + 0x97, + 0x6f, + 0xb6, + 0x87, + 0xcf, + 0x90, + 0x25, + 0xef, + 0xb8, + 0x1f, + 0xc6, + 0xdc, + 0x8d, + 0xcd, + 0x21, + 0x33, + 0xa7, + 0x7e, + 0xa3, + 0x9a, + 0x43, + 0x10, + 0x38, + 0xc5, + 0x90, + 0x28, + 0xd6, + 0x3e, + 0x7a, + 0x14, + 0xce, + 0x5e, + 0x02, + 0xd2, + 0x7f, + 0xe6, + 0x13, + 0x2f, + 0xfb, + 0x32, + 0x8c, + 0xd1, + 0xec, + 0xeb, + 0xd9, + 0x03, + 0x22, + 0x31, + 0x8c, + 0xa6, + 0xcc, + 0xc3, + 0x12, + 0x87, + 0x12, + 0x24, + 0x6b, + 0x73, + 0x79, + 0x15, + 0xc7, + 0x93, + 0x04, + 0xd5, + 0x50, + 0x37, + 0x8b, + 0xa9, + 0xdf, + 0xcc, + 0x21, + 0xb4, + 0xba, + 0xca, + 0xd1, + 0xde, + 0x86, + 0x4e, + 0x1d, + 0x20, + 0xee, + 0xa2, + 0x1b, + 0x5a, + 0xc5, + 0x2a, + 0x7c, + 0x63, + 0xd2, + 0xda, + 0xba, + 0xe3, + 0xa7, + 0xd5, + 0x37, + 0x5b, + 0xef, + 0x73, + 0xc8, + 0x18, + 0x0d, + 0x17, + 0xef, + 0x53, + 0xbc, + 0xcd, + 0x32, + 0xfd, + 0xc1, + 0xbc, + 0xa7, + 0xd6, + 0xa8, + 0xdc, + 0xb8, + 0x98, + 0xa8, + 0xf7, + 0x6e, + 0x56, + 0x86, + 0x2d, + 0x26, + 0x42, + 0x46, + 0x25, + 0x16, + 0x43, + 0x36, + 0xbf, + 0xfc, + 0x78, + 0xdc, + 0x7b, + 0x35, + 0xc9, + 0xe2, + 0x48, + 0x35, + 0xd8, + 0x52, + 0xc9, + 0x75, + 0xec, + 0x4f, + 0xac, + 0x93, + 0xb9, + 0x1d, + 0x6c, + 0xde, + 0xa1, + 0x21, + 0xda, + 0x0f, + 0x3c, + 0x49, + 0x78, + 0x80, + 0xec, + 0xa1, + 0xa3, + 0x41, + 0x22, + 0xe7, + 0x8a, + 0xce, + 0xbb, + 0xb6, + 0xef, + 0x62, + 0x82, + 0xd9, + 0x96, + 0x66, + 0xe1, + 0x6f, + 0xa0, + 0x07, + 0xc0, + 0x1c, + 0x61, + 0xd4, + 0x53, + 0x23, + 0x09, + 0xd4, + 0x34, + 0xbe, + 0x3a, + 0xa9, + 0x5f, + 0x52, + 0xa2, + 0x7d, + 0xbd, + 0xc2, + 0xcb, + 0x71, + 0xaa, + 0xa6, + 0xca, + 0x1a, + 0x9e, + 0x74, + 0xf4, + 0x84, + 0x02, + 0xfc, + 0x0f, + 0xb0, + 0x4f, + 0x9d, + 0x3c, + 0x35, + 0x82, + 0x04, + 0xe0, + 0x88, + 0x24, + 0x93, + 0x29, + 0x96, + 0x7a, + 0xb8, + 0xb7, + 0xe9, + 0xec, + 0x87, + 0xbe, + 0x75, + 0x61, + 0x56, + 0x80, + 0xdd, + 0x54, + 0x80, + 0xde, + 0x40, + 0xe2, + 0x63, + 0x62, + 0x4b, + 0x5a, + 0x63, + 0x07, + 0x77, + 0xba, + 0x0b, + 0x90, + 0x77, + 0xa8, + 0xc6, + 0x24, + 0x8d, + 0xd0, + 0x82, + 0xcd, + 0xec, + 0x11, + 0xf8, + 0xba, + 0xd6, + 0x6c, + 0xf1, + 0x1a, + 0x90, + 0xa7, + 0xfd, + 0xff, + 0x61, + 0xcd, + 0x48, + 0x93, + 0x83, + 0xec, + 0x2e, + 0x52, + 0x3f, + 0xcb, + 0x0a, + 0x06, + 0xfe, + 0x46, + 0x5f, + 0xe5, + 0x88, + 0xbb, + 0xc7, + 0x27, + 0x16, + 0xef, + 0x92, + 0xb4, + 0x1e, + 0x66, + 0x67, + 0x42, + 0xe1, + 0xd3, + 0x15, + 0xf1, + 0x58, + 0x8d, + 0x8e, + 0x42, + 0xdb, + 0x35, + 0xea, + 0xcd, + 0x40, + 0x59, + 0x3a, + 0xb3, + 0x9a, + 0xc9, + 0x1e, + 0x4f, + 0x59, + 0x20, + 0x03, + 0xdf, + 0xed, + 0x3e, + 0xd7, + 0xbb, + 0x0f, + 0x0b, + 0xbb, + 0xf0, + 0xa2, + 0x9f, + 0xad, + 0x8e, + 0x64, + 0x1c, + 0x44, + 0x9f, + 0x13, + 0x1e, + 0xa7, + 0xd3, + 0x8c, + 0x7a, + 0xd6, + 0xfd, + 0x9f, + 0xa2, + 0xf0, + 0x61, + 0xfe, + 0x29, + 0xd8, + 0x84, + 0x56, + 0x96, + 0xda, + 0xa9, + 0x82, + 0x15, + 0xf6, + 0x79, + 0xf8, + 0xe6, + 0xd5, + 0xdc, + 0xe0, + 0xfd, + 0x77, + 0x4b, + 0x1a, + 0x3c, + 0x7e, + 0x61, + 0x3e, + 0x1f, + 0xf3, + 0x05, + 0xfc, + 0xac, + 0x34, + 0x2b, + 0xf0, + 0x95, + 0x47, + 0x31, + 0x63, + 0xe9, + 0x9f, + 0x4b, + 0x9d, + 0xc2, + 0x44, + 0xd4, + 0xc3, + 0xbb, + 0x65, + 0xc3, + 0x9f, + 0xcf, + 0x3e, + 0xe3, + 0x99, + 0x89, + 0x33, + 0x61, + 0x46, + 0xdc, + 0xb7, + 0xba, + 0x76, ]) export const testVectors = [ - { testName: 'vector 1', + { + testName: 'vector 1', whichSha: 'sha256', ikm: tv0Ikm, salt: tv0Salt, info: tv0Info, okmDesired: tv0OkmDesired, - okmLen: 42 }, + okmLen: 42, + }, - { testName: 'vector 2', + { + testName: 'vector 2', whichSha: 'sha256', ikm: tv1Ikm, salt: tv1Salt, info: tv1Info, okmDesired: tv1OkmDesired, - okmLen: 82 }, + okmLen: 82, + }, - { testName: 'vector 3', + { + testName: 'vector 3', whichSha: 'sha256', ikm: tv2Ikm, salt: undefined, info: undefined, okmDesired: tv2OkmDesired, - okmLen: 42 }, + okmLen: 42, + }, - { testName: 'vector 4', + { + testName: 'vector 4', whichSha: 'sha384', ikm: tv3Ikm, salt: tv3Salt, info: tv3Info, okmDesired: tv3OkmDesired, - okmLen: 42 }, + okmLen: 42, + }, - { testName: 'vector 5', + { + testName: 'vector 5', whichSha: 'sha384', ikm: tv4Ikm, salt: tv4Salt, info: tv4Info, okmDesired: tv4OkmDesired, - okmLen: 82 }, + okmLen: 82, + }, - { testName: 'vector 6', + { + testName: 'vector 6', whichSha: 'sha384', ikm: tv5Ikm, salt: undefined, info: undefined, okmDesired: tv5OkmDesired, - okmLen: 42 }, + okmLen: 42, + }, /* Test vector #6 is testing types in C which is not the same as JavaScript. */ // { .whichSha = AWS_CRYPTOSDK_NOSHA, .ikm = tv6Ikm, .ikm_len = 10 }, - { testName: 'vector 8', + { + testName: 'vector 8', whichSha: 'sha256', ikm: tv7Ikm, salt: tv7Salt, info: tv7Info, okmDesired: tv7OkmDesired, - okmLen: 8129 } + okmLen: 8129, + }, ] diff --git a/modules/hkdf-node/test/test.ts b/modules/hkdf-node/test/test.ts index c57fb417e..994d5f236 100644 --- a/modules/hkdf-node/test/test.ts +++ b/modules/hkdf-node/test/test.ts @@ -23,15 +23,24 @@ describe('HKDF', () => { it('should be able to expand from a given length and info', () => { const expand = HKDF()('some key', 'some salt') - const expectedKey = Buffer.from('9a7b6b60ce53ce195ee18877c70dbaae2a9a8fca1b53cc82e0f4237fe754cda0', 'hex') - const key = expand(32, Buffer.from('00b242383932394230313735334434413435', 'hex')) + const expectedKey = Buffer.from( + '9a7b6b60ce53ce195ee18877c70dbaae2a9a8fca1b53cc82e0f4237fe754cda0', + 'hex' + ) + const key = expand( + 32, + Buffer.from('00b242383932394230313735334434413435', 'hex') + ) expect(key.equals(expectedKey)).to.equal(true) }) it('should be able to expand from a length shorter than hashLength', () => { const expand = HKDF('sha256')('some key', 'some salt') const expectedKey = Buffer.from('9a7b6b60ce53ce195ee18877c70dba', 'hex') - const key = expand(15, Buffer.from('00b242383932394230313735334434413435', 'hex')) + const key = expand( + 15, + Buffer.from('00b242383932394230313735334434413435', 'hex') + ) expect(key.equals(expectedKey)).to.equal(true) }) @@ -44,15 +53,20 @@ describe('HKDF', () => { it('should be able to expand to a length significantly longer than hashLength', () => { const expand = HKDF('sha256')('some key', 'some salt') - const key = expand(32 * 10, Buffer.from('00b242383932394230313735334434413435', 'hex')) + const key = expand( + 32 * 10, + Buffer.from('00b242383932394230313735334434413435', 'hex') + ) const expectedKey = Buffer.from( [ 'mntrYM5Tzhle4Yh3xw26riqaj8obU8yC4PQjf+dUzaDQicn+rgyNoN1xaG24vLWH40mq8ZW4+bysfQdKW3xBtdAS4', 'pV8UM2ING05ZDr3M5qifH9AprEaLF3KdSFRqUIp33k2sj3aQE+rquaJn5dOOxrpCAp+oVORsxl4SWbRA4oX1CgIZp', 'xOquvTjCqkQD6PGA2DtH/iU6xknfp3gNqbHb1Osye6sAMjHBjfvLbYwFkEAodKGAsitZaP06SzOcwxLczyDoa2G1M', 'wHvyGgSYouXrDZZej+INmv285VzxTJ5OoT7t63FNtzf4qRwKiAQ7OaNM19M7pXkmDLDjlw6Km2U9zpi6sZPdj4Xrj', - 'DjVZdjbQohAy1gUxwrDP0oISAMMqrhp9jYKNos1WYnkU3eG8w0bkdYSHcv6hrECFn8OWY+s=' - ].join(''), 'base64') + 'DjVZdjbQohAy1gUxwrDP0oISAMMqrhp9jYKNos1WYnkU3eG8w0bkdYSHcv6hrECFn8OWY+s=', + ].join(''), + 'base64' + ) expect(key.equals(expectedKey)).to.equal(true) }) @@ -65,13 +79,22 @@ describe('HKDF', () => { describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { it('A.1. Test Case 1 Basic test case with SHA-256', () => { const Hash = 'sha256' - const IKM = Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex') + const IKM = Buffer.from( + '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', + 'hex' + ) const salt = Buffer.from('000102030405060708090a0b0c', 'hex') const info = Buffer.from('f0f1f2f3f4f5f6f7f8f9', 'hex') const L = 42 - const PRK = Buffer.from('077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5', 'hex') - const OKM = Buffer.from('3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865', 'hex') + const PRK = Buffer.from( + '077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5', + 'hex' + ) + const OKM = Buffer.from( + '3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf @@ -87,13 +110,28 @@ describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { it('A.2. Test Case 2: Test with SHA-256 and longer inputs/outputs', () => { const Hash = 'sha256' - const IKM = Buffer.from('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f', 'hex') - const salt = Buffer.from('606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf', 'hex') - const info = Buffer.from('b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', 'hex') + const IKM = Buffer.from( + '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f', + 'hex' + ) + const salt = Buffer.from( + '606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf', + 'hex' + ) + const info = Buffer.from( + 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', + 'hex' + ) const L = 82 - const PRK = Buffer.from('06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244', 'hex') - const OKM = Buffer.from('b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87', 'hex') + const PRK = Buffer.from( + '06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244', + 'hex' + ) + const OKM = Buffer.from( + 'b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf @@ -109,13 +147,22 @@ describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { it('A.3. Test Case 3: Test with SHA-256 and zero-length salt/info', () => { const Hash = 'sha256' - const IKM = Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex') + const IKM = Buffer.from( + '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', + 'hex' + ) const salt = Buffer.alloc(0) const info = Buffer.alloc(0) const L = 42 - const PRK = Buffer.from('19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04', 'hex') - const OKM = Buffer.from('8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8', 'hex') + const PRK = Buffer.from( + '19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04', + 'hex' + ) + const OKM = Buffer.from( + '8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf @@ -137,7 +184,10 @@ describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { const L = 42 const PRK = Buffer.from('9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243', 'hex') - const OKM = Buffer.from('085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896', 'hex') + const OKM = Buffer.from( + '085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf @@ -153,13 +203,25 @@ describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { it('A.5. Test Case 5: Test with SHA-1 and longer inputs/outputs', () => { const Hash = 'sha1' - const IKM = Buffer.from('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f', 'hex') - const salt = Buffer.from('606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf', 'hex') - const info = Buffer.from('b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', 'hex') + const IKM = Buffer.from( + '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f', + 'hex' + ) + const salt = Buffer.from( + '606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf', + 'hex' + ) + const info = Buffer.from( + 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', + 'hex' + ) const L = 82 const PRK = Buffer.from('8adae09a2a307059478d309b26c4115a224cfaf6', 'hex') - const OKM = Buffer.from('0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4', 'hex') + const OKM = Buffer.from( + '0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf @@ -175,13 +237,19 @@ describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { it('A.6. Test Case 6: Test with SHA-1 and zero-length salt/info', () => { const Hash = 'sha1' - const IKM = Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex') + const IKM = Buffer.from( + '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', + 'hex' + ) const salt = Buffer.alloc(0) const info = Buffer.alloc(0) const L = 42 const PRK = Buffer.from('da8c8a73c7fa77288ec6f5e7c297786aa0d32d01', 'hex') - const OKM = Buffer.from('0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918', 'hex') + const OKM = Buffer.from( + '0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf @@ -197,13 +265,19 @@ describe('https://tools.ietf.org/html/rfc5869#appendix-A', () => { it('A.7. Test Case 7: Test with SHA-1, salt not provided (defaults to HashLen zero octets zero-length info),', () => { const Hash = 'sha1' - const IKM = Buffer.from('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex') + const IKM = Buffer.from( + '0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', + 'hex' + ) const salt = false // not provided (defaults to HashLen zero octets) const info = Buffer.alloc(0) const L = 42 const PRK = Buffer.from('2adccada18779e7c2077ad2eb19d3f3e731385dd', 'hex') - const OKM = Buffer.from('2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48', 'hex') + const OKM = Buffer.from( + '2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48', + 'hex' + ) const hkdf = HKDF(Hash) const { extract, expand } = hkdf diff --git a/modules/integration-node/test/decrypt_materials_manager_node.test.ts b/modules/integration-node/test/decrypt_materials_manager_node.test.ts index ba53156c5..0960c73cd 100644 --- a/modules/integration-node/test/decrypt_materials_manager_node.test.ts +++ b/modules/integration-node/test/decrypt_materials_manager_node.test.ts @@ -4,57 +4,61 @@ /* eslint-env mocha */ import { expect } from 'chai' +import { kmsKeyring, aesKeyring, rsaKeyring, keyringNode } from '../src/index' import { - kmsKeyring, - aesKeyring, - rsaKeyring, - keyringNode -} from '../src/index' -import { KMSKey, KmsKeyInfo, AESKey, AesKeyInfo, RSAKey, RsaKeyInfo } from '../src/types' // eslint-disable-line no-unused-vars + KMSKey, + KmsKeyInfo, + AESKey, + AesKeyInfo, + RSAKey, + RsaKeyInfo, +} from '../src/types' const kmsKey: KMSKey = { - 'encrypt': true, - 'decrypt': true, - 'type': 'aws-kms', - 'key-id': 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' + encrypt: true, + decrypt: true, + type: 'aws-kms', + 'key-id': + 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f', } const kmsInfo: KmsKeyInfo = { - 'type': 'aws-kms', - 'key': 'us-west-2-decryptable' + type: 'aws-kms', + key: 'us-west-2-decryptable', } const aesKey: AESKey = { - 'encrypt': true, - 'decrypt': true, - 'algorithm': 'aes', - 'type': 'symmetric', - 'bits': 128, - 'encoding': 'base64', - 'material': 'AAECAwQFBgcICRAREhMUFQ==', - 'key-id': 'aes-128' + encrypt: true, + decrypt: true, + algorithm: 'aes', + type: 'symmetric', + bits: 128, + encoding: 'base64', + material: 'AAECAwQFBgcICRAREhMUFQ==', + 'key-id': 'aes-128', } const aesInfo: AesKeyInfo = { - 'type': 'raw', - 'key': 'aes-128', + type: 'raw', + key: 'aes-128', 'provider-id': 'aws-raw-vectors-persistant', 'encryption-algorithm': 'aes', - 'padding-algorithm': null + 'padding-algorithm': null, } const rsaKey: RSAKey = { - 'encrypt': true, - 'decrypt': true, - 'algorithm': 'rsa', - 'type': 'private', - 'bits': 4096, - 'encoding': 'pem', - 'material': '-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCztGg1gQ8AjCzz\n1VX6StqtW//jBt2ZQBoApaBa7FmLmdr0YlKaeEKSrItGbvA9tBjgsKhrn8gxTGQc\nuxgM92651jRCbQZyjE6W8kodijhGMXsfKJLfgPp2/I7gZ3dqrSZkejFIYLFb/uF/\nTfAQzNyJUldYdeFojSUPqevMgSAusTgv7dXYt4BCO9mxMp35tgyp5k4vazKJVUgB\nTw87AAYZUGugmi94Wb9JSnqUKI3QzaRN7JADZrHdBO1lIBryfCsjtTnZc7NWZ0yJ\nwmzLY+C5b3y17cy44N0rbjI2QciRhqZ4/9SZ/9ImyFQlB3lr9NSndcT4eE5YC6bH\nba0gOUK9lLXVy6TZ+nRZ4dSddoLX03mpYp+8cQpK6DO3L/PeUY/si0WGsXZfWokd\n4ACwvXWSOjotzjwqwTW8q9udbhUvIHfB02JW+ZQ07b209fBpHRDkZuveOTedTN2Q\nQei4dZDjWW5s4cIIE3dXXeaH8yC02ERIeN+aY6eHngSsP2xoDV3sKNN/yDbCqaMS\nq8ZJbo2rvOFxZHa2nWiV+VLugfO6Xj8jeGeR8vopvbEBZZpAq+Dea2xjY4+XMUQ/\nS1HlRwc9+nkJ5LVfODuE3q9EgJbqbiXe7YckWV3ZqQMybW+dLPxEJs9buOntgHFS\nRYmbKky0bti/ZoZlcZtS0zyjVxlqsQIDAQABAoICAEr3m/GWIXgNAkPGX9PGnmtr\n0dgX6SIhh7d1YOwNZV3DlYAV9HfUa5Fcwc1kQny7QRWbHOepBI7sW2dQ9buTDXIh\nVjPP37yxo6d89EZWfxtpUP+yoXL0D4jL257qCvtJuJZ6E00qaVMDhXbiQKABlo8C\n9sVEiABhwXBDZsctpwtTiykTgv6hrrPy2+H8R8MAm0/VcBCAG9kG5r8FCEmIvQKa\ndgvNxrfiWNZuZ6yfLmpJH54SbhG9Kb4WbCKfvh4ihqyi0btRdSM6fMeLgG9o/zrc\ns54B0kHeLOYNVo0j7FQpZBFeSIbmHfln4RKBh7ntrTke/Ejbh3NbiPvxWSP0P067\nSYWPkQpip2q0ION81wSQZ1haP2GewFFu4IEjG3DlqqpKKGLqXrmjMufnildVFpBx\nir+MgvgQfEBoGEx0aElyO7QuRYaEiXeb/BhMZeC5O65YhJrWSuTVizh3xgJWjgfV\naYwYgxN8SBXBhXLIVvnPhadTqsW1C/aevLOk110eSFWcHf+FCK781ykIzcpXoRGX\nOwWcZzC/fmSABS0yH56ow+I0tjdLIEEMhoa4/kkamioHOJ4yyB+W1DO6/DnMyQlx\ng7y2WsAaIEBoWUARy776k70xPPMtYAxzFXI9KhqRVrPfeaRZ+ojeyLyr3GQGyyoo\ncuGRdMUblsmODv4ixmOxAoIBAQDvkznvVYNdP3Eg5vQeLm/qsP6dLejLijBLeq9i\n7DZH2gRpKcflXZxCkRjsKDDE+fgDcBYEp2zYfRIVvgrxlTQZdaSG+GoDcbjbNQn3\ndjCCtOOACioN/vg2zFlX4Bs6Q+NaV7g5qP5SUaxUBjuHLe7Nc+ZkyheMHuNYVLvk\nHL/IoWyANpZYjMUU3xMbL/J29Gz7CPGr8Si28TihAHGfcNgn8S04OQZhTX+bU805\n/+7B4XW47Mthg/u7hlqFl+YIAaSJYvWkEaVP1A9I7Ve0aMDSMWwzTg9cle2uVaL3\n+PTzWY5coBlHKjqAg9ufhYSDhAqBd/JOSlv8RwcA3PDXJ6C/AoIBAQDABmXXYQky\n7phExXBvkLtJt2TBGjjwulf4R8TC6W5F51jJuoqY/mTqYcLcOn2nYGVwoFvPsy/Q\nCTjfODwJBXzbloXtYFR3PWAeL1Y6+7Cm+koMWIPJyVbD5Fzm+gZStM0GwP8FhDt2\nWt8fWEyXmoLdAy6RAwiEmCagEh8o+13oBfwnBllbz7TxaErsUuR+XVgl/iHwztdv\ncdJKyRgaFfWSh9aiO7EMV2rBGWsoX09SRvprPFAGx8Ffm7YcqIk34QXsQyc45Dyn\nCwkvypxHoaB3ot/48FeFm9IubApb/ctv+EgkBfL4S4bdwRXS1rt+0+QihBoFyP2o\nJ91cdm4hEWCPAoIBAQC6l11hFaYZo0bWDGsHcr2B+dZkzxPoKznQH76n+jeQoLIc\nwgjJkK4afm39yJOrZtEOxGaxu0CgIFFMk9ZsL/wC9EhvQt02z4TdXiLkFK5VrtMd\nr0zv16y06VWQhqBOMf/KJlX6uq9RqADi9HO6pkC+zc0cpPXQEWKaMmygju+kMG2U\nMm/IieMZjWCRJTfgBCE5J88qTsqaKagkZXcZakdAXKwOhQN+F2EStiM6UCZB5PrO\nS8dfrO8ML+ki8Zqck8L1qhiNb5zkXtKExy4u+gNr8khGcT6vqqoSxOoH3mPRgOfL\nJnppne8wlwIf7Vq3H8ka6zPSXEHma999gZcmy9t7AoIBAGbQhiLl79j3a0wXMvZp\nVf5IVYgXFDnAbG2hb7a06bhAAIgyexcjzsC4C2+DWdgOgwHkuoPg+062QV8zauGh\nsJKaa6cHlvIpSJeg3NjD/nfJN3CYzCd0yCIm2Z9Ka6xI5iYhm+pGPNhIG4Na8deS\ngVL46yv1pc/o73VxfoGg5UzgN3xlp97Cva0sHEGguHr4W8Qr59xZw3wGQ4SLW35M\nF6qXVNKUh12GSMCPbZK2RXBWVKqqJmca+WzJoJ6DlsT2lQdFhXCus9L007xlDXxF\nC/hCmw1dEl+VaNo2Ou26W/zdwTKYhNlxBwsg4SB8nPNxXIsmlBBY54froFhriNfn\nx/0CggEAUzz+VMtjoEWw2HSHLOXrO4EmwJniNgiiwfX3DfZE4tMNZgqZwLkq67ns\nT0n3b0XfAOOkLgMZrUoOxPHkxFeyLLf7pAEJe7QNB+Qilw8e2zVqtiJrRk6uDIGJ\nSv+yM52zkImZAe2jOdU3KeUZxSMmb5vIoiPBm+tb2WupAg3YdpKn1/jWTpVmV/+G\nUtTLVE6YpAyFp1gMxhutE9vfIS94ek+vt03AoEOlltt6hqZfv3xmY8vGuAjlnj12\nzHaq+fhCRPsbsZkzJ9nIVdXYnNIEGtMGNnxax7tYRej/UXqyazbxHiJ0iPF4PeDn\ndzxtGxpeTBi+KhKlca8SlCdCqYwG6Q==\n-----END PRIVATE KEY-----', - 'key-id': 'rsa-4096-private' + encrypt: true, + decrypt: true, + algorithm: 'rsa', + type: 'private', + bits: 4096, + encoding: 'pem', + material: + '-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCztGg1gQ8AjCzz\n1VX6StqtW//jBt2ZQBoApaBa7FmLmdr0YlKaeEKSrItGbvA9tBjgsKhrn8gxTGQc\nuxgM92651jRCbQZyjE6W8kodijhGMXsfKJLfgPp2/I7gZ3dqrSZkejFIYLFb/uF/\nTfAQzNyJUldYdeFojSUPqevMgSAusTgv7dXYt4BCO9mxMp35tgyp5k4vazKJVUgB\nTw87AAYZUGugmi94Wb9JSnqUKI3QzaRN7JADZrHdBO1lIBryfCsjtTnZc7NWZ0yJ\nwmzLY+C5b3y17cy44N0rbjI2QciRhqZ4/9SZ/9ImyFQlB3lr9NSndcT4eE5YC6bH\nba0gOUK9lLXVy6TZ+nRZ4dSddoLX03mpYp+8cQpK6DO3L/PeUY/si0WGsXZfWokd\n4ACwvXWSOjotzjwqwTW8q9udbhUvIHfB02JW+ZQ07b209fBpHRDkZuveOTedTN2Q\nQei4dZDjWW5s4cIIE3dXXeaH8yC02ERIeN+aY6eHngSsP2xoDV3sKNN/yDbCqaMS\nq8ZJbo2rvOFxZHa2nWiV+VLugfO6Xj8jeGeR8vopvbEBZZpAq+Dea2xjY4+XMUQ/\nS1HlRwc9+nkJ5LVfODuE3q9EgJbqbiXe7YckWV3ZqQMybW+dLPxEJs9buOntgHFS\nRYmbKky0bti/ZoZlcZtS0zyjVxlqsQIDAQABAoICAEr3m/GWIXgNAkPGX9PGnmtr\n0dgX6SIhh7d1YOwNZV3DlYAV9HfUa5Fcwc1kQny7QRWbHOepBI7sW2dQ9buTDXIh\nVjPP37yxo6d89EZWfxtpUP+yoXL0D4jL257qCvtJuJZ6E00qaVMDhXbiQKABlo8C\n9sVEiABhwXBDZsctpwtTiykTgv6hrrPy2+H8R8MAm0/VcBCAG9kG5r8FCEmIvQKa\ndgvNxrfiWNZuZ6yfLmpJH54SbhG9Kb4WbCKfvh4ihqyi0btRdSM6fMeLgG9o/zrc\ns54B0kHeLOYNVo0j7FQpZBFeSIbmHfln4RKBh7ntrTke/Ejbh3NbiPvxWSP0P067\nSYWPkQpip2q0ION81wSQZ1haP2GewFFu4IEjG3DlqqpKKGLqXrmjMufnildVFpBx\nir+MgvgQfEBoGEx0aElyO7QuRYaEiXeb/BhMZeC5O65YhJrWSuTVizh3xgJWjgfV\naYwYgxN8SBXBhXLIVvnPhadTqsW1C/aevLOk110eSFWcHf+FCK781ykIzcpXoRGX\nOwWcZzC/fmSABS0yH56ow+I0tjdLIEEMhoa4/kkamioHOJ4yyB+W1DO6/DnMyQlx\ng7y2WsAaIEBoWUARy776k70xPPMtYAxzFXI9KhqRVrPfeaRZ+ojeyLyr3GQGyyoo\ncuGRdMUblsmODv4ixmOxAoIBAQDvkznvVYNdP3Eg5vQeLm/qsP6dLejLijBLeq9i\n7DZH2gRpKcflXZxCkRjsKDDE+fgDcBYEp2zYfRIVvgrxlTQZdaSG+GoDcbjbNQn3\ndjCCtOOACioN/vg2zFlX4Bs6Q+NaV7g5qP5SUaxUBjuHLe7Nc+ZkyheMHuNYVLvk\nHL/IoWyANpZYjMUU3xMbL/J29Gz7CPGr8Si28TihAHGfcNgn8S04OQZhTX+bU805\n/+7B4XW47Mthg/u7hlqFl+YIAaSJYvWkEaVP1A9I7Ve0aMDSMWwzTg9cle2uVaL3\n+PTzWY5coBlHKjqAg9ufhYSDhAqBd/JOSlv8RwcA3PDXJ6C/AoIBAQDABmXXYQky\n7phExXBvkLtJt2TBGjjwulf4R8TC6W5F51jJuoqY/mTqYcLcOn2nYGVwoFvPsy/Q\nCTjfODwJBXzbloXtYFR3PWAeL1Y6+7Cm+koMWIPJyVbD5Fzm+gZStM0GwP8FhDt2\nWt8fWEyXmoLdAy6RAwiEmCagEh8o+13oBfwnBllbz7TxaErsUuR+XVgl/iHwztdv\ncdJKyRgaFfWSh9aiO7EMV2rBGWsoX09SRvprPFAGx8Ffm7YcqIk34QXsQyc45Dyn\nCwkvypxHoaB3ot/48FeFm9IubApb/ctv+EgkBfL4S4bdwRXS1rt+0+QihBoFyP2o\nJ91cdm4hEWCPAoIBAQC6l11hFaYZo0bWDGsHcr2B+dZkzxPoKznQH76n+jeQoLIc\nwgjJkK4afm39yJOrZtEOxGaxu0CgIFFMk9ZsL/wC9EhvQt02z4TdXiLkFK5VrtMd\nr0zv16y06VWQhqBOMf/KJlX6uq9RqADi9HO6pkC+zc0cpPXQEWKaMmygju+kMG2U\nMm/IieMZjWCRJTfgBCE5J88qTsqaKagkZXcZakdAXKwOhQN+F2EStiM6UCZB5PrO\nS8dfrO8ML+ki8Zqck8L1qhiNb5zkXtKExy4u+gNr8khGcT6vqqoSxOoH3mPRgOfL\nJnppne8wlwIf7Vq3H8ka6zPSXEHma999gZcmy9t7AoIBAGbQhiLl79j3a0wXMvZp\nVf5IVYgXFDnAbG2hb7a06bhAAIgyexcjzsC4C2+DWdgOgwHkuoPg+062QV8zauGh\nsJKaa6cHlvIpSJeg3NjD/nfJN3CYzCd0yCIm2Z9Ka6xI5iYhm+pGPNhIG4Na8deS\ngVL46yv1pc/o73VxfoGg5UzgN3xlp97Cva0sHEGguHr4W8Qr59xZw3wGQ4SLW35M\nF6qXVNKUh12GSMCPbZK2RXBWVKqqJmca+WzJoJ6DlsT2lQdFhXCus9L007xlDXxF\nC/hCmw1dEl+VaNo2Ou26W/zdwTKYhNlxBwsg4SB8nPNxXIsmlBBY54froFhriNfn\nx/0CggEAUzz+VMtjoEWw2HSHLOXrO4EmwJniNgiiwfX3DfZE4tMNZgqZwLkq67ns\nT0n3b0XfAOOkLgMZrUoOxPHkxFeyLLf7pAEJe7QNB+Qilw8e2zVqtiJrRk6uDIGJ\nSv+yM52zkImZAe2jOdU3KeUZxSMmb5vIoiPBm+tb2WupAg3YdpKn1/jWTpVmV/+G\nUtTLVE6YpAyFp1gMxhutE9vfIS94ek+vt03AoEOlltt6hqZfv3xmY8vGuAjlnj12\nzHaq+fhCRPsbsZkzJ9nIVdXYnNIEGtMGNnxax7tYRej/UXqyazbxHiJ0iPF4PeDn\ndzxtGxpeTBi+KhKlca8SlCdCqYwG6Q==\n-----END PRIVATE KEY-----', + 'key-id': 'rsa-4096-private', } const rsaInfo: RsaKeyInfo = { - 'type': 'raw', - 'key': 'rsa-4096-private', + type: 'raw', + key: 'rsa-4096-private', 'provider-id': 'aws-raw-vectors-persistant', 'encryption-algorithm': 'rsa', - 'padding-algorithm': 'pkcs1' + 'padding-algorithm': 'pkcs1', } describe('how to build keyrings', () => { diff --git a/modules/integration-node/test/get_decrypt_test_iterator.test.ts b/modules/integration-node/test/get_decrypt_test_iterator.test.ts index 0081161fe..afb5fd74a 100644 --- a/modules/integration-node/test/get_decrypt_test_iterator.test.ts +++ b/modules/integration-node/test/get_decrypt_test_iterator.test.ts @@ -4,84 +4,86 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { - _getDecryptTestVectorIterator -} from '../src/index' -import { DecryptManifestList, KeyList } from '../src/types' // eslint-disable-line no-unused-vars +import { _getDecryptTestVectorIterator } from '../src/index' +import { DecryptManifestList, KeyList } from '../src/types' import { PassThrough } from 'stream' const keyList: KeyList = { - 'manifest': { - 'type': 'keys', - 'version': 3 + manifest: { + type: 'keys', + version: 3, }, - 'keys': { + keys: { 'us-west-2-decryptable': { - 'type': 'aws-kms', + type: 'aws-kms', 'key-id': 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt', - 'encrypt': true, - 'decrypt': true - } - } + encrypt: true, + decrypt: true, + }, + }, } -const manifest:DecryptManifestList = { - 'manifest': { - 'type': 'awses-decrypt', - 'version': 1 +const manifest: DecryptManifestList = { + manifest: { + type: 'awses-decrypt', + version: 1, }, - 'client': { - 'name': 'aws/aws-encryption-sdk-python', - 'version': '1.3.8' + client: { + name: 'aws/aws-encryption-sdk-python', + version: '1.3.8', }, - 'keys': 'file://keys.json', - 'tests': { + keys: 'file://keys.json', + tests: { 'c17b05d0-915e-44cc-98a3-cc29b71aa42b': { - 'plaintext': 'file://plaintexts/small', - 'ciphertext': 'file://ciphertexts/460bd892-c137-4178-8201-4ab5ee5d3041', + plaintext: 'file://plaintexts/small', + ciphertext: 'file://ciphertexts/460bd892-c137-4178-8201-4ab5ee5d3041', 'master-keys': [ { - 'type': 'aws-kms', - 'key': 'us-west-2-decryptable' - } - ] - } - } + type: 'aws-kms', + key: 'us-west-2-decryptable', + }, + ], + }, + }, } const filesMap = new Map([ [ - 'file://manifest.json', { - async stream () { + 'file://manifest.json', + { + async stream() { const stream = new PassThrough() setImmediate(() => stream.end(Buffer.from(JSON.stringify(manifest)))) return stream - } - } as any + }, + } as any, ], [ - 'file://keys.json', { - async stream () { + 'file://keys.json', + { + async stream() { const stream = new PassThrough() setImmediate(() => stream.end(Buffer.from(JSON.stringify(keyList)))) return stream - } - } as any + }, + } as any, ], [ - 'file://ciphertexts/460bd892-c137-4178-8201-4ab5ee5d3041', { - async stream () { + 'file://ciphertexts/460bd892-c137-4178-8201-4ab5ee5d3041', + { + async stream() { return {} as any - } - } as any + }, + } as any, ], [ - 'file://plaintexts/small', { - async stream () { + 'file://plaintexts/small', + { + async stream() { return {} as any - } - } as any - ] + }, + } as any, + ], ]) describe('_getDecryptTestVectorIterator', () => { diff --git a/modules/integration-node/test/get_encrypt_test_iterator.test.ts b/modules/integration-node/test/get_encrypt_test_iterator.test.ts index a5ddb26ce..c99748147 100644 --- a/modules/integration-node/test/get_encrypt_test_iterator.test.ts +++ b/modules/integration-node/test/get_encrypt_test_iterator.test.ts @@ -4,48 +4,47 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { - _getEncryptTestVectorIterator -} from '../src/index' -import { EncryptManifestList, KeyList } from '../src/types' // eslint-disable-line no-unused-vars +import { _getEncryptTestVectorIterator } from '../src/index' +import { EncryptManifestList, KeyList } from '../src/types' const manifiest: EncryptManifestList = { - 'manifest': { - 'type': 'awses-encrypt', - 'version': 1 + manifest: { + type: 'awses-encrypt', + version: 1, }, - 'keys': 'file://0002-keys.v1.json', - 'plaintexts': { - 'small': 10240 + keys: 'file://0002-keys.v1.json', + plaintexts: { + small: 10240, }, - 'tests': { + tests: { '0c9c3222-b8f6-4b5f-97bc-c2a97f5255b1': { - 'plaintext': 'small', - 'algorithm': '0014', + plaintext: 'small', + algorithm: '0014', 'frame-size': 0, 'encryption-context': {}, 'master-keys': [ { - 'type': 'aws-kms', - 'key': 'us-west-2-decryptable' - } - ] - } - } + type: 'aws-kms', + key: 'us-west-2-decryptable', + }, + ], + }, + }, } const keyList: KeyList = { - 'manifest': { - 'type': 'keys', - 'version': 3 + manifest: { + type: 'keys', + version: 3, + }, + keys: { + 'us-west-2-decryptable': { + type: 'aws-kms', + 'key-id': 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt', + encrypt: true, + decrypt: true, + }, }, - 'keys': { 'us-west-2-decryptable': { - 'type': 'aws-kms', - 'key-id': 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt', - 'encrypt': true, - 'decrypt': true - } - } } describe('_getEncryptTestVectorIterator', () => { diff --git a/modules/kms-keyring-browser/test/kms_keyring_browser.test.ts b/modules/kms-keyring-browser/test/kms_keyring_browser.test.ts index 80eb2a2ca..5bf21ee07 100644 --- a/modules/kms-keyring-browser/test/kms_keyring_browser.test.ts +++ b/modules/kms-keyring-browser/test/kms_keyring_browser.test.ts @@ -5,18 +5,14 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { - KmsKeyringBrowser, - getClient, - KMS -} from '../src/index' +import { KmsKeyringBrowser, getClient, KMS } from '../src/index' import { KeyringWebCrypto, WebCryptoEncryptionMaterial, WebCryptoAlgorithmSuite, AlgorithmSuiteIdentifier, - EncryptedDataKey, // eslint-disable-line no-unused-vars - WebCryptoDecryptionMaterial + EncryptedDataKey, + WebCryptoDecryptionMaterial, } from '@aws-crypto/material-management-browser' chai.use(chaiAsPromised) @@ -27,12 +23,18 @@ declare const credentials: any describe('KmsKeyringBrowser::constructor', () => { it('constructor decorates', async () => { - const generatorKeyId = 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' - const keyArn = 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' + const generatorKeyId = + 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' + const keyArn = + 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' const keyIds = [keyArn] const clientProvider = getClient(KMS, { credentials }) - const test = new KmsKeyringBrowser({ clientProvider, generatorKeyId, keyIds }) + const test = new KmsKeyringBrowser({ + clientProvider, + generatorKeyId, + keyIds, + }) expect(test.generatorKeyId).to.equal(generatorKeyId) expect(test.keyIds).to.have.lengthOf(1) @@ -48,15 +50,23 @@ describe('KmsKeyringBrowser::constructor', () => { }) describe('KmsKeyringBrowser encrypt/decrypt', () => { - const generatorKeyId = 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' - const keyArn = 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' + const generatorKeyId = + 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' + const keyArn = + 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' const keyIds = [keyArn] const clientProvider = getClient(KMS, { credentials }) - const keyring = new KmsKeyringBrowser({ clientProvider, generatorKeyId, keyIds }) + const keyring = new KmsKeyringBrowser({ + clientProvider, + generatorKeyId, + keyIds, + }) let encryptedDataKey: EncryptedDataKey it('can encrypt and create unencrypted data key', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const test = await keyring.onEncrypt(material) expect(test.hasValidKey()).to.equal(true) @@ -68,7 +78,9 @@ describe('KmsKeyringBrowser encrypt/decrypt', () => { }) it('can decrypt an EncryptedDataKey', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) const test = await keyring.onDecrypt(material, [encryptedDataKey]) expect(test.hasValidKey()).to.equal(true) diff --git a/modules/kms-keyring-node/test/kms_keyring_node.test.ts b/modules/kms-keyring-node/test/kms_keyring_node.test.ts index 24e69f344..60136ab9d 100644 --- a/modules/kms-keyring-node/test/kms_keyring_node.test.ts +++ b/modules/kms-keyring-node/test/kms_keyring_node.test.ts @@ -10,15 +10,17 @@ import { NodeEncryptionMaterial, NodeAlgorithmSuite, AlgorithmSuiteIdentifier, - EncryptedDataKey, // eslint-disable-line no-unused-vars + EncryptedDataKey, NodeDecryptionMaterial, - unwrapDataKey + unwrapDataKey, } from '@aws-crypto/material-management-node' describe('KmsKeyringNode::constructor', () => { it('constructor decorates', async () => { - const generatorKeyId = 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' - const keyArn = 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' + const generatorKeyId = + 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' + const keyArn = + 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' const keyIds = [keyArn] const test = new KmsKeyringNode({ generatorKeyId, keyIds }) @@ -37,15 +39,19 @@ describe('KmsKeyringNode::constructor', () => { }) describe('KmsKeyringNode encrypt/decrypt', () => { - const generatorKeyId = 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' - const keyArn = 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' + const generatorKeyId = + 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' + const keyArn = + 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f' const keyIds = [keyArn] const keyring = new KmsKeyringNode({ generatorKeyId, keyIds }) let encryptedDataKey: EncryptedDataKey let udk: Uint8Array it('can encrypt and create unencrypted data key', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new NodeEncryptionMaterial(suite, {}) const test = await keyring.onEncrypt(material) expect(test.hasValidKey()).to.equal(true) @@ -57,7 +63,9 @@ describe('KmsKeyringNode encrypt/decrypt', () => { }) it('can decrypt an EncryptedDataKey', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new NodeDecryptionMaterial(suite, {}) const test = await keyring.onDecrypt(material, [encryptedDataKey]) expect(test.hasValidKey()).to.equal(true) diff --git a/modules/kms-keyring/test/helpers.test.ts b/modules/kms-keyring/test/helpers.test.ts index 74233338f..129c37f9d 100644 --- a/modules/kms-keyring/test/helpers.test.ts +++ b/modules/kms-keyring/test/helpers.test.ts @@ -4,7 +4,12 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { generateDataKey, encrypt, decrypt, kmsResponseToEncryptedDataKey } from '../src/helpers' +import { + generateDataKey, + encrypt, + decrypt, + kmsResponseToEncryptedDataKey, +} from '../src/helpers' import { EncryptedDataKey } from '@aws-crypto/material-management' describe('kmsResponseToEncryptedDataKey', () => { @@ -12,7 +17,7 @@ describe('kmsResponseToEncryptedDataKey', () => { const response = { KeyId: 'asdf', CiphertextBlob: new Uint8Array(5), - $metadata: {} as any + $metadata: {} as any, } const test = kmsResponseToEncryptedDataKey(response) expect(test).instanceOf(EncryptedDataKey) @@ -25,7 +30,7 @@ describe('kmsResponseToEncryptedDataKey', () => { describe('generateDataKey', () => { it('return', async () => { // the string Plaintext as bytes - const key = [ 80, 108, 97, 105, 110, 116, 101, 120, 116 ] + const key = [80, 108, 97, 105, 110, 116, 101, 120, 116] const Plaintext = new Uint8Array(key) const KeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' const GrantTokens = ['grantToken'] @@ -35,7 +40,7 @@ describe('generateDataKey', () => { const clientProvider: any = (region: string) => { expect(region).to.equal('us-east-1') return { generateDataKey } - async function generateDataKey (input: any) { + async function generateDataKey(input: any) { expect(input.KeyId).to.equal(KeyId) expect(input.GrantTokens).to.equal(GrantTokens) expect(input.NumberOfBytes).to.equal(NumberOfBytes) @@ -43,12 +48,18 @@ describe('generateDataKey', () => { return { Plaintext, KeyId: 'KeyId', - CiphertextBlob: new Uint8Array([1, 2, 3, 4]) + CiphertextBlob: new Uint8Array([1, 2, 3, 4]), } } } - const test = await generateDataKey(clientProvider, NumberOfBytes, KeyId, EncryptionContext, GrantTokens) + const test = await generateDataKey( + clientProvider, + NumberOfBytes, + KeyId, + EncryptionContext, + GrantTokens + ) if (!test) throw new Error('never') expect(test.Plaintext).to.deep.equal(new Uint8Array(key)) expect(test.KeyId).to.equal('KeyId') @@ -65,7 +76,13 @@ describe('generateDataKey', () => { return false } - const test = await generateDataKey(clientProvider, NumberOfBytes, KeyId, EncryptionContext, GrantTokens) + const test = await generateDataKey( + clientProvider, + NumberOfBytes, + KeyId, + EncryptionContext, + GrantTokens + ) expect(test).to.equal(false) }) @@ -77,13 +94,19 @@ describe('generateDataKey', () => { const clientProvider: any = () => { return { generateDataKey } - function generateDataKey () { + function generateDataKey() { return {} } } try { - await generateDataKey(clientProvider, NumberOfBytes, KeyId, EncryptionContext, GrantTokens) + await generateDataKey( + clientProvider, + NumberOfBytes, + KeyId, + EncryptionContext, + GrantTokens + ) } catch { return } @@ -102,19 +125,25 @@ describe('encrypt', () => { const clientProvider: any = (region: string) => { expect(region).to.equal('us-east-1') return { encrypt } - function encrypt (input: any) { + function encrypt(input: any) { expect(input.KeyId).to.equal(KeyId) expect(input.GrantTokens).to.equal(GrantTokens) expect(input.Plaintext).to.equal(Plaintext) expect(input.EncryptionContext).to.equal(EncryptionContext) return { KeyId: 'KeyId', - CiphertextBlob + CiphertextBlob, } } } - const test = await encrypt(clientProvider, Plaintext, KeyId, EncryptionContext, GrantTokens) + const test = await encrypt( + clientProvider, + Plaintext, + KeyId, + EncryptionContext, + GrantTokens + ) if (!test) throw new Error('never') expect(test.KeyId).to.equal('KeyId') expect(test.CiphertextBlob).to.deep.equal(CiphertextBlob) @@ -130,7 +159,13 @@ describe('encrypt', () => { return false } - const test = await encrypt(clientProvider, Plaintext, KeyId, EncryptionContext, GrantTokens) + const test = await encrypt( + clientProvider, + Plaintext, + KeyId, + EncryptionContext, + GrantTokens + ) expect(test).to.equal(false) }) @@ -142,13 +177,19 @@ describe('encrypt', () => { const clientProvider: any = () => { return { encrypt } - function encrypt () { + function encrypt() { return {} } } try { - await encrypt(clientProvider, Plaintext, KeyId, EncryptionContext, GrantTokens) + await encrypt( + clientProvider, + Plaintext, + KeyId, + EncryptionContext, + GrantTokens + ) } catch { return } @@ -159,32 +200,37 @@ describe('encrypt', () => { describe('decrypt', () => { it('return', async () => { // the string Plaintext as bytes - const key = [ 80, 108, 97, 105, 110, 116, 101, 120, 116 ] + const key = [80, 108, 97, 105, 110, 116, 101, 120, 116] const Plaintext = new Uint8Array(key) const GrantTokens = ['grantToken'] const KeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' const edk = new EncryptedDataKey({ providerId: 'aws-kms', providerInfo: KeyId, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) const EncryptionContext = { some: 'context' } const clientProvider: any = (region: string) => { expect(region).to.equal('us-east-1') return { decrypt } - function decrypt (input: any) { + function decrypt(input: any) { expect(input.GrantTokens).to.equal(GrantTokens) expect(input.CiphertextBlob).lengthOf(5) expect(input.EncryptionContext).to.equal(EncryptionContext) return { KeyId: 'KeyId', - Plaintext + Plaintext, } } } - const test = await decrypt(clientProvider, edk, EncryptionContext, GrantTokens) + const test = await decrypt( + clientProvider, + edk, + EncryptionContext, + GrantTokens + ) if (!test) throw new Error('never') expect(test.KeyId).to.equal('KeyId') expect(test.Plaintext).to.deep.equal(new Uint8Array(key)) @@ -196,16 +242,16 @@ describe('decrypt', () => { const edk = new EncryptedDataKey({ providerId: 'NOTaws-kms', providerInfo: KeyId, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) const EncryptionContext = { some: 'context' } const clientProvider: any = () => { return { decrypt } - function decrypt () { + function decrypt() { return { KeyId: 'KeyId', - Plaintext: 'Plaintext' + Plaintext: 'Plaintext', } } } @@ -224,7 +270,7 @@ describe('decrypt', () => { const edk = new EncryptedDataKey({ providerId: 'aws-kms', providerInfo: KeyId, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) const EncryptionContext = { some: 'context' } @@ -232,7 +278,12 @@ describe('decrypt', () => { return false } - const test = await decrypt(clientProvider, edk, EncryptionContext, GrantTokens) + const test = await decrypt( + clientProvider, + edk, + EncryptionContext, + GrantTokens + ) expect(test).to.equal(false) }) @@ -242,13 +293,13 @@ describe('decrypt', () => { const edk = new EncryptedDataKey({ providerId: 'aws-kms', providerInfo: KeyId, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) const EncryptionContext = { some: 'context' } const clientProvider: any = () => { return { decrypt } - function decrypt () { + function decrypt() { return {} } } diff --git a/modules/kms-keyring/test/kms_client_supplier.test.ts b/modules/kms-keyring/test/kms_client_supplier.test.ts index a4df2813f..0acecf6f3 100644 --- a/modules/kms-keyring/test/kms_client_supplier.test.ts +++ b/modules/kms-keyring/test/kms_client_supplier.test.ts @@ -4,7 +4,13 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { getClient, limitRegions, excludeRegions, cacheClients, deferCache } from '../src/kms_client_supplier' +import { + getClient, + limitRegions, + excludeRegions, + cacheClients, + deferCache, +} from '../src/kms_client_supplier' describe('getClient', () => { it('return a client', () => { @@ -12,7 +18,7 @@ describe('getClient', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } @@ -29,7 +35,7 @@ describe('getClient', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) expect(config.extra).to.equal('value') assertCount++ @@ -47,7 +53,7 @@ describe('getClient', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } @@ -62,7 +68,7 @@ describe('getClient', () => { it('Postcondition: A region must be configured.', () => { let assertCount = 0 const TestKMS: any = class { - constructor () { + constructor() { assertCount++ } } @@ -79,7 +85,7 @@ describe('limitRegions', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } @@ -96,7 +102,7 @@ describe('limitRegions', () => { const region = 'us-west-2' let assertCount = 0 const TestKMS: any = class { - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ } @@ -110,7 +116,9 @@ describe('limitRegions', () => { it('Precondition: limitRegions requires that region be a string.', () => { expect(() => limitRegions(['us-east-2', ''], (() => {}) as any)).to.throw() - expect(() => limitRegions(['us-east-2', {}] as any, (() => {}) as any)).to.throw() + expect(() => + limitRegions(['us-east-2', {}] as any, (() => {}) as any) + ).to.throw() }) }) @@ -119,7 +127,7 @@ describe('excludeRegions', () => { const region = 'us-west-2' let assertCount = 0 const TestKMS: any = class { - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ } @@ -136,7 +144,7 @@ describe('excludeRegions', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } @@ -150,8 +158,12 @@ describe('excludeRegions', () => { }) it('Precondition: excludeRegions requires region be a string.', () => { - expect(() => excludeRegions(['us-east-2', ''], (() => {}) as any)).to.throw() - expect(() => excludeRegions(['us-east-2', {}] as any, (() => {}) as any)).to.throw() + expect(() => + excludeRegions(['us-east-2', ''], (() => {}) as any) + ).to.throw() + expect(() => + excludeRegions(['us-east-2', {}] as any, (() => {}) as any) + ).to.throw() }) }) @@ -161,7 +173,7 @@ describe('cacheClients', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } @@ -178,7 +190,7 @@ describe('cacheClients', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } @@ -199,14 +211,12 @@ describe('cacheClients', () => { let assertCount = 0 const TestKMS: any = class { config: any - constructor (config: any) { + constructor(config: any) { expect(config.region).to.equal(region) assertCount++ this.config = { region } } - async decrypt () { - - } + async decrypt() {} } const getKmsClient = cacheClients(getClient(TestKMS)) const test = getKmsClient(region) @@ -228,7 +238,7 @@ describe('deferCache', () => { const client: any = { encrypt: noop, decrypt: noop, - generateDataKey: noop + generateDataKey: noop, } const clientsCache: any = {} const region = 'region' diff --git a/modules/kms-keyring/test/kms_keyring.constructor.test.ts b/modules/kms-keyring/test/kms_keyring.constructor.test.ts index 95b419448..cd8f2885e 100644 --- a/modules/kms-keyring/test/kms_keyring.constructor.test.ts +++ b/modules/kms-keyring/test/kms_keyring.constructor.test.ts @@ -4,22 +4,27 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { - KmsKeyringClass, - KeyRingConstructible // eslint-disable-line no-unused-vars -} from '../src/kms_keyring' -import { NodeAlgorithmSuite, Keyring } from '@aws-crypto/material-management' // eslint-disable-line no-unused-vars +import { KmsKeyringClass, KeyRingConstructible } from '../src/kms_keyring' +import { NodeAlgorithmSuite, Keyring } from '@aws-crypto/material-management' describe('KmsKeyring: constructor', () => { it('set properties', () => { const clientProvider: any = () => {} - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' const keyIds = ['arn:aws:kms:us-east-1:123456789012:alias/example-alias'] const grantTokens = ['grant'] - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} - const test = new TestKmsKeyring({ clientProvider, generatorKeyId, keyIds, grantTokens }) + const test = new TestKmsKeyring({ + clientProvider, + generatorKeyId, + keyIds, + grantTokens, + }) expect(test.clientProvider).to.equal(clientProvider) expect(test.generatorKeyId).to.equal(generatorKeyId) expect(test.keyIds).to.deep.equal(keyIds) @@ -31,7 +36,9 @@ describe('KmsKeyring: constructor', () => { const clientProvider: any = () => {} const discovery = true - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const test = new TestKmsKeyring({ clientProvider, discovery }) expect(test.clientProvider).to.equal(clientProvider) @@ -43,59 +50,94 @@ describe('KmsKeyring: constructor', () => { it('Precondition: This is an abstract class. (But TypeScript does not have a clean way to model this)', () => { const clientProvider: any = () => {} - const KmsKeyring = KmsKeyringClass(Keyring as KeyRingConstructible) - expect(() => new KmsKeyring({ clientProvider })).to.throw('new KmsKeyring is not allowed') + const KmsKeyring = KmsKeyringClass( + Keyring as KeyRingConstructible + ) + expect(() => new KmsKeyring({ clientProvider })).to.throw( + 'new KmsKeyring is not allowed' + ) }) it('Precondition: A noop KmsKeyring is not allowed.', () => { - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const clientProvider: any = () => {} expect(() => new TestKmsKeyring({ clientProvider })).to.throw() }) it('Precondition: A keyring can be either a Discovery or have keyIds configured.', () => { - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const clientProvider: any = () => {} - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' const keyIds = ['arn:aws:kms:us-east-1:123456789012:alias/example-alias'] const discovery = true - expect(() => new TestKmsKeyring({ clientProvider, generatorKeyId, keyIds, discovery })).to.throw() + expect( + () => + new TestKmsKeyring({ + clientProvider, + generatorKeyId, + keyIds, + discovery, + }) + ).to.throw() }) it('Precondition: All KMS key identifiers must be valid.', () => { const clientProvider: any = () => {} - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} - - expect(() => new TestKmsKeyring({ - clientProvider, - generatorKeyId: 'Not arn' - })).to.throw() - - expect(() => new TestKmsKeyring({ - clientProvider, - keyIds: ['Not arn'] - })).to.throw() - - expect(() => new TestKmsKeyring({ - clientProvider, - keyIds: ['arn:aws:kms:us-east-1:123456789012:alias/example-alias', 'Not arn'] - })).to.throw() + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + expect( + () => + new TestKmsKeyring({ + clientProvider, + generatorKeyId: 'Not arn', + }) + ).to.throw() + + expect( + () => + new TestKmsKeyring({ + clientProvider, + keyIds: ['Not arn'], + }) + ).to.throw() + + expect( + () => + new TestKmsKeyring({ + clientProvider, + keyIds: [ + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias', + 'Not arn', + ], + }) + ).to.throw() }) it('An KMS CMK alias is a valid CMK identifier', () => { const clientProvider: any = () => {} - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const test = new TestKmsKeyring({ clientProvider, generatorKeyId: 'alias/example-alias', - keyIds: ['alias:example-alias'] + keyIds: ['alias:example-alias'], }) expect(test).to.be.instanceOf(TestKmsKeyring) }) it('Precondition: clientProvider needs to be a callable function.', () => { - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const clientProvider: any = 'not function' const discovery = true expect(() => new TestKmsKeyring({ clientProvider, discovery })).to.throw() diff --git a/modules/kms-keyring/test/kms_keyring.ondecrypt.test.ts b/modules/kms-keyring/test/kms_keyring.ondecrypt.test.ts index 54df4957d..fba2e50d9 100644 --- a/modules/kms-keyring/test/kms_keyring.ondecrypt.test.ts +++ b/modules/kms-keyring/test/kms_keyring.ondecrypt.test.ts @@ -5,320 +5,394 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { - KmsKeyringClass, - KeyRingConstructible // eslint-disable-line no-unused-vars -} from '../src/kms_keyring' +import { KmsKeyringClass, KeyRingConstructible } from '../src/kms_keyring' import { NodeAlgorithmSuite, AlgorithmSuiteIdentifier, KeyringTraceFlag, NodeDecryptionMaterial, EncryptedDataKey, - Keyring + Keyring, } from '@aws-crypto/material-management' chai.use(chaiAsPromised) const { expect } = chai -describe('KmsKeyring: _onDecrypt', - () => { - it('returns material', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' - const keyIds = [encryptKmsKey] - const context = { some: 'context' } - const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - - const clientProvider: any = () => { - return { decrypt } - function decrypt ({ CiphertextBlob, EncryptionContext, GrantTokens }: any) { - expect(EncryptionContext).to.deep.equal(context) - expect(GrantTokens).to.equal(grantTokens) - return { - Plaintext: new Uint8Array(suite.keyLengthBytes), - KeyId: Buffer.from(CiphertextBlob).toString('utf8') - } +describe('KmsKeyring: _onDecrypt', () => { + it('returns material', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const keyIds = [encryptKmsKey] + const context = { some: 'context' } + const grantTokens = ['grant'] + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + const clientProvider: any = () => { + return { decrypt } + function decrypt({ + CiphertextBlob, + EncryptionContext, + GrantTokens, + }: any) { + expect(EncryptionContext).to.deep.equal(context) + expect(GrantTokens).to.equal(grantTokens) + return { + Plaintext: new Uint8Array(suite.keyLengthBytes), + KeyId: Buffer.from(CiphertextBlob as Uint8Array).toString('utf8'), } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} - - const testKeyring = new TestKmsKeyring({ - clientProvider, - generatorKeyId, - keyIds, - grantTokens - }) - - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) - - const material = await testKeyring.onDecrypt( - new NodeDecryptionMaterial(suite, context), - [edk] - ) + } + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider, + generatorKeyId, + keyIds, + grantTokens, + }) - expect(material.hasUnencryptedDataKey).to.equal(true) + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), + }) + + const material = await testKeyring.onDecrypt( + new NodeDecryptionMaterial(suite, context), + [edk] + ) + + expect(material.hasUnencryptedDataKey).to.equal(true) + + expect(material.keyringTrace).to.have.lengthOf(1) + const [traceDecrypt] = material.keyringTrace + expect(traceDecrypt.keyNamespace).to.equal('aws-kms') + expect(traceDecrypt.keyName).to.equal(generatorKeyId) + expect( + traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + expect( + traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX) + }) - expect(material.keyringTrace).to.have.lengthOf(1) - const [traceDecrypt] = material.keyringTrace - expect(traceDecrypt.keyNamespace).to.equal('aws-kms') - expect(traceDecrypt.keyName).to.equal(generatorKeyId) - expect(traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - expect(traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX).to.equal(KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX) + it('discovery keyring should return material', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const context = { some: 'context' } + const grantTokens = ['grant'] + const discovery = true + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + const clientProvider: any = () => { + return { decrypt } + function decrypt({ + CiphertextBlob, + EncryptionContext, + GrantTokens, + }: any) { + expect(EncryptionContext).to.deep.equal(context) + expect(GrantTokens).to.equal(grantTokens) + return { + Plaintext: new Uint8Array(suite.keyLengthBytes), + KeyId: Buffer.from(CiphertextBlob as Uint8Array).toString('utf8'), + } + } + } + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider, + grantTokens, + discovery, + }) + + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), }) - it('discovery keyring should return material', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const context = { some: 'context' } - const grantTokens = ['grant'] - const discovery = true - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - - const clientProvider: any = () => { - return { decrypt } - function decrypt ({ CiphertextBlob, EncryptionContext, GrantTokens }: any) { - expect(EncryptionContext).to.deep.equal(context) - expect(GrantTokens).to.equal(grantTokens) - return { - Plaintext: new Uint8Array(suite.keyLengthBytes), - KeyId: Buffer.from(CiphertextBlob).toString('utf8') - } + const material = await testKeyring.onDecrypt( + new NodeDecryptionMaterial(suite, context), + [edk] + ) + + expect(material.hasUnencryptedDataKey).to.equal(true) + + expect(material.keyringTrace).to.have.lengthOf(1) + const [traceDecrypt] = material.keyringTrace + expect(traceDecrypt.keyNamespace).to.equal('aws-kms') + expect(traceDecrypt.keyName).to.equal(generatorKeyId) + expect( + traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + expect( + traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX) + }) + + it('decrypt errors should not halt', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const context = { some: 'context' } + const grantTokens = ['grant'] + const discovery = true + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + let edkCount = 0 + const clientProvider: any = () => { + return { decrypt } + function decrypt({ + CiphertextBlob, + EncryptionContext, + GrantTokens, + }: any) { + if (edkCount === 0) { + edkCount += 1 + throw new Error('failed to decrypt') + } + expect(EncryptionContext).to.deep.equal(context) + expect(GrantTokens).to.equal(grantTokens) + return { + Plaintext: new Uint8Array(suite.keyLengthBytes), + KeyId: Buffer.from(CiphertextBlob as Uint8Array).toString('utf8'), } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + } + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider, + grantTokens, + discovery, + }) - const testKeyring = new TestKmsKeyring({ - clientProvider, - grantTokens, - discovery - }) + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), + }) - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) + const material = await testKeyring.onDecrypt( + new NodeDecryptionMaterial(suite, context), + [edk, edk] + ) - const material = await testKeyring.onDecrypt( - new NodeDecryptionMaterial(suite, context), - [edk] - ) + expect(material.hasUnencryptedDataKey).to.equal(true) + expect(material.keyringTrace).to.have.lengthOf(1) + }) - expect(material.hasUnencryptedDataKey).to.equal(true) + it('Check for early return (Postcondition): clientProvider may not return a client.', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const keyIds = [encryptKmsKey] + const encryptionContext = { some: 'context' } + const grantTokens = ['grant'] + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + const clientProvider: any = () => false + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider, + generatorKeyId, + keyIds, + grantTokens, + }) - expect(material.keyringTrace).to.have.lengthOf(1) - const [traceDecrypt] = material.keyringTrace - expect(traceDecrypt.keyNamespace).to.equal('aws-kms') - expect(traceDecrypt.keyName).to.equal(generatorKeyId) - expect(traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - expect(traceDecrypt.flags & KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX).to.equal(KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX) + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), }) - it('decrypt errors should not halt', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const context = { some: 'context' } - const grantTokens = ['grant'] - const discovery = true - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - - let edkCount = 0 - const clientProvider: any = () => { - return { decrypt } - function decrypt ({ CiphertextBlob, EncryptionContext, GrantTokens }: any) { - if (edkCount === 0) { - edkCount += 1 - throw new Error('failed to decrypt') - } - expect(EncryptionContext).to.deep.equal(context) - expect(GrantTokens).to.equal(grantTokens) - return { - Plaintext: new Uint8Array(suite.keyLengthBytes), - KeyId: Buffer.from(CiphertextBlob).toString('utf8') - } + const material = await testKeyring.onDecrypt( + new NodeDecryptionMaterial(suite, encryptionContext), + [edk] + ) + + expect(material.hasUnencryptedDataKey).to.equal(false) + expect(material.keyringTrace).to.have.lengthOf(0) + }) + + it('Postcondition: The KeyId from KMS must match the encoded KeyID.', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const keyIds = [encryptKmsKey] + const encryptionContext = { some: 'context' } + const grantTokens = ['grant'] + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + const clientProvider: any = () => { + return { decrypt } + function decrypt({ EncryptionContext, GrantTokens }: any) { + expect(EncryptionContext).to.deep.equal(encryptionContext) + expect(GrantTokens).to.equal(grantTokens) + return { + Plaintext: new Uint8Array(suite.keyLengthBytes), + KeyId: 'Not the Encrypted ARN', } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} - - const testKeyring = new TestKmsKeyring({ - clientProvider, - grantTokens, - discovery - }) - - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) - - const material = await testKeyring.onDecrypt( - new NodeDecryptionMaterial(suite, context), - [edk, edk] - ) + } + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider, + generatorKeyId, + keyIds, + grantTokens, + }) - expect(material.hasUnencryptedDataKey).to.equal(true) - expect(material.keyringTrace).to.have.lengthOf(1) + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), }) - it('Check for early return (Postcondition): clientProvider may not return a client.', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' - const keyIds = [encryptKmsKey] - const encryptionContext = { some: 'context' } - const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - - const clientProvider: any = () => false - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} - - const testKeyring = new TestKmsKeyring({ - clientProvider, - generatorKeyId, - keyIds, - grantTokens - }) - - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) - - const material = await testKeyring.onDecrypt( + return expect( + testKeyring.onDecrypt( new NodeDecryptionMaterial(suite, encryptionContext), [edk] ) + ).to.rejectedWith( + Error, + 'KMS Decryption key does not match serialized provider.' + ) + }) - expect(material.hasUnencryptedDataKey).to.equal(false) - expect(material.keyringTrace).to.have.lengthOf(0) - }) - - it('Postcondition: The KeyId from KMS must match the encoded KeyID.', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' - const keyIds = [encryptKmsKey] - const encryptionContext = { some: 'context' } - const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - - const clientProvider: any = () => { - return { decrypt } - function decrypt ({ EncryptionContext, GrantTokens }: any) { - expect(EncryptionContext).to.deep.equal(encryptionContext) - expect(GrantTokens).to.equal(grantTokens) - return { - Plaintext: new Uint8Array(suite.keyLengthBytes), - KeyId: 'Not the Encrypted ARN' - } + it('Postcondition: The decrypted unencryptedDataKey length must match the algorithm specification.', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const keyIds = [encryptKmsKey] + const encryptionContext = { some: 'context' } + const grantTokens = ['grant'] + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + const clientProvider: any = () => { + return { decrypt } + function decrypt({ + CiphertextBlob, + EncryptionContext, + GrantTokens, + }: any) { + expect(EncryptionContext).to.deep.equal(encryptionContext) + expect(GrantTokens).to.equal(grantTokens) + return { + Plaintext: new Uint8Array(suite.keyLengthBytes - 5), + KeyId: Buffer.from(CiphertextBlob as Uint8Array).toString('utf8'), } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} - - const testKeyring = new TestKmsKeyring({ - clientProvider, - generatorKeyId, - keyIds, - grantTokens - }) - - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) - - return expect(testKeyring.onDecrypt( - new NodeDecryptionMaterial(suite, encryptionContext), - [edk] - )).to.rejectedWith(Error, 'KMS Decryption key does not match serialized provider.') + } + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider, + generatorKeyId, + keyIds, + grantTokens, }) - it('Postcondition: The decrypted unencryptedDataKey length must match the algorithm specification.', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' - const keyIds = [encryptKmsKey] - const encryptionContext = { some: 'context' } - const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - - const clientProvider: any = () => { - return { decrypt } - function decrypt ({ CiphertextBlob, EncryptionContext, GrantTokens }: any) { - expect(EncryptionContext).to.deep.equal(encryptionContext) - expect(GrantTokens).to.equal(grantTokens) - return { - Plaintext: new Uint8Array(suite.keyLengthBytes - 5), - KeyId: Buffer.from(CiphertextBlob).toString('utf8') - } - } - } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} - - const testKeyring = new TestKmsKeyring({ - clientProvider, - generatorKeyId, - keyIds, - grantTokens - }) - - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) - - return expect(testKeyring.onDecrypt( - new NodeDecryptionMaterial(suite, encryptionContext), - [edk] - )).to.rejectedWith(Error, 'Key length does not agree with the algorithm specification.') + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), }) - it('Postcondition: A CMK must provide a valid data key or KMS must not have raised any errors.', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const context = { some: 'context' } - const grantTokens = ['grant'] - const discovery = true - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + return expect( + testKeyring.onDecrypt( + new NodeDecryptionMaterial(suite, encryptionContext), + [edk] + ) + ).to.rejectedWith( + Error, + 'Key length does not agree with the algorithm specification.' + ) + }) - const clientProviderError: any = () => { - return { decrypt } - function decrypt () { - throw new Error('failed to decrypt') - } + it('Postcondition: A CMK must provide a valid data key or KMS must not have raised any errors.', async () => { + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const context = { some: 'context' } + const grantTokens = ['grant'] + const discovery = true + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + + const clientProviderError: any = () => { + return { decrypt } + function decrypt() { + throw new Error('failed to decrypt') } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + } + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} + + const testKeyring = new TestKmsKeyring({ + clientProvider: clientProviderError, + grantTokens, + discovery, + }) - const testKeyring = new TestKmsKeyring({ - clientProvider: clientProviderError, - grantTokens, - discovery - }) - - const edk = new EncryptedDataKey({ - providerId: 'aws-kms', - providerInfo: generatorKeyId, - encryptedDataKey: Buffer.from(generatorKeyId) - }) - - await expect(testKeyring.onDecrypt( - new NodeDecryptionMaterial(suite, context), - [edk, edk] - )).to.rejectedWith(Error, 'Unable to decrypt data key and one or more KMS CMKs had an error.') - - /* This will make the decrypt loop not have an error. - * This will exercise the `(!material.hasValidKey() && !cmkErrors.length)` `needs` condition. - */ - const clientProviderNoError: any = () => false - await expect(new TestKmsKeyring({ + const edk = new EncryptedDataKey({ + providerId: 'aws-kms', + providerInfo: generatorKeyId, + encryptedDataKey: Buffer.from(generatorKeyId), + }) + + await expect( + testKeyring.onDecrypt(new NodeDecryptionMaterial(suite, context), [ + edk, + edk, + ]) + ).to.rejectedWith( + Error, + 'Unable to decrypt data key and one or more KMS CMKs had an error.' + ) + + /* This will make the decrypt loop not have an error. + * This will exercise the `(!material.hasValidKey() && !cmkErrors.length)` `needs` condition. + */ + const clientProviderNoError: any = () => false + await expect( + new TestKmsKeyring({ clientProvider: clientProviderNoError, grantTokens, - discovery - }).onDecrypt(new NodeDecryptionMaterial(suite, context), - [edk, edk] - )).to.not.rejectedWith(Error) - }) + discovery, + }).onDecrypt(new NodeDecryptionMaterial(suite, context), [edk, edk]) + ).to.not.rejectedWith(Error) }) +}) diff --git a/modules/kms-keyring/test/kms_keyring.onencrypt.test.ts b/modules/kms-keyring/test/kms_keyring.onencrypt.test.ts index 5d001d214..c90543370 100644 --- a/modules/kms-keyring/test/kms_keyring.onencrypt.test.ts +++ b/modules/kms-keyring/test/kms_keyring.onencrypt.test.ts @@ -5,59 +5,64 @@ import chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { - KmsKeyringClass, - KeyRingConstructible // eslint-disable-line no-unused-vars -} from '../src/kms_keyring' +import { KmsKeyringClass, KeyRingConstructible } from '../src/kms_keyring' import { NodeAlgorithmSuite, AlgorithmSuiteIdentifier, NodeEncryptionMaterial, KeyringTraceFlag, - Keyring + Keyring, } from '@aws-crypto/material-management' chai.use(chaiAsPromised) const { expect } = chai describe('KmsKeyring: _onEncrypt', () => { it('returns material', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' const keyIds = [encryptKmsKey] const context = { some: 'context' } const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return { generateDataKey, encrypt } - function generateDataKey ({ KeyId, EncryptionContext, GrantTokens }: any) { + function generateDataKey({ KeyId, EncryptionContext, GrantTokens }: any) { expect(EncryptionContext).to.deep.equal(context) expect(GrantTokens).to.equal(grantTokens) return { Plaintext: new Uint8Array(suite.keyLengthBytes), KeyId, - CiphertextBlob: new Uint8Array(5) + CiphertextBlob: new Uint8Array(5), } } - function encrypt ({ KeyId, EncryptionContext, GrantTokens }: any) { + function encrypt({ KeyId, EncryptionContext, GrantTokens }: any) { expect(EncryptionContext).to.deep.equal(context) expect(GrantTokens).to.equal(grantTokens) return { KeyId, - CiphertextBlob: new Uint8Array(5) + CiphertextBlob: new Uint8Array(5), } } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, generatorKeyId, keyIds, - grantTokens + grantTokens, }) - const material = await testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, context)) + const material = await testKeyring.onEncrypt( + new NodeEncryptionMaterial(suite, context) + ) expect(material.hasUnencryptedDataKey).to.equal(true) @@ -72,143 +77,195 @@ describe('KmsKeyring: _onEncrypt', () => { const [traceGenerate, traceEncrypt1, traceEncrypt2] = material.keyringTrace expect(traceGenerate.keyNamespace).to.equal('aws-kms') expect(traceGenerate.keyName).to.equal(generatorKeyId) - expect(traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) - expect(traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - expect(traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) + expect( + traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + expect( + traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + expect( + traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) expect(traceEncrypt1.keyNamespace).to.equal('aws-kms') expect(traceEncrypt1.keyName).to.equal(generatorKeyId) - expect(traceEncrypt1.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - expect(traceEncrypt1.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) + expect( + traceEncrypt1.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + expect( + traceEncrypt1.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) expect(traceEncrypt2.keyNamespace).to.equal('aws-kms') expect(traceEncrypt2.keyName).to.equal(encryptKmsKey) - expect(traceEncrypt2.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - expect(traceEncrypt2.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) + expect( + traceEncrypt2.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + expect( + traceEncrypt2.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) }) it('Check for early return (Postcondition): Discovery Keyrings do not encrypt.', async () => { const encryptionContext = { some: 'context' } const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return false } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, discovery: true, - grantTokens + grantTokens, }) - const material = await testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, encryptionContext)) + const material = await testKeyring.onEncrypt( + new NodeEncryptionMaterial(suite, encryptionContext) + ) expect(material.hasUnencryptedDataKey).to.equal(false) expect(material.encryptedDataKeys).to.have.lengthOf(0) }) it('Precondition: A generatorKeyId must generate if we do not have an unencrypted data key.', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' const keyIds = [encryptKmsKey] const context = { some: 'context' } const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return false } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, generatorKeyId, keyIds, - grantTokens + grantTokens, }) - await expect(testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, context))) - .to.rejectedWith(Error) + await expect( + testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, context)) + ).to.rejectedWith(Error) }) it('Postcondition: The generated unencryptedDataKey length must match the algorithm specification.', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' const encryptionContext = { some: 'context' } const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return { generateDataKey } - function generateDataKey ({ KeyId, EncryptionContext, GrantTokens }: any) { + function generateDataKey({ KeyId, EncryptionContext, GrantTokens }: any) { expect(EncryptionContext).to.deep.equal(encryptionContext) expect(GrantTokens).to.equal(grantTokens) return { Plaintext: new Uint8Array(suite.keyLengthBytes - 5), KeyId, - CiphertextBlob: new Uint8Array(5) + CiphertextBlob: new Uint8Array(5), } } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, generatorKeyId, - grantTokens + grantTokens, }) - return expect(testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, encryptionContext))).to.rejectedWith(Error, 'Key length does not agree with the algorithm specification.') + return expect( + testKeyring.onEncrypt( + new NodeEncryptionMaterial(suite, encryptionContext) + ) + ).to.rejectedWith( + Error, + 'Key length does not agree with the algorithm specification.' + ) }) it('Precondition: If a generator does not exist, an unencryptedDataKey *must* already exist.', async () => { - const encryptKmsKey = 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + const encryptKmsKey = + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' const keyIds = [encryptKmsKey] const context = { some: 'context' } const grantTokens = ['grant'] - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return false } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, keyIds, - grantTokens + grantTokens, }) - await expect(testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, context))) - .to.rejectedWith(Error) + await expect( + testKeyring.onEncrypt(new NodeEncryptionMaterial(suite, context)) + ).to.rejectedWith(Error) }) it('generator should encrypt if material already generated', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return { encrypt } - function encrypt ({ KeyId }: any) { + function encrypt({ KeyId }: any) { return { KeyId, - CiphertextBlob: new Uint8Array(5) + CiphertextBlob: new Uint8Array(5), } } } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, - generatorKeyId + generatorKeyId, }) - const seedMaterial = new NodeEncryptionMaterial(suite, {}) - .setUnencryptedDataKey(new Uint8Array(suite.keyLengthBytes), { - keyName: 'keyName', - keyNamespace: 'keyNamespace', - flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY - }) + const seedMaterial = new NodeEncryptionMaterial( + suite, + {} + ).setUnencryptedDataKey(new Uint8Array(suite.keyLengthBytes), { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) const material = await testKeyring.onEncrypt(seedMaterial) @@ -222,30 +279,41 @@ describe('KmsKeyring: _onEncrypt', () => { const [, kmsTrace] = material.keyringTrace expect(kmsTrace.keyNamespace).to.equal('aws-kms') expect(kmsTrace.keyName).to.equal(generatorKeyId) - expect(kmsTrace.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - expect(kmsTrace.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) + expect( + kmsTrace.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + expect( + kmsTrace.flags & KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX + ).to.equal(KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX) }) it('clientProvider may not return a client, in this case there is not an EDK to add', async () => { - const generatorKeyId = 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const generatorKeyId = + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const clientProvider: any = () => { return false } - class TestKmsKeyring extends KmsKeyringClass(Keyring as KeyRingConstructible) {} + class TestKmsKeyring extends KmsKeyringClass( + Keyring as KeyRingConstructible + ) {} const testKeyring = new TestKmsKeyring({ clientProvider, - generatorKeyId + generatorKeyId, }) - const seedMaterial = new NodeEncryptionMaterial(suite, {}) - .setUnencryptedDataKey(new Uint8Array(suite.keyLengthBytes), { - keyName: 'keyName', - keyNamespace: 'keyNamespace', - flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY - }) + const seedMaterial = new NodeEncryptionMaterial( + suite, + {} + ).setUnencryptedDataKey(new Uint8Array(suite.keyLengthBytes), { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) const material = await testKeyring.onEncrypt(seedMaterial) diff --git a/modules/kms-keyring/test/region_from_kms_key_arn.test.ts b/modules/kms-keyring/test/region_from_kms_key_arn.test.ts index 7c23435f7..41d1396dd 100644 --- a/modules/kms-keyring/test/region_from_kms_key_arn.test.ts +++ b/modules/kms-keyring/test/region_from_kms_key_arn.test.ts @@ -8,11 +8,17 @@ import { regionFromKmsKeyArn } from '../src/region_from_kms_key_arn' describe('regionFromKmsKeyArn', () => { it('return region', () => { - const test1 = regionFromKmsKeyArn('arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012') + const test1 = regionFromKmsKeyArn( + 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012' + ) expect(test1).to.equal('us-east-1') - const test2 = regionFromKmsKeyArn('arn:aws:kms:us-east-1:123456789012:alias/example-alias') + const test2 = regionFromKmsKeyArn( + 'arn:aws:kms:us-east-1:123456789012:alias/example-alias' + ) expect(test2).to.equal('us-east-1') - const test3 = regionFromKmsKeyArn('arn:aws:kms:us-east-1:123456789012:12345678-1234-1234-1234-123456789012') + const test3 = regionFromKmsKeyArn( + 'arn:aws:kms:us-east-1:123456789012:12345678-1234-1234-1234-123456789012' + ) expect(test3).to.equal('us-east-1') }) @@ -23,8 +29,12 @@ describe('regionFromKmsKeyArn', () => { * It should work but is not recommended. * Figuring out what region they CMK exist in is difficult. */ - expect(regionFromKmsKeyArn('key/12345678-1234-1234-1234-123456789012')).to.equal('') - expect(regionFromKmsKeyArn('key:12345678-1234-1234-1234-123456789012')).to.equal('') + expect( + regionFromKmsKeyArn('key/12345678-1234-1234-1234-123456789012') + ).to.equal('') + expect( + regionFromKmsKeyArn('key:12345678-1234-1234-1234-123456789012') + ).to.equal('') }) it('Precondition: A KMS key arn must be a string.', () => { @@ -34,12 +44,24 @@ describe('regionFromKmsKeyArn', () => { it('Postcondition: The ARN must be well formed.', () => { expect(() => regionFromKmsKeyArn('')).to.throw() - expect(() => regionFromKmsKeyArn('NOTarn:aws:kms:us-east-1:123456789012:alias/example-alias')).to.throw() + expect(() => + regionFromKmsKeyArn( + 'NOTarn:aws:kms:us-east-1:123456789012:alias/example-alias' + ) + ).to.throw() // empty partition - expect(() => regionFromKmsKeyArn('arn::kms:us-east-1:123456789012:alias/example-alias')).to.throw() - expect(() => regionFromKmsKeyArn('arn:aws:NOTkms:us-east-1:123456789012:alias/example-alias')).to.throw() + expect(() => + regionFromKmsKeyArn('arn::kms:us-east-1:123456789012:alias/example-alias') + ).to.throw() + expect(() => + regionFromKmsKeyArn( + 'arn:aws:NOTkms:us-east-1:123456789012:alias/example-alias' + ) + ).to.throw() // empty region - expect(() => regionFromKmsKeyArn('arn:aws:kms::123456789012:alias/example-alias')).to.throw() + expect(() => + regionFromKmsKeyArn('arn:aws:kms::123456789012:alias/example-alias') + ).to.throw() // no resource type expect(() => regionFromKmsKeyArn('example-alias')).to.throw() @@ -48,6 +70,8 @@ describe('regionFromKmsKeyArn', () => { expect(() => regionFromKmsKeyArn('something:example-alias')).to.throw() // invalid delimiter expect(() => regionFromKmsKeyArn('alias_example-alias')).to.throw() - expect(() => regionFromKmsKeyArn('key_12345678-1234-1234-1234-123456789012')).to.throw() + expect(() => + regionFromKmsKeyArn('key_12345678-1234-1234-1234-123456789012') + ).to.throw() }) }) diff --git a/modules/material-management-browser/test/browser_cryptographic_materials_manager.test.ts b/modules/material-management-browser/test/browser_cryptographic_materials_manager.test.ts index 232968663..2fc60b0ac 100644 --- a/modules/material-management-browser/test/browser_cryptographic_materials_manager.test.ts +++ b/modules/material-management-browser/test/browser_cryptographic_materials_manager.test.ts @@ -6,13 +6,19 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { - WebCryptoEncryptionMaterial, // eslint-disable-line no-unused-vars - WebCryptoDecryptionMaterial, // eslint-disable-line no-unused-vars + WebCryptoEncryptionMaterial, + WebCryptoDecryptionMaterial, WebCryptoDefaultCryptographicMaterialsManager, importForWebCryptoEncryptionMaterial, - importForWebCryptoDecryptionMaterial + importForWebCryptoDecryptionMaterial, } from '../src/index' -import { KeyringWebCrypto, WebCryptoAlgorithmSuite, AlgorithmSuiteIdentifier, KeyringTraceFlag, EncryptedDataKey } from '@aws-crypto/material-management' +import { + KeyringWebCrypto, + WebCryptoAlgorithmSuite, + AlgorithmSuiteIdentifier, + KeyringTraceFlag, + EncryptedDataKey, +} from '@aws-crypto/material-management' import { ENCODED_SIGNER_KEY } from '@aws-crypto/serialize' import { toBase64 } from '@aws-sdk/util-base64-browser' import { synchronousRandomValues } from '@aws-crypto/web-crypto-backend' @@ -23,10 +29,10 @@ const { expect } = chai describe('WebCryptoDefaultCryptographicMaterialsManager', () => { it('constructor sets keyring', () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -38,72 +44,94 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { value: keyring, writable: false, enumerable: true, - configurable: false + configurable: false, }) }) it('Precondition: keyrings must be a KeyringWebCrypto.', () => { - expect(() => new WebCryptoDefaultCryptographicMaterialsManager({} as any)).to.throw() + expect( + () => new WebCryptoDefaultCryptographicMaterialsManager({} as any) + ).to.throw() }) it('set a signatureKey and the compress point on the encryption context', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) - const test = await cmm._initializeEncryptionMaterial(suite, { some: 'context' }) + const test = await cmm._initializeEncryptionMaterial(suite, { + some: 'context', + }) expect(test).to.be.instanceOf(WebCryptoEncryptionMaterial) const { signatureKey, encryptionContext } = test if (!signatureKey) throw new Error('I should never see this error') expect(Object.keys(encryptionContext)).lengthOf(2) - expect(encryptionContext).to.have.haveOwnProperty(ENCODED_SIGNER_KEY).and.to.equal(toBase64(signatureKey.compressPoint)) - expect(encryptionContext).to.have.haveOwnProperty('some').and.to.equal('context') + expect(encryptionContext) + .to.have.haveOwnProperty(ENCODED_SIGNER_KEY) + .and.to.equal(toBase64(signatureKey.compressPoint)) + expect(encryptionContext) + .to.have.haveOwnProperty('some') + .and.to.equal('context') }) it('Check for early return (Postcondition): The WebCryptoAlgorithmSuite specification must support a signatureCurve to generate a signing key.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) - const { encryptionContext } = await cmm._initializeEncryptionMaterial(suite, { some: 'context' }) + const { encryptionContext } = await cmm._initializeEncryptionMaterial( + suite, + { some: 'context' } + ) expect(Object.keys(encryptionContext)).lengthOf(1) - expect(encryptionContext).to.have.haveOwnProperty('some').and.to.equal('context') + expect(encryptionContext) + .to.have.haveOwnProperty('some') + .and.to.equal('context') }) it('set a verificationKey from encryption context', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) - const context = { some: 'context', [ENCODED_SIGNER_KEY]: 'A29gmBT/NscB90u6npOulZQwAAiKVtoShudOm2J2sCgC' } + const context = { + some: 'context', + [ENCODED_SIGNER_KEY]: 'A29gmBT/NscB90u6npOulZQwAAiKVtoShudOm2J2sCgC', + } const test = await cmm._initializeDecryptionMaterial(suite, context) expect(test).to.be.instanceOf(WebCryptoDecryptionMaterial) @@ -114,15 +142,17 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { it('Check for early return (Postcondition): The WebCryptoAlgorithmSuite specification must support a signatureCurve to extract a verification key.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const context = { some: 'context' } @@ -133,83 +163,126 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { it('Precondition: WebCryptoDefaultCryptographicMaterialsManager If the algorithm suite specification requires a signatureCurve a context must exist.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) - expect(cmm._initializeDecryptionMaterial(suite, {})).to.rejectedWith(Error) + await expect(cmm._initializeDecryptionMaterial(suite, {})).to.rejectedWith( + Error + ) }) it('Precondition: WebCryptoDefaultCryptographicMaterialsManager The context must contain the public key.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const context = { missing: 'signer key' } - expect(cmm._initializeDecryptionMaterial(suite, context)).to.rejectedWith(Error) + await expect( + cmm._initializeDecryptionMaterial(suite, context) + ).to.rejectedWith(Error) }) it('can return a encryption material', async () => { + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (material: WebCryptoEncryptionMaterial): Promise { + async _onEncrypt( + material: WebCryptoEncryptionMaterial + ): Promise { const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const edk = new EncryptedDataKey({ providerId: ' keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array(5) }) + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const edk = new EncryptedDataKey({ + providerId: ' keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array(5), + }) material .setUnencryptedDataKey(udk, trace) - .addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) return importForWebCryptoEncryptionMaterial(material) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const encryptionContext = { - some: 'context' + some: 'context', } - const material = await cmm.getEncryptionMaterials({ suite, encryptionContext }) + const material = await cmm.getEncryptionMaterials({ + suite, + encryptionContext, + }) expect(Object.keys(material.encryptionContext)).lengthOf(2) if (!material.signatureKey) throw new Error('I should never see this error') - expect(material.encryptionContext).to.have.haveOwnProperty(ENCODED_SIGNER_KEY).and.to.equal(toBase64(material.signatureKey.compressPoint)) - expect(material.encryptionContext).to.have.haveOwnProperty('some').and.to.equal('context') + expect(material.encryptionContext) + .to.have.haveOwnProperty(ENCODED_SIGNER_KEY) + .and.to.equal(toBase64(material.signatureKey.compressPoint)) + expect(material.encryptionContext) + .to.have.haveOwnProperty('some') + .and.to.equal('context') }) it('will pick a default Algorithm Suite', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (material: WebCryptoEncryptionMaterial): Promise { + async _onEncrypt( + material: WebCryptoEncryptionMaterial + ): Promise { const udk = synchronousRandomValues(material.suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const edk = new EncryptedDataKey({ providerId: ' keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array(5) }) + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const edk = new EncryptedDataKey({ + providerId: ' keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array(5), + }) material .setUnencryptedDataKey(udk, trace) - .addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) return importForWebCryptoEncryptionMaterial(material) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -217,22 +290,26 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const encryptionContext = { - some: 'context' + some: 'context', } const material = await cmm.getEncryptionMaterials({ encryptionContext }) expect(Object.keys(material.encryptionContext)).lengthOf(2) if (!material.signatureKey) throw new Error('I should never see this error') - expect(material.encryptionContext).to.have.haveOwnProperty(ENCODED_SIGNER_KEY).and.to.equal(toBase64(material.signatureKey.compressPoint)) - expect(material.encryptionContext).to.have.haveOwnProperty('some').and.to.equal('context') + expect(material.encryptionContext) + .to.have.haveOwnProperty(ENCODED_SIGNER_KEY) + .and.to.equal(toBase64(material.signatureKey.compressPoint)) + expect(material.encryptionContext) + .to.have.haveOwnProperty('some') + .and.to.equal('context') }) it('Precondition: WebCryptoDefaultCryptographicMaterialsManager must reserve the ENCODED_SIGNER_KEY constant from @aws-crypto/serialize.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -240,23 +317,38 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const encryptionContext = { - [ENCODED_SIGNER_KEY]: 'context' + [ENCODED_SIGNER_KEY]: 'context', } - expect(cmm.getEncryptionMaterials({ encryptionContext })).to.rejectedWith(Error, 'Reserved encryptionContext value') + await expect( + cmm.getEncryptionMaterials({ encryptionContext }) + ).to.rejectedWith(Error, 'Reserved encryptionContext value') }) it('Postcondition: The WebCryptoEncryptionMaterial must contain a valid dataKey.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (material: WebCryptoEncryptionMaterial): Promise { + async _onEncrypt( + material: WebCryptoEncryptionMaterial + ): Promise { const udk = synchronousRandomValues(material.suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const edk = new EncryptedDataKey({ providerId: ' keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array(5) }) + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const edk = new EncryptedDataKey({ + providerId: ' keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array(5), + }) return material .setUnencryptedDataKey(udk, trace) - .addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -264,23 +356,30 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const encryptionContext = { - some: 'context' + some: 'context', } - expect(cmm.getEncryptionMaterials({ encryptionContext })).to.rejectedWith(Error) + await expect( + cmm.getEncryptionMaterials({ encryptionContext }) + ).to.rejectedWith(Error) }) it('Postcondition: The WebCryptoEncryptionMaterial must contain at least 1 EncryptedDataKey.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (material: WebCryptoEncryptionMaterial): Promise { + async _onEncrypt( + material: WebCryptoEncryptionMaterial + ): Promise { const udk = synchronousRandomValues(material.suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - material - .setUnencryptedDataKey(udk, trace) + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + material.setUnencryptedDataKey(udk, trace) return importForWebCryptoEncryptionMaterial(material) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('I should never see this error') } } @@ -288,47 +387,76 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) const encryptionContext = { - some: 'context' + some: 'context', } - expect(cmm.getEncryptionMaterials({ encryptionContext })).to.rejectedWith(Error) + await expect( + cmm.getEncryptionMaterials({ encryptionContext }) + ).to.rejectedWith(Error) }) it('can return decryption material', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (material: WebCryptoDecryptionMaterial): Promise { + async _onDecrypt( + material: WebCryptoDecryptionMaterial + ): Promise { const udk = synchronousRandomValues(material.suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } - material - .setUnencryptedDataKey(udk, trace) + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } + material.setUnencryptedDataKey(udk, trace) return importForWebCryptoDecryptionMaterial(material) } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) - const encryptionContext = { some: 'context', [ENCODED_SIGNER_KEY]: 'A29gmBT/NscB90u6npOulZQwAAiKVtoShudOm2J2sCgC' } - const edk = new EncryptedDataKey({ providerId: ' keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array(5) }) + const encryptionContext = { + some: 'context', + [ENCODED_SIGNER_KEY]: 'A29gmBT/NscB90u6npOulZQwAAiKVtoShudOm2J2sCgC', + } + const edk = new EncryptedDataKey({ + providerId: ' keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array(5), + }) - const material = await cmm.decryptMaterials({ suite, encryptionContext, encryptedDataKeys: [edk] }) - if (!material.verificationKey) throw new Error('I should never see this error') + const material = await cmm.decryptMaterials({ + suite, + encryptionContext, + encryptedDataKeys: [edk], + }) + if (!material.verificationKey) + throw new Error('I should never see this error') expect(material.encryptionContext).to.deep.equal(encryptionContext) - expect(material.verificationKey.signatureCurve).to.equal(suite.signatureCurve) + expect(material.verificationKey.signatureCurve).to.equal( + suite.signatureCurve + ) }) it('Postcondition: The WebCryptoDecryptionMaterial must contain a valid dataKey.', async () => { class TestKeyring extends KeyringWebCrypto { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('I should never see this error') } - async _onDecrypt (material: WebCryptoDecryptionMaterial): Promise { + async _onDecrypt( + material: WebCryptoDecryptionMaterial + ): Promise { const udk = synchronousRandomValues(material.suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } /* This is intentionally trickery. * An unencrypted data key *without* a cryptoKey, should not be valid. */ @@ -336,12 +464,27 @@ describe('WebCryptoDefaultCryptographicMaterialsManager', () => { } } - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const keyring = new TestKeyring() const cmm = new WebCryptoDefaultCryptographicMaterialsManager(keyring) - const encryptionContext = { some: 'context', [ENCODED_SIGNER_KEY]: 'A29gmBT/NscB90u6npOulZQwAAiKVtoShudOm2J2sCgC' } - const edk = new EncryptedDataKey({ providerId: ' keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array(5) }) + const encryptionContext = { + some: 'context', + [ENCODED_SIGNER_KEY]: 'A29gmBT/NscB90u6npOulZQwAAiKVtoShudOm2J2sCgC', + } + const edk = new EncryptedDataKey({ + providerId: ' keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array(5), + }) - expect(cmm.decryptMaterials({ suite, encryptionContext, encryptedDataKeys: [edk] })).to.rejectedWith(Error) + await expect( + cmm.decryptMaterials({ + suite, + encryptionContext, + encryptedDataKeys: [edk], + }) + ).to.rejectedWith(Error) }) }) diff --git a/modules/material-management-browser/test/keyring_helpers.test.ts b/modules/material-management-browser/test/keyring_helpers.test.ts index 962fe1d4d..777963174 100644 --- a/modules/material-management-browser/test/keyring_helpers.test.ts +++ b/modules/material-management-browser/test/keyring_helpers.test.ts @@ -8,14 +8,14 @@ import chaiAsPromised from 'chai-as-promised' import { importCryptoKeyToMaterial, importForWebCryptoEncryptionMaterial, - importForWebCryptoDecryptionMaterial + importForWebCryptoDecryptionMaterial, } from '../src/index' import { WebCryptoEncryptionMaterial, WebCryptoDecryptionMaterial, WebCryptoAlgorithmSuite, AlgorithmSuiteIdentifier, - KeyringTraceFlag + KeyringTraceFlag, } from '@aws-crypto/material-management' import { synchronousRandomValues } from '@aws-crypto/web-crypto-backend' @@ -31,7 +31,7 @@ describe('importCryptoKeyToMaterial', () => { }) }) -describe('importForWebCryptoEncryptionMaterial', async () => { +describe('importForWebCryptoEncryptionMaterial', () => { it('adds a cryptoKey to Encryption Material', async () => { const material = getWebCryptoEncryptionMaterial() @@ -76,7 +76,9 @@ describe('importForWebCryptoDecryptionMaterial', () => { }) it('Check for early return (Postcondition): If no key was able to be decrypted, return.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) await importForWebCryptoDecryptionMaterial(material) @@ -84,18 +86,30 @@ describe('importForWebCryptoDecryptionMaterial', () => { }) }) -function getWebCryptoDecryptionMaterial () { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) +function getWebCryptoDecryptionMaterial() { + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } return material.setUnencryptedDataKey(udk, trace) } -function getWebCryptoEncryptionMaterial () { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) +function getWebCryptoEncryptionMaterial() { + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } return material.setUnencryptedDataKey(udk, trace) } diff --git a/modules/material-management-browser/test/material_helpers.test.ts b/modules/material-management-browser/test/material_helpers.test.ts index 4b697cd00..fb57e97f5 100644 --- a/modules/material-management-browser/test/material_helpers.test.ts +++ b/modules/material-management-browser/test/material_helpers.test.ts @@ -11,7 +11,7 @@ import { WebCryptoKdf, getSubtleFunction, getEncryptHelper, - getDecryptionHelper + getDecryptionHelper, } from '../src/index' import { WebCryptoEncryptionMaterial, @@ -21,9 +21,14 @@ import { KeyringTraceFlag, isValidCryptoKey, SignatureKey, - VerificationKey + VerificationKey, } from '@aws-crypto/material-management' -import { synchronousRandomValues, getWebCryptoBackend, getZeroByteSubtle, getNonZeroByteBackend } from '@aws-crypto/web-crypto-backend' +import { + synchronousRandomValues, + getWebCryptoBackend, + getZeroByteSubtle, + getNonZeroByteBackend, +} from '@aws-crypto/web-crypto-backend' chai.use(chaiAsPromised) const { expect } = chai @@ -32,10 +37,16 @@ declare const CryptoKey: CryptoKey describe('_importCryptoKey', () => { it('can import WebCryptoEncryptionMaterial with a algorithm suite without a KDF', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) @@ -47,10 +58,16 @@ describe('_importCryptoKey', () => { }) it('can import WebCryptoEncryptionMaterial with a algorithm suite with a KDF', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) @@ -61,10 +78,16 @@ describe('_importCryptoKey', () => { }) it('can import WebCryptoDecryptionMaterial with a algorithm suite without a KDF', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) @@ -75,10 +98,16 @@ describe('_importCryptoKey', () => { }) it('can import WebCryptoDecryptionMaterial with a algorithm suite with a KDF', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) @@ -91,10 +120,16 @@ describe('_importCryptoKey', () => { describe('importCryptoKey', () => { it('can import when backend is isFullSupportWebCryptoBackend', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() @@ -104,10 +139,16 @@ describe('importCryptoKey', () => { }) it('can import when backend is mixed support', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const realBackend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(realBackend) @@ -116,12 +157,19 @@ describe('importCryptoKey', () => { */ const mixedSupportBackend = { nonZeroByteSubtle: subtle, - zeroByteSubtle: subtle + zeroByteSubtle: subtle, } as any - const mixedBackendCryptoKey = await importCryptoKey(mixedSupportBackend, material, ['encrypt']) + const mixedBackendCryptoKey = await importCryptoKey( + mixedSupportBackend, + material, + ['encrypt'] + ) expect(mixedBackendCryptoKey).to.not.be.instanceOf(CryptoKey) - const { nonZeroByteCryptoKey, zeroByteCryptoKey } = mixedBackendCryptoKey as any + const { + nonZeroByteCryptoKey, + zeroByteCryptoKey, + } = mixedBackendCryptoKey as any expect(nonZeroByteCryptoKey).to.be.instanceOf(CryptoKey) expect(zeroByteCryptoKey).to.be.instanceOf(CryptoKey) expect(isValidCryptoKey(nonZeroByteCryptoKey, material)).to.equal(true) @@ -131,16 +179,28 @@ describe('importCryptoKey', () => { describe('WebCryptoKdf', () => { it('returns a valid kdf key', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) const cryptoKey = await _importCryptoKey(subtle, material, ['deriveKey']) - const kdfKey = await WebCryptoKdf(subtle, material, cryptoKey, ['encrypt'], new Uint8Array(5)) + const kdfKey = await WebCryptoKdf( + subtle, + material, + cryptoKey, + ['encrypt'], + new Uint8Array(5) + ) expect(kdfKey).to.be.instanceOf(CryptoKey) expect(isValidCryptoKey(kdfKey, material)).to.equal(true) // for kdf... @@ -148,16 +208,28 @@ describe('WebCryptoKdf', () => { }) it('Check for early return (Postcondition): No WebCrypto KDF, just return the unencrypted data key.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) const cryptoKey = await _importCryptoKey(subtle, material, ['encrypt']) - const kdfKey = await WebCryptoKdf(subtle, material, cryptoKey, ['encrypt'], new Uint8Array(5)) + const kdfKey = await WebCryptoKdf( + subtle, + material, + cryptoKey, + ['encrypt'], + new Uint8Array(5) + ) expect(kdfKey).to.be.instanceOf(CryptoKey) expect(isValidCryptoKey(kdfKey, material)).to.equal(true) // for non-kdf... @@ -165,44 +237,72 @@ describe('WebCryptoKdf', () => { }) it('Precondition: Valid HKDF values must exist for browsers.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) const cryptoKey = await _importCryptoKey(subtle, material, ['deriveKey']) - expect(WebCryptoKdf(subtle, material, cryptoKey, ['encrypt'], new Uint8Array(0))).to.rejectedWith(Error) + await expect( + WebCryptoKdf(subtle, material, cryptoKey, ['encrypt'], new Uint8Array(0)) + ).to.rejectedWith(Error) }) it('Postcondition: The derived key must conform to the algorith suite specification.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) const subtleHack = { - deriveKey () { + deriveKey() { return {} as any - } + }, } as any const cryptoKey = await _importCryptoKey(subtle, material, ['deriveKey']) - expect(WebCryptoKdf(subtleHack, material, cryptoKey, ['encrypt'], new Uint8Array(5))).to.rejectedWith(Error) + await expect( + WebCryptoKdf( + subtleHack, + material, + cryptoKey, + ['encrypt'], + new Uint8Array(5) + ) + ).to.rejectedWith(Error) }) }) describe('getSubtleFunction', () => { it('can get encrypt', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() @@ -222,10 +322,16 @@ describe('getSubtleFunction', () => { }) it('Precondition: The material must have a CryptoKey.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() @@ -233,10 +339,16 @@ describe('getSubtleFunction', () => { }) it('Precondition: The cryptoKey and backend must match in terms of Mixed vs Full support.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) @@ -245,21 +357,29 @@ describe('getSubtleFunction', () => { */ const mixedSupportBackend = { nonZeroByteSubtle: subtle, - zeroByteSubtle: subtle + zeroByteSubtle: subtle, } as any /* I always want the cryptoKey to not match the backend. */ const cryptoKey = await _importCryptoKey(subtle, material, ['encrypt']) material.setCryptoKey(cryptoKey, trace) - expect(() => getSubtleFunction(mixedSupportBackend, backend, 'encrypt')).to.throw() + expect(() => + getSubtleFunction(mixedSupportBackend, backend, 'encrypt') + ).to.throw() }) it('Precondition: The length of the IV must match the WebCryptoAlgorithmSuite specification.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() @@ -276,10 +396,16 @@ describe('getSubtleFunction', () => { }) it('can encrypt/decrypt 0 bytes', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() @@ -289,10 +415,13 @@ describe('getSubtleFunction', () => { const mixedBackend = { nonZeroByteSubtle: getZeroByteSubtle(backend), zeroByteSubtle: getNonZeroByteBackend(backend), - randomValues: backend.randomValues + randomValues: backend.randomValues, } - const cryptoKey = await importCryptoKey(mixedBackend, material, ['encrypt', 'decrypt']) + const cryptoKey = await importCryptoKey(mixedBackend, material, [ + 'encrypt', + 'decrypt', + ]) material.setCryptoKey(cryptoKey, trace) const iv = new Uint8Array(suite.ivLength) @@ -311,17 +440,25 @@ describe('getSubtleFunction', () => { const testDecryptInfo = getSubtleFunction(material, mixedBackend, 'decrypt') const testDecryptIvAad = testDecryptInfo(new Uint8Array(1)) const testDecryptFunction = testDecryptIvAad(iv, aad) - const testDecryptedData = await testDecryptFunction(new Uint8Array(testEncryptedData)) + const testDecryptedData = await testDecryptFunction( + new Uint8Array(testEncryptedData) + ) // Because I encrypted 0 bytes, the data should be 0 length expect(testDecryptedData.byteLength).to.equal(0) }) it('Precondition: The WebCrypto AES-GCM decrypt API expects the data *and* tag together.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const trace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(udk, trace) const backend = await getWebCryptoBackend() @@ -331,10 +468,13 @@ describe('getSubtleFunction', () => { const mixedBackend = { nonZeroByteSubtle: getZeroByteSubtle(backend), zeroByteSubtle: getNonZeroByteBackend(backend), - randomValues: backend.randomValues + randomValues: backend.randomValues, } - const cryptoKey = await importCryptoKey(mixedBackend, material, ['encrypt', 'decrypt']) + const cryptoKey = await importCryptoKey(mixedBackend, material, [ + 'encrypt', + 'decrypt', + ]) material.setCryptoKey(cryptoKey, trace) const iv = new Uint8Array(suite.ivLength) @@ -356,23 +496,37 @@ describe('getSubtleFunction', () => { const testDecryptFunction = testDecryptIvAad(iv, aad) for (let i = 0; tagLengthBytes > i; i++) { - await expect(testDecryptFunction(new Uint8Array(testEncryptedData.slice(0, i)))) - .to.eventually.rejectedWith(Error, 'Invalid data length.') + await expect( + testDecryptFunction(new Uint8Array(testEncryptedData.slice(0, i))) + ).to.eventually.rejectedWith(Error, 'Invalid data length.') } }) it('no kdf, simple backend, can encrypt/decrypt', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const decryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const decryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } encryptionMaterial.setUnencryptedDataKey(udk, encryptTrace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, ['encrypt', 'decrypt']) + const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, [ + 'encrypt', + 'decrypt', + ]) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) decryptionMaterial.setCryptoKey(cryptoKey, decryptTrace) @@ -382,24 +536,50 @@ describe('getSubtleFunction', () => { const aad = synchronousRandomValues(5) const data = new Uint8Array([1, 2, 3, 4, 5]) - const ciphertext = await getSubtleFunction(encryptionMaterial, backend, 'encrypt')(info)(iv, aad)(data) - const plaintext = await getSubtleFunction(decryptionMaterial, backend, 'decrypt')(info)(iv, aad)(new Uint8Array(ciphertext)) + const ciphertext = await getSubtleFunction( + encryptionMaterial, + backend, + 'encrypt' + )(info)( + iv, + aad + )(data) + const plaintext = await getSubtleFunction( + decryptionMaterial, + backend, + 'decrypt' + )(info)( + iv, + aad + )(new Uint8Array(ciphertext)) expect(new Uint8Array(plaintext)).to.deep.equal(data) }) it('KDF, simple backend, can encrypt/decrypt', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const decryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const decryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } encryptionMaterial.setUnencryptedDataKey(udk, encryptTrace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, ['deriveKey']) + const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, [ + 'deriveKey', + ]) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) decryptionMaterial.setCryptoKey(cryptoKey, decryptTrace) @@ -409,19 +589,43 @@ describe('getSubtleFunction', () => { const aad = synchronousRandomValues(5) const data = new Uint8Array([1, 2, 3, 4, 5]) - const ciphertext = await getSubtleFunction(encryptionMaterial, backend, 'encrypt')(info)(iv, aad)(data) - const plaintext = await getSubtleFunction(decryptionMaterial, backend, 'decrypt')(info)(iv, aad)(new Uint8Array(ciphertext)) + const ciphertext = await getSubtleFunction( + encryptionMaterial, + backend, + 'encrypt' + )(info)( + iv, + aad + )(data) + const plaintext = await getSubtleFunction( + decryptionMaterial, + backend, + 'decrypt' + )(info)( + iv, + aad + )(new Uint8Array(ciphertext)) expect(new Uint8Array(plaintext)).to.deep.equal(data) }) it('no kdf, mixed backend, can encrypt/decrypt', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const decryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const decryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } encryptionMaterial.setUnencryptedDataKey(udk, encryptTrace) const backend = await getWebCryptoBackend() @@ -432,10 +636,14 @@ describe('getSubtleFunction', () => { */ const mixedSupportBackend = { nonZeroByteSubtle: subtle, - zeroByteSubtle: subtle + zeroByteSubtle: subtle, } as any - const cryptoKey = await importCryptoKey(mixedSupportBackend, encryptionMaterial, ['encrypt', 'decrypt']) + const cryptoKey = await importCryptoKey( + mixedSupportBackend, + encryptionMaterial, + ['encrypt', 'decrypt'] + ) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) decryptionMaterial.setCryptoKey(cryptoKey, decryptTrace) @@ -445,24 +653,64 @@ describe('getSubtleFunction', () => { const aad = synchronousRandomValues(5) const data = new Uint8Array([1, 2, 3, 4, 5]) - const ciphertext = await getSubtleFunction(encryptionMaterial, mixedSupportBackend, 'encrypt')(info)(iv, aad)(data) - const plaintext = await getSubtleFunction(decryptionMaterial, mixedSupportBackend, 'decrypt')(info)(iv, aad)(new Uint8Array(ciphertext)) + const ciphertext = await getSubtleFunction( + encryptionMaterial, + mixedSupportBackend, + 'encrypt' + )(info)( + iv, + aad + )(data) + const plaintext = await getSubtleFunction( + decryptionMaterial, + mixedSupportBackend, + 'decrypt' + )(info)( + iv, + aad + )(new Uint8Array(ciphertext)) expect(new Uint8Array(plaintext)).to.deep.equal(data) - const ciphertextZeroByteData = await getSubtleFunction(encryptionMaterial, mixedSupportBackend, 'encrypt')(info)(iv, aad)(new Uint8Array(0)) - const plaintextZeroByteData = await getSubtleFunction(decryptionMaterial, mixedSupportBackend, 'decrypt')(info)(iv, aad)(new Uint8Array(ciphertextZeroByteData)) - - expect(new Uint8Array(plaintextZeroByteData)).to.deep.equal(new Uint8Array(0)) + const ciphertextZeroByteData = await getSubtleFunction( + encryptionMaterial, + mixedSupportBackend, + 'encrypt' + )(info)( + iv, + aad + )(new Uint8Array(0)) + const plaintextZeroByteData = await getSubtleFunction( + decryptionMaterial, + mixedSupportBackend, + 'decrypt' + )(info)( + iv, + aad + )(new Uint8Array(ciphertextZeroByteData)) + + expect(new Uint8Array(plaintextZeroByteData)).to.deep.equal( + new Uint8Array(0) + ) }) it('kdf, mixed backend, can encrypt/decrypt', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const decryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const decryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } encryptionMaterial.setUnencryptedDataKey(udk, encryptTrace) const backend = await getWebCryptoBackend() @@ -473,10 +721,14 @@ describe('getSubtleFunction', () => { */ const mixedSupportBackend = { nonZeroByteSubtle: subtle, - zeroByteSubtle: subtle + zeroByteSubtle: subtle, } as any - const cryptoKey = await importCryptoKey(mixedSupportBackend, encryptionMaterial, ['deriveKey']) + const cryptoKey = await importCryptoKey( + mixedSupportBackend, + encryptionMaterial, + ['deriveKey'] + ) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) decryptionMaterial.setCryptoKey(cryptoKey, decryptTrace) @@ -486,15 +738,45 @@ describe('getSubtleFunction', () => { const aad = synchronousRandomValues(5) const data = new Uint8Array([1, 2, 3, 4, 5]) - const ciphertext = await getSubtleFunction(encryptionMaterial, mixedSupportBackend, 'encrypt')(info)(iv, aad)(data) - const plaintext = await getSubtleFunction(decryptionMaterial, mixedSupportBackend, 'decrypt')(info)(iv, aad)(new Uint8Array(ciphertext)) + const ciphertext = await getSubtleFunction( + encryptionMaterial, + mixedSupportBackend, + 'encrypt' + )(info)( + iv, + aad + )(data) + const plaintext = await getSubtleFunction( + decryptionMaterial, + mixedSupportBackend, + 'decrypt' + )(info)( + iv, + aad + )(new Uint8Array(ciphertext)) expect(new Uint8Array(plaintext)).to.deep.equal(data) - const ciphertextZeroByteData = await getSubtleFunction(encryptionMaterial, mixedSupportBackend, 'encrypt')(info)(iv, aad)(new Uint8Array(0)) - const plaintextZeroByteData = await getSubtleFunction(decryptionMaterial, mixedSupportBackend, 'decrypt')(info)(iv, aad)(new Uint8Array(ciphertextZeroByteData)) - - expect(new Uint8Array(plaintextZeroByteData)).to.deep.equal(new Uint8Array(0)) + const ciphertextZeroByteData = await getSubtleFunction( + encryptionMaterial, + mixedSupportBackend, + 'encrypt' + )(info)( + iv, + aad + )(new Uint8Array(0)) + const plaintextZeroByteData = await getSubtleFunction( + decryptionMaterial, + mixedSupportBackend, + 'decrypt' + )(info)( + iv, + aad + )(new Uint8Array(ciphertextZeroByteData)) + + expect(new Uint8Array(plaintextZeroByteData)).to.deep.equal( + new Uint8Array(0) + ) }) }) @@ -503,15 +785,23 @@ describe('getSubtleFunction', () => { describe('getEncryptHelper/getDecryptionHelper', () => { it('encryption helpers without a signature', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } encryptionMaterial.setUnencryptedDataKey(udk, encryptTrace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, ['deriveKey']) + const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, [ + 'deriveKey', + ]) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) const test = await getEncryptHelper(encryptionMaterial) @@ -521,15 +811,23 @@ describe('getEncryptHelper/getDecryptionHelper', () => { }) it('decryption helpers without a signature ', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } decryptionMaterial.setUnencryptedDataKey(udk, encryptTrace) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, decryptionMaterial, ['deriveKey']) + const cryptoKey = await _importCryptoKey(subtle, decryptionMaterial, [ + 'deriveKey', + ]) decryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) const test = await getDecryptionHelper(decryptionMaterial) @@ -539,18 +837,26 @@ describe('getEncryptHelper/getDecryptionHelper', () => { }) it('encryption helpers with a signature', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) const { signatureKey } = await sigKeys(suite) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } encryptionMaterial .setUnencryptedDataKey(udk, encryptTrace) .setSignatureKey(signatureKey) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, ['deriveKey']) + const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, [ + 'deriveKey', + ]) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) const test = await getEncryptHelper(encryptionMaterial) @@ -560,18 +866,26 @@ describe('getEncryptHelper/getDecryptionHelper', () => { }) it('decryption helpers with a signature ', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) const { verificationKey } = await sigKeys(suite) - const decryptionTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const decryptionTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } decryptionMaterial .setUnencryptedDataKey(udk, decryptionTrace) .setVerificationKey(verificationKey) const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, decryptionMaterial, ['deriveKey']) + const cryptoKey = await _importCryptoKey(subtle, decryptionMaterial, [ + 'deriveKey', + ]) decryptionMaterial.setCryptoKey(cryptoKey, decryptionTrace) const test = await getDecryptionHelper(decryptionMaterial) @@ -581,27 +895,41 @@ describe('getEncryptHelper/getDecryptionHelper', () => { }) it('Precondition: WebCryptoEncryptionMaterial must have a valid data key.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) - expect(getEncryptHelper(encryptionMaterial)).to.rejectedWith(Error) + await expect(getEncryptHelper(encryptionMaterial)).to.rejectedWith(Error) }) it('Precondition: WebCryptoDecryptionMaterial must have a valid data key.', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) - expect(getDecryptionHelper(decryptionMaterial)).to.rejectedWith(Error) + await expect(getDecryptionHelper(decryptionMaterial)).to.rejectedWith(Error) }) it('can verify what was signed', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const decryptionMaterial = new WebCryptoDecryptionMaterial(suite, {}) const encryptionMaterial = new WebCryptoEncryptionMaterial(suite, {}) const udk = synchronousRandomValues(suite.keyLengthBytes) const { signatureKey, verificationKey } = await sigKeys(suite) - const encryptTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - const decryptionTrace = { keyName: 'keyName', keyNamespace: 'keyNamespace', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const encryptTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + const decryptionTrace = { + keyName: 'keyName', + keyNamespace: 'keyNamespace', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } decryptionMaterial .setUnencryptedDataKey(udk, decryptionTrace) .setVerificationKey(verificationKey) @@ -611,7 +939,9 @@ describe('getEncryptHelper/getDecryptionHelper', () => { const backend = await getWebCryptoBackend() const subtle = getZeroByteSubtle(backend) - const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, ['deriveKey']) + const cryptoKey = await _importCryptoKey(subtle, encryptionMaterial, [ + 'deriveKey', + ]) encryptionMaterial.setCryptoKey(cryptoKey, encryptTrace) decryptionMaterial.setCryptoKey(cryptoKey, decryptionTrace) @@ -632,7 +962,7 @@ describe('getEncryptHelper/getDecryptionHelper', () => { /* A simple helper to get signature/verification keys. * Basically a copy from the cmm. */ -async function sigKeys (suite: WebCryptoAlgorithmSuite) { +async function sigKeys(suite: WebCryptoAlgorithmSuite) { const { signatureCurve: namedCurve } = suite if (!namedCurve) throw new Error('never') const backend = await getWebCryptoBackend() @@ -643,9 +973,16 @@ async function sigKeys (suite: WebCryptoAlgorithmSuite) { const usages = ['sign', 'verify'] const format = 'raw' - const { publicKey, privateKey } = await subtle.generateKey(webCryptoAlgorithm, extractable, usages) + const { publicKey, privateKey } = await subtle.generateKey( + webCryptoAlgorithm, + extractable, + usages + ) const publicKeyBytes = await subtle.exportKey(format, publicKey) - const compressPoint = SignatureKey.encodeCompressPoint(new Uint8Array(publicKeyBytes), suite) + const compressPoint = SignatureKey.encodeCompressPoint( + new Uint8Array(publicKeyBytes), + suite + ) const signatureKey = new SignatureKey(privateKey, compressPoint, suite) const verificationKey = new VerificationKey(publicKey, suite) diff --git a/modules/material-management-node/test/material_helpers.test.ts b/modules/material-management-node/test/material_helpers.test.ts index c1d5259b7..2b5b6da9f 100644 --- a/modules/material-management-node/test/material_helpers.test.ts +++ b/modules/material-management-node/test/material_helpers.test.ts @@ -4,17 +4,37 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { NodeDecryptionMaterial, NodeEncryptionMaterial, NodeAlgorithmSuite, AlgorithmSuiteIdentifier, KeyringTraceFlag, SignatureKey, VerificationKey, unwrapDataKey } from '@aws-crypto/material-management' -import { nodeKdf, getCryptoStream, getEncryptHelper, getDecryptionHelper } from '../src/material_helpers' +import { + NodeDecryptionMaterial, + NodeEncryptionMaterial, + NodeAlgorithmSuite, + AlgorithmSuiteIdentifier, + KeyringTraceFlag, + SignatureKey, + VerificationKey, + unwrapDataKey, +} from '@aws-crypto/material-management' +import { + nodeKdf, + getCryptoStream, + getEncryptHelper, + getDecryptionHelper, +} from '../src/material_helpers' // @ts-ignore import { Decipheriv, Cipheriv, createECDH } from 'crypto' describe('nodeKdf', () => { it('Check for early return (Postcondition): No Node.js KDF, just return the unencrypted data key.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = unwrapDataKey(nodeKdf(material, new Uint8Array(5))) @@ -22,10 +42,16 @@ describe('nodeKdf', () => { }) it('HKDF SHA256', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = unwrapDataKey(nodeKdf(material, new Uint8Array(5))) @@ -34,10 +60,16 @@ describe('nodeKdf', () => { }) it('HKDF SHA384', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = unwrapDataKey(nodeKdf(material, new Uint8Array(5))) @@ -46,38 +78,59 @@ describe('nodeKdf', () => { }) it('Precondition: Valid HKDF values must exist for Node.js.', () => { - expect(() => nodeKdf({ - getUnencryptedDataKey () {}, - suite: { - kdf: 'HKDF', - kdfHash: 'sha256' - } as any - } as any, {} as any)).to.throw() - - expect(() => nodeKdf({ - getUnencryptedDataKey () {}, - suite: { - kdf: 'NOT-HKDF', - kdfHash: 'sha256' - } as any - } as any, new Uint8Array(8))).to.throw() - - expect(() => nodeKdf({ - getUnencryptedDataKey () {}, - suite: { - kdf: 'NOT-HKDF', - kdfHash: 'NOT-sha256' - } as any - } as any, new Uint8Array(8))).to.throw() + expect(() => + nodeKdf( + { + getUnencryptedDataKey() {}, + suite: { + kdf: 'HKDF', + kdfHash: 'sha256', + } as any, + } as any, + {} as any + ) + ).to.throw() + + expect(() => + nodeKdf( + { + getUnencryptedDataKey() {}, + suite: { + kdf: 'NOT-HKDF', + kdfHash: 'sha256', + } as any, + } as any, + new Uint8Array(8) + ) + ).to.throw() + + expect(() => + nodeKdf( + { + getUnencryptedDataKey() {}, + suite: { + kdf: 'NOT-HKDF', + kdfHash: 'NOT-sha256', + } as any, + } as any, + new Uint8Array(8) + ) + ).to.throw() }) }) describe('getCryptoStream', () => { it('return a Cipheriv', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = getCryptoStream(material)() @@ -87,10 +140,16 @@ describe('getCryptoStream', () => { }) it('return a Decipheriv', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeDecryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = getCryptoStream(material)() @@ -100,15 +159,25 @@ describe('getCryptoStream', () => { }) it('Precondition: material must be either NodeEncryptionMaterial or NodeDecryptionMaterial.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - expect(() => getCryptoStream({ suite } as any)).to.throw('Unsupported cryptographic material.') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + expect(() => getCryptoStream({ suite } as any)).to.throw( + 'Unsupported cryptographic material.' + ) }) it('Precondition: The length of the IV must match the NodeAlgorithmSuite specification.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = getCryptoStream(material)() @@ -117,10 +186,16 @@ describe('getCryptoStream', () => { }) it('Precondition: The material must have not been zeroed.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const test = getCryptoStream(material)() @@ -132,10 +207,16 @@ describe('getCryptoStream', () => { describe('getEncryptHelper', () => { it('basic shape', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const helper = getEncryptHelper(material) @@ -152,18 +233,26 @@ describe('getEncryptHelper', () => { }) it('signer', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } const ecdh = createECDH(suite.signatureCurve || '') ecdh.generateKeys() - const sigKey = new SignatureKey(ecdh.getPrivateKey(), ecdh.getPublicKey(), suite) + const sigKey = new SignatureKey( + ecdh.getPrivateKey(), + ecdh.getPublicKey(), + suite + ) - material - .setUnencryptedDataKey(dataKey, trace) - .setSignatureKey(sigKey) + material.setUnencryptedDataKey(dataKey, trace).setSignatureKey(sigKey) const helper = getEncryptHelper(material) if (typeof helper.getSigner !== 'function') throw new Error('bad') @@ -181,25 +270,37 @@ describe('getEncryptHelper', () => { }) it('Precondition: NodeEncryptionMaterial must have a valid data key.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) - expect(() => getEncryptHelper(material)).to.throw('Material has no unencrypted data key.') + expect(() => getEncryptHelper(material)).to.throw( + 'Material has no unencrypted data key.' + ) }) it('Precondition: The NodeEncryptionMaterial must have not been zeroed.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) const material = new NodeEncryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } const ecdh = createECDH(suite.signatureCurve || '') ecdh.generateKeys() - const sigKey = new SignatureKey(ecdh.getPrivateKey(), ecdh.getPublicKey(), suite) + const sigKey = new SignatureKey( + ecdh.getPrivateKey(), + ecdh.getPublicKey(), + suite + ) - material - .setUnencryptedDataKey(dataKey, trace) - .setSignatureKey(sigKey) + material.setUnencryptedDataKey(dataKey, trace).setSignatureKey(sigKey) const helper = getEncryptHelper(material) material.zeroUnencryptedDataKey() @@ -213,10 +314,16 @@ describe('getEncryptHelper', () => { describe('getDecryptionHelper', () => { it('first test', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeDecryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } material.setUnencryptedDataKey(new Uint8Array(dataKey), trace) const helper = getDecryptionHelper(material) @@ -233,10 +340,16 @@ describe('getDecryptionHelper', () => { }) it('verify', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) const material = new NodeDecryptionMaterial(suite, {}) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } const ecdh = createECDH(suite.signatureCurve || '') ecdh.generateKeys() @@ -263,8 +376,12 @@ describe('getDecryptionHelper', () => { }) it('Precondition: NodeDecryptionMaterial must have a valid data key.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) const material = new NodeDecryptionMaterial(suite, {}) - expect(() => getDecryptionHelper(material)).to.throw('Material has no unencrypted data key.') + expect(() => getDecryptionHelper(material)).to.throw( + 'Material has no unencrypted data key.' + ) }) }) diff --git a/modules/material-management-node/test/node_cryptographic_materials_manager.test.ts b/modules/material-management-node/test/node_cryptographic_materials_manager.test.ts index 568cd3d37..a53d9271f 100644 --- a/modules/material-management-node/test/node_cryptographic_materials_manager.test.ts +++ b/modules/material-management-node/test/node_cryptographic_materials_manager.test.ts @@ -8,12 +8,12 @@ import chaiAsPromised from 'chai-as-promised' import { KeyringNode } from '@aws-crypto/material-management' import { NodeDefaultCryptographicMaterialsManager } from '../src/node_cryptographic_materials_manager' import { - NodeEncryptionMaterial, // eslint-disable-line no-unused-vars - NodeDecryptionMaterial, // eslint-disable-line no-unused-vars + NodeEncryptionMaterial, + NodeDecryptionMaterial, NodeAlgorithmSuite, AlgorithmSuiteIdentifier, KeyringTraceFlag, - EncryptedDataKey + EncryptedDataKey, } from '../src/index' import { ENCODED_SIGNER_KEY } from '@aws-crypto/serialize' chai.use(chaiAsPromised) @@ -22,10 +22,10 @@ const { expect } = chai describe('NodeDefaultCryptographicMaterialsManager', () => { it('constructor sets keyring', () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } @@ -36,27 +36,31 @@ describe('NodeDefaultCryptographicMaterialsManager', () => { value: keyring, writable: false, enumerable: true, - configurable: false + configurable: false, }) }) it('Precondition: keyrings must be a KeyringNode.', () => { - expect(() => new NodeDefaultCryptographicMaterialsManager({} as any)).to.throw() + expect( + () => new NodeDefaultCryptographicMaterialsManager({} as any) + ).to.throw() }) it('should create signature key and append the verification key to context and return NodeEncryptionMaterial', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const context = { some: 'context' } const test = cmm._initializeEncryptionMaterial(suite, context) expect(test).to.be.instanceOf(NodeEncryptionMaterial) @@ -64,23 +68,27 @@ describe('NodeDefaultCryptographicMaterialsManager', () => { expect(Object.keys(test.encryptionContext)).lengthOf(2) expect(Object.isFrozen(test.encryptionContext)).to.equal(true) expect(Object.isFrozen(context)).to.equal(false) - expect(test.encryptionContext).to.have.ownProperty('some').and.to.equal('context') + expect(test.encryptionContext) + .to.have.ownProperty('some') + .and.to.equal('context') expect(test.encryptionContext).to.have.ownProperty(ENCODED_SIGNER_KEY) }) it('Check for early return (Postcondition): The algorithm suite specification must support a signatureCurve to generate a ECDH key.', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const context = { some: 'context' } const test = cmm._initializeEncryptionMaterial(suite, context) expect(test).to.be.instanceOf(NodeEncryptionMaterial) @@ -88,182 +96,236 @@ describe('NodeDefaultCryptographicMaterialsManager', () => { expect(Object.keys(test.encryptionContext)).lengthOf(1) expect(Object.isFrozen(test.encryptionContext)).to.equal(true) expect(Object.isFrozen(context)).to.equal(false) - expect(test.encryptionContext).to.have.ownProperty('some').and.to.equal('context') + expect(test.encryptionContext) + .to.have.ownProperty('some') + .and.to.equal('context') }) it('Set the verification key.', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - - const { encryptionContext } = cmm._initializeEncryptionMaterial( - suite, - { some: 'context' } + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 ) - const material = cmm._initializeDecryptionMaterial( - suite, - encryptionContext - ) + const { encryptionContext } = cmm._initializeEncryptionMaterial(suite, { + some: 'context', + }) + + const material = cmm._initializeDecryptionMaterial(suite, encryptionContext) expect(material.verificationKey).to.have.ownProperty('publicKey') }) it('Check for early return (Postcondition): The algorithm suite specification must support a signatureCurve to load a signature key.', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const context = { some: 'context' } - const { encryptionContext } = cmm._initializeDecryptionMaterial(suite, context) + const { encryptionContext } = cmm._initializeDecryptionMaterial( + suite, + context + ) expect(encryptionContext).to.deep.equal(context) }) it('Precondition: NodeDefaultCryptographicMaterialsManager If the algorithm suite specification requires a signatureCurve a context must exist.', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) - expect(() => cmm._initializeDecryptionMaterial(suite, undefined as any)).to.throw() + expect(() => + cmm._initializeDecryptionMaterial(suite, undefined as any) + ).to.throw() }) it('Precondition: NodeDefaultCryptographicMaterialsManager The context must contain the public key.', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) - expect(() => cmm._initializeDecryptionMaterial( - suite, - { no: 'signature' } - )).to.throw() + expect(() => + cmm._initializeDecryptionMaterial(suite, { no: 'signature' }) + ).to.throw() }) it('Precondition: NodeDefaultCryptographicMaterialsManager must reserve the ENCODED_SIGNER_KEY constant from @aws-crypto/serialize.', async () => { class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('this should never happen') } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('this should never happen') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) const encryptionContext = { - [ENCODED_SIGNER_KEY]: 'something' + [ENCODED_SIGNER_KEY]: 'something', } - await expect(cmm.getEncryptionMaterials({ encryptionContext })).to.rejectedWith(Error, 'Reserved encryptionContext value') + await expect( + cmm.getEncryptionMaterials({ encryptionContext }) + ).to.rejectedWith(Error, 'Reserved encryptionContext value') }) it('Postcondition: The NodeEncryptionMaterial must contain a valid dataKey.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) class TestKeyring extends KeyringNode { - async _onEncrypt (material: NodeEncryptionMaterial): Promise { + async _onEncrypt( + material: NodeEncryptionMaterial + ): Promise { return material } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - await expect(cmm.getEncryptionMaterials({ suite, encryptionContext: {} })).to.rejectedWith(Error) + await expect( + cmm.getEncryptionMaterials({ suite, encryptionContext: {} }) + ).to.rejectedWith(Error) }) it('Postcondition: The NodeEncryptionMaterial must contain at least 1 EncryptedDataKey.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) class TestKeyring extends KeyringNode { - async _onEncrypt (material: NodeEncryptionMaterial): Promise { + async _onEncrypt( + material: NodeEncryptionMaterial + ): Promise { const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } return material.setUnencryptedDataKey(dataKey, trace) } - async _onDecrypt (): Promise { + async _onDecrypt(): Promise { throw new Error('never') } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - await expect(cmm.getEncryptionMaterials({ suite, encryptionContext: {} })).to.rejectedWith(Error) + await expect( + cmm.getEncryptionMaterials({ suite, encryptionContext: {} }) + ).to.rejectedWith(Error) }) it('Postcondition: The NodeDecryptionMaterial must contain a valid dataKey.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (material: NodeDecryptionMaterial): Promise { + async _onDecrypt( + material: NodeDecryptionMaterial + ): Promise { return material } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const encryptedDataKeys = [new EncryptedDataKey({ - providerId: 'p', providerInfo: 'p', encryptedDataKey: new Uint8Array(5) - })] - - await expect(cmm.decryptMaterials({ suite, encryptedDataKeys, encryptionContext: {} })).to.rejectedWith(Error) + const encryptedDataKeys = [ + new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'p', + encryptedDataKey: new Uint8Array(5), + }), + ] + + await expect( + cmm.decryptMaterials({ suite, encryptedDataKeys, encryptionContext: {} }) + ).to.rejectedWith(Error) }) it('Return decryption material', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) class TestKeyring extends KeyringNode { - async _onEncrypt (): Promise { + async _onEncrypt(): Promise { throw new Error('never') } - async _onDecrypt (material: NodeDecryptionMaterial): Promise { + async _onDecrypt( + material: NodeDecryptionMaterial + ): Promise { const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } return material.setUnencryptedDataKey(dataKey, trace) } } const keyring = new TestKeyring() const cmm = new NodeDefaultCryptographicMaterialsManager(keyring) - const encryptedDataKeys = [new EncryptedDataKey({ - providerId: 'p', providerInfo: 'p', encryptedDataKey: new Uint8Array(5) - })] - - const material = await cmm.decryptMaterials({ suite, encryptedDataKeys, encryptionContext: {} }) + const encryptedDataKeys = [ + new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'p', + encryptedDataKey: new Uint8Array(5), + }), + ] + + const material = await cmm.decryptMaterials({ + suite, + encryptedDataKeys, + encryptionContext: {}, + }) expect(material.hasUnencryptedDataKey).to.equal(true) }) }) diff --git a/modules/material-management/test/algorithm_suites.test.ts b/modules/material-management/test/algorithm_suites.test.ts index a8ed69484..7c32af951 100644 --- a/modules/material-management/test/algorithm_suites.test.ts +++ b/modules/material-management/test/algorithm_suites.test.ts @@ -4,7 +4,10 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { AlgorithmSuiteIdentifier, AlgorithmSuite } from '../src/algorithm_suites' +import { + AlgorithmSuiteIdentifier, + AlgorithmSuite, +} from '../src/algorithm_suites' describe('AlgorithmSuiteIdentifier', () => { it('should be frozen', () => { @@ -15,7 +18,9 @@ describe('AlgorithmSuiteIdentifier', () => { describe('AlgorithmSuite', () => { it('should not allow an instance', () => { // @ts-ignore Trying to test something that Typescript should deny... - expect(() => new AlgorithmSuite()).to.throw('new AlgorithmSuite is not allowed') + expect(() => new AlgorithmSuite()).to.throw( + 'new AlgorithmSuite is not allowed' + ) }) it('prototype should be immutable', () => { @@ -25,12 +30,16 @@ describe('AlgorithmSuite', () => { it('Precondition: A algorithm suite specification must be passed.', () => { class Test extends AlgorithmSuite {} - expect(() => new Test(undefined as any)).to.throw('Algorithm specification not set.') + expect(() => new Test(undefined as any)).to.throw( + 'Algorithm specification not set.' + ) }) it('Precondition: The Algorithm Suite Identifier must exist.', () => { class Test extends AlgorithmSuite {} - expect(() => new Test({ id: 'does not exist' } as any)).to.throw('No suite by that identifier exists.') + expect(() => new Test({ id: 'does not exist' } as any)).to.throw( + 'No suite by that identifier exists.' + ) }) }) diff --git a/modules/material-management/test/clone_cryptographic_material.test.ts b/modules/material-management/test/clone_cryptographic_material.test.ts index 81c7d351b..cae98ab8d 100644 --- a/modules/material-management/test/clone_cryptographic_material.test.ts +++ b/modules/material-management/test/clone_cryptographic_material.test.ts @@ -15,34 +15,77 @@ import { AlgorithmSuiteIdentifier, KeyringTraceFlag, EncryptedDataKey, - unwrapDataKey + unwrapDataKey, } from '../src/index' -const nodeSuite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) -const webCryptoSuite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) -const udk128 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) +const nodeSuite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 +) +const webCryptoSuite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 +) +const udk128 = new Uint8Array([ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, +]) const encryptTrace = { keyNamespace: 'keyNamespace', keyName: 'keyName', - flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, } const decryptTrace = { keyNamespace: 'keyNamespace', keyName: 'keyName', - flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, } -const edk1 = new EncryptedDataKey({ providerId: 'keyNamespace', providerInfo: 'keyName', encryptedDataKey: new Uint8Array([1]) }) -const edk2 = new EncryptedDataKey({ providerId: 'p2', providerInfo: 'pi2', encryptedDataKey: new Uint8Array([2]) }) +const edk1 = new EncryptedDataKey({ + providerId: 'keyNamespace', + providerInfo: 'keyName', + encryptedDataKey: new Uint8Array([1]), +}) +const edk2 = new EncryptedDataKey({ + providerId: 'p2', + providerInfo: 'pi2', + encryptedDataKey: new Uint8Array([2]), +}) -const cryptoKey: any = { type: 'secret', algorithm: { name: webCryptoSuite.encryption, length: webCryptoSuite.keyLength }, usages: ['encrypt', 'decrypt'], extractable: false } +const cryptoKey: any = { + type: 'secret', + algorithm: { + name: webCryptoSuite.encryption, + length: webCryptoSuite.keyLength, + }, + usages: ['encrypt', 'decrypt'], + extractable: false, +} describe('cloneMaterial', () => { it('clone NodeEncryptionMaterial', () => { const material = new NodeEncryptionMaterial(nodeSuite, { some: 'context' }) .setUnencryptedDataKey(new Uint8Array(udk128), encryptTrace) - .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + .addEncryptedDataKey( + edk2, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) const test = cloneMaterial(material) expect(test).to.be.instanceOf(NodeEncryptionMaterial) @@ -53,8 +96,9 @@ describe('cloneMaterial', () => { }) it('clone NodeDecryptionMaterial', () => { - const material = new NodeDecryptionMaterial(nodeSuite, { some: 'context' }) - .setUnencryptedDataKey(new Uint8Array(udk128), decryptTrace) + const material = new NodeDecryptionMaterial(nodeSuite, { + some: 'context', + }).setUnencryptedDataKey(new Uint8Array(udk128), decryptTrace) const test = cloneMaterial(material) expect(test).to.be.instanceOf(NodeDecryptionMaterial) @@ -64,11 +108,19 @@ describe('cloneMaterial', () => { }) it('clone WebCryptoEncryptionMaterial', () => { - const material = new WebCryptoEncryptionMaterial(webCryptoSuite, { some: 'context' }) + const material = new WebCryptoEncryptionMaterial(webCryptoSuite, { + some: 'context', + }) .setUnencryptedDataKey(new Uint8Array(udk128), encryptTrace) .setCryptoKey(cryptoKey, encryptTrace) - .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + .addEncryptedDataKey( + edk2, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) const test = cloneMaterial(material) expect(test).to.be.instanceOf(WebCryptoEncryptionMaterial) @@ -81,8 +133,9 @@ describe('cloneMaterial', () => { it('clone WebCryptoDecryptionMaterial', () => { /* WebCryptoDecryptionMaterial do not have an unencrypted data key. */ - const material = new WebCryptoDecryptionMaterial(webCryptoSuite, { some: 'context' }) - .setCryptoKey(cryptoKey, decryptTrace) + const material = new WebCryptoDecryptionMaterial(webCryptoSuite, { + some: 'context', + }).setCryptoKey(cryptoKey, decryptTrace) const test = cloneMaterial(material) expect(test).to.be.instanceOf(WebCryptoDecryptionMaterial) @@ -94,31 +147,53 @@ describe('cloneMaterial', () => { it('Precondition: For each encrypted data key, there must be a trace.', () => { const material = new NodeEncryptionMaterial(nodeSuite, { some: 'context' }) .setUnencryptedDataKey(new Uint8Array(udk128), encryptTrace) - .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + .addEncryptedDataKey( + edk2, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) // remove a trace... material.keyringTrace.pop() - expect(() => cloneMaterial(material)).to.throw(Error, 'KeyringTrace length does not match encrypted data keys.') + expect(() => cloneMaterial(material)).to.throw( + Error, + 'KeyringTrace length does not match encrypted data keys.' + ) }) it('Precondition: The traces must be in the same order as the encrypted data keys.', () => { const material = new NodeEncryptionMaterial(nodeSuite, { some: 'context' }) .setUnencryptedDataKey(new Uint8Array(udk128), encryptTrace) - .addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) - .addEncryptedDataKey(edk2, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + .addEncryptedDataKey( + edk2, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) // @ts-ignore Typescript is trying to save us... material.keyringTrace[1].keyName = 'does not exist' - expect(() => cloneMaterial(material)).to.throw(Error, 'Keyring trace does not match encrypted data key.') + expect(() => cloneMaterial(material)).to.throw( + Error, + 'Keyring trace does not match encrypted data key.' + ) }) it('Precondition: On Decrypt there must not be any additional traces other than the setTrace.', () => { - const material = new NodeDecryptionMaterial(nodeSuite, { some: 'context' }) - .setUnencryptedDataKey(new Uint8Array(udk128), decryptTrace) + const material = new NodeDecryptionMaterial(nodeSuite, { + some: 'context', + }).setUnencryptedDataKey(new Uint8Array(udk128), decryptTrace) // Just push _something_ on material.keyringTrace.push({} as any) - expect(() => cloneMaterial(material)).to.throw(Error, 'Only 1 trace is valid on DecryptionMaterials.') + expect(() => cloneMaterial(material)).to.throw( + Error, + 'Only 1 trace is valid on DecryptionMaterials.' + ) }) }) diff --git a/modules/material-management/test/cryptographic_material.test.ts b/modules/material-management/test/cryptographic_material.test.ts index 8263438db..b0e7e110a 100644 --- a/modules/material-management/test/cryptographic_material.test.ts +++ b/modules/material-management/test/cryptographic_material.test.ts @@ -11,7 +11,7 @@ import { SignatureKey, VerificationKey, WebCryptoAlgorithmSuite, - KeyringTraceFlag + KeyringTraceFlag, } from '../src' import { decorateCryptographicMaterial, @@ -28,37 +28,65 @@ import { isCryptoKey, unwrapDataKey, wrapWithKeyObjectIfSupported, - supportsKeyObject + supportsKeyObject, } from '../src/cryptographic_material' import { createSecretKey } from 'crypto' describe('decorateCryptographicMaterial', () => { it('will decorate', () => { - const test = decorateCryptographicMaterial(({}), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) - expect(test).to.haveOwnProperty('setUnencryptedDataKey').and.to.be.a('function') - expect(test).to.haveOwnProperty('getUnencryptedDataKey').and.to.be.a('function') - expect(test).to.haveOwnProperty('zeroUnencryptedDataKey').and.to.be.a('function') + const test = decorateCryptographicMaterial( + {} as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) + expect(test) + .to.haveOwnProperty('setUnencryptedDataKey') + .and.to.be.a('function') + expect(test) + .to.haveOwnProperty('getUnencryptedDataKey') + .and.to.be.a('function') + expect(test) + .to.haveOwnProperty('zeroUnencryptedDataKey') + .and.to.be.a('function') expect(test).to.haveOwnProperty('hasUnencryptedDataKey').and.to.equal(false) }) it('Precondition: setFlag must be in the set of KeyringTraceFlag.SET_FLAGS.', () => { - expect(() => decorateCryptographicMaterial(({}), KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX)).to.throw('') + expect(() => + decorateCryptographicMaterial( + {} as any, + KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX + ) + ).to.throw('') }) it('set, inspect, get works', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - test.setUnencryptedDataKey(new Uint8Array(dataKey), { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY }) + test.setUnencryptedDataKey(new Uint8Array(dataKey), { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) expect(test.hasUnencryptedDataKey).to.equal(true) const udk = unwrapDataKey(test.getUnencryptedDataKey()) expect(udk).to.deep.equal(dataKey) }) it('zeroing out the unencrypted data key', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) /* This is complicated. * Now that I support KeyObjects it is good to pass a copy, @@ -66,11 +94,17 @@ describe('decorateCryptographicMaterial', () => { * But in this case, if this is a version of Node.js that does not support KeyObjects * passing the dataKey lets me verify that the value memory is really zeroed. */ - test.setUnencryptedDataKey(dataKey, { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY }) + test.setUnencryptedDataKey(dataKey, { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) test.zeroUnencryptedDataKey() expect(test.hasUnencryptedDataKey).to.equal(false) if (!supportsKeyObject) { - expect(dataKey).to.deep.equal(new Uint8Array(suite.keyLengthBytes).fill(0)) + expect(dataKey).to.deep.equal( + new Uint8Array(suite.keyLengthBytes).fill(0) + ) } else { // If the environment supports KeyObjects then the udk was wrapped. // There is no way to confirm that @@ -78,97 +112,196 @@ describe('decorateCryptographicMaterial', () => { }) it('Precondition: The data key length must agree with algorithm specification.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes - 1).fill(1) expect(() => test.setUnencryptedDataKey(new Uint8Array(dataKey))).to.throw() }) it('Precondition: unencryptedDataKey must not be Zeroed out.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - test.setUnencryptedDataKey(new Uint8Array(dataKey), { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY }) + test.setUnencryptedDataKey(new Uint8Array(dataKey), { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) test.zeroUnencryptedDataKey() expect(() => test.getUnencryptedDataKey()).to.throw() }) it('Precondition: unencryptedDataKey must be set before we can return it.', () => { - const test: any = decorateCryptographicMaterial(({}), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const test: any = decorateCryptographicMaterial( + {} as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) expect(() => test.getUnencryptedDataKey()).to.throw() }) it(`Precondition: If the unencryptedDataKey has not been set, it should not be settable later. Precondition: If the udkForVerification has not been set, it should not be settable later.`, () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) test.zeroUnencryptedDataKey() const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } // It is very hard to test this perfectly. However, this tests the spirit. - expect(() => test.setUnencryptedDataKey(new Uint8Array(dataKey), trace)).to.throw() + expect(() => + test.setUnencryptedDataKey(new Uint8Array(dataKey), trace) + ).to.throw() }) it('Precondition: dataKey must be Binary Data', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) expect(() => test.setUnencryptedDataKey('')).to.throw() }) it('Precondition: unencryptedDataKey must not be set. Modifying the unencryptedDataKey is denied', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } test.setUnencryptedDataKey(new Uint8Array(dataKey), trace) - expect(() => test.setUnencryptedDataKey(new Uint8Array(dataKey), trace)).to.throw('unencryptedDataKey has already been set') + expect(() => + test.setUnencryptedDataKey(new Uint8Array(dataKey), trace) + ).to.throw('unencryptedDataKey has already been set') }) it('Precondition: dataKey should have an ArrayBuffer that *only* stores the key.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) - const dataKey = new Uint8Array(new ArrayBuffer(suite.keyLengthBytes + 10), 5, suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } - expect(() => test.setUnencryptedDataKey(dataKey, trace)).to.throw('Unencrypted Master Key must be an isolated buffer.') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) + const dataKey = new Uint8Array( + new ArrayBuffer(suite.keyLengthBytes + 10), + 5, + suite.keyLengthBytes + ).fill(1) + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } + expect(() => test.setUnencryptedDataKey(dataKey, trace)).to.throw( + 'Unencrypted Master Key must be an isolated buffer.' + ) }) it('Precondition: Trace must be set, and the flag must indicate that the data key was generated.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - expect(() => test.setUnencryptedDataKey(new Uint8Array(dataKey), {} as any)).to.throw('Malformed KeyringTrace') + expect(() => + test.setUnencryptedDataKey(new Uint8Array(dataKey), {} as any) + ).to.throw('Malformed KeyringTrace') }) it('Precondition: On set the required KeyringTraceFlag must be set.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX } - expect(() => test.setUnencryptedDataKey(new Uint8Array(dataKey), trace)).to.throw('Required KeyringTraceFlag not set') + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX, + } + expect(() => + test.setUnencryptedDataKey(new Uint8Array(dataKey), trace) + ).to.throw('Required KeyringTraceFlag not set') }) it('Precondition: Only valid flags are allowed.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY | KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } - expect(() => test.setUnencryptedDataKey(new Uint8Array(dataKey), trace)).to.throw('Invalid KeyringTraceFlags set.') + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY | + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } + expect(() => + test.setUnencryptedDataKey(new Uint8Array(dataKey), trace) + ).to.throw('Invalid KeyringTraceFlags set.') }) it('Precondition: The unencryptedDataKey must not have been modified.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const material = decorateCryptographicMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const material = decorateCryptographicMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) const dataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - material.setUnencryptedDataKey(dataKey, { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY }) + material.setUnencryptedDataKey(dataKey, { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) const test = material.getUnencryptedDataKey() test[0] = 12 expect(() => { const udk = unwrapDataKey(material.getUnencryptedDataKey()) if (supportsKeyObject) { /* This should NOT be true. - * If the udk is a KeyObject then the change above was on independent memory. - * This check follows the code, and is *intended* to fail. - */ + * If the udk is a KeyObject then the change above was on independent memory. + * This check follows the code, and is *intended* to fail. + */ expect(udk[0]).to.equal(12) } }).to.throw() @@ -177,144 +310,305 @@ describe('decorateCryptographicMaterial', () => { describe('decorateEncryptionMaterial', () => { it('will decorate', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [] })) - expect(test).to.haveOwnProperty('addEncryptedDataKey').and.to.be.a('function') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) + expect(test) + .to.haveOwnProperty('addEncryptedDataKey') + .and.to.be.a('function') expect(test).to.haveOwnProperty('setSignatureKey').and.to.be.a('function') - expect(test).to.haveOwnProperty('encryptedDataKeys').and.to.be.a('array').with.lengthOf(0) + expect(test) + .to.haveOwnProperty('encryptedDataKeys') + .and.to.be.a('array') + .with.lengthOf(0) expect(test).to.haveOwnProperty('signatureKey').and.to.equal(undefined) }) it('add EncryptedDataKey', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'p', encryptedDataKey: new Uint8Array(3) }) - test.addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + hasUnencryptedDataKey: true, + } as any) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'p', + encryptedDataKey: new Uint8Array(3), + }) + test.addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) expect(test.encryptedDataKeys).to.have.length(1) expect(test.encryptedDataKeys[0] === edk).to.equal(true) }) it('add SignatureKey', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) const key = new SignatureKey(new Uint8Array(3), new Uint8Array(3), suite) test.setSignatureKey(key) expect(test.signatureKey === key).to.equal(true) }) it('Precondition: If a data key has not already been generated, there must be no EDKs.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'p', encryptedDataKey: new Uint8Array(3) }) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: false })) - expect(() => test.addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY)).to.throw() + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'p', + encryptedDataKey: new Uint8Array(3), + }) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + hasUnencryptedDataKey: false, + } as any) + expect(() => + test.addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + ).to.throw() }) it('Precondition: Edk must be EncryptedDataKey', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const edk: any = {} - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) - expect(() => test.addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY)).to.throw() + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) + expect(() => + test.addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) + ).to.throw() }) it('Precondition: flags must indicate that the key was encrypted.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'p', encryptedDataKey: new Uint8Array(3) }) - expect(() => test.addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX)).to.throw('Encrypted data key flag must be set.') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + hasUnencryptedDataKey: true, + } as any) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'p', + encryptedDataKey: new Uint8Array(3), + }) + expect(() => + test.addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX + ) + ).to.throw('Encrypted data key flag must be set.') }) it('Precondition: flags must not include a setFlag or a decrypt flag.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'p', encryptedDataKey: new Uint8Array(3) }) - expect(() => test.addEncryptedDataKey(edk, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY | KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX)).to.throw('Invalid flag for EncryptedDataKey.') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + hasUnencryptedDataKey: true, + } as any) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'p', + encryptedDataKey: new Uint8Array(3), + }) + expect(() => + test.addEncryptedDataKey( + edk, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY | + KeyringTraceFlag.WRAPPING_KEY_VERIFIED_ENC_CTX + ) + ).to.throw('Invalid flag for EncryptedDataKey.') }) it('Precondition: The SignatureKey stored must agree with the algorithm specification.', () => { - const suiteWithSig = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const key = new SignatureKey(new Uint8Array(3), new Uint8Array(3), suiteWithSig) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suiteWithSig = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const key = new SignatureKey( + new Uint8Array(3), + new Uint8Array(3), + suiteWithSig + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) expect(() => test.setSignatureKey(key)).to.throw() }) it('Precondition: signatureKey must not be set. Modifying the signatureKey is denied.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const key = new SignatureKey(new Uint8Array(3), new Uint8Array(3), suite) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) test.setSignatureKey(key) expect(() => test.setSignatureKey(key)).to.throw() }) it('Precondition: key must be a SignatureKey.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const key : any = {} - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const key: any = {} + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) expect(() => test.setSignatureKey(key)).to.throw() }) it('Precondition: The SignatureKey requested must agree with the algorithm specification.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateEncryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateEncryptionMaterial({ + suite, + keyringTrace: [], + } as any) expect(() => test.signatureKey).to.throw() }) }) describe('decorateDecryptionMaterial', () => { it('will decorate', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const test: any = decorateDecryptionMaterial(({ suite, keyringTrace: [] })) - expect(test).to.haveOwnProperty('setVerificationKey').and.to.be.a('function') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const test: any = decorateDecryptionMaterial({ + suite, + keyringTrace: [], + } as any) + expect(test) + .to.haveOwnProperty('setVerificationKey') + .and.to.be.a('function') expect(test).to.haveOwnProperty('verificationKey').and.to.equal(undefined) }) it('add VerificationKey', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateDecryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateDecryptionMaterial({ + suite, + keyringTrace: [], + } as any) const key = new VerificationKey(new Uint8Array(3), suite) test.setVerificationKey(key) expect(test.verificationKey === key).to.equal(true) }) it('Precondition: The VerificationKey stored must agree with the algorithm specification.', () => { - const suiteWithSig = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suiteWithSig = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const key = new VerificationKey(new Uint8Array(3), suiteWithSig) - const test: any = decorateDecryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const test: any = decorateDecryptionMaterial({ + suite, + keyringTrace: [], + } as any) expect(() => test.setVerificationKey(key)).to.throw() }) it('Precondition: verificationKey must not be set. Modifying the verificationKey is denied.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const key = new VerificationKey(new Uint8Array(3), suite) - const test: any = decorateDecryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const test: any = decorateDecryptionMaterial({ + suite, + keyringTrace: [], + } as any) test.setVerificationKey(key) expect(() => test.setVerificationKey(key)).to.throw() }) it('Precondition: key must be a VerificationKey.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const key : any = {} - const test: any = decorateDecryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const key: any = {} + const test: any = decorateDecryptionMaterial({ + suite, + keyringTrace: [], + } as any) expect(() => test.setVerificationKey(key)).to.throw() }) it('Precondition: The VerificationKey requested must agree with the algorithm specification.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateDecryptionMaterial(({ suite, keyringTrace: [], hasUnencryptedDataKey: true })) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateDecryptionMaterial({ + suite, + keyringTrace: [], + } as any) expect(() => test.verificationKey).to.throw() }) }) describe('decorateWebCryptoMaterial', () => { it('add CryptoKey', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateWebCryptoMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateWebCryptoMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) // setCryptoKey uses `zeroUnencryptedDataKey` when setting a cryptoKey *without* a unencrypted data key - decorateCryptographicMaterial(test, KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + decorateCryptographicMaterial( + test, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) test.validUsages = ['deriveKey'] - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } test.setCryptoKey(key, trace) expect(test.getCryptoKey() === key).to.equal(true) expect(test.hasCryptoKey).to.equal(true) @@ -322,76 +616,204 @@ describe('decorateWebCryptoMaterial', () => { }) it('add MixedBackendCryptoKey', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateWebCryptoMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateWebCryptoMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) test.validUsages = ['deriveKey'] // setCryptoKey uses `zeroUnencryptedDataKey` when setting a cryptoKey *without* a unencrypted data key - decorateCryptographicMaterial(test, KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } + decorateCryptographicMaterial( + test, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } const mixedKey: any = { zeroByteCryptoKey: key, nonZeroByteCryptoKey: key } - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } test.setCryptoKey(mixedKey, trace) expect(test.getCryptoKey() !== mixedKey).to.equal(true) expect(test.hasCryptoKey).to.equal(true) expect(test.hasUnencryptedDataKey).to.equal(false) - expect(test.getCryptoKey().zeroByteCryptoKey === mixedKey.zeroByteCryptoKey).to.equal(true) - expect(test.getCryptoKey().nonZeroByteCryptoKey === mixedKey.nonZeroByteCryptoKey).to.equal(true) + expect( + test.getCryptoKey().zeroByteCryptoKey === mixedKey.zeroByteCryptoKey + ).to.equal(true) + expect( + test.getCryptoKey().nonZeroByteCryptoKey === mixedKey.nonZeroByteCryptoKey + ).to.equal(true) expect(Object.isFrozen(test.getCryptoKey())).to.equal(true) }) it('Precondition: The cryptoKey must be set before we can return it.', () => { - const test: any = decorateWebCryptoMaterial(({}), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + const test: any = decorateWebCryptoMaterial( + {} as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) expect(() => test.getCryptoKey()).to.throw() }) it('Precondition: cryptoKey must not be set. Modifying the cryptoKey is denied', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateWebCryptoMaterial(({ suite, keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateWebCryptoMaterial( + { suite, keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) test.validUsages = ['deriveKey'] // setCryptoKey uses `zeroUnencryptedDataKey` when setting a cryptoKey *without* a unencrypted data key - decorateCryptographicMaterial(test, KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + decorateCryptographicMaterial( + test, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } test.setCryptoKey(key, trace) expect(() => test.setCryptoKey(key, trace)).to.throw() }) it('Precondition: The CryptoKey must match the algorithm suite specification.', () => { - const test: any = decorateWebCryptoMaterial(({}), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: true } - const key1: any = { zeroByteCryptoKey: { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: true }, nonZeroByteCryptoKey: { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } } - const key2: any = { zeroByteCryptoKey: { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false }, nonZeroByteCryptoKey: { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: true } } - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const test: any = decorateWebCryptoMaterial( + {} as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: true, + } + const key1: any = { + zeroByteCryptoKey: { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: true, + }, + nonZeroByteCryptoKey: { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + }, + } + const key2: any = { + zeroByteCryptoKey: { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + }, + nonZeroByteCryptoKey: { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: true, + }, + } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } expect(() => test.setCryptoKey(key, trace)).to.throw() expect(() => test.setCryptoKey(key1, trace)).to.throw() expect(() => test.setCryptoKey(key2, trace)).to.throw() }) it('Precondition: If the CryptoKey is the only version, the trace information must be set here.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateWebCryptoMaterial(({ suite, validUsages: ['deriveKey'], keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - decorateCryptographicMaterial(test, KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } - expect(() => test.setCryptoKey(key, { keyNamespace: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY })).to.throw('Malformed KeyringTrace') - expect(() => test.setCryptoKey(key, { keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY })).to.throw('Malformed KeyringTrace') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateWebCryptoMaterial( + { suite, validUsages: ['deriveKey'], keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + decorateCryptographicMaterial( + test, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } + expect(() => + test.setCryptoKey(key, { + keyNamespace: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + }) + ).to.throw('Malformed KeyringTrace') + expect(() => + test.setCryptoKey(key, { + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + }) + ).to.throw('Malformed KeyringTrace') expect(() => test.setCryptoKey(key)).to.throw('Malformed KeyringTrace') }) it('Precondition: On setting the CryptoKey the required KeyringTraceFlag must be set.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) - const test: any = decorateWebCryptoMaterial(({ suite, validUsages: ['deriveKey'], keyringTrace: [] }), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - decorateCryptographicMaterial(test, KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) - - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX } - expect(() => test.setCryptoKey(key, trace)).to.throw('Required KeyringTraceFlag not set') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) + const test: any = decorateWebCryptoMaterial( + { suite, validUsages: ['deriveKey'], keyringTrace: [] } as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + decorateCryptographicMaterial( + test, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) + + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX, + } + expect(() => test.setCryptoKey(key, trace)).to.throw( + 'Required KeyringTraceFlag not set' + ) }) it('Precondition: dataKey must be a supported type.', () => { - const test: any = decorateWebCryptoMaterial(({}), KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + const test: any = decorateWebCryptoMaterial( + {} as any, + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) const key: any = {} - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } expect(() => test.setCryptoKey(key, trace)).to.throw() }) }) @@ -399,13 +821,17 @@ describe('decorateWebCryptoMaterial', () => { describe('decorateWebCryptoMaterial:Helpers', () => { describe('subtleFunctionForMaterial', () => { it('WebCryptoDecryptionMaterial is decrypt', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) expect(subtleFunctionForMaterial(material)).to.equal('decrypt') }) it('WebCryptoEncryptionMaterial is encrypt', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) expect(subtleFunctionForMaterial(material)).to.equal('encrypt') }) @@ -417,25 +843,33 @@ describe('decorateWebCryptoMaterial:Helpers', () => { describe('keyUsageForMaterial', () => { it('ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 is deriveKey', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) expect(keyUsageForMaterial(material)).to.equal('deriveKey') }) it('ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 is decrypt', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) expect(keyUsageForMaterial(material)).to.equal('deriveKey') }) it('WebCryptoDecryptionMaterial is decrypt', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) expect(keyUsageForMaterial(material)).to.equal('decrypt') }) it('WebCryptoEncryptionMaterial is encrypt', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) expect(keyUsageForMaterial(material)).to.equal('encrypt') }) @@ -447,67 +881,130 @@ describe('decorateWebCryptoMaterial:Helpers', () => { }) it('isCryptoKey', () => { - const key: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } + const key: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } expect(isCryptoKey(key)).to.equal(true) }) describe('isValidCryptoKey', () => { it('Suite with KDF is valid for both the derivable key and the derived key', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - const keyKdf: any = { type: 'secret', algorithm: { name: suite.kdf }, usages: ['deriveKey'], extractable: false } - const deriveKey: any = { type: 'secret', algorithm: { name: suite.encryption, length: suite.keyLength }, usages: ['encrypt'], extractable: false } + const keyKdf: any = { + type: 'secret', + algorithm: { name: suite.kdf }, + usages: ['deriveKey'], + extractable: false, + } + const deriveKey: any = { + type: 'secret', + algorithm: { name: suite.encryption, length: suite.keyLength }, + usages: ['encrypt'], + extractable: false, + } expect(isValidCryptoKey(keyKdf, material)).to.equal(true) expect(isValidCryptoKey(deriveKey, material)).to.equal(true) }) it('Suite without the KDF is only derivable with the key', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - const keyKdf: any = { type: 'secret', algorithm: { name: 'HKDF' }, usages: ['deriveKey'], extractable: false } - const key: any = { type: 'secret', algorithm: { name: suite.encryption, length: suite.keyLength }, usages: ['encrypt'], extractable: false } + const keyKdf: any = { + type: 'secret', + algorithm: { name: 'HKDF' }, + usages: ['deriveKey'], + extractable: false, + } + const key: any = { + type: 'secret', + algorithm: { name: suite.encryption, length: suite.keyLength }, + usages: ['encrypt'], + extractable: false, + } expect(isValidCryptoKey(keyKdf, material)).to.equal(false) expect(isValidCryptoKey(key, material)).to.equal(true) }) it('only type === secret is valid', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - const key: any = { type: 'private', algorithm: { name: suite.encryption, length: suite.keyLength }, usages: ['encrypt'], extractable: false } + const key: any = { + type: 'private', + algorithm: { name: suite.encryption, length: suite.keyLength }, + usages: ['encrypt'], + extractable: false, + } expect(isValidCryptoKey(key, material)).to.equal(false) }) it('length must match', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - const key: any = { type: 'secret', algorithm: { name: suite.encryption, length: suite.keyLength - 1 }, usages: ['encrypt'], extractable: false } + const key: any = { + type: 'secret', + algorithm: { name: suite.encryption, length: suite.keyLength - 1 }, + usages: ['encrypt'], + extractable: false, + } expect(isValidCryptoKey(key, material)).to.equal(false) }) it('can not be extractable', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - const key: any = { type: 'secret', algorithm: { name: suite.encryption, length: suite.keyLength }, usages: ['encrypt'], extractable: true } + const key: any = { + type: 'secret', + algorithm: { name: suite.encryption, length: suite.keyLength }, + usages: ['encrypt'], + extractable: true, + } expect(isValidCryptoKey(key, material)).to.equal(false) }) it('usage must match', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - const key: any = { type: 'secret', algorithm: { name: suite.encryption, length: suite.keyLength }, usages: ['decrypt'], extractable: false } + const key: any = { + type: 'secret', + algorithm: { name: suite.encryption, length: suite.keyLength }, + usages: ['decrypt'], + extractable: false, + } expect(isValidCryptoKey(key, material)).to.equal(false) }) }) }) describe('NodeEncryptionMaterial', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const test: any = new NodeEncryptionMaterial(suite, {}) it('instance is frozen', () => expect(Object.isFrozen(test)).to.equal(true)) it('has a suite', () => expect(test.suite === suite).to.equal(true)) - it('class is frozen', () => expect(Object.isFrozen(NodeAlgorithmSuite)).to.equal(true)) - it('class prototype is frozen', () => expect(Object.isFrozen(NodeAlgorithmSuite.prototype)).to.equal(true)) + it('class is frozen', () => + expect(Object.isFrozen(NodeAlgorithmSuite)).to.equal(true)) + it('class prototype is frozen', () => + expect(Object.isFrozen(NodeAlgorithmSuite.prototype)).to.equal(true)) it('Precondition: NodeEncryptionMaterial suite must be NodeAlgorithmSuite.', () => { - const suite: any = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite: any = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(() => new NodeEncryptionMaterial(suite, {})).to.throw() }) it('Precondition: NodeEncryptionMaterial encryptionContext must be an object, even if it is empty.', () => { @@ -517,14 +1014,20 @@ describe('NodeEncryptionMaterial', () => { }) describe('NodeDecryptionMaterial', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const test: any = new NodeDecryptionMaterial(suite, {}) it('instance is frozen', () => expect(Object.isFrozen(test)).to.equal(true)) it('has a suite', () => expect(test.suite === suite).to.equal(true)) - it('class is frozen', () => expect(Object.isFrozen(NodeAlgorithmSuite)).to.equal(true)) - it('class prototype is frozen', () => expect(Object.isFrozen(NodeAlgorithmSuite.prototype)).to.equal(true)) + it('class is frozen', () => + expect(Object.isFrozen(NodeAlgorithmSuite)).to.equal(true)) + it('class prototype is frozen', () => + expect(Object.isFrozen(NodeAlgorithmSuite.prototype)).to.equal(true)) it('Precondition: NodeDecryptionMaterial suite must be NodeAlgorithmSuite.', () => { - const suite: any = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite: any = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(() => new NodeDecryptionMaterial(suite, {})).to.throw() }) it('Precondition: NodeDecryptionMaterial encryptionContext must be an object, even if it is empty.', () => { @@ -534,35 +1037,51 @@ describe('NodeDecryptionMaterial', () => { }) describe('WebCryptoEncryptionMaterial', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const test: any = new WebCryptoEncryptionMaterial(suite, {}) it('instance is frozen', () => expect(Object.isFrozen(test)).to.equal(true)) it('has a suite', () => expect(test.suite === suite).to.equal(true)) - it('class is frozen', () => expect(Object.isFrozen(WebCryptoAlgorithmSuite)).to.equal(true)) - it('class prototype is frozen', () => expect(Object.isFrozen(WebCryptoAlgorithmSuite.prototype)).to.equal(true)) + it('class is frozen', () => + expect(Object.isFrozen(WebCryptoAlgorithmSuite)).to.equal(true)) + it('class prototype is frozen', () => + expect(Object.isFrozen(WebCryptoAlgorithmSuite.prototype)).to.equal(true)) it('Precondition: WebCryptoEncryptionMaterial suite must be WebCryptoAlgorithmSuite.', () => { - const suite: any = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite: any = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(() => new WebCryptoEncryptionMaterial(suite, {})).to.throw() }) it('Precondition: WebCryptoEncryptionMaterial encryptionContext must be an object, even if it is empty.', () => { - expect(() => new WebCryptoEncryptionMaterial(suite, undefined as any)).to.throw() + expect( + () => new WebCryptoEncryptionMaterial(suite, undefined as any) + ).to.throw() expect(() => new WebCryptoEncryptionMaterial(suite, true as any)).to.throw() }) }) describe('WebCryptoDecryptionMaterial', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const test: any = new WebCryptoDecryptionMaterial(suite, {}) it('instance is frozen', () => expect(Object.isFrozen(test)).to.equal(true)) it('has a suite', () => expect(test.suite === suite).to.equal(true)) - it('class is frozen', () => expect(Object.isFrozen(WebCryptoAlgorithmSuite)).to.equal(true)) - it('class prototype is frozen', () => expect(Object.isFrozen(WebCryptoAlgorithmSuite.prototype)).to.equal(true)) + it('class is frozen', () => + expect(Object.isFrozen(WebCryptoAlgorithmSuite)).to.equal(true)) + it('class prototype is frozen', () => + expect(Object.isFrozen(WebCryptoAlgorithmSuite.prototype)).to.equal(true)) it('Precondition: WebCryptoDecryptionMaterial suite must be WebCryptoAlgorithmSuite.', () => { - const suite: any = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite: any = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(() => new WebCryptoDecryptionMaterial(suite, {})).to.throw() }) it('Precondition: WebCryptoDecryptionMaterial encryptionContext must be an object, even if it is empty.', () => { - expect(() => new WebCryptoDecryptionMaterial(suite, undefined as any)).to.throw() + expect( + () => new WebCryptoDecryptionMaterial(suite, undefined as any) + ).to.throw() expect(() => new WebCryptoDecryptionMaterial(suite, true as any)).to.throw() }) }) @@ -587,7 +1106,9 @@ describe('KeyObject support', () => { }) it('throws for unsupported types', () => { - expect(() => wrapWithKeyObjectIfSupported({} as any)).to.throw('Unsupported dataKey type') + expect(() => wrapWithKeyObjectIfSupported({} as any)).to.throw( + 'Unsupported dataKey type' + ) }) it('Postcondition: Zero the secret. It is now inside the KeyObject.', () => { @@ -612,7 +1133,9 @@ describe('KeyObject support', () => { }) it('throws for unsupported types', () => { - expect(() => unwrapDataKey({} as any)).to.throw('Unsupported dataKey type') + expect(() => unwrapDataKey({} as any)).to.throw( + 'Unsupported dataKey type' + ) }) }) } else { @@ -625,7 +1148,9 @@ describe('KeyObject support', () => { }) it('throws for unsupported types', () => { - expect(() => wrapWithKeyObjectIfSupported({} as any)).to.throw('Unsupported dataKey type') + expect(() => wrapWithKeyObjectIfSupported({} as any)).to.throw( + 'Unsupported dataKey type' + ) }) }) @@ -637,7 +1162,9 @@ describe('KeyObject support', () => { }) it('throws for unsupported types', () => { - expect(() => unwrapDataKey({} as any)).to.throw('Unsupported dataKey type') + expect(() => unwrapDataKey({} as any)).to.throw( + 'Unsupported dataKey type' + ) }) }) } diff --git a/modules/material-management/test/ecc.test.ts b/modules/material-management/test/ecc.test.ts index 5cb4679f7..0dd723b66 100644 --- a/modules/material-management/test/ecc.test.ts +++ b/modules/material-management/test/ecc.test.ts @@ -7,44 +7,269 @@ import { expect } from 'chai' import { decodeNamedCurves } from '../src/ecc_decode' import { encodeNamedCurves } from '../src/ecc_encode' -const prime256v1PublicFixture = [ 4, - 54, 131, 184, 190, 94, 145, 250, 132, 150, 193, - 178, 150, 190, 22, 22, 11, 201, 60, 9, 53, - 128, 68, 120, 118, 83, 106, 52, 226, 143, 155, - 120, 178, 217, 246, 201, 43, 28, 98, 154, 24, - 59, 251, 229, 162, 89, 161, 79, 81, 23, 238, - 208, 108, 15, 209, 56, 91, 237, 38, 60, 72, - 98, 181, 219, 196 ] +const prime256v1PublicFixture = [ + 4, + 54, + 131, + 184, + 190, + 94, + 145, + 250, + 132, + 150, + 193, + 178, + 150, + 190, + 22, + 22, + 11, + 201, + 60, + 9, + 53, + 128, + 68, + 120, + 118, + 83, + 106, + 52, + 226, + 143, + 155, + 120, + 178, + 217, + 246, + 201, + 43, + 28, + 98, + 154, + 24, + 59, + 251, + 229, + 162, + 89, + 161, + 79, + 81, + 23, + 238, + 208, + 108, + 15, + 209, + 56, + 91, + 237, + 38, + 60, + 72, + 98, + 181, + 219, + 196, +] -const prime256v1CompressedFixture = [ 2, - 54, 131, 184, 190, 94, 145, 250, 132, 150, 193, - 178, 150, 190, 22, 22, 11, 201, 60, 9, 53, - 128, 68, 120, 118, 83, 106, 52, 226, 143, 155, - 120, 178 ] +const prime256v1CompressedFixture = [ + 2, + 54, + 131, + 184, + 190, + 94, + 145, + 250, + 132, + 150, + 193, + 178, + 150, + 190, + 22, + 22, + 11, + 201, + 60, + 9, + 53, + 128, + 68, + 120, + 118, + 83, + 106, + 52, + 226, + 143, + 155, + 120, + 178, +] -const secp384r1PublicFixture = [ 4, - 207, 62, 215, 143, 116, 128, 174, 103, 1, 81, 127, - 212, 163, 19, 165, 220, 74, 144, 26, 59, 87, 0, - 214, 47, 66, 73, 152, 227, 196, 81, 14, 28, 58, - 221, 178, 63, 150, 119, 62, 195, 99, 63, 60, 42, - 223, 207, 28, 65, 180, 143, 190, 5, 150, 247, 225, - 240, 153, 150, 119, 109, 210, 243, 151, 206, 217, 120, - 2, 171, 75, 180, 31, 4, 91, 78, 206, 217, 241, - 119, 55, 230, 216, 23, 237, 101, 21, 89, 132, 84, - 100, 3, 255, 90, 197, 237, 139, 209 ] +const secp384r1PublicFixture = [ + 4, + 207, + 62, + 215, + 143, + 116, + 128, + 174, + 103, + 1, + 81, + 127, + 212, + 163, + 19, + 165, + 220, + 74, + 144, + 26, + 59, + 87, + 0, + 214, + 47, + 66, + 73, + 152, + 227, + 196, + 81, + 14, + 28, + 58, + 221, + 178, + 63, + 150, + 119, + 62, + 195, + 99, + 63, + 60, + 42, + 223, + 207, + 28, + 65, + 180, + 143, + 190, + 5, + 150, + 247, + 225, + 240, + 153, + 150, + 119, + 109, + 210, + 243, + 151, + 206, + 217, + 120, + 2, + 171, + 75, + 180, + 31, + 4, + 91, + 78, + 206, + 217, + 241, + 119, + 55, + 230, + 216, + 23, + 237, + 101, + 21, + 89, + 132, + 84, + 100, + 3, + 255, + 90, + 197, + 237, + 139, + 209, +] -const secp384r1CompressedFixture = [ 3, - 207, 62, 215, 143, 116, 128, 174, 103, 1, 81, 127, - 212, 163, 19, 165, 220, 74, 144, 26, 59, 87, 0, - 214, 47, 66, 73, 152, 227, 196, 81, 14, 28, 58, - 221, 178, 63, 150, 119, 62, 195, 99, 63, 60, 42, - 223, 207, 28, 65 ] +const secp384r1CompressedFixture = [ + 3, + 207, + 62, + 215, + 143, + 116, + 128, + 174, + 103, + 1, + 81, + 127, + 212, + 163, + 19, + 165, + 220, + 74, + 144, + 26, + 59, + 87, + 0, + 214, + 47, + 66, + 73, + 152, + 227, + 196, + 81, + 14, + 28, + 58, + 221, + 178, + 63, + 150, + 119, + 62, + 195, + 99, + 63, + 60, + 42, + 223, + 207, + 28, + 65, +] describe('ecc', () => { it('encodeNamedCurves.prime256v1', () => { const publicKey = new Uint8Array(prime256v1PublicFixture) const compressPoint = encodeNamedCurves.prime256v1(publicKey) - expect(compressPoint).to.deep.equal(new Uint8Array(prime256v1CompressedFixture)) + expect(compressPoint).to.deep.equal( + new Uint8Array(prime256v1CompressedFixture) + ) }) it('Precondition: publicKey must be the right length.', () => { @@ -66,7 +291,9 @@ describe('ecc', () => { it('encodeNamedCurves.secp384r1', () => { const publicKey = new Uint8Array(secp384r1PublicFixture) const compressPoint = encodeNamedCurves.secp384r1(publicKey) - expect(compressPoint).to.deep.equal(new Uint8Array(secp384r1CompressedFixture)) + expect(compressPoint).to.deep.equal( + new Uint8Array(secp384r1CompressedFixture) + ) }) it('decodeNamedCurves.secp384r1', () => { diff --git a/modules/material-management/test/encrypted_data_key.test.ts b/modules/material-management/test/encrypted_data_key.test.ts index 8b9750406..1f3351661 100644 --- a/modules/material-management/test/encrypted_data_key.test.ts +++ b/modules/material-management/test/encrypted_data_key.test.ts @@ -12,7 +12,11 @@ describe('EncryptedDataKey', () => { const providerId = 'providerId' const encryptedDataKey = new Uint8Array([1, 2, 3]) - const test = new EncryptedDataKey({ providerInfo, providerId, encryptedDataKey }) + const test = new EncryptedDataKey({ + providerInfo, + providerId, + encryptedDataKey, + }) expect(Object.isFrozen(test)).to.eql(true) expect(test.providerInfo).to.eql(providerInfo) diff --git a/modules/material-management/test/environmental_integration.test.ts b/modules/material-management/test/environmental_integration.test.ts index e89d7bc0b..73d7fe886 100644 --- a/modules/material-management/test/environmental_integration.test.ts +++ b/modules/material-management/test/environmental_integration.test.ts @@ -5,7 +5,7 @@ import { expect } from 'chai' -function isNode (): boolean { +function isNode(): boolean { return ( Object.prototype.toString.call( // @ts-ignore @@ -18,7 +18,7 @@ describe('environmental integration', () => { it('Node.js crypto exports timingSafeEqual for supported Node.js Versions.', () => { if (isNode()) { // @ts-ignore - const { timingSafeEqual } = require('crypto') + const { timingSafeEqual } = require('crypto') // eslint-disable-line @typescript-eslint/no-var-requires expect(typeof timingSafeEqual === 'function').to.equal(true) } }) diff --git a/modules/material-management/test/immutable_class.test.ts b/modules/material-management/test/immutable_class.test.ts index 7334a58f0..2d365f9ad 100644 --- a/modules/material-management/test/immutable_class.test.ts +++ b/modules/material-management/test/immutable_class.test.ts @@ -4,21 +4,25 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { immutableClass, immutableBaseClass, frozenClass } from '../src/immutable_class' +import { + immutableClass, + immutableBaseClass, + frozenClass, +} from '../src/immutable_class' describe('frozenClass', () => { class Test { public name: string - constructor (name: string) { + constructor(name: string) { this.name = name // This is important, or the new instance // can be modified Object.freeze(this) } - qwer () { + qwer() { return 'qwer' } - static asdf () { + static asdf() { return 'asdf' } } @@ -37,32 +41,40 @@ describe('frozenClass', () => { }) it('can not change static properties', () => { - expect(() => { (Test).asdf = 'something' }).to.throw() + expect(() => { + ;(Test as any).asdf = 'something' + }).to.throw() }) it('can not add new static properties', () => { - expect(() => { (Test).something = 'something' }).to.throw() + expect(() => { + ;(Test as any).something = 'something' + }).to.throw() }) it('can not change prototype properties', () => { - expect(() => { (Test).prototype.qwer = 'something' }).to.throw() + expect(() => { + ;(Test as any).prototype.qwer = 'something' + }).to.throw() }) it('can not add new prototype properties', () => { - expect(() => { (Test).prototype.something = 'something' }).to.throw() + expect(() => { + ;(Test as any).prototype.something = 'something' + }).to.throw() }) }) describe('immutableBaseClass', () => { class Test { public name: string - constructor (name: string) { + constructor(name: string) { this.name = name } - qwer () { + qwer() { return 'qwer' } - static asdf () { + static asdf() { return 'asdf' } } @@ -82,56 +94,68 @@ describe('immutableBaseClass', () => { it('is an orphaned object (not an connected to Object)', () => { const test = new Test('test') - expect(Object.prototype.isPrototypeOf(test)).to.equal(false) + // This test is VERY deliberate. + // I want to know that test is not in the prototype chain, with Object. + expect(Object.prototype.isPrototypeOf(test)).to.equal(false) // eslint-disable-line no-prototype-builtins }) it('can not change static properties', () => { - expect(() => { (Test).asdf = 'something' }).to.throw() + expect(() => { + ;(Test as any).asdf = 'something' + }).to.throw() }) it('can not add new static properties', () => { - expect(() => { (Test).something = 'something' }).to.throw() + expect(() => { + ;(Test as any).something = 'something' + }).to.throw() }) it('can not change prototype properties', () => { - expect(() => { (Test).prototype.qwer = 'something' }).to.throw() + expect(() => { + ;(Test as any).prototype.qwer = 'something' + }).to.throw() }) it('can not add new prototype properties', () => { - expect(() => { (Test).prototype.something = 'something' }).to.throw() + expect(() => { + ;(Test as any).prototype.something = 'something' + }).to.throw() }) it('can not change the prototype of Test', () => { class Sneaky {} - expect(() => Object.setPrototypeOf(Test.prototype, Sneaky.prototype)).to.throw() + expect(() => + Object.setPrototypeOf(Test.prototype, Sneaky.prototype) + ).to.throw() }) }) describe('immutableClass: Extending a BaseClass', () => { class Base { public name: string - constructor (name: string) { + constructor(name: string) { this.name = name } - qwer () { + qwer() { return 'qwer' } - static asdf () { + static asdf() { return 'asdf' } } immutableBaseClass(Base) class Test extends Base { public thing: string - constructor (thing: string) { + constructor(thing: string) { super('extend') this.thing = thing Object.freeze(this) } - more () { + more() { return 'more' } - static myCount () { + static myCount() { return 1 } } @@ -158,15 +182,23 @@ describe('immutableClass: Extending a BaseClass', () => { // Properties of test are covered by tests of immutableBaseClass // which calls immutableClass it('can not change static properties', () => { - expect(() => { (Test).asdf = 'something' }).to.throw() + expect(() => { + ;(Test as any).asdf = 'something' + }).to.throw() }) it('can not add new static properties', () => { - expect(() => { (Test).something = 'something' }).to.throw() + expect(() => { + ;(Test as any).something = 'something' + }).to.throw() }) it('can not change prototype properties', () => { - expect(() => { (Test).prototype.qwer = 'something' }).to.throw() + expect(() => { + ;(Test as any).prototype.qwer = 'something' + }).to.throw() }) it('can not add new prototype properties', () => { - expect(() => { (Test).prototype.something = 'something' }).to.throw() + expect(() => { + ;(Test as any).prototype.something = 'something' + }).to.throw() }) }) diff --git a/modules/material-management/test/keyring.test.ts b/modules/material-management/test/keyring.test.ts index 2fad7d24e..523db718c 100644 --- a/modules/material-management/test/keyring.test.ts +++ b/modules/material-management/test/keyring.test.ts @@ -5,7 +5,10 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { NodeEncryptionMaterial, NodeDecryptionMaterial } from '../src/cryptographic_material' // eslint-disable-line no-unused-vars +import { + NodeEncryptionMaterial, + NodeDecryptionMaterial, +} from '../src/cryptographic_material' import { AlgorithmSuiteIdentifier } from '../src/algorithm_suites' import { NodeAlgorithmSuite } from '../src/node_algorithms' import { EncryptedDataKey } from '../src/encrypted_data_key' @@ -13,15 +16,17 @@ import { Keyring } from '../src/keyring' import { KeyringTraceFlag } from '../src' chai.use(chaiAsPromised) const { expect } = chai -const never = () => { throw new Error('never') } +const never = () => { + throw new Error('never') +} describe('Keyring', () => { it('can be extended', () => { class TestKeyring extends Keyring { - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { return material } - async _onDecrypt (material: NodeDecryptionMaterial) { + async _onDecrypt(material: NodeDecryptionMaterial) { return material } } @@ -30,51 +35,66 @@ describe('Keyring', () => { }) it('onEncrypt calls _onEncrypt', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const { keyLengthBytes } = suite const m = new NodeEncryptionMaterial(suite, {}) const unencryptedDataKey = new Uint8Array(keyLengthBytes).fill(1) let assertCount = 0 class TestKeyring extends Keyring { - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { expect(material.suite === suite).to.equal(true) expect(material.hasUnencryptedDataKey).to.equal(false) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + } assertCount += 1 return material.setUnencryptedDataKey(unencryptedDataKey, trace) } - async _onDecrypt (material: NodeDecryptionMaterial) { + async _onDecrypt(material: NodeDecryptionMaterial) { never() return material } } - const material = await (new TestKeyring()).onEncrypt(m) + const material = await new TestKeyring().onEncrypt(m) expect(material === m).to.equal(true) expect(assertCount).to.equal(1) }) it('onDecrypt calls _onDecrypt', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'i', encryptedDataKey: new Uint8Array(3) }) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'i', + encryptedDataKey: new Uint8Array(3), + }) const encryptionContext = { some: 'context' } const material = new NodeDecryptionMaterial(suite, encryptionContext) let assertCount = 0 class TestKeyring extends Keyring { - async _onDecrypt (_material: NodeDecryptionMaterial, encryptedDataKeys: EncryptedDataKey[]) { + async _onDecrypt( + _material: NodeDecryptionMaterial, + encryptedDataKeys: EncryptedDataKey[] + ) { expect(_material === material).to.equal(true) expect(encryptedDataKeys[0] === edk).to.equal(true) expect(_material.encryptionContext).to.deep.equal(encryptionContext) assertCount += 1 return _material } - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { never() return material } } - const _material = await (new TestKeyring()).onDecrypt(material, [edk]) + const _material = await new TestKeyring().onDecrypt(material, [edk]) expect(material === _material).to.equal(true) expect(assertCount).to.equal(1) }) @@ -84,35 +104,37 @@ describe('Keyring: onEncrypt', () => { it('Precondition: material must be a type of isEncryptionMaterial.', async () => { let assertCount = 0 class TestKeyring extends Keyring { - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { assertCount += 1 return material } - async _onDecrypt (material: NodeDecryptionMaterial) { + async _onDecrypt(material: NodeDecryptionMaterial) { never() return material } } const material: any = {} - await expect((new TestKeyring()).onEncrypt(material)).to.rejectedWith(Error) + await expect(new TestKeyring().onEncrypt(material)).to.rejectedWith(Error) expect(assertCount).to.equal(0) }) it('Postcondition: The EncryptionMaterial objects must be the same.', async () => { let assertCount = 0 class TestKeyring extends Keyring { - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { assertCount += 1 return new NodeEncryptionMaterial(material.suite, {}) } - async _onDecrypt (material: NodeDecryptionMaterial) { + async _onDecrypt(material: NodeDecryptionMaterial) { never() return material } } - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) - await expect((new TestKeyring()).onEncrypt(material)).to.rejectedWith(Error) + await expect(new TestKeyring().onEncrypt(material)).to.rejectedWith(Error) expect(assertCount).to.equal(1) }) }) @@ -120,81 +142,115 @@ describe('Keyring: onEncrypt', () => { describe('Keyring: onDecrypt', () => { it('Precondition: material must be DecryptionMaterial.', async () => { const material: any = {} - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'i', encryptedDataKey: new Uint8Array(3) }) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'i', + encryptedDataKey: new Uint8Array(3), + }) let assertCount = 0 class TestKeyring extends Keyring { - async _onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { + async _onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { assertCount += 1 return material } - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { never() return material } } - await expect((new TestKeyring()).onDecrypt(material, [edk])).to.rejectedWith(Error) + await expect(new TestKeyring().onDecrypt(material, [edk])).to.rejectedWith( + Error + ) expect(assertCount).to.equal(0) }) it('Precondition: Attempt to decrypt iif material does not have an unencrypted data key.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeDecryptionMaterial(suite, {}) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes).fill(1) - const trace = { keyNamespace: 'k', keyName: 'k', flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY } + const trace = { + keyNamespace: 'k', + keyName: 'k', + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + } material.setUnencryptedDataKey(unencryptedDataKey, trace) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'i', encryptedDataKey: new Uint8Array(3) }) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'i', + encryptedDataKey: new Uint8Array(3), + }) let assertCount = 0 class TestKeyring extends Keyring { - async _onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { + async _onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { assertCount += 1 return material } - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { never() return material } } - const _material = await (new TestKeyring()).onDecrypt(material, [edk]) + const _material = await new TestKeyring().onDecrypt(material, [edk]) expect(assertCount).to.equal(0) expect(_material === material).to.equal(true) }) it('Precondition: encryptedDataKeys must all be EncryptedDataKey.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeDecryptionMaterial(suite, {}) const edk: any = {} let assertCount = 0 class TestKeyring extends Keyring { - async _onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { + async _onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { assertCount += 1 return material } - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { never() return material } } - await expect((new TestKeyring()).onDecrypt(material, [edk])).to.rejectedWith(Error) + await expect(new TestKeyring().onDecrypt(material, [edk])).to.rejectedWith( + Error + ) expect(assertCount).to.equal(0) }) it('Postcondition: The DecryptionMaterial objects must be the same.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeDecryptionMaterial(suite, {}) - const edk = new EncryptedDataKey({ providerId: 'p', providerInfo: 'i', encryptedDataKey: new Uint8Array(3) }) + const edk = new EncryptedDataKey({ + providerId: 'p', + providerInfo: 'i', + encryptedDataKey: new Uint8Array(3), + }) let assertCount = 0 class TestKeyring extends Keyring { - async _onDecrypt (/* material: NodeDecryptionMaterial , encryptedDataKeys: EncryptedDataKey[] */) { + async _onDecrypt(/* material: NodeDecryptionMaterial , encryptedDataKeys: EncryptedDataKey[] */) { assertCount += 1 const _material: any = {} return _material } - async _onEncrypt (material: NodeEncryptionMaterial) { + async _onEncrypt(material: NodeEncryptionMaterial) { never() return material } } - await expect((new TestKeyring()).onDecrypt(material, [edk])).to.rejectedWith(Error) + await expect(new TestKeyring().onDecrypt(material, [edk])).to.rejectedWith( + Error + ) expect(assertCount).to.equal(1) }) }) diff --git a/modules/material-management/test/multi_keyring.test.ts b/modules/material-management/test/multi_keyring.test.ts index aaac7d63b..f4c7e7cbd 100644 --- a/modules/material-management/test/multi_keyring.test.ts +++ b/modules/material-management/test/multi_keyring.test.ts @@ -7,16 +7,22 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { MultiKeyringNode } from '../src/multi_keyring' import { KeyringNode, KeyringWebCrypto } from '../src/keyring' -import { NodeEncryptionMaterial, NodeDecryptionMaterial, unwrapDataKey } from '../src/cryptographic_material' +import { + NodeEncryptionMaterial, + NodeDecryptionMaterial, + unwrapDataKey, +} from '../src/cryptographic_material' import { NodeAlgorithmSuite } from '../src/node_algorithms' import { AlgorithmSuiteIdentifier } from '../src/algorithm_suites' import { EncryptedDataKey } from '../src/encrypted_data_key' -import { KeyringTraceFlag, KeyringTrace } from '../src/keyring_trace' // eslint-disable-line no-unused-vars +import { KeyringTraceFlag, KeyringTrace } from '../src/keyring_trace' chai.use(chaiAsPromised) const { expect } = chai -const never = async () => { throw new Error('never') } +const never = async () => { + throw new Error('never') +} describe('MultiKeyring: Creating', () => { it('Precondition: MultiKeyring must have keyrings.', () => { @@ -62,15 +68,17 @@ describe('MultiKeyring: Creating', () => { expect(() => new MultiKeyringNode({ generator: {} as any })).to.throw() const testClass = new (class extends KeyringWebCrypto { - _onEncrypt () { + _onEncrypt() { return {} as any } - _onDecrypt () { + _onDecrypt() { return {} as any } })() - expect(() => new MultiKeyringNode({ generator: testClass as any })).to.throw() + expect( + () => new MultiKeyringNode({ generator: testClass as any }) + ).to.throw() }) it('can not create with a child that does not look like a KeyRing', () => { @@ -84,30 +92,40 @@ describe('MultiKeyring: Creating', () => { expect(() => new MultiKeyringNode({ children: [{} as any] })).to.throw() const testClass = new (class extends KeyringWebCrypto { - _onEncrypt () { + _onEncrypt() { return {} as any } - _onDecrypt () { + _onDecrypt() { return {} as any } })() - expect(() => new MultiKeyringNode({ children: [testClass as any] })).to.throw() + expect( + () => new MultiKeyringNode({ children: [testClass as any] }) + ).to.throw() }) }) describe('MultiKeyring: onEncrypt', () => { it('calls generator.onEncrypt', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForEncrypt(0) const generator = keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { + async onEncrypt(material: NodeEncryptionMaterial) { return material - .setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) - .addEncryptedDataKey(edk0, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .setUnencryptedDataKey( + new Uint8Array(unencryptedDataKey), + keyringTrace0 + ) + .addEncryptedDataKey( + edk0, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) }, - onDecrypt: never + onDecrypt: never, }) const mkeyring = new MultiKeyringNode({ generator }) @@ -122,29 +140,42 @@ describe('MultiKeyring: onEncrypt', () => { expect(test.keyringTrace[0] === keyringTrace0).to.equal(true) // Make sure the unencrypted data key match - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(unencryptedDataKey) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + unencryptedDataKey + ) }) it('calls generator then child keyrings', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForEncrypt(0) const [edk1] = makeEDKandTraceForEncrypt(1) const generator = keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { + async onEncrypt(material: NodeEncryptionMaterial) { return material - .setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) - .addEncryptedDataKey(edk0, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + .setUnencryptedDataKey( + new Uint8Array(unencryptedDataKey), + keyringTrace0 + ) + .addEncryptedDataKey( + edk0, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) }, - onDecrypt: never + onDecrypt: never, }) const children = [ keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { - return material.addEncryptedDataKey(edk1, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + async onEncrypt(material: NodeEncryptionMaterial) { + return material.addEncryptedDataKey( + edk1, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) }, - onDecrypt: never - }) + onDecrypt: never, + }), ] const mkeyring = new MultiKeyringNode({ generator, children }) @@ -159,70 +190,98 @@ describe('MultiKeyring: onEncrypt', () => { expect(test.keyringTrace).to.be.an('Array').with.lengthOf(3) // Make sure the unencrypted data key match - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(unencryptedDataKey) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + unencryptedDataKey + ) }) it('Precondition: A Generator Keyring *must* ensure generated material.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const [, keyringTrace0] = makeEDKandTraceForEncrypt(0) const generator = keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { + async onEncrypt(material: NodeEncryptionMaterial) { material.keyringTrace.push(keyringTrace0) return material }, - onDecrypt: never + onDecrypt: never, }) const mkeyring = new MultiKeyringNode({ generator }) const material = new NodeEncryptionMaterial(suite, {}) - await expect(mkeyring.onEncrypt(material)).to.rejectedWith(Error, 'Generator Keyring has not generated material.') + await expect(mkeyring.onEncrypt(material)).to.rejectedWith( + Error, + 'Generator Keyring has not generated material.' + ) }) it('Precondition: Only Keyrings explicitly designated as generators can generate material.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const child = keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { + async onEncrypt(material: NodeEncryptionMaterial) { return material }, - onDecrypt: never + onDecrypt: never, }) - const mkeyring = new MultiKeyringNode({ children: [ child ] }) + const mkeyring = new MultiKeyringNode({ children: [child] }) const material = new NodeEncryptionMaterial(suite, {}) - return expect(mkeyring.onEncrypt(material)).to.rejectedWith(Error, 'Only Keyrings explicitly designated as generators can generate material.') + return expect(mkeyring.onEncrypt(material)).to.rejectedWith( + Error, + 'Only Keyrings explicitly designated as generators can generate material.' + ) }) it('Generator Keyrings do not *have* to generate material if material already exists', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForEncrypt(0) const generator = keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { - return material.addEncryptedDataKey(edk0, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + async onEncrypt(material: NodeEncryptionMaterial) { + return material.addEncryptedDataKey( + edk0, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) }, - onDecrypt: never + onDecrypt: never, }) const mkeyring = new MultiKeyringNode({ generator }) - const material = new NodeEncryptionMaterial(suite, {}).setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) + const material = new NodeEncryptionMaterial( + suite, + {} + ).setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) await mkeyring.onEncrypt(material) }) it('If material already exists, you do not need a generator.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForEncrypt(0) const child = keyRingFactory({ - async onEncrypt (material: NodeEncryptionMaterial) { - return material.addEncryptedDataKey(edk0, KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY) + async onEncrypt(material: NodeEncryptionMaterial) { + return material.addEncryptedDataKey( + edk0, + KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY + ) }, - onDecrypt: never + onDecrypt: never, }) - const mkeyring = new MultiKeyringNode({ children: [ child ] }) - const material = new NodeEncryptionMaterial(suite, {}).setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) + const mkeyring = new MultiKeyringNode({ children: [child] }) + const material = new NodeEncryptionMaterial( + suite, + {} + ).setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) await mkeyring.onEncrypt(material) }) @@ -230,16 +289,23 @@ describe('MultiKeyring: onEncrypt', () => { describe('MultiKeyring: onDecrypt', () => { it('calls generator.onDecrypt', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForDecrypt(0) const material = new NodeDecryptionMaterial(suite, {}) const generator = keyRingFactory({ - async onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { - return material.setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) + async onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { + return material.setUnencryptedDataKey( + new Uint8Array(unencryptedDataKey), + keyringTrace0 + ) }, - onEncrypt: never + onEncrypt: never, }) const mkeyring = new MultiKeyringNode({ generator }) @@ -250,20 +316,29 @@ describe('MultiKeyring: onDecrypt', () => { expect(test.keyringTrace[0] === keyringTrace0).to.equal(true) // Make sure the unencrypted data key match - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(unencryptedDataKey) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + unencryptedDataKey + ) }) it('calls children.onDecrypt', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForDecrypt(0) const material = new NodeDecryptionMaterial(suite, {}) const child = keyRingFactory({ - async onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { - return material.setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) + async onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { + return material.setUnencryptedDataKey( + new Uint8Array(unencryptedDataKey), + keyringTrace0 + ) }, - onEncrypt: never + onEncrypt: never, }) const mkeyring = new MultiKeyringNode({ children: [child] }) @@ -274,28 +349,37 @@ describe('MultiKeyring: onDecrypt', () => { expect(test.keyringTrace[0] === keyringTrace0).to.equal(true) // Make sure the unencrypted data key match - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(unencryptedDataKey) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + unencryptedDataKey + ) }) it('Check for early return (Postcondition): Do not attempt to decrypt once I have a valid key.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForDecrypt(0) const material = new NodeDecryptionMaterial(suite, {}) const child = keyRingFactory({ - async onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { - return material.setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) + async onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { + return material.setUnencryptedDataKey( + new Uint8Array(unencryptedDataKey), + keyringTrace0 + ) }, - onEncrypt: never + onEncrypt: never, }) let notCalled = true const childNotCalled = keyRingFactory({ - async onDecrypt () { + async onDecrypt() { notCalled = false }, - onEncrypt: never + onEncrypt: never, }) const children = [child, childNotCalled] @@ -307,30 +391,39 @@ describe('MultiKeyring: onDecrypt', () => { expect(test.keyringTrace[0] === keyringTrace0).to.equal(true) // Make sure the unencrypted data key match - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(unencryptedDataKey) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + unencryptedDataKey + ) expect(notCalled).to.equal(true) }) it('will call subsequent Keyrings after errors', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const unencryptedDataKey = new Uint8Array(suite.keyLengthBytes) const [edk0, keyringTrace0] = makeEDKandTraceForDecrypt(0) const material = new NodeDecryptionMaterial(suite, {}) const child = keyRingFactory({ - async onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { - return material.setUnencryptedDataKey(new Uint8Array(unencryptedDataKey), keyringTrace0) + async onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { + return material.setUnencryptedDataKey( + new Uint8Array(unencryptedDataKey), + keyringTrace0 + ) }, - onEncrypt: never + onEncrypt: never, }) let called = false const childNotSucceeded = keyRingFactory({ - async onDecrypt () { + async onDecrypt() { // Because this keyring does not return a value, it will result in an error called = true }, - onEncrypt: never + onEncrypt: never, }) const children = [childNotSucceeded, child] @@ -342,70 +435,94 @@ describe('MultiKeyring: onDecrypt', () => { expect(test.keyringTrace[0] === keyringTrace0).to.equal(true) // Make sure the unencrypted data key match - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(unencryptedDataKey) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + unencryptedDataKey + ) expect(called).to.equal(true) }) it('Postcondition: A child keyring must provide a valid data key or no child keyring must have raised an error.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const [edk0] = makeEDKandTraceForDecrypt(0) const material = new NodeDecryptionMaterial(suite, {}) const childNotSucceeded = keyRingFactory({ - async onDecrypt () { + async onDecrypt() { // Because this keyring does not return a value, it will result in an error }, - onEncrypt: never + onEncrypt: never, }) const children = [childNotSucceeded] const mkeyring = new MultiKeyringNode({ children }) - await expect(mkeyring.onDecrypt(material, [edk0])).to.rejectedWith(Error, 'Unable to decrypt data key and one or more child keyrings had an error.') + await expect(mkeyring.onDecrypt(material, [edk0])).to.rejectedWith( + Error, + 'Unable to decrypt data key and one or more child keyrings had an error.' + ) /* This will make the decrypt loop not have an error. * This will exercise the `(!material.hasValidKey() && !childKeyringErrors.length)` `needs` condition. */ const childNoDataKey = keyRingFactory({ - async onDecrypt (material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */) { + async onDecrypt( + material: NodeDecryptionMaterial /*, encryptedDataKeys: EncryptedDataKey[] */ + ) { return material }, - onEncrypt: never + onEncrypt: never, }) - const mkeyringNoErrors = new MultiKeyringNode({ children: [ childNoDataKey ] }) + const mkeyringNoErrors = new MultiKeyringNode({ + children: [childNoDataKey], + }) - await expect(mkeyringNoErrors.onDecrypt(material, [edk0])).to.not.rejectedWith(Error) + await expect( + mkeyringNoErrors.onDecrypt(material, [edk0]) + ).to.not.rejectedWith(Error) }) }) -function makeEDKandTraceForEncrypt (num: number): [EncryptedDataKey, KeyringTrace] { +function makeEDKandTraceForEncrypt( + num: number +): [EncryptedDataKey, KeyringTrace] { return makeEDKandTrace(num, KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) } -function makeEDKandTraceForDecrypt (num: number): [EncryptedDataKey, KeyringTrace] { +function makeEDKandTraceForDecrypt( + num: number +): [EncryptedDataKey, KeyringTrace] { return makeEDKandTrace(num, KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) } -function makeEDKandTrace (num: number, flags: KeyringTraceFlag): [EncryptedDataKey, KeyringTrace] { +function makeEDKandTrace( + num: number, + flags: KeyringTraceFlag +): [EncryptedDataKey, KeyringTrace] { const providerId = 'providerId' + num const providerInfo = 'providerInfo' + num const encryptedDataKey = new Uint8Array([0, 0, 0]).fill(num) - const edk = new EncryptedDataKey({ providerId, providerInfo, encryptedDataKey }) + const edk = new EncryptedDataKey({ + providerId, + providerInfo, + encryptedDataKey, + }) const keyringTrace = { keyNamespace: providerId, keyName: providerInfo, - flags + flags, } return [edk, keyringTrace] } -type factoryOp = {onEncrypt: any, onDecrypt: any} -function keyRingFactory ({ onEncrypt, onDecrypt }: factoryOp): KeyringNode { +type factoryOp = { onEncrypt: any; onDecrypt: any } +function keyRingFactory({ onEncrypt, onDecrypt }: factoryOp): KeyringNode { return new (class extends KeyringNode { - _onEncrypt (...args: any[]) { + _onEncrypt(...args: any[]) { return onEncrypt.call(this, ...args) } - _onDecrypt (...args: any[]) { + _onDecrypt(...args: any[]) { return onDecrypt.call(this, ...args) } })() diff --git a/modules/material-management/test/node_algorithms.test.ts b/modules/material-management/test/node_algorithms.test.ts index 980b9d351..74e489bae 100644 --- a/modules/material-management/test/node_algorithms.test.ts +++ b/modules/material-management/test/node_algorithms.test.ts @@ -9,7 +9,9 @@ import { NodeAlgorithmSuite } from '../src/node_algorithms' describe('NodeAlgorithmSuite', () => { it('should return WebCryptoAlgorithmSuite', () => { - const test = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const test = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(test).to.be.instanceof(NodeAlgorithmSuite) expect(Object.isFrozen(test)).to.equal(true) }) @@ -19,7 +21,9 @@ describe('NodeAlgorithmSuite', () => { }) it('instance should be frozen', () => { - const test = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const test = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(Object.isFrozen(test)) }) diff --git a/modules/material-management/test/pem_helpers.test.ts b/modules/material-management/test/pem_helpers.test.ts index 680602a49..1191da932 100644 --- a/modules/material-management/test/pem_helpers.test.ts +++ b/modules/material-management/test/pem_helpers.test.ts @@ -15,27 +15,31 @@ describe('chunk64', () => { }) /* Each Base64 digit represents exactly 6 bits of data, - * so to get 64 characters I need 48 Bytes: - * 64 characters = 64*6 bits of data == 384 - * 384 bits of data === 384/8 === 48 Bytes - * - * See: https://tools.ietf.org/html/rfc4648#section-4 - * Each 6-bit group is used as an index into an array of 64 printable - * characters. The character referenced by the index is placed in the - * output string. - */ + * so to get 64 characters I need 48 Bytes: + * 64 characters = 64*6 bits of data == 384 + * 384 bits of data === 384/8 === 48 Bytes + * + * See: https://tools.ietf.org/html/rfc4648#section-4 + * Each 6-bit group is used as an index into an array of 64 printable + * characters. The character referenced by the index is placed in the + * output string. + */ it('returns a single line', () => { const buff = Buffer.alloc(48) const test = chunk64(buff) expect(test).to.be.an('array').and.to.have.lengthOf(1) - expect(test[0]).to.equal('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') + expect(test[0]).to.equal( + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) }) it('returns a new line at the demarcation', () => { const buff = Buffer.alloc(49) const test = chunk64(buff) expect(test).to.be.an('array').and.to.have.lengthOf(2) - expect(test[0]).to.equal('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') + expect(test[0]).to.equal( + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) expect(test[1]).to.equal('AA==') }) @@ -43,17 +47,29 @@ describe('chunk64', () => { const buff = Buffer.alloc(97) const test = chunk64(buff) expect(test).to.be.an('array').and.to.have.lengthOf(3) - expect(test[0]).to.equal('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') - expect(test[1]).to.equal('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') + expect(test[0]).to.equal( + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) + expect(test[1]).to.equal( + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) expect(test[2]).to.equal('AA==') }) }) -const publicPEM = '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuJDriNevbNaMlxogs2hWo4e581BE\nvFOH3ZE6E7EvM2On0+zDd8RGsyg66E6sYNZZYe7lPg/tEz6ZDy0H4dwPaA==\n-----END PUBLIC KEY-----\n' -const privatePEM = '-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAKqZVbQgpM90q+mGBGwi6TWnWrH39Dv386uH421mPfqoAoGCCqGSM49\nAwEHoUQDQgAEuJDriNevbNaMlxogs2hWo4e581BEvFOH3ZE6E7EvM2On0+zDd8RG\nsyg66E6sYNZZYe7lPg/tEz6ZDy0H4dwPaA==\n-----END EC PRIVATE KEY-----\n' +const publicPEM = + '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuJDriNevbNaMlxogs2hWo4e581BE\nvFOH3ZE6E7EvM2On0+zDd8RGsyg66E6sYNZZYe7lPg/tEz6ZDy0H4dwPaA==\n-----END PUBLIC KEY-----\n' +const privatePEM = + '-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAKqZVbQgpM90q+mGBGwi6TWnWrH39Dv386uH421mPfqoAoGCCqGSM49\nAwEHoUQDQgAEuJDriNevbNaMlxogs2hWo4e581BEvFOH3ZE6E7EvM2On0+zDd8RG\nsyg66E6sYNZZYe7lPg/tEz6ZDy0H4dwPaA==\n-----END EC PRIVATE KEY-----\n' const curve = 'prime256v1' -const publicKeyBytes = Buffer.from('04B890EB88D7AF6CD68C971A20B36856A387B9F35044BC5387DD913A13B12F3363A7D3ECC377C446B3283AE84EAC60D65961EEE53E0FED133E990F2D07E1DC0F68', 'hex') -const privateKeyBytes = Buffer.from('02AA6556D082933DD2AFA61811B08BA4D69D6AC7DFD0EFDFCEAE1F8DB598F7EA', 'hex') +const publicKeyBytes = Buffer.from( + '04B890EB88D7AF6CD68C971A20B36856A387B9F35044BC5387DD913A13B12F3363A7D3ECC377C446B3283AE84EAC60D65961EEE53E0FED133E990F2D07E1DC0F68', + 'hex' +) +const privateKeyBytes = Buffer.from( + '02AA6556D082933DD2AFA61811B08BA4D69D6AC7DFD0EFDFCEAE1F8DB598F7EA', + 'hex' +) describe('pem formating', () => { it('convert public key bytes to PEM', () => { diff --git a/modules/material-management/test/signature_key.test.ts b/modules/material-management/test/signature_key.test.ts index 26d1e0adb..cc73679c2 100644 --- a/modules/material-management/test/signature_key.test.ts +++ b/modules/material-management/test/signature_key.test.ts @@ -4,74 +4,200 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { SignatureKey, VerificationKey, AlgorithmSuiteIdentifier, NodeAlgorithmSuite } from '../src' +import { + SignatureKey, + VerificationKey, + AlgorithmSuiteIdentifier, + NodeAlgorithmSuite, +} from '../src' -const prime256v1PublicFixture = [ 4, - 54, 131, 184, 190, 94, 145, 250, 132, 150, 193, - 178, 150, 190, 22, 22, 11, 201, 60, 9, 53, - 128, 68, 120, 118, 83, 106, 52, 226, 143, 155, - 120, 178, 217, 246, 201, 43, 28, 98, 154, 24, - 59, 251, 229, 162, 89, 161, 79, 81, 23, 238, - 208, 108, 15, 209, 56, 91, 237, 38, 60, 72, - 98, 181, 219, 196 ] +const prime256v1PublicFixture = [ + 4, + 54, + 131, + 184, + 190, + 94, + 145, + 250, + 132, + 150, + 193, + 178, + 150, + 190, + 22, + 22, + 11, + 201, + 60, + 9, + 53, + 128, + 68, + 120, + 118, + 83, + 106, + 52, + 226, + 143, + 155, + 120, + 178, + 217, + 246, + 201, + 43, + 28, + 98, + 154, + 24, + 59, + 251, + 229, + 162, + 89, + 161, + 79, + 81, + 23, + 238, + 208, + 108, + 15, + 209, + 56, + 91, + 237, + 38, + 60, + 72, + 98, + 181, + 219, + 196, +] -const prime256v1CompressedFixture = [ 2, - 54, 131, 184, 190, 94, 145, 250, 132, 150, 193, - 178, 150, 190, 22, 22, 11, 201, 60, 9, 53, - 128, 68, 120, 118, 83, 106, 52, 226, 143, 155, - 120, 178 ] +const prime256v1CompressedFixture = [ + 2, + 54, + 131, + 184, + 190, + 94, + 145, + 250, + 132, + 150, + 193, + 178, + 150, + 190, + 22, + 22, + 11, + 201, + 60, + 9, + 53, + 128, + 68, + 120, + 118, + 83, + 106, + 52, + 226, + 143, + 155, + 120, + 178, +] describe('SignatureKey', () => { it('basic usage', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const sigKey = new SignatureKey(new Uint8Array(3), new Uint8Array(3), suite) expect(sigKey).to.haveOwnProperty('privateKey').to.be.a('string') - expect(sigKey).to.haveOwnProperty('compressPoint').to.be.instanceOf(Uint8Array) - expect(sigKey).to.haveOwnProperty('signatureCurve').and.to.equal(suite.signatureCurve) + expect(sigKey) + .to.haveOwnProperty('compressPoint') + .to.be.instanceOf(Uint8Array) + expect(sigKey) + .to.haveOwnProperty('signatureCurve') + .and.to.equal(suite.signatureCurve) }) it('encodeCompressPoint', () => { const publicKey = new Uint8Array(prime256v1PublicFixture) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const compressPoint = SignatureKey.encodeCompressPoint(publicKey, suite) - expect(compressPoint).to.deep.equal(new Uint8Array(prime256v1CompressedFixture)) + expect(compressPoint).to.deep.equal( + new Uint8Array(prime256v1CompressedFixture) + ) }) it('Precondition: Do not create a SignatureKey for an algorithm suite that does not have an EC named curve.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - expect(() => new SignatureKey(new Uint8Array(3), new Uint8Array(3), suite)).to.throw('Unsupported Algorithm') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + expect( + () => new SignatureKey(new Uint8Array(3), new Uint8Array(3), suite) + ).to.throw('Unsupported Algorithm') }) it('Precondition: Do not return a compress point for an algorithm suite that does not have an EC named curve.', () => { const publicKey = new Uint8Array(prime256v1PublicFixture) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - expect(() => SignatureKey.encodeCompressPoint(publicKey, suite)).to.throw('Unsupported Algorithm') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + expect(() => SignatureKey.encodeCompressPoint(publicKey, suite)).to.throw( + 'Unsupported Algorithm' + ) }) }) describe('VerificationKey', () => { it('basic usage', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const verKey = new VerificationKey(new Uint8Array(3), suite) expect(verKey).to.haveOwnProperty('publicKey').to.be.a('string') - expect(verKey).to.haveOwnProperty('signatureCurve').and.to.equal(suite.signatureCurve) + expect(verKey) + .to.haveOwnProperty('signatureCurve') + .and.to.equal(suite.signatureCurve) }) it('decodeCompressPoint', () => { const compressPoint = new Uint8Array(prime256v1CompressedFixture) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 + ) const publicKey = VerificationKey.decodeCompressPoint(compressPoint, suite) expect(publicKey).to.deep.equal(new Uint8Array(prime256v1PublicFixture)) }) it('Precondition: Do not create a VerificationKey for an algorithm suite that does not have an EC named curve.', () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - expect(() => new VerificationKey(new Uint8Array(3), suite)).to.throw('Unsupported Algorithm') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + expect(() => new VerificationKey(new Uint8Array(3), suite)).to.throw( + 'Unsupported Algorithm' + ) }) it('Precondition: Do not decode a public key for an algorithm suite that does not have an EC named curve.', () => { const compressPoint = new Uint8Array(prime256v1CompressedFixture) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) - expect(() => VerificationKey.decodeCompressPoint(compressPoint, suite)).to.throw('Unsupported Algorithm') + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) + expect(() => + VerificationKey.decodeCompressPoint(compressPoint, suite) + ).to.throw('Unsupported Algorithm') }) }) diff --git a/modules/material-management/test/web_crypto_algorithms.test.ts b/modules/material-management/test/web_crypto_algorithms.test.ts index 33bd180f6..b22c3cb29 100644 --- a/modules/material-management/test/web_crypto_algorithms.test.ts +++ b/modules/material-management/test/web_crypto_algorithms.test.ts @@ -9,7 +9,9 @@ import { WebCryptoAlgorithmSuite } from '../src/web_crypto_algorithms' describe('WebCryptoAlgorithmSuite', () => { it('should return WebCryptoAlgorithmSuite', () => { - const test = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const test = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(test).to.be.instanceof(WebCryptoAlgorithmSuite) expect(Object.isFrozen(test)).to.equal(true) }) @@ -19,7 +21,9 @@ describe('WebCryptoAlgorithmSuite', () => { }) it('instance should be immutable', () => { - const test = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const test = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(Object.isFrozen(test)).to.equal(true) }) @@ -29,8 +33,23 @@ describe('WebCryptoAlgorithmSuite', () => { }) it('Precondition: Browsers do not support 192 bit keys so the AlgorithmSuiteIdentifier is removed.', () => { - expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16)).to.throw() - expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256)).to.throw() - expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384)).to.throw() + expect( + () => + new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16 + ) + ).to.throw() + expect( + () => + new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256 + ) + ).to.throw() + expect( + () => + new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + ).to.throw() }) }) diff --git a/modules/raw-aes-keyring-browser/test/raw_aes_keyring_browser.test.ts b/modules/raw-aes-keyring-browser/test/raw_aes_keyring_browser.test.ts index b685ed701..68ad37051 100644 --- a/modules/raw-aes-keyring-browser/test/raw_aes_keyring_browser.test.ts +++ b/modules/raw-aes-keyring-browser/test/raw_aes_keyring_browser.test.ts @@ -5,13 +5,16 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { RawAesKeyringWebCrypto, RawAesWrappingSuiteIdentifier } from '../src/index' +import { + RawAesKeyringWebCrypto, + RawAesWrappingSuiteIdentifier, +} from '../src/index' import { WebCryptoEncryptionMaterial, WebCryptoAlgorithmSuite, AlgorithmSuiteIdentifier, - EncryptedDataKey, // eslint-disable-line no-unused-vars - WebCryptoDecryptionMaterial + EncryptedDataKey, + WebCryptoDecryptionMaterial, } from '@aws-crypto/material-management-browser' chai.use(chaiAsPromised) @@ -20,29 +23,42 @@ const { expect } = chai declare const CryptoKey: CryptoKey describe('importCryptoKey', () => { it('returns CryptoKey', async () => { - const suiteId = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const suiteId = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const udk = new Uint8Array(128 / 8) const cryptoKey = await RawAesKeyringWebCrypto.importCryptoKey(udk, suiteId) expect(cryptoKey).to.be.instanceOf(CryptoKey) }) it('Precondition: masterKey must correspond to the algorithm suite specification.', async () => { - const suiteId = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const suiteId = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const notValidLength = new Uint8Array(10) - expect(RawAesKeyringWebCrypto.importCryptoKey(notValidLength, suiteId)).to.rejectedWith(Error) + await expect( + RawAesKeyringWebCrypto.importCryptoKey(notValidLength, suiteId) + ).to.rejectedWith(Error) }) }) describe('RawAesKeyringWebCrypto::constructor', () => { - const wrappingSuite = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const wrappingSuite = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const udk = new Uint8Array(128 / 8) const keyNamespace = 'keyNamespace' const keyName = 'keyName' it('constructor decorates', async () => { - const masterKey = await RawAesKeyringWebCrypto.importCryptoKey(udk, wrappingSuite) - const test = new RawAesKeyringWebCrypto({ keyName, keyNamespace, masterKey, wrappingSuite }) + const masterKey = await RawAesKeyringWebCrypto.importCryptoKey( + udk, + wrappingSuite + ) + const test = new RawAesKeyringWebCrypto({ + keyName, + keyNamespace, + masterKey, + wrappingSuite, + }) expect(test.keyName).to.equal(keyName) expect(test.keyNamespace).to.equal(keyNamespace) expect(test._wrapKey).to.be.a('function') @@ -50,50 +66,82 @@ describe('RawAesKeyringWebCrypto::constructor', () => { }) it('Precondition: AesKeyringWebCrypto needs identifying information for encrypt and decrypt.', async () => { - const masterKey = await RawAesKeyringWebCrypto.importCryptoKey(udk, wrappingSuite) - // @ts-ignore doing something typescript protects us from doing...s - expect(() => new RawAesKeyringWebCrypto({ keyNamespace, masterKey, wrappingSuite })).to.throw() - // @ts-ignore doing something typescript protects us from doing...s - expect(() => new RawAesKeyringWebCrypto({ keyName, masterKey, wrappingSuite })).to.throw() + const masterKey = await RawAesKeyringWebCrypto.importCryptoKey( + udk, + wrappingSuite + ) + expect( + () => + new RawAesKeyringWebCrypto({ + keyNamespace, + masterKey, + wrappingSuite, + } as any) + ).to.throw() + expect( + () => + new RawAesKeyringWebCrypto({ keyName, masterKey, wrappingSuite } as any) + ).to.throw() }) it('Precondition: RawAesKeyringWebCrypto requires a wrappingSuite to be a valid RawAesWrappingSuite.', async () => { - const masterKey = await RawAesKeyringWebCrypto.importCryptoKey(udk, wrappingSuite) - expect(() => new RawAesKeyringWebCrypto({ - keyName, - keyNamespace, - masterKey, - wrappingSuite: 111 as any - })).to.throw() + const masterKey = await RawAesKeyringWebCrypto.importCryptoKey( + udk, + wrappingSuite + ) + expect( + () => + new RawAesKeyringWebCrypto({ + keyName, + keyNamespace, + masterKey, + wrappingSuite: 111 as any, + }) + ).to.throw() }) it('Precondition: unencryptedMasterKey must correspond to the WebCryptoAlgorithmSuite specification.', async () => { - const masterKey = await RawAesKeyringWebCrypto - .importCryptoKey(udk, wrappingSuite) - expect(() => new RawAesKeyringWebCrypto({ - keyName, - keyNamespace, - masterKey, - wrappingSuite: RawAesWrappingSuiteIdentifier.AES192_GCM_IV12_TAG16_NO_PADDING - })).to.throw() + const masterKey = await RawAesKeyringWebCrypto.importCryptoKey( + udk, + wrappingSuite + ) + expect( + () => + new RawAesKeyringWebCrypto({ + keyName, + keyNamespace, + masterKey, + wrappingSuite: + RawAesWrappingSuiteIdentifier.AES192_GCM_IV12_TAG16_NO_PADDING, + }) + ).to.throw() }) }) describe('RawAesKeyringWebCrypto::_filter', () => { - const wrappingSuite = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const wrappingSuite = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const udk = new Uint8Array(128 / 8) const keyNamespace = 'keyNamespace' const keyName = 'keyName' let keyring: RawAesKeyringWebCrypto before(async () => { - const masterKey = await RawAesKeyringWebCrypto.importCryptoKey(udk, wrappingSuite) - keyring = new RawAesKeyringWebCrypto({ keyName, keyNamespace, masterKey, wrappingSuite }) + const masterKey = await RawAesKeyringWebCrypto.importCryptoKey( + udk, + wrappingSuite + ) + keyring = new RawAesKeyringWebCrypto({ + keyName, + keyNamespace, + masterKey, + wrappingSuite, + }) }) it('true', async () => { const test = keyring._filter({ providerId: keyNamespace, - providerInfo: keyName + providerInfo: keyName, } as any) expect(test).to.equal(true) }) @@ -101,38 +149,53 @@ describe('RawAesKeyringWebCrypto::_filter', () => { it('true', async () => { const test = keyring._filter({ providerId: keyNamespace, - providerInfo: keyName + 'other stuff' + providerInfo: keyName + 'other stuff', } as any) expect(test).to.equal(true) }) it('false', async () => { - expect(keyring._filter({ - providerId: 'not: keyNamespace', - providerInfo: keyName + 'other stuff' - } as any)).to.equal(false) - - expect(keyring._filter({ - providerId: keyNamespace, - providerInfo: 'not: keyName' - } as any)).to.equal(false) + expect( + keyring._filter({ + providerId: 'not: keyNamespace', + providerInfo: keyName + 'other stuff', + } as any) + ).to.equal(false) + + expect( + keyring._filter({ + providerId: keyNamespace, + providerInfo: 'not: keyName', + } as any) + ).to.equal(false) }) }) describe('RawAesKeyringWebCrypto encrypt/decrypt', () => { - const wrappingSuite = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const wrappingSuite = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const masterUdk = new Uint8Array(128 / 8) const keyNamespace = 'keyNamespace' const keyName = 'keyName' let keyring: RawAesKeyringWebCrypto let encryptedDataKey: EncryptedDataKey before(async () => { - const masterKey = await RawAesKeyringWebCrypto.importCryptoKey(masterUdk, wrappingSuite) - keyring = new RawAesKeyringWebCrypto({ keyName, keyNamespace, masterKey, wrappingSuite }) + const masterKey = await RawAesKeyringWebCrypto.importCryptoKey( + masterUdk, + wrappingSuite + ) + keyring = new RawAesKeyringWebCrypto({ + keyName, + keyNamespace, + masterKey, + wrappingSuite, + }) }) it('can encrypt and create unencrypted data key', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const test = await keyring.onEncrypt(material) expect(test.hasValidKey()).to.equal(true) @@ -145,7 +208,9 @@ describe('RawAesKeyringWebCrypto encrypt/decrypt', () => { }) it('can decrypt an EncryptedDataKey', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) const test = await keyring.onDecrypt(material, [encryptedDataKey]) expect(test.hasValidKey()).to.equal(true) diff --git a/modules/raw-aes-keyring-node/test/raw_aes_keyring_node.test.ts b/modules/raw-aes-keyring-node/test/raw_aes_keyring_node.test.ts index 6859efccf..a76de9a59 100644 --- a/modules/raw-aes-keyring-node/test/raw_aes_keyring_node.test.ts +++ b/modules/raw-aes-keyring-node/test/raw_aes_keyring_node.test.ts @@ -10,22 +10,28 @@ import { NodeEncryptionMaterial, NodeAlgorithmSuite, AlgorithmSuiteIdentifier, - EncryptedDataKey, // eslint-disable-line no-unused-vars + EncryptedDataKey, NodeDecryptionMaterial, - unwrapDataKey + unwrapDataKey, } from '@aws-crypto/material-management-node' chai.use(chaiAsPromised) const { expect } = chai describe('RawAesKeyringNode::constructor', () => { - const wrappingSuite = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const wrappingSuite = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const unencryptedMasterKey = new Uint8Array(128 / 8) const keyNamespace = 'keyNamespace' const keyName = 'keyName' it('constructor decorates', async () => { - const test = new RawAesKeyringNode({ keyName, keyNamespace, unencryptedMasterKey, wrappingSuite }) + const test = new RawAesKeyringNode({ + keyName, + keyNamespace, + unencryptedMasterKey, + wrappingSuite, + }) expect(test.keyName).to.equal(keyName) expect(test.keyNamespace).to.equal(keyNamespace) expect(test._wrapKey).to.be.a('function') @@ -33,42 +39,67 @@ describe('RawAesKeyringNode::constructor', () => { }) it('Precondition: AesKeyringNode needs identifying information for encrypt and decrypt.', async () => { - // @ts-ignore doing something typescript protects us from doing... - expect(() => new RawAesKeyringNode({ keyNamespace, unencryptedMasterKey, wrappingSuite })).to.throw() - // @ts-ignore doing something typescript protects us from doing... - expect(() => new RawAesKeyringNode({ keyName, unencryptedMasterKey, wrappingSuite })).to.throw() + expect( + () => + new RawAesKeyringNode({ + keyNamespace, + unencryptedMasterKey, + wrappingSuite, + } as any) + ).to.throw() + expect( + () => + new RawAesKeyringNode({ + keyName, + unencryptedMasterKey, + wrappingSuite, + } as any) + ).to.throw() }) it('Precondition: RawAesKeyringNode requires wrappingSuite to be a valid RawAesWrappingSuite.', async () => { - expect(() => new RawAesKeyringNode({ - keyName, - keyNamespace, - unencryptedMasterKey, - wrappingSuite: 111 as any - })).to.throw() + expect( + () => + new RawAesKeyringNode({ + keyName, + keyNamespace, + unencryptedMasterKey, + wrappingSuite: 111 as any, + }) + ).to.throw() }) it('Precondition: unencryptedMasterKey must correspond to the NodeAlgorithmSuite specification.', async () => { - expect(() => new RawAesKeyringNode({ - keyName, - keyNamespace, - unencryptedMasterKey, - wrappingSuite: RawAesWrappingSuiteIdentifier.AES192_GCM_IV12_TAG16_NO_PADDING - })).to.throw() + expect( + () => + new RawAesKeyringNode({ + keyName, + keyNamespace, + unencryptedMasterKey, + wrappingSuite: + RawAesWrappingSuiteIdentifier.AES192_GCM_IV12_TAG16_NO_PADDING, + }) + ).to.throw() }) }) describe('RawAesKeyringNode::_filter', () => { - const wrappingSuite = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const wrappingSuite = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const unencryptedMasterKey = new Uint8Array(128 / 8) const keyNamespace = 'keyNamespace' const keyName = 'keyName' - const keyring = new RawAesKeyringNode({ keyName, keyNamespace, unencryptedMasterKey, wrappingSuite }) + const keyring = new RawAesKeyringNode({ + keyName, + keyNamespace, + unencryptedMasterKey, + wrappingSuite, + }) it('true', async () => { const test = keyring._filter({ providerId: keyNamespace, - providerInfo: keyName + providerInfo: keyName, } as any) expect(test).to.equal(true) }) @@ -76,34 +107,46 @@ describe('RawAesKeyringNode::_filter', () => { it('true', async () => { const test = keyring._filter({ providerId: keyNamespace, - providerInfo: keyName + 'other stuff' + providerInfo: keyName + 'other stuff', } as any) expect(test).to.equal(true) }) it('false', async () => { - expect(keyring._filter({ - providerId: 'not: keyNamespace', - providerInfo: keyName + 'other stuff' - } as any)).to.equal(false) - - expect(keyring._filter({ - providerId: keyNamespace, - providerInfo: 'not: keyName' - } as any)).to.equal(false) + expect( + keyring._filter({ + providerId: 'not: keyNamespace', + providerInfo: keyName + 'other stuff', + } as any) + ).to.equal(false) + + expect( + keyring._filter({ + providerId: keyNamespace, + providerInfo: 'not: keyName', + } as any) + ).to.equal(false) }) }) describe('RawAesKeyringNode encrypt/decrypt', () => { - const wrappingSuite = RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING + const wrappingSuite = + RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING const unencryptedMasterKey = new Uint8Array(128 / 8) const keyNamespace = 'keyNamespace' const keyName = 'keyName' - const keyring = new RawAesKeyringNode({ keyName, keyNamespace, unencryptedMasterKey, wrappingSuite }) + const keyring = new RawAesKeyringNode({ + keyName, + keyNamespace, + unencryptedMasterKey, + wrappingSuite, + }) let encryptedDataKey: EncryptedDataKey it('can encrypt and create unencrypted data key', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new NodeEncryptionMaterial(suite, {}) const test = await keyring.onEncrypt(material) expect(test.hasValidKey()).to.equal(true) @@ -116,7 +159,9 @@ describe('RawAesKeyringNode encrypt/decrypt', () => { }) it('can decrypt an EncryptedDataKey', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new NodeDecryptionMaterial(suite, {}) const test = await keyring.onDecrypt(material, [encryptedDataKey]) expect(test.hasValidKey()).to.equal(true) diff --git a/modules/raw-keyring/test/raw_aes_encrypted_data_keys.test.ts b/modules/raw-keyring/test/raw_aes_encrypted_data_keys.test.ts index 1baf04b60..ede80da48 100644 --- a/modules/raw-keyring/test/raw_aes_encrypted_data_keys.test.ts +++ b/modules/raw-keyring/test/raw_aes_encrypted_data_keys.test.ts @@ -4,28 +4,59 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { rawAesEncryptedDataKeyFactory, rawAesEncryptedPartsFactory } from '../src/raw_aes_encrypted_data_keys' -import { EncryptedDataKey, NodeAlgorithmSuite, AlgorithmSuiteIdentifier } from '@aws-crypto/material-management' +import { + rawAesEncryptedDataKeyFactory, + rawAesEncryptedPartsFactory, +} from '../src/raw_aes_encrypted_data_keys' +import { + EncryptedDataKey, + NodeAlgorithmSuite, + AlgorithmSuiteIdentifier, +} from '@aws-crypto/material-management' const keyNamespace = 'keyNamespace' const keyName = 'keyName' const keyNameFromUtf8 = new Uint8Array([107, 101, 121, 78, 97, 109, 101]) const iv = new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) -const ciphertext = new Uint8Array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) +const ciphertext = new Uint8Array([ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, +]) const authTag = new Uint8Array([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]) -const compoundString = keyName + '\u0000\u0000\u0000�\u0000\u0000\u0000\f\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001' +const compoundString = + keyName + + '\u0000\u0000\u0000�\u0000\u0000\u0000\f\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001' const compoundUint8Array = new Uint8Array([ ...keyNameFromUtf8, // keyName as UTF-8 - 0, 0, 0, 16 * 8, // uInt32BE(authTagBitLength) - 0, 0, 0, 12, // uInt32BE(ivLength) - ...iv -]) -const encryptedDataKey = new Uint8Array([ - ...ciphertext, - ...authTag + 0, + 0, + 0, + 16 * 8, // uInt32BE(authTagBitLength) + 0, + 0, + 0, + 12, // uInt32BE(ivLength) + ...iv, ]) -const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) +const encryptedDataKey = new Uint8Array([...ciphertext, ...authTag]) +const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 +) describe('rawAesEncryptedDataKeyFactory:rawAesEncryptedDataKey', () => { it('will build an EncryptedDataKey', () => { @@ -33,7 +64,7 @@ describe('rawAesEncryptedDataKeyFactory:rawAesEncryptedDataKey', () => { const fromUtf8 = (str: string) => { expect(str).to.equal(keyName) fromUtf8Called += 1 - return new Uint8Array([ 107, 101, 121, 78, 97, 109, 101 ]) + return new Uint8Array([107, 101, 121, 78, 97, 109, 101]) } let toUtf8Called = 0 @@ -44,7 +75,10 @@ describe('rawAesEncryptedDataKeyFactory:rawAesEncryptedDataKey', () => { return compoundString } - const { rawAesEncryptedDataKey } = rawAesEncryptedDataKeyFactory(toUtf8, fromUtf8) + const { rawAesEncryptedDataKey } = rawAesEncryptedDataKeyFactory( + toUtf8, + fromUtf8 + ) const test = rawAesEncryptedDataKey( keyNamespace, @@ -70,7 +104,7 @@ describe('rawAesEncryptedPartsFactory:rawAesEncryptedParts', () => { encryptedDataKey, providerId: keyNamespace, providerInfo: compoundString, - rawInfo: compoundUint8Array + rawInfo: compoundUint8Array, }) let fromUtf8Called = 0 @@ -94,11 +128,13 @@ describe('rawAesEncryptedPartsFactory:rawAesEncryptedParts', () => { encryptedDataKey, providerId: keyNamespace, providerInfo: compoundString, - rawInfo: '' + rawInfo: '', } as any - let fromUtf8Called = 0 - const fromUtf8 = () => { throw new Error('never') } + const fromUtf8Called = 0 + const fromUtf8 = () => { + throw new Error('never') + } const { rawAesEncryptedParts } = rawAesEncryptedPartsFactory(fromUtf8) @@ -109,16 +145,22 @@ describe('rawAesEncryptedPartsFactory:rawAesEncryptedParts', () => { it('Precondition: The ivLength must match the algorith suite specification.', () => { const compoundUint8Array = new Uint8Array([ ...keyNameFromUtf8, // keyName as UTF-8 - 0, 0, 0, 16 * 8, // uInt32BE(authTagBitLength) - 0, 0, 0, 13, // wrong length - ...iv + 0, + 0, + 0, + 16 * 8, // uInt32BE(authTagBitLength) + 0, + 0, + 0, + 13, // wrong length + ...iv, ]) const edk = new EncryptedDataKey({ encryptedDataKey, providerId: keyNamespace, providerInfo: compoundString, - rawInfo: compoundUint8Array + rawInfo: compoundUint8Array, }) const fromUtf8 = () => keyNameFromUtf8 @@ -130,16 +172,22 @@ describe('rawAesEncryptedPartsFactory:rawAesEncryptedParts', () => { it('Precondition: The tagLength must match the algorith suite specification.', () => { const compoundUint8Array = new Uint8Array([ ...keyNameFromUtf8, // keyName as UTF-8 - 0, 0, 0, 17 * 8, // wrong length - 0, 0, 0, 12, // right length - ...iv + 0, + 0, + 0, + 17 * 8, // wrong length + 0, + 0, + 0, + 12, // right length + ...iv, ]) const edk = new EncryptedDataKey({ encryptedDataKey, providerId: keyNamespace, providerInfo: compoundString, - rawInfo: compoundUint8Array + rawInfo: compoundUint8Array, }) const fromUtf8 = () => keyNameFromUtf8 @@ -149,12 +197,13 @@ describe('rawAesEncryptedPartsFactory:rawAesEncryptedParts', () => { }) it('Precondition: The byteLength of rawInfo should match the encoded length.', () => { - const makeEdk = (rawInfo: Uint8Array) => new EncryptedDataKey({ - encryptedDataKey, - providerId: keyNamespace, - providerInfo: compoundString, - rawInfo - }) + const makeEdk = (rawInfo: Uint8Array) => + new EncryptedDataKey({ + encryptedDataKey, + providerId: keyNamespace, + providerInfo: compoundString, + rawInfo, + }) const fromUtf8 = () => keyNameFromUtf8 @@ -163,29 +212,45 @@ describe('rawAesEncryptedPartsFactory:rawAesEncryptedParts', () => { const tooShort = new Uint8Array([1, 1, 1]) const tooLong = new Uint8Array([ ...keyNameFromUtf8, // keyName as UTF-8 - 0, 0, 0, 16 * 8, // wrong length - 0, 0, 0, 12, // right length + 0, + 0, + 0, + 16 * 8, // wrong length + 0, + 0, + 0, + 12, // right length ...iv, - 0 + 0, ]) - expect(() => rawAesEncryptedParts(suite, keyName, makeEdk(tooShort))).to.throw() - expect(() => rawAesEncryptedParts(suite, keyName, makeEdk(tooLong))).to.throw() + expect(() => + rawAesEncryptedParts(suite, keyName, makeEdk(tooShort)) + ).to.throw() + expect(() => + rawAesEncryptedParts(suite, keyName, makeEdk(tooLong)) + ).to.throw() }) it('Precondition: The encryptedDataKey byteLength must match the algorith suite specification and encoded length.', () => { const compoundUint8Array = new Uint8Array([ ...keyNameFromUtf8, // keyName as UTF-8 - 0, 0, 0, 17 * 8, // wrong length - 0, 0, 0, 12, // right length - ...iv + 0, + 0, + 0, + 17 * 8, // wrong length + 0, + 0, + 0, + 12, // right length + ...iv, ]) const edk = new EncryptedDataKey({ encryptedDataKey: new Uint8Array([...encryptedDataKey, 0]), providerId: keyNamespace, providerInfo: compoundString, - rawInfo: compoundUint8Array + rawInfo: compoundUint8Array, }) const fromUtf8 = () => keyNameFromUtf8 diff --git a/modules/raw-keyring/test/raw_aes_material.test.ts b/modules/raw-keyring/test/raw_aes_material.test.ts index 0624b96a2..f1e98b981 100644 --- a/modules/raw-keyring/test/raw_aes_material.test.ts +++ b/modules/raw-keyring/test/raw_aes_material.test.ts @@ -4,7 +4,10 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { NodeRawAesMaterial, WebCryptoRawAesMaterial } from '../src/raw_aes_material' +import { + NodeRawAesMaterial, + WebCryptoRawAesMaterial, +} from '../src/raw_aes_material' import { RawAesWrappingSuiteIdentifier } from '../src/raw_aes_algorithm_suite' import { AlgorithmSuiteIdentifier } from '@aws-crypto/material-management' @@ -13,8 +16,10 @@ describe('NodeRawAesMaterial', () => { const test = new NodeRawAesMaterial(suiteId) it('instance is frozen', () => expect(Object.isFrozen(test)).to.equal(true)) it('has a suite', () => expect(test.suite.id === suiteId).to.equal(true)) - it('class is frozen', () => expect(Object.isFrozen(NodeRawAesMaterial)).to.equal(true)) - it('class prototype is frozen', () => expect(Object.isFrozen(NodeRawAesMaterial.prototype)).to.equal(true)) + it('class is frozen', () => + expect(Object.isFrozen(NodeRawAesMaterial)).to.equal(true)) + it('class prototype is frozen', () => + expect(Object.isFrozen(NodeRawAesMaterial.prototype)).to.equal(true)) it('hasValidKey is false', () => expect(test.hasValidKey()).to.equal(false)) it('Precondition: NodeRawAesMaterial suiteId must be RawAesWrappingSuiteIdentifier.', () => { const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 as any @@ -27,8 +32,10 @@ describe('WebCryptoRawAesMaterial', () => { const test = new WebCryptoRawAesMaterial(suiteId) it('instance is frozen', () => expect(Object.isFrozen(test)).to.equal(true)) it('has a suite', () => expect(test.suite.id === suiteId).to.equal(true)) - it('class is frozen', () => expect(Object.isFrozen(WebCryptoRawAesMaterial)).to.equal(true)) - it('class prototype is frozen', () => expect(Object.isFrozen(WebCryptoRawAesMaterial.prototype)).to.equal(true)) + it('class is frozen', () => + expect(Object.isFrozen(WebCryptoRawAesMaterial)).to.equal(true)) + it('class prototype is frozen', () => + expect(Object.isFrozen(WebCryptoRawAesMaterial.prototype)).to.equal(true)) it('hasValidKey is false', () => expect(test.hasValidKey()).to.equal(false)) it('Precondition: WebCryptoAlgorithmSuite suiteId must be RawAesWrappingSuiteIdentifier.', () => { const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256 as any diff --git a/modules/raw-keyring/test/raw_keyring_decorators.test.ts b/modules/raw-keyring/test/raw_keyring_decorators.test.ts index 92716e750..0f9a80528 100644 --- a/modules/raw-keyring/test/raw_keyring_decorators.test.ts +++ b/modules/raw-keyring/test/raw_keyring_decorators.test.ts @@ -5,14 +5,25 @@ import { expect } from 'chai' import { _onEncrypt, _onDecrypt } from '../src/raw_keyring_decorators' -import { AlgorithmSuiteIdentifier, NodeEncryptionMaterial, NodeAlgorithmSuite, KeyringTraceFlag, NodeDecryptionMaterial, EncryptedDataKey, unwrapDataKey } from '@aws-crypto/material-management' +import { + AlgorithmSuiteIdentifier, + NodeEncryptionMaterial, + NodeAlgorithmSuite, + KeyringTraceFlag, + NodeDecryptionMaterial, + EncryptedDataKey, + unwrapDataKey, +} from '@aws-crypto/material-management' describe('_onEncrypt', () => { it('will create UnencryptedDataKey and call _wrapKey', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const material = new NodeEncryptionMaterial(suite, {}) let wrapCalled = 0 - const notRandomBytes = async (bytes: number) => new Uint8Array(Array(bytes).fill(1)) + const notRandomBytes = async (bytes: number) => + new Uint8Array(Array(bytes).fill(1)) const _wrapKey = (material: any) => { wrapCalled += 1 return material @@ -24,27 +35,41 @@ describe('_onEncrypt', () => { keyName, keyNamespace, _onEncrypt: _onEncrypt(notRandomBytes), - _wrapKey + _wrapKey, } as any const test = await testKeyring._onEncrypt(material) - expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal(new Uint8Array(Array(suite.keyLengthBytes).fill(1))) + expect(unwrapDataKey(test.getUnencryptedDataKey())).to.deep.equal( + new Uint8Array(Array(suite.keyLengthBytes).fill(1)) + ) expect(test.keyringTrace).to.have.lengthOf(1) expect(test.keyringTrace[0].keyName).to.equal(keyName) expect(test.keyringTrace[0].keyNamespace).to.equal(keyNamespace) - expect(test.keyringTrace[0].flags).to.equal(KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY) + expect(test.keyringTrace[0].flags).to.equal( + KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY + ) expect(wrapCalled).to.equal(1) }) it('will not create a UnencryptedDataKey if one exists, but will call _wrapKey', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const udk = new Uint8Array(Array(suite.keyLengthBytes).fill(2)) const keyName = 'keyName' const keyNamespace = 'keyNamespace' - const material = new NodeEncryptionMaterial(suite, {}) - .setUnencryptedDataKey(new Uint8Array(udk), { keyName, keyNamespace, flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY }) + const material = new NodeEncryptionMaterial( + suite, + {} + ).setUnencryptedDataKey(new Uint8Array(udk), { + keyName, + keyNamespace, + flags: KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY, + }) let wrapCalled = 0 - const notRandomBytes = async () => { throw new Error('never') } + const notRandomBytes = async () => { + throw new Error('never') + } const _wrapKey = (material: any) => { wrapCalled += 1 return material @@ -54,7 +79,7 @@ describe('_onEncrypt', () => { keyName, keyNamespace, _onEncrypt: _onEncrypt(notRandomBytes), - _wrapKey + _wrapKey, } as any const test = await testKeyring._onEncrypt(material) @@ -65,7 +90,9 @@ describe('_onEncrypt', () => { describe('_onDecrypt', () => { it('basic usage', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const udk = new Uint8Array(Array(suite.keyLengthBytes).fill(2)) const material = new NodeDecryptionMaterial(suite, {}) const keyName = 'keyName' @@ -74,7 +101,7 @@ describe('_onDecrypt', () => { const edk = new EncryptedDataKey({ providerId: keyName, providerInfo: keyNamespace, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) let unwrapCalled = 0 let filterCalled = 0 @@ -85,8 +112,11 @@ describe('_onDecrypt', () => { } const _unwrapKey = (material: NodeDecryptionMaterial) => { unwrapCalled += 1 - return material - .setUnencryptedDataKey(new Uint8Array(udk), { keyName, keyNamespace, flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY }) + return material.setUnencryptedDataKey(new Uint8Array(udk), { + keyName, + keyNamespace, + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + }) } const testKeyring = { @@ -94,7 +124,7 @@ describe('_onDecrypt', () => { keyNamespace, _onDecrypt: _onDecrypt(), _unwrapKey, - _filter + _filter, } as any const test = await testKeyring._onDecrypt(material, [edk]) @@ -102,23 +132,33 @@ describe('_onDecrypt', () => { expect(test.keyringTrace).to.have.lengthOf(1) expect(test.keyringTrace[0].keyName).to.equal(keyName) expect(test.keyringTrace[0].keyNamespace).to.equal(keyNamespace) - expect(test.keyringTrace[0].flags).to.equal(KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY) + expect(test.keyringTrace[0].flags).to.equal( + KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY + ) expect(unwrapCalled).to.equal(1) expect(filterCalled).to.equal(1) }) it('Check for early return (Postcondition): If the material is already valid, attempting to decrypt is a bad idea.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const udk = new Uint8Array(Array(suite.keyLengthBytes).fill(2)) const keyName = 'keyName' const keyNamespace = 'keyNamespace' - const material = new NodeDecryptionMaterial(suite, {}) - .setUnencryptedDataKey(new Uint8Array(udk), { keyName, keyNamespace, flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY }) + const material = new NodeDecryptionMaterial( + suite, + {} + ).setUnencryptedDataKey(new Uint8Array(udk), { + keyName, + keyNamespace, + flags: KeyringTraceFlag.WRAPPING_KEY_DECRYPTED_DATA_KEY, + }) const edk = new EncryptedDataKey({ providerId: keyName, providerInfo: keyNamespace, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) let unwrapCalled = 0 let filterCalled = 0 @@ -137,7 +177,7 @@ describe('_onDecrypt', () => { keyNamespace, _onDecrypt: _onDecrypt(), _unwrapKey, - _filter + _filter, } as any const test = await testKeyring._onDecrypt(material, [edk]) @@ -147,7 +187,9 @@ describe('_onDecrypt', () => { }) it('Check for early return (Postcondition): If there are not EncryptedDataKeys for this keyring, do nothing.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const keyName = 'keyName' const keyNamespace = 'keyNamespace' const material = new NodeDecryptionMaterial(suite, {}) @@ -155,7 +197,7 @@ describe('_onDecrypt', () => { const edk = new EncryptedDataKey({ providerId: keyName, providerInfo: keyNamespace, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) let unwrapCalled = 0 let filterCalled = 0 @@ -174,7 +216,7 @@ describe('_onDecrypt', () => { keyNamespace, _onDecrypt: _onDecrypt(), _unwrapKey, - _filter + _filter, } as any const test = await testKeyring._onDecrypt(material, [edk]) @@ -184,7 +226,9 @@ describe('_onDecrypt', () => { }) it('errors in _unwrapKey should not cause _onDecrypt to throw.', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) const keyName = 'keyName' const keyNamespace = 'keyNamespace' const material = new NodeDecryptionMaterial(suite, {}) @@ -192,7 +236,7 @@ describe('_onDecrypt', () => { const edk = new EncryptedDataKey({ providerId: keyName, providerInfo: keyNamespace, - encryptedDataKey: new Uint8Array(5) + encryptedDataKey: new Uint8Array(5), }) let unwrapCalled = 0 let filterCalled = 0 @@ -211,7 +255,7 @@ describe('_onDecrypt', () => { keyNamespace, _onDecrypt: _onDecrypt(), _unwrapKey, - _filter + _filter, } as any const test = await testKeyring._onDecrypt(material, [edk]) diff --git a/modules/raw-rsa-keyring-browser/test/get_import_options.test.ts b/modules/raw-rsa-keyring-browser/test/get_import_options.test.ts index c92c92c14..c443c12ad 100644 --- a/modules/raw-rsa-keyring-browser/test/get_import_options.test.ts +++ b/modules/raw-rsa-keyring-browser/test/get_import_options.test.ts @@ -5,10 +5,7 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { - flattenMixedCryptoKey, - verify -} from '../src/get_import_options' +import { flattenMixedCryptoKey, verify } from '../src/get_import_options' chai.use(chaiAsPromised) const { expect } = chai @@ -24,7 +21,7 @@ describe('flattenMixedCryptoKey', () => { algorithm: 'algo', type: 'secret', usages: ['encrypt'], - extractable: false + extractable: false, } const mixedKey: any = { zeroByteCryptoKey: key, nonZeroByteCryptoKey: key } @@ -37,13 +34,27 @@ describe('flattenMixedCryptoKey', () => { algorithm: 'algo', type: 'secret', usages: ['encrypt'], - extractable: false + extractable: false, } const notKey: any = {} - expect(() => flattenMixedCryptoKey({ zeroByteCryptoKey: notKey, nonZeroByteCryptoKey: key } as any)).to.throw('Not all keys are CryptoKeys.') - expect(() => flattenMixedCryptoKey({ zeroByteCryptoKey: notKey, nonZeroByteCryptoKey: notKey } as any)).to.throw('Not all keys are CryptoKeys.') - expect(() => flattenMixedCryptoKey({ zeroByteCryptoKey: key } as any)).to.throw('Not all keys are CryptoKeys.') - expect(() => flattenMixedCryptoKey({ nonZeroByteCryptoKey: key } as any)).to.throw('Not all keys are CryptoKeys.') + expect(() => + flattenMixedCryptoKey({ + zeroByteCryptoKey: notKey, + nonZeroByteCryptoKey: key, + } as any) + ).to.throw('Not all keys are CryptoKeys.') + expect(() => + flattenMixedCryptoKey({ + zeroByteCryptoKey: notKey, + nonZeroByteCryptoKey: notKey, + } as any) + ).to.throw('Not all keys are CryptoKeys.') + expect(() => + flattenMixedCryptoKey({ zeroByteCryptoKey: key } as any) + ).to.throw('Not all keys are CryptoKeys.') + expect(() => + flattenMixedCryptoKey({ nonZeroByteCryptoKey: key } as any) + ).to.throw('Not all keys are CryptoKeys.') }) }) @@ -51,20 +62,22 @@ describe('verify', () => { it('verifies that all wrapping algorithms are valid', () => { const wrapping: any = { name: 'RSA-OAEP', - hash: { name: 'SHA-1' } + hash: { name: 'SHA-1' }, } const test = verify(wrapping, wrapping) expect(test === wrapping).to.equal(true) }) it('Precondition: Need at least 1 algorithm to verify.', () => { - expect(() => verify()).to.throw('Can not verify an empty set of algorithms.') + expect(() => verify()).to.throw( + 'Can not verify an empty set of algorithms.' + ) }) it('Precondition: The wrappingAlgorithm name must be a supported value.', () => { const wrapping: any = { name: 'not supported', - hash: { name: 'SHA-1' } + hash: { name: 'SHA-1' }, } expect(() => verify(wrapping)).to.throw('Algorithm name is not supported.') }) @@ -72,7 +85,7 @@ describe('verify', () => { it('Precondition: The hash name must be a supported value.', () => { const wrapping: any = { name: 'RSA-OAEP', - hash: { name: 'not supported' } + hash: { name: 'not supported' }, } expect(() => verify(wrapping)).to.throw('Hash name is not supported.') }) @@ -80,7 +93,7 @@ describe('verify', () => { it('Check for early return (Postcondition): Only 1 wrappingAlgorithm is clearly valid.', () => { const wrapping: any = { name: 'RSA-OAEP', - hash: { name: 'SHA-1' } + hash: { name: 'SHA-1' }, } const test = verify(wrapping) expect(test === wrapping).to.equal(true) @@ -89,12 +102,14 @@ describe('verify', () => { it('Precondition: All keys must have the same wrappingAlgorithm.', () => { const wrapping: any = { name: 'RSA-OAEP', - hash: { name: 'SHA-1' } + hash: { name: 'SHA-1' }, } const differentWrapping: any = { name: 'RSA-OAEP', - hash: { name: 'SHA-512' } + hash: { name: 'SHA-512' }, } - expect(() => verify(wrapping, differentWrapping)).to.throw('Not all RSA keys have the same wrappingAlgorithm.') + expect(() => verify(wrapping, differentWrapping)).to.throw( + 'Not all RSA keys have the same wrappingAlgorithm.' + ) }) }) diff --git a/modules/raw-rsa-keyring-browser/test/raw_rsa_keyring_web_crypto.test.ts b/modules/raw-rsa-keyring-browser/test/raw_rsa_keyring_web_crypto.test.ts index ebbd11404..ff46259a6 100644 --- a/modules/raw-rsa-keyring-browser/test/raw_rsa_keyring_web_crypto.test.ts +++ b/modules/raw-rsa-keyring-browser/test/raw_rsa_keyring_web_crypto.test.ts @@ -6,16 +6,16 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { - RsaImportableKey, // eslint-disable-line no-unused-vars - RawRsaKeyringWebCrypto + RsaImportableKey, + RawRsaKeyringWebCrypto, } from '@aws-crypto/raw-rsa-keyring-browser' import { KeyringWebCrypto, WebCryptoEncryptionMaterial, WebCryptoAlgorithmSuite, AlgorithmSuiteIdentifier, - EncryptedDataKey, // eslint-disable-line no-unused-vars - WebCryptoDecryptionMaterial + EncryptedDataKey, + WebCryptoDecryptionMaterial, } from '@aws-crypto/material-management-browser' chai.use(chaiAsPromised) @@ -27,17 +27,49 @@ declare const CryptoKey: CryptoKey * These keys are *Public*! * *DO NOT USE* */ -const privateRsaJwkKey: RsaImportableKey = { 'alg': 'RSA-OAEP-256', 'd': 'XcAlS3OYtZ5F3BFGRQH5B8soiqstUk9JkH6_sUhBUfM7yjFpn3MQACtGgOKsFIO01KWCVl7Cn6E3c-MuuT3QqNQrUx8n-WrJU8qNpDOGJ5CVpG9-xTSQVNzRV92gj8g7-BIgehtzMmirXXNsb1XeTg9zsm3iptt9VyhplGqcgOdmm72sT1Z8ZmkagaElHSg0dR1ZNGgzSfTtRg_J1tTh7cmFb1LVz069o6cRaa5ueOPNKxmEslBdVWsDo9naxd_keLiqOOMIQp-KlLuQ-Zhn5fZyqxkRPGjTKZZHitgurzfWG4ERjjrYCbZsOjEt9Tj8FXXUB8bd3qRPy5UkN-XLEQ', 'dp': 'V8QYdWm4OqWpfF_NPdCGr5eqztfHiQQn1NLmkvNO8c9dc2yNizZ4GxtNNEARYjgnLK0ROCoiK5yamtVDyjZ_zzZUvE0CG8iNRg1qvaOM8n_7B2YgmUs9rJ-QKK3HVEsi_M0x-hHeRl3ocAkNfby3__yt6s43FvyrccQh89WcAr0', 'dq': 'NT5lrYlvkOwXIHl8P9AQm1nNL0RkHSrWahYlagRkyU3ELySlWr2laDxXzPnngpuBvyA98iq6Z2JTn8ArtXXvTqQk6BF6np6qqg1QNQxsQeU4Aj3xOMV9EGh57Zpa8Rs0jVydxBdlRW03Fr0UChHKxmT2kS0622gdlGQAs3YxMck', 'e': 'AQAB', 'ext': true, 'key_ops': ['unwrapKey'], 'kty': 'RSA', 'n': '6k_jrxg7mpz7CzgAr6eRqJr1VlvjJ9uQY71hadkDZkLLZHiMl7hz73lqq3w2MfHCa3Pf3BVo5TCXGYuxKOlPb7bH0WWpMeAzOKR_X27UqfA8MBVGb4YO5HXqw0jup8-I-Zi3CQAmP87uE6GDuh7xzeAcwpGD5xE0N74-uWq3YS92PFHCavtryx-ad9VGTgfAbkV3k1-RSxIiZjzbAt3exBAn5EjMfF6FMI70_HYqO-5xGv_aAPSa1OMc_buK5QACN7gmFwqHBzw98v93iyGUc4_XJNL-jPzKNP4AT1zMc6p6RxF3SYytNq7iXIjUmm-oY8fvCSmT1F13XKdzv7DLOw', 'p': '9dGuBwEDeOHFwJ_AQXHBWu53bv_L1_9lh2X-NEBO1B7YMhYWu2nMqXEvLpwvPqyBXwWnuPdfGqu6BHv22RDAF7Lu_oUshq-9dzSwFxaC5PQ2NwtHnz0-zwhEzCE3Qw9t63_OXX87gjp5vy6c5bvb3B9EbZU33Xf9nqVEJhzFreU', 'q': '9AQ0oYhctBbFuIu4jt1HBmqQGGAECbhQAMw324MX8pVUg6GOtF0X822iEsq7aIfY8u5nTWu1kKl6s84US1yII0sJmW2Jj722r5VYDIrxk5x_mLQ6jXmfuH2kl-Lvzo6aHIVkDLIK-IaPt5teSwG71QfAPDgR6drIAuSFnJZ2Ap8', 'qi': 'mfoT9tmXPhLBanX5Mg76pO21NAXR1aAQ76tS1_hJZYxP8iZtmlEdvvAMIdSibvIt7Gfi60rBPnxqmmKuitJfzIVCd4sVLjIVEjT_njjLAzU-NTQdGugPCWWo8jB8NyeFy6nrZa_Hy52ijBn-Xt5G8pzvz5lF5gRfCe09y14oNeQ' } -const publicRsaJwkKey: RsaImportableKey = { 'alg': 'RSA-OAEP-256', 'e': 'AQAB', 'ext': true, 'key_ops': ['wrapKey'], 'kty': 'RSA', 'n': '6k_jrxg7mpz7CzgAr6eRqJr1VlvjJ9uQY71hadkDZkLLZHiMl7hz73lqq3w2MfHCa3Pf3BVo5TCXGYuxKOlPb7bH0WWpMeAzOKR_X27UqfA8MBVGb4YO5HXqw0jup8-I-Zi3CQAmP87uE6GDuh7xzeAcwpGD5xE0N74-uWq3YS92PFHCavtryx-ad9VGTgfAbkV3k1-RSxIiZjzbAt3exBAn5EjMfF6FMI70_HYqO-5xGv_aAPSa1OMc_buK5QACN7gmFwqHBzw98v93iyGUc4_XJNL-jPzKNP4AT1zMc6p6RxF3SYytNq7iXIjUmm-oY8fvCSmT1F13XKdzv7DLOw' } +const privateRsaJwkKey: RsaImportableKey = { + alg: 'RSA-OAEP-256', + d: + 'XcAlS3OYtZ5F3BFGRQH5B8soiqstUk9JkH6_sUhBUfM7yjFpn3MQACtGgOKsFIO01KWCVl7Cn6E3c-MuuT3QqNQrUx8n-WrJU8qNpDOGJ5CVpG9-xTSQVNzRV92gj8g7-BIgehtzMmirXXNsb1XeTg9zsm3iptt9VyhplGqcgOdmm72sT1Z8ZmkagaElHSg0dR1ZNGgzSfTtRg_J1tTh7cmFb1LVz069o6cRaa5ueOPNKxmEslBdVWsDo9naxd_keLiqOOMIQp-KlLuQ-Zhn5fZyqxkRPGjTKZZHitgurzfWG4ERjjrYCbZsOjEt9Tj8FXXUB8bd3qRPy5UkN-XLEQ', + dp: + 'V8QYdWm4OqWpfF_NPdCGr5eqztfHiQQn1NLmkvNO8c9dc2yNizZ4GxtNNEARYjgnLK0ROCoiK5yamtVDyjZ_zzZUvE0CG8iNRg1qvaOM8n_7B2YgmUs9rJ-QKK3HVEsi_M0x-hHeRl3ocAkNfby3__yt6s43FvyrccQh89WcAr0', + dq: + 'NT5lrYlvkOwXIHl8P9AQm1nNL0RkHSrWahYlagRkyU3ELySlWr2laDxXzPnngpuBvyA98iq6Z2JTn8ArtXXvTqQk6BF6np6qqg1QNQxsQeU4Aj3xOMV9EGh57Zpa8Rs0jVydxBdlRW03Fr0UChHKxmT2kS0622gdlGQAs3YxMck', + e: 'AQAB', + ext: true, + key_ops: ['unwrapKey'], // eslint-disable-line @typescript-eslint/camelcase + kty: 'RSA', + n: + '6k_jrxg7mpz7CzgAr6eRqJr1VlvjJ9uQY71hadkDZkLLZHiMl7hz73lqq3w2MfHCa3Pf3BVo5TCXGYuxKOlPb7bH0WWpMeAzOKR_X27UqfA8MBVGb4YO5HXqw0jup8-I-Zi3CQAmP87uE6GDuh7xzeAcwpGD5xE0N74-uWq3YS92PFHCavtryx-ad9VGTgfAbkV3k1-RSxIiZjzbAt3exBAn5EjMfF6FMI70_HYqO-5xGv_aAPSa1OMc_buK5QACN7gmFwqHBzw98v93iyGUc4_XJNL-jPzKNP4AT1zMc6p6RxF3SYytNq7iXIjUmm-oY8fvCSmT1F13XKdzv7DLOw', + p: + '9dGuBwEDeOHFwJ_AQXHBWu53bv_L1_9lh2X-NEBO1B7YMhYWu2nMqXEvLpwvPqyBXwWnuPdfGqu6BHv22RDAF7Lu_oUshq-9dzSwFxaC5PQ2NwtHnz0-zwhEzCE3Qw9t63_OXX87gjp5vy6c5bvb3B9EbZU33Xf9nqVEJhzFreU', + q: + '9AQ0oYhctBbFuIu4jt1HBmqQGGAECbhQAMw324MX8pVUg6GOtF0X822iEsq7aIfY8u5nTWu1kKl6s84US1yII0sJmW2Jj722r5VYDIrxk5x_mLQ6jXmfuH2kl-Lvzo6aHIVkDLIK-IaPt5teSwG71QfAPDgR6drIAuSFnJZ2Ap8', + qi: + 'mfoT9tmXPhLBanX5Mg76pO21NAXR1aAQ76tS1_hJZYxP8iZtmlEdvvAMIdSibvIt7Gfi60rBPnxqmmKuitJfzIVCd4sVLjIVEjT_njjLAzU-NTQdGugPCWWo8jB8NyeFy6nrZa_Hy52ijBn-Xt5G8pzvz5lF5gRfCe09y14oNeQ', +} +const publicRsaJwkKey: RsaImportableKey = { + alg: 'RSA-OAEP-256', + e: 'AQAB', + ext: true, + key_ops: ['wrapKey'], // eslint-disable-line @typescript-eslint/camelcase + kty: 'RSA', + n: + '6k_jrxg7mpz7CzgAr6eRqJr1VlvjJ9uQY71hadkDZkLLZHiMl7hz73lqq3w2MfHCa3Pf3BVo5TCXGYuxKOlPb7bH0WWpMeAzOKR_X27UqfA8MBVGb4YO5HXqw0jup8-I-Zi3CQAmP87uE6GDuh7xzeAcwpGD5xE0N74-uWq3YS92PFHCavtryx-ad9VGTgfAbkV3k1-RSxIiZjzbAt3exBAn5EjMfF6FMI70_HYqO-5xGv_aAPSa1OMc_buK5QACN7gmFwqHBzw98v93iyGUc4_XJNL-jPzKNP4AT1zMc6p6RxF3SYytNq7iXIjUmm-oY8fvCSmT1F13XKdzv7DLOw', +} describe('import CryptoKey helpers', () => { it('imports public CryptoKey', async () => { - const cryptoKey = await RawRsaKeyringWebCrypto.importPublicKey(publicRsaJwkKey) + const cryptoKey = await RawRsaKeyringWebCrypto.importPublicKey( + publicRsaJwkKey + ) expect(cryptoKey).to.be.instanceOf(CryptoKey) }) it('imports private CryptoKey', async () => { - const cryptoKey = await RawRsaKeyringWebCrypto.importPrivateKey(privateRsaJwkKey) + const cryptoKey = await RawRsaKeyringWebCrypto.importPrivateKey( + privateRsaJwkKey + ) expect(cryptoKey).to.be.instanceOf(CryptoKey) }) }) @@ -49,8 +81,12 @@ describe('RawRsaKeyringWebCrypto::constructor', () => { const keyNamespace = 'keyNamespace' before(async () => { - publicCryptoKey = await await RawRsaKeyringWebCrypto.importPublicKey(publicRsaJwkKey) - privateCryptoKey = await await RawRsaKeyringWebCrypto.importPrivateKey(privateRsaJwkKey) + publicCryptoKey = await await RawRsaKeyringWebCrypto.importPublicKey( + publicRsaJwkKey + ) + privateCryptoKey = await await RawRsaKeyringWebCrypto.importPrivateKey( + privateRsaJwkKey + ) }) it('constructor decorates', async () => { @@ -58,7 +94,7 @@ describe('RawRsaKeyringWebCrypto::constructor', () => { privateKey: privateCryptoKey, publicKey: publicCryptoKey, keyName, - keyNamespace + keyNamespace, }) expect(test.keyName).to.equal(keyName) @@ -72,7 +108,7 @@ describe('RawRsaKeyringWebCrypto::constructor', () => { const testPublicOnly = new RawRsaKeyringWebCrypto({ publicKey: publicCryptoKey, keyName, - keyNamespace + keyNamespace, }) expect(testPublicOnly).to.be.instanceOf(RawRsaKeyringWebCrypto) }) @@ -81,36 +117,45 @@ describe('RawRsaKeyringWebCrypto::constructor', () => { const testPrivateOnly = new RawRsaKeyringWebCrypto({ privateKey: privateCryptoKey, keyName, - keyNamespace + keyNamespace, }) expect(testPrivateOnly).to.be.instanceOf(RawRsaKeyringWebCrypto) }) it('Precondition: RsaKeyringWebCrypto needs either a public or a private key to operate.', () => { - expect(() => new RawRsaKeyringWebCrypto({ - keyName, - keyNamespace - })).to.throw() + expect( + () => + new RawRsaKeyringWebCrypto({ + keyName, + keyNamespace, + }) + ).to.throw() }) it('Precondition: RsaKeyringWebCrypto needs identifying information for encrypt and decrypt.', () => { - // @ts-ignore Typescript is trying to save us. - expect(() => new RawRsaKeyringWebCrypto({ - privateKey: privateCryptoKey, - publicKey: publicCryptoKey - })).to.throw() - // @ts-ignore Typescript is trying to save us. - expect(() => new RawRsaKeyringWebCrypto({ - privateKey: privateCryptoKey, - publicKey: publicCryptoKey, - keyNamespace - })).to.throw() - // @ts-ignore Typescript is trying to save us. - expect(() => new RawRsaKeyringWebCrypto({ - privateKey: privateCryptoKey, - publicKey: publicCryptoKey, - keyName - })).to.throw() + expect( + () => + new RawRsaKeyringWebCrypto({ + privateKey: privateCryptoKey, + publicKey: publicCryptoKey, + } as any) + ).to.throw() + expect( + () => + new RawRsaKeyringWebCrypto({ + privateKey: privateCryptoKey, + publicKey: publicCryptoKey, + keyNamespace, + } as any) + ).to.throw() + expect( + () => + new RawRsaKeyringWebCrypto({ + privateKey: privateCryptoKey, + publicKey: publicCryptoKey, + keyName, + } as any) + ).to.throw() }) }) @@ -121,13 +166,24 @@ describe('RawRsaKeyringWebCrypto encrypt/decrypt', () => { let encryptedDataKey: EncryptedDataKey before(async () => { - const publicKey = await await RawRsaKeyringWebCrypto.importPublicKey(publicRsaJwkKey) - const privateKey = await await RawRsaKeyringWebCrypto.importPrivateKey(privateRsaJwkKey) - keyring = new RawRsaKeyringWebCrypto({ publicKey, privateKey, keyName, keyNamespace }) + const publicKey = await await RawRsaKeyringWebCrypto.importPublicKey( + publicRsaJwkKey + ) + const privateKey = await await RawRsaKeyringWebCrypto.importPrivateKey( + privateRsaJwkKey + ) + keyring = new RawRsaKeyringWebCrypto({ + publicKey, + privateKey, + keyName, + keyNamespace, + }) }) it('can encrypt and create unencrypted data key', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) const test = await keyring.onEncrypt(material) expect(test.hasValidKey()).to.equal(true) @@ -140,7 +196,9 @@ describe('RawRsaKeyringWebCrypto encrypt/decrypt', () => { }) it('can decrypt an EncryptedDataKey', async () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) const test = await keyring.onDecrypt(material, [encryptedDataKey]) expect(test.hasValidKey()).to.equal(true) @@ -149,20 +207,38 @@ describe('RawRsaKeyringWebCrypto encrypt/decrypt', () => { }) it('Precondition: I must have a publicKey to wrap.', async () => { - const privateKey = await await RawRsaKeyringWebCrypto.importPrivateKey(privateRsaJwkKey) - const keyring = new RawRsaKeyringWebCrypto({ privateKey, keyName, keyNamespace }) + const privateKey = await await RawRsaKeyringWebCrypto.importPrivateKey( + privateRsaJwkKey + ) + const keyring = new RawRsaKeyringWebCrypto({ + privateKey, + keyName, + keyNamespace, + }) - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoEncryptionMaterial(suite, {}) - expect(keyring.onEncrypt(material)).to.rejectedWith(Error) + await expect(keyring.onEncrypt(material)).to.rejectedWith(Error) }) it('Precondition: I must have a privateKey to unwrap.', async () => { - const publicKey = await await RawRsaKeyringWebCrypto.importPublicKey(publicRsaJwkKey) - const keyring = new RawRsaKeyringWebCrypto({ publicKey, keyName, keyNamespace }) + const publicKey = await await RawRsaKeyringWebCrypto.importPublicKey( + publicRsaJwkKey + ) + const keyring = new RawRsaKeyringWebCrypto({ + publicKey, + keyName, + keyNamespace, + }) - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) const material = new WebCryptoDecryptionMaterial(suite, {}) - expect(keyring.onDecrypt(material, [encryptedDataKey])).to.rejectedWith(Error) + await expect( + keyring._unwrapKey(material, encryptedDataKey) + ).to.rejectedWith(Error) }) }) diff --git a/modules/raw-rsa-keyring-node/test/raw_rsa_keyring_node.test.ts b/modules/raw-rsa-keyring-node/test/raw_rsa_keyring_node.test.ts index b27a7b5ce..e389474a6 100644 --- a/modules/raw-rsa-keyring-node/test/raw_rsa_keyring_node.test.ts +++ b/modules/raw-rsa-keyring-node/test/raw_rsa_keyring_node.test.ts @@ -5,18 +5,15 @@ import * as chai from 'chai' import chaiAsPromised from 'chai-as-promised' -import { - RawRsaKeyringNode, - OaepHash // eslint-disable-line no-unused-vars -} from '../src/index' +import { RawRsaKeyringNode, OaepHash } from '../src/index' import { KeyringNode, NodeEncryptionMaterial, NodeAlgorithmSuite, AlgorithmSuiteIdentifier, - EncryptedDataKey, // eslint-disable-line no-unused-vars + EncryptedDataKey, NodeDecryptionMaterial, - unwrapDataKey + unwrapDataKey, } from '@aws-crypto/material-management-node' import { oaepHashSupported } from '../src/oaep_hash_supported' @@ -43,8 +40,10 @@ crypto.generateKeyPair('rsa', { private = v }) */ -const publicPem = '-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAu3eAVbBR//sN05yszjSh\n09D9L9e5q6W7z5SqdnsJ7WyENvDunOuuwIKBYOlj6P1XUKtxzwO4/v3Mu4SY4Tu2\n0rH3yP+rnGPSpRSwOOZOOBQcq6b1hK2ucGAbvYNZQSup/eqi1M+9hEgVBvMTrPfP\nm89N6xiwLaJhPAXLhVeAXroGv8yOIClkezcYkZxBx+/vdt0R31R8o08XoyniLWZt\np8xd2ge/hX8RxLc+7EhTouzHR/Pz63bhy9O9aNVVKcb2W5H4lOU9gNdPMEhmjERB\ne9M7u2rU2VyWSzwEpHx/8Vxl5T3f6i7lK0YLrFYhmmR311mCjZ50oEzJgsL+CtIO\nmq1aOYg1EJE7fOxzVPswG+BLp0r2Tx/4sevRh3Ap+BTSuOeTWlS1piV04JA5eeLE\nPrlScIVr4zj4uxMFkIxFMxMar4DD+TZGCnhqAokF56MZs9xndC6xWAnZWf3KV+il\nNN7yGo5CBGIv3Fu7CTsHTB7xOxAQyOeMSu0uGP2XO3N1DGRqv5imfRH8Jy5FhGzt\nwkSf8wPbUHINnqcQLnFvlqj1pc1j272tfVFDifr2IyToTyMIEY3S60VRBUs/F529\njCyhp8+0LMlw1WVbGt9Hxqwfzmt0rOfVc4/qnIKSc1IaBKCkwmeFOWK9qIGKMVtc\nMqsi59G6k0Ik3PjcwZ0gmv8CAwEAAQ==\n-----END PUBLIC KEY-----\n' -const privatePem = '-----BEGIN PRIVATE KEY-----\nMIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC7d4BVsFH/+w3T\nnKzONKHT0P0v17mrpbvPlKp2ewntbIQ28O6c667AgoFg6WPo/VdQq3HPA7j+/cy7\nhJjhO7bSsffI/6ucY9KlFLA45k44FByrpvWEra5wYBu9g1lBK6n96qLUz72ESBUG\n8xOs98+bz03rGLAtomE8BcuFV4Beuga/zI4gKWR7NxiRnEHH7+923RHfVHyjTxej\nKeItZm2nzF3aB7+FfxHEtz7sSFOi7MdH8/PrduHL071o1VUpxvZbkfiU5T2A108w\nSGaMREF70zu7atTZXJZLPASkfH/xXGXlPd/qLuUrRgusViGaZHfXWYKNnnSgTMmC\nwv4K0g6arVo5iDUQkTt87HNU+zAb4EunSvZPH/ix69GHcCn4FNK455NaVLWmJXTg\nkDl54sQ+uVJwhWvjOPi7EwWQjEUzExqvgMP5NkYKeGoCiQXnoxmz3Gd0LrFYCdlZ\n/cpX6KU03vIajkIEYi/cW7sJOwdMHvE7EBDI54xK7S4Y/Zc7c3UMZGq/mKZ9Efwn\nLkWEbO3CRJ/zA9tQcg2epxAucW+WqPWlzWPbva19UUOJ+vYjJOhPIwgRjdLrRVEF\nSz8Xnb2MLKGnz7QsyXDVZVsa30fGrB/Oa3Ss59Vzj+qcgpJzUhoEoKTCZ4U5Yr2o\ngYoxW1wyqyLn0bqTQiTc+NzBnSCa/wIDAQABAoICACuWf4ps8sP4FaDsPum7Jx1e\n7F+hYxRb9q0vPetKdGZ14s/7eR+XVQyBy59C5O4ZaaHiGxYtIWh4jo/TJtDH15xp\nsNlVSQuV0jZ79vVj5y/2zSvEKDXvRC3wysJntesHQgE9+xpMKx6EvA7fmeWPwP/T\nVaSiGuShasZP+qBIVhqwWj1iTHGB7lEP4HCKymi4iw8yG6O3uzslerN/W41+0WRA\nilnVj1x0zSbWDJVXw8qQD03VlRNckueXleS4JZMPJdzotcm4+3Hnngv16ZIXlLo7\nxRmwn0ji1Dct/05XfFAcUbzZhCSpPrOvF6u8YxfI4Gx77XUMMMXM1NXIjNTrPmWm\nfOtNmCsUiWjFi/aM8cNlH+veoa4SAgY0k3d51ilupd+H7CkHGnvDFKSLK+AWERWr\nGK37ffmJH0p7fXcI445+KQoT2ujm+UKNNfx8PB8jXRs7BTHb2xXhd2kjh/VmV6Gw\nVpgFloNm+OEcFcuqxQdl/Co+EsXhbmtVfb7xDhYxVkwnDRISuQyeahKf2b9sQMrf\noXOiwFLaBdsiqsxAVAVWgzA4brZdZfsLyq8tqdWrIddIDIruvk6UvLjDfhcK9dO9\nNkzIm88CAJi68lS2m/zIitvao5OJ3KyESkdAJzMSGnBYrD7fWyk1wbv0T9PbQpdo\nk/YIwuCVlKosOd355ynxAoIBAQDnm+ODTjv/HhDWLlZyxYZiXe4GfcBrukA9NF/1\nOqIqR93SpR9du2Pc7z1mCkWGFGFx4/KRVsLVl2bUgw0IEkAu4XF5ydy/dG2eLnX0\nMJjJvkXle2Z10zzp45sn8Cx8hYRfehYefBg/vG3QWfXvLGM2A2G3Niqd96FNAIc1\nM7FKcicFvM1NkxEugTK20ZgqzBZIv+WzXtG5qr4aOImBnpQa0+ucien722LE6UNw\nNShsU5kVBhraW/H+ko68xdF2CJS6poySggkd3S5yHOUXga5sPUjIErguILMVw5p1\niXf8hV2NgUp9K4zmG5rHmowMQKwckDu8Zn0oBOe/CAHVQhiDAoIBAQDPNY2V1AlY\nR97zNk8xFYk/G5I/kqcrlxyHcQlJC3ALJXKFdn8vgFfC2oSO4I8VZrieP6s1xYtA\nhdvxOu+8mpUNBal3N/1z/mBMBwmA1La3SE0RW7nWnxwoPMy64uxzVJv3/O8HvOah\n/hk3odxZuGZJ8LOCXeUllwBzPIOoP++ke92EscIL/Uo67hXd04+wkmGvzIJOkmAa\nyhPZUUuTLRSFuQzjJui3f+j95GxeuHTGOxeqSQL6I4WskHkKExY5O0nZXjoiz0tB\nI1B4jQIe/Plcr62hgraTD++8iHTSbcMINSc9qp247H9Hdi01fN1V/PAtJJZuwcS2\n8xsUEFGkoxLVAoIBAFFwGvuckrQN2lW1TWhl0+7aoEtgBDzc7KGYvPT5fPPo+TKM\nJQ9MSLzy0mAC1Jdkqy7ku/Im07NO3TV0LyzbXf4d/0yXkisvwSuRoqAORmsJoIIk\ndc6QTCbhhTjx1nKib/0ybHyjndMramGMgFFtBiWD4uQNA8cvv2PX/7LRTlGi+d2m\nmXnhcHUtsKtf32WNBXjnINmFSbFDPDz0DEWrgOA+C+arB78rUPt0GeZmiqQscPNX\nhjGpitm8prvxwskCE2neDiel2ZbKov408sjlLHOayPCwxFpT3SSV9sXFZI9CRbbv\n80U3/v8aTb5JtVzJkLsqbBa+4tsjfmlJY3udFgkCggEATU9p2DEYm3uVT6E/wsyK\nPKWI13dcMANdfZtLH5nI4B/Ers8bfRmhpO3q73QRbqa40zJmKtXdsuE+wq5+rBvw\n6L7oD7cwNYr/Wt51SUAUPCYZuxRCLjWHR+wHZuMr3Yv/9XLFrFlqo54uwnb9w+vt\nHkFUeJuX14KThGtbo/bW7sPYTp4UDG0guQQD3JQG1JaJJBJlu/MZMGWdKkQOsobr\nVUlJ6aamxXBP+gqz9FNWHnAF0F8VYUbHpS7yOjQM4qWgVB24CyzUoyUN7SyPUgiI\n8XAKlGw0uoIDrJAtJiYV0oYicfuqhUiX5I3PKFnCK0cIRY+VIRXi02+49q9wBsFh\nUQKCAQB190+U+7Z7YsvKWIbFxnSIGRpzae2HlVJzRI/aoo79ij5qNfisaZvxhvfY\nUTkz6FzHIJoxq/mAJXKQgQ9ofW+XMR/xWKaFRkiGE2aPy3JecoVOx1OL6TWV7KDX\n2prwflF4WEzkZA25BPmg2GM8sTXXln9xSVwNLe24lF6UNj0KG+6zioUM+oepf70v\nUB63Bn/qQwBGgh72oBni4HxqskNG1bNkKt6emgyr/tRNZGqrKCxjqq3Oa8YMrfbr\nP4goDm0LICzbeLlFtVUT7xpAGuItkK26JGypoAfdU5SybjuKaXDygTcq1EEMyduV\nnUwWh19LU+597M0VXIKm2/H3v4up\n-----END PRIVATE KEY-----\n' +const publicPem = + '-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAu3eAVbBR//sN05yszjSh\n09D9L9e5q6W7z5SqdnsJ7WyENvDunOuuwIKBYOlj6P1XUKtxzwO4/v3Mu4SY4Tu2\n0rH3yP+rnGPSpRSwOOZOOBQcq6b1hK2ucGAbvYNZQSup/eqi1M+9hEgVBvMTrPfP\nm89N6xiwLaJhPAXLhVeAXroGv8yOIClkezcYkZxBx+/vdt0R31R8o08XoyniLWZt\np8xd2ge/hX8RxLc+7EhTouzHR/Pz63bhy9O9aNVVKcb2W5H4lOU9gNdPMEhmjERB\ne9M7u2rU2VyWSzwEpHx/8Vxl5T3f6i7lK0YLrFYhmmR311mCjZ50oEzJgsL+CtIO\nmq1aOYg1EJE7fOxzVPswG+BLp0r2Tx/4sevRh3Ap+BTSuOeTWlS1piV04JA5eeLE\nPrlScIVr4zj4uxMFkIxFMxMar4DD+TZGCnhqAokF56MZs9xndC6xWAnZWf3KV+il\nNN7yGo5CBGIv3Fu7CTsHTB7xOxAQyOeMSu0uGP2XO3N1DGRqv5imfRH8Jy5FhGzt\nwkSf8wPbUHINnqcQLnFvlqj1pc1j272tfVFDifr2IyToTyMIEY3S60VRBUs/F529\njCyhp8+0LMlw1WVbGt9Hxqwfzmt0rOfVc4/qnIKSc1IaBKCkwmeFOWK9qIGKMVtc\nMqsi59G6k0Ik3PjcwZ0gmv8CAwEAAQ==\n-----END PUBLIC KEY-----\n' +const privatePem = + '-----BEGIN PRIVATE KEY-----\nMIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC7d4BVsFH/+w3T\nnKzONKHT0P0v17mrpbvPlKp2ewntbIQ28O6c667AgoFg6WPo/VdQq3HPA7j+/cy7\nhJjhO7bSsffI/6ucY9KlFLA45k44FByrpvWEra5wYBu9g1lBK6n96qLUz72ESBUG\n8xOs98+bz03rGLAtomE8BcuFV4Beuga/zI4gKWR7NxiRnEHH7+923RHfVHyjTxej\nKeItZm2nzF3aB7+FfxHEtz7sSFOi7MdH8/PrduHL071o1VUpxvZbkfiU5T2A108w\nSGaMREF70zu7atTZXJZLPASkfH/xXGXlPd/qLuUrRgusViGaZHfXWYKNnnSgTMmC\nwv4K0g6arVo5iDUQkTt87HNU+zAb4EunSvZPH/ix69GHcCn4FNK455NaVLWmJXTg\nkDl54sQ+uVJwhWvjOPi7EwWQjEUzExqvgMP5NkYKeGoCiQXnoxmz3Gd0LrFYCdlZ\n/cpX6KU03vIajkIEYi/cW7sJOwdMHvE7EBDI54xK7S4Y/Zc7c3UMZGq/mKZ9Efwn\nLkWEbO3CRJ/zA9tQcg2epxAucW+WqPWlzWPbva19UUOJ+vYjJOhPIwgRjdLrRVEF\nSz8Xnb2MLKGnz7QsyXDVZVsa30fGrB/Oa3Ss59Vzj+qcgpJzUhoEoKTCZ4U5Yr2o\ngYoxW1wyqyLn0bqTQiTc+NzBnSCa/wIDAQABAoICACuWf4ps8sP4FaDsPum7Jx1e\n7F+hYxRb9q0vPetKdGZ14s/7eR+XVQyBy59C5O4ZaaHiGxYtIWh4jo/TJtDH15xp\nsNlVSQuV0jZ79vVj5y/2zSvEKDXvRC3wysJntesHQgE9+xpMKx6EvA7fmeWPwP/T\nVaSiGuShasZP+qBIVhqwWj1iTHGB7lEP4HCKymi4iw8yG6O3uzslerN/W41+0WRA\nilnVj1x0zSbWDJVXw8qQD03VlRNckueXleS4JZMPJdzotcm4+3Hnngv16ZIXlLo7\nxRmwn0ji1Dct/05XfFAcUbzZhCSpPrOvF6u8YxfI4Gx77XUMMMXM1NXIjNTrPmWm\nfOtNmCsUiWjFi/aM8cNlH+veoa4SAgY0k3d51ilupd+H7CkHGnvDFKSLK+AWERWr\nGK37ffmJH0p7fXcI445+KQoT2ujm+UKNNfx8PB8jXRs7BTHb2xXhd2kjh/VmV6Gw\nVpgFloNm+OEcFcuqxQdl/Co+EsXhbmtVfb7xDhYxVkwnDRISuQyeahKf2b9sQMrf\noXOiwFLaBdsiqsxAVAVWgzA4brZdZfsLyq8tqdWrIddIDIruvk6UvLjDfhcK9dO9\nNkzIm88CAJi68lS2m/zIitvao5OJ3KyESkdAJzMSGnBYrD7fWyk1wbv0T9PbQpdo\nk/YIwuCVlKosOd355ynxAoIBAQDnm+ODTjv/HhDWLlZyxYZiXe4GfcBrukA9NF/1\nOqIqR93SpR9du2Pc7z1mCkWGFGFx4/KRVsLVl2bUgw0IEkAu4XF5ydy/dG2eLnX0\nMJjJvkXle2Z10zzp45sn8Cx8hYRfehYefBg/vG3QWfXvLGM2A2G3Niqd96FNAIc1\nM7FKcicFvM1NkxEugTK20ZgqzBZIv+WzXtG5qr4aOImBnpQa0+ucien722LE6UNw\nNShsU5kVBhraW/H+ko68xdF2CJS6poySggkd3S5yHOUXga5sPUjIErguILMVw5p1\niXf8hV2NgUp9K4zmG5rHmowMQKwckDu8Zn0oBOe/CAHVQhiDAoIBAQDPNY2V1AlY\nR97zNk8xFYk/G5I/kqcrlxyHcQlJC3ALJXKFdn8vgFfC2oSO4I8VZrieP6s1xYtA\nhdvxOu+8mpUNBal3N/1z/mBMBwmA1La3SE0RW7nWnxwoPMy64uxzVJv3/O8HvOah\n/hk3odxZuGZJ8LOCXeUllwBzPIOoP++ke92EscIL/Uo67hXd04+wkmGvzIJOkmAa\nyhPZUUuTLRSFuQzjJui3f+j95GxeuHTGOxeqSQL6I4WskHkKExY5O0nZXjoiz0tB\nI1B4jQIe/Plcr62hgraTD++8iHTSbcMINSc9qp247H9Hdi01fN1V/PAtJJZuwcS2\n8xsUEFGkoxLVAoIBAFFwGvuckrQN2lW1TWhl0+7aoEtgBDzc7KGYvPT5fPPo+TKM\nJQ9MSLzy0mAC1Jdkqy7ku/Im07NO3TV0LyzbXf4d/0yXkisvwSuRoqAORmsJoIIk\ndc6QTCbhhTjx1nKib/0ybHyjndMramGMgFFtBiWD4uQNA8cvv2PX/7LRTlGi+d2m\nmXnhcHUtsKtf32WNBXjnINmFSbFDPDz0DEWrgOA+C+arB78rUPt0GeZmiqQscPNX\nhjGpitm8prvxwskCE2neDiel2ZbKov408sjlLHOayPCwxFpT3SSV9sXFZI9CRbbv\n80U3/v8aTb5JtVzJkLsqbBa+4tsjfmlJY3udFgkCggEATU9p2DEYm3uVT6E/wsyK\nPKWI13dcMANdfZtLH5nI4B/Ers8bfRmhpO3q73QRbqa40zJmKtXdsuE+wq5+rBvw\n6L7oD7cwNYr/Wt51SUAUPCYZuxRCLjWHR+wHZuMr3Yv/9XLFrFlqo54uwnb9w+vt\nHkFUeJuX14KThGtbo/bW7sPYTp4UDG0guQQD3JQG1JaJJBJlu/MZMGWdKkQOsobr\nVUlJ6aamxXBP+gqz9FNWHnAF0F8VYUbHpS7yOjQM4qWgVB24CyzUoyUN7SyPUgiI\n8XAKlGw0uoIDrJAtJiYV0oYicfuqhUiX5I3PKFnCK0cIRY+VIRXi02+49q9wBsFh\nUQKCAQB190+U+7Z7YsvKWIbFxnSIGRpzae2HlVJzRI/aoo79ij5qNfisaZvxhvfY\nUTkz6FzHIJoxq/mAJXKQgQ9ofW+XMR/xWKaFRkiGE2aPy3JecoVOx1OL6TWV7KDX\n2prwflF4WEzkZA25BPmg2GM8sTXXln9xSVwNLe24lF6UNj0KG+6zioUM+oepf70v\nUB63Bn/qQwBGgh72oBni4HxqskNG1bNkKt6emgyr/tRNZGqrKCxjqq3Oa8YMrfbr\nP4goDm0LICzbeLlFtVUT7xpAGuItkK26JGypoAfdU5SybjuKaXDygTcq1EEMyduV\nnUwWh19LU+597M0VXIKm2/H3v4up\n-----END PRIVATE KEY-----\n' describe('RawRsaKeyringNode::constructor', () => { const keyName = 'keyName' @@ -54,10 +53,10 @@ describe('RawRsaKeyringNode::constructor', () => { const test = new RawRsaKeyringNode({ rsaKey: { privateKey: privatePem, - publicKey: publicPem + publicKey: publicPem, }, keyName, - keyNamespace + keyNamespace, }) expect(test.keyName).to.equal(keyName) @@ -70,10 +69,10 @@ describe('RawRsaKeyringNode::constructor', () => { it('can construct with only public key', () => { const testPublicOnly = new RawRsaKeyringNode({ rsaKey: { - publicKey: publicPem + publicKey: publicPem, }, keyName, - keyNamespace + keyNamespace, }) expect(testPublicOnly).to.be.instanceOf(RawRsaKeyringNode) }) @@ -81,105 +80,139 @@ describe('RawRsaKeyringNode::constructor', () => { it('can construct with only private key', () => { const testPrivateOnly = new RawRsaKeyringNode({ rsaKey: { - privateKey: privatePem + privateKey: privatePem, }, keyName, - keyNamespace + keyNamespace, }) expect(testPrivateOnly).to.be.instanceOf(RawRsaKeyringNode) }) it('Precondition: RsaKeyringNode needs either a public or a private key to operate.', () => { - expect(() => new RawRsaKeyringNode({ - keyName, - keyNamespace, - rsaKey: {} - })).to.throw() + expect( + () => + new RawRsaKeyringNode({ + keyName, + keyNamespace, + rsaKey: {}, + }) + ).to.throw() }) it('Precondition: The AWS ESDK only supports specific hash values for OAEP padding.', () => { - expect(() => new RawRsaKeyringNode({ - keyName, - keyNamespace, - // @ts-ignore Valid hash, but not supported by the ESDK - oaepHash: 'rmd160', - rsaKey: { privateKey: privatePem } - })).to.throw('Unsupported oaepHash') + expect( + () => + new RawRsaKeyringNode({ + keyName, + keyNamespace, + // @ts-ignore Valid hash, but not supported by the ESDK + oaepHash: 'rmd160', + rsaKey: { privateKey: privatePem }, + }) + ).to.throw('Unsupported oaepHash') }) it('Precondition: RsaKeyringNode needs identifying information for encrypt and decrypt.', () => { - // @ts-ignore Typescript is trying to save us. - expect(() => new RawRsaKeyringNode({ - rsaKey: { privateKey: privatePem, publicKey: publicPem } - })).to.throw() - // @ts-ignore Typescript is trying to save us. - expect(() => new RawRsaKeyringNode({ - rsaKey: { privateKey: privatePem, publicKey: publicPem }, - keyNamespace - })).to.throw() - // @ts-ignore Typescript is trying to save us. - expect(() => new RawRsaKeyringNode({ - rsaKey: { privateKey: privatePem, publicKey: publicPem }, - keyName - })).to.throw() + expect( + () => + new RawRsaKeyringNode({ + rsaKey: { privateKey: privatePem, publicKey: publicPem }, + } as any) + ).to.throw() + expect( + () => + new RawRsaKeyringNode({ + rsaKey: { privateKey: privatePem, publicKey: publicPem }, + keyNamespace, + } as any) + ).to.throw() + expect( + () => + new RawRsaKeyringNode({ + rsaKey: { privateKey: privatePem, publicKey: publicPem }, + keyName, + } as any) + ).to.throw() }) }) -const oaepHashOptions: OaepHash[] = [undefined, 'sha1', 'sha256', 'sha384', 'sha512'] +const oaepHashOptions: OaepHash[] = [ + undefined, + 'sha1', + 'sha256', + 'sha384', + 'sha512', +] oaepHashOptions - .filter(oaepHash => oaepHashSupported || [undefined, 'sha1'].includes(oaepHash)) - .forEach(oaepHash => describe(`RawRsaKeyringNode encrypt/decrypt for oaepHash=${oaepHash || 'undefined'}`, () => { - const keyNamespace = 'keyNamespace' - const keyName = 'keyName' - const keyring = new RawRsaKeyringNode({ - rsaKey: { privateKey: privatePem, publicKey: publicPem }, - keyName, - keyNamespace, - oaepHash - }) - let encryptedDataKey: EncryptedDataKey - - it('can encrypt and create unencrypted data key', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) - const material = new NodeEncryptionMaterial(suite, {}) - const test = await keyring.onEncrypt(material) - expect(test.hasValidKey()).to.equal(true) - const udk = unwrapDataKey(test.getUnencryptedDataKey()) - expect(udk).to.have.lengthOf(suite.keyLengthBytes) - expect(test.encryptedDataKeys).to.have.lengthOf(1) - const [edk] = test.encryptedDataKeys - expect(edk.providerId).to.equal(keyNamespace) - encryptedDataKey = edk - }) - - it('can decrypt an EncryptedDataKey', async () => { - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) - const material = new NodeDecryptionMaterial(suite, {}) - const test = await keyring.onDecrypt(material, [encryptedDataKey]) - expect(test.hasValidKey()).to.equal(true) - }) - - it('Precondition: Public key must be defined to support encrypt.', async () => { + .filter( + (oaepHash) => oaepHashSupported || [undefined, 'sha1'].includes(oaepHash) + ) + .forEach((oaepHash) => + describe(`RawRsaKeyringNode encrypt/decrypt for oaepHash=${ + oaepHash || 'undefined' + }`, () => { + const keyNamespace = 'keyNamespace' + const keyName = 'keyName' const keyring = new RawRsaKeyringNode({ - rsaKey: { privateKey: privatePem }, + rsaKey: { privateKey: privatePem, publicKey: publicPem }, keyName, - keyNamespace + keyNamespace, + oaepHash, + }) + let encryptedDataKey: EncryptedDataKey + + it('can encrypt and create unencrypted data key', async () => { + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) + const material = new NodeEncryptionMaterial(suite, {}) + const test = await keyring.onEncrypt(material) + expect(test.hasValidKey()).to.equal(true) + const udk = unwrapDataKey(test.getUnencryptedDataKey()) + expect(udk).to.have.lengthOf(suite.keyLengthBytes) + expect(test.encryptedDataKeys).to.have.lengthOf(1) + const [edk] = test.encryptedDataKeys + expect(edk.providerId).to.equal(keyNamespace) + encryptedDataKey = edk }) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) - const material = new NodeEncryptionMaterial(suite, {}) - return expect(keyring.onEncrypt(material)).to.rejectedWith(Error) - }) + it('can decrypt an EncryptedDataKey', async () => { + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) + const material = new NodeDecryptionMaterial(suite, {}) + const test = await keyring.onDecrypt(material, [encryptedDataKey]) + expect(test.hasValidKey()).to.equal(true) + }) - it('Precondition: Private key must be defined to support decrypt.', async () => { - const keyring = new RawRsaKeyringNode({ - rsaKey: { publicKey: publicPem }, - keyName, - keyNamespace + it('Precondition: Public key must be defined to support encrypt.', async () => { + const keyring = new RawRsaKeyringNode({ + rsaKey: { privateKey: privatePem }, + keyName, + keyNamespace, + }) + + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) + const material = new NodeEncryptionMaterial(suite, {}) + return expect(keyring.onEncrypt(material)).to.rejectedWith(Error) }) - const suite = new NodeAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256) - const material = new NodeDecryptionMaterial(suite, {}) - return expect(keyring._unwrapKey(material, encryptedDataKey)).to.rejectedWith(Error) + it('Precondition: Private key must be defined to support decrypt.', async () => { + const keyring = new RawRsaKeyringNode({ + rsaKey: { publicKey: publicPem }, + keyName, + keyNamespace, + }) + + const suite = new NodeAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256 + ) + const material = new NodeDecryptionMaterial(suite, {}) + return expect( + keyring._unwrapKey(material, encryptedDataKey) + ).to.rejectedWith(Error) + }) }) - })) + ) diff --git a/modules/serialize/test/aad_factory.test.ts b/modules/serialize/test/aad_factory.test.ts index e95d8204a..95703b86f 100644 --- a/modules/serialize/test/aad_factory.test.ts +++ b/modules/serialize/test/aad_factory.test.ts @@ -9,33 +9,52 @@ import { ContentType, ContentAADString } from '../src/identifiers' describe('aadFactory:messageAADContentString', () => { it('should return framed string for a non-final-frame', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { messageAADContentString } = aadFactory(fromUtf8) const contentType = ContentType.FRAMED_DATA const isFinalFrame = false - expect(messageAADContentString({ contentType, isFinalFrame })).to.eql(ContentAADString.FRAME_STRING_ID) + expect(messageAADContentString({ contentType, isFinalFrame })).to.eql( + ContentAADString.FRAME_STRING_ID + ) }) it('should return final framed string for a final-frame', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { messageAADContentString } = aadFactory(fromUtf8) const contentType = ContentType.FRAMED_DATA const isFinalFrame = true - expect(messageAADContentString({ contentType, isFinalFrame })).to.eql(ContentAADString.FINAL_FRAME_STRING_ID) + expect(messageAADContentString({ contentType, isFinalFrame })).to.eql( + ContentAADString.FINAL_FRAME_STRING_ID + ) }) it('should return non-framed string for a non-frame case', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { messageAADContentString } = aadFactory(fromUtf8) const contentType = ContentType.NO_FRAMING - expect(messageAADContentString({ contentType, isFinalFrame: true })).to.eql(ContentAADString.NON_FRAMED_STRING_ID) - expect(messageAADContentString({ contentType, isFinalFrame: false })).to.eql(ContentAADString.NON_FRAMED_STRING_ID) + expect(messageAADContentString({ contentType, isFinalFrame: true })).to.eql( + ContentAADString.NON_FRAMED_STRING_ID + ) + expect( + messageAADContentString({ contentType, isFinalFrame: false }) + ).to.eql(ContentAADString.NON_FRAMED_STRING_ID) }) it('should throw for an unrecognized frame types', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { messageAADContentString } = aadFactory(fromUtf8) - // @ts-ignore to force the error - const test = () => messageAADContentString({ contentType: 'something', isFinalFrame: true }) + const test = () => + messageAADContentString({ + contentType: 'something', + isFinalFrame: true, + } as any) expect(test).to.throw() }) }) @@ -50,19 +69,83 @@ describe('aadFactory:messageAAD', () => { const messageId = Buffer.alloc(16, 1) - const test = messageAAD(messageId, ContentAADString.NON_FRAMED_STRING_ID, 1, 100) + const test = messageAAD( + messageId, + ContentAADString.NON_FRAMED_STRING_ID, + 1, + 100 + ) expect(test).to.be.instanceof(Uint8Array) const length = 16 + ContentAADString.NON_FRAMED_STRING_ID.length + 4 + 8 expect(test.byteLength).to.eql(length) - expect(test).to.deep.equal(new Uint8Array([ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 65, 87, 83, 75, 77, 83, - 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 67, - 108, 105, 101, 110, 116, 32, 83, 105, 110, 103, 108, 101, - 32, 66, 108, 111, 99, 107, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 100 - ])) + expect(test).to.deep.equal( + new Uint8Array([ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 65, + 87, + 83, + 75, + 77, + 83, + 69, + 110, + 99, + 114, + 121, + 112, + 116, + 105, + 111, + 110, + 67, + 108, + 105, + 101, + 110, + 116, + 32, + 83, + 105, + 110, + 103, + 108, + 101, + 32, + 66, + 108, + 111, + 99, + 107, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 100, + ]) + ) }) }) diff --git a/modules/serialize/test/concat_buffers.test.ts b/modules/serialize/test/concat_buffers.test.ts index 811bb65ed..1efb8535c 100644 --- a/modules/serialize/test/concat_buffers.test.ts +++ b/modules/serialize/test/concat_buffers.test.ts @@ -9,7 +9,9 @@ import { Buffer } from 'buffer' describe('concatBuffers', () => { it('should concatenate simple Uint8Array', () => { - const buff = Array(5).fill(1).map((_, i) => new Uint8Array([i])) + const buff = Array(5) + .fill(1) + .map((_, i) => new Uint8Array([i])) const test = concatBuffers(...buff) expect(test).to.be.instanceof(Uint8Array) expect(test.byteLength).to.eql(5) @@ -17,7 +19,9 @@ describe('concatBuffers', () => { }) it('should concatenate simple ArrayBuffer', () => { - const buff = Array(5).fill(1).map((_, i) => new Uint8Array([i]).buffer) + const buff = Array(5) + .fill(1) + .map((_, i) => new Uint8Array([i]).buffer) const test = concatBuffers(...buff) expect(test).to.be.instanceof(Uint8Array) expect(test.byteLength).to.eql(5) @@ -25,7 +29,9 @@ describe('concatBuffers', () => { }) it('should concatenate simple Node Buffer', () => { - const buff = Array(5).fill(1).map((_, i) => Buffer.alloc(1, i)) + const buff = Array(5) + .fill(1) + .map((_, i) => Buffer.alloc(1, i)) const test = concatBuffers(...buff) expect(test).to.be.instanceof(Uint8Array) expect(test.byteLength).to.eql(5) diff --git a/modules/serialize/test/decode_body_header.test.ts b/modules/serialize/test/decode_body_header.test.ts index 2efa82083..0c52ae6dd 100644 --- a/modules/serialize/test/decode_body_header.test.ts +++ b/modules/serialize/test/decode_body_header.test.ts @@ -8,7 +8,7 @@ import { decodeFrameBodyHeader, decodeNonFrameBodyHeader, decodeBodyHeader, - decodeFinalFrameBodyHeader + decodeFinalFrameBodyHeader, } from '../src/decode_body_header' import { concatBuffers } from '../src' import * as fixtures from './fixtures' @@ -19,12 +19,12 @@ describe('decodeBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const test = decodeBodyHeader(fixtures.basicFrameHeader(), headerInfo, 0) @@ -35,12 +35,12 @@ describe('decodeBodyHeader', () => { it('calls decodeNonFrameBodyHeader', () => { const headerInfo = { messageHeader: { - contentType: ContentType.NO_FRAMING + contentType: ContentType.NO_FRAMING, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const test = decodeBodyHeader(fixtures.basicNonFrameHeader(), headerInfo, 0) @@ -51,15 +51,17 @@ describe('decodeBodyHeader', () => { it('Precondition: The contentType must be a supported format.', () => { const headerInfo = { messageHeader: { - contentType: 'does not exist' + contentType: 'does not exist', }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any - expect(() => decodeBodyHeader(fixtures.basicNonFrameHeader(), headerInfo, 0)).to.throw('Unknown contentType') + expect(() => + decodeBodyHeader(fixtures.basicNonFrameHeader(), headerInfo, 0) + ).to.throw('Unknown contentType') }) }) @@ -68,15 +70,19 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any - const test = decodeFrameBodyHeader(fixtures.basicFrameHeader(), headerInfo, 0) + const test = decodeFrameBodyHeader( + fixtures.basicFrameHeader(), + headerInfo, + 0 + ) if (!test) throw new Error('failure') expect(test.sequenceNumber).to.eql(1) expect(test.iv).to.eql(fixtures.basicFrameIV()) @@ -90,15 +96,19 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any - const test = decodeFrameBodyHeader(fixtures.finalFrameHeader(), headerInfo, 0) + const test = decodeFrameBodyHeader( + fixtures.finalFrameHeader(), + headerInfo, + 0 + ) if (!test) throw new Error('failure') expect(test.sequenceNumber).to.eql(1) expect(test.iv).to.eql(fixtures.basicFrameIV()) @@ -112,15 +122,17 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: 'not FRAMED_DATA' + contentType: 'not FRAMED_DATA', }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any - expect(() => decodeFrameBodyHeader(fixtures.basicFrameHeader(), headerInfo, 0)).to.throw('Unknown contentType') + expect(() => + decodeFrameBodyHeader(fixtures.basicFrameHeader(), headerInfo, 0) + ).to.throw('Unknown contentType') }) it('Check for early return (Postcondition): There must be enough data to decodeFrameBodyHeader.', () => { @@ -128,12 +140,12 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any for (let i = 0; frameHeader.byteLength > i; i++) { @@ -146,12 +158,12 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = concatBuffers( @@ -171,16 +183,19 @@ describe('decodeFrameBodyHeader', () => { }) it('return false for partial basic frame from readPos', () => { - const buffer = concatBuffers(new Uint8Array(10), fixtures.basicFrameHeader()) + const buffer = concatBuffers( + new Uint8Array(10), + fixtures.basicFrameHeader() + ) const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any for (let i = 10; buffer.byteLength - 1 > i; i++) { @@ -190,16 +205,19 @@ describe('decodeFrameBodyHeader', () => { }) it('return false for partial frame from readPos', () => { - const buffer = concatBuffers(new Uint8Array(10), fixtures.finalFrameHeader()) + const buffer = concatBuffers( + new Uint8Array(10), + fixtures.finalFrameHeader() + ) const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any for (let i = 10; buffer.byteLength > i; i++) { @@ -212,16 +230,18 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.basicFrameHeader() - expect(() => decodeFrameBodyHeader(buffer, headerInfo, buffer.byteLength + 1)).to.throw() + expect(() => + decodeFrameBodyHeader(buffer, headerInfo, buffer.byteLength + 1) + ).to.throw() expect(() => decodeFrameBodyHeader(buffer, headerInfo, -1)).to.throw() }) @@ -229,27 +249,33 @@ describe('decodeFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any - expect(() => decodeFrameBodyHeader(fixtures.invalidSequenceNumberFrameHeader(), headerInfo, 0)).to.throw('Malformed sequenceNumber.') + expect(() => + decodeFrameBodyHeader( + fixtures.invalidSequenceNumberFrameHeader(), + headerInfo, + 0 + ) + ).to.throw('Malformed sequenceNumber.') }) it('ArrayBuffer for a Uint8Array or Buffer may be larger than the Uint8Array or Buffer that it is a view over is.', () => { const headerInfo = { messageHeader: { frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any /* Create a Uint8Array that has an a valid FrameHeader but is proceeded by "invalid" bytes. */ @@ -268,7 +294,11 @@ describe('decodeFrameBodyHeader', () => { /* Given this I can use this to construct a new view of part of the * ArrayBuffer to simulate a large ArrayBuffer that is sliced * into parts for efficiency. */ - const sharingArrayBuffer = new Uint8Array(buff.buffer, 5, buff.byteLength - 5) + const sharingArrayBuffer = new Uint8Array( + buff.buffer, + 5, + buff.byteLength - 5 + ) const test = decodeFrameBodyHeader(sharingArrayBuffer, headerInfo, 0) if (!test) throw new Error('failure') expect(test.sequenceNumber).to.eql(1) @@ -285,12 +315,12 @@ describe('decodeFinalFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = concatBuffers( new Uint8Array(10), // pre @@ -313,12 +343,12 @@ describe('decodeFinalFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.finalFrameHeaderZeroBytes() @@ -336,64 +366,74 @@ describe('decodeFinalFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: 'not FRAMED_DATA' + contentType: 'not FRAMED_DATA', }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any - expect(() => decodeFinalFrameBodyHeader(fixtures.finalFrameHeader(), headerInfo, 0)).to.throw('Unknown contentType') + expect(() => + decodeFinalFrameBodyHeader(fixtures.finalFrameHeader(), headerInfo, 0) + ).to.throw('Unknown contentType') }) it('Precondition: decodeFinalFrameBodyHeader readPos must be within the byte length of the buffer given.', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.finalFrameHeader() - expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, buffer.byteLength + 1)).to.throw('readPos out of bounds.') - expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, -1)).to.throw('readPos out of bounds.') + expect(() => + decodeFinalFrameBodyHeader(buffer, headerInfo, buffer.byteLength + 1) + ).to.throw('readPos out of bounds.') + expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, -1)).to.throw( + 'readPos out of bounds.' + ) }) it('Postcondition: sequenceEnd must be SEQUENCE_NUMBER_END.', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.invalidSequenceEndFinalFrameHeader() - expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, 0)).to.throw('Malformed final frame: Invalid sequence number end value') + expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, 0)).to.throw( + 'Malformed final frame: Invalid sequence number end value' + ) }) it('Postcondition: decodeFinalFrameBodyHeader sequenceNumber must be greater than 0.', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.invalidSequenceNumberFinalFrameHeader() - expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, 0)).to.throw('Malformed sequenceNumber.') + expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, 0)).to.throw( + 'Malformed sequenceNumber.' + ) }) it('Check for early return (Postcondition): There must be enough data to decodeFinalFrameBodyHeader.', () => { @@ -401,16 +441,20 @@ describe('decodeFinalFrameBodyHeader', () => { const headerInfo = { messageHeader: { frameLength: 999, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any for (let i = 0; frameHeader.byteLength > i; i++) { - const test = decodeFinalFrameBodyHeader(frameHeader.slice(0, i), headerInfo, 0) + const test = decodeFinalFrameBodyHeader( + frameHeader.slice(0, i), + headerInfo, + 0 + ) expect(test).to.eql(false) } }) @@ -421,16 +465,18 @@ describe('decodeFinalFrameBodyHeader', () => { // The content length in this final frame is 999 // So I set the frame length to less than this frameLength: 99, - contentType: ContentType.FRAMED_DATA + contentType: ContentType.FRAMED_DATA, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.finalFrameHeader() - expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, 0)).to.throw('Final frame length exceeds frame length.') + expect(() => decodeFinalFrameBodyHeader(buffer, headerInfo, 0)).to.throw( + 'Final frame length exceeds frame length.' + ) }) }) @@ -438,12 +484,12 @@ describe('decodeNonFrameBodyHeader', () => { it('return non frame header', () => { const headerInfo = { messageHeader: { - contentType: ContentType.NO_FRAMING + contentType: ContentType.NO_FRAMING, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.basicNonFrameHeader() @@ -461,33 +507,39 @@ describe('decodeNonFrameBodyHeader', () => { it('Precondition: The contentType must be NO_FRAMING.', () => { const headerInfo = { messageHeader: { - contentType: 'not NO_FRAMING' + contentType: 'not NO_FRAMING', }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.basicNonFrameHeader() - expect(() => decodeNonFrameBodyHeader(buffer, headerInfo, 0)).to.throw('Unknown contentType') + expect(() => decodeNonFrameBodyHeader(buffer, headerInfo, 0)).to.throw( + 'Unknown contentType' + ) }) it('Check for early return (Postcondition): There must be enough data to decodeNonFrameBodyHeader.', () => { const headerInfo = { messageHeader: { - contentType: ContentType.NO_FRAMING + contentType: ContentType.NO_FRAMING, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const frameHeader = fixtures.basicNonFrameHeader() for (let i = 0; frameHeader.byteLength > i; i++) { - const test = decodeNonFrameBodyHeader(frameHeader.slice(0, i), headerInfo, 0) + const test = decodeNonFrameBodyHeader( + frameHeader.slice(0, i), + headerInfo, + 0 + ) expect(test).to.eql(false) } }) @@ -495,32 +547,37 @@ describe('decodeNonFrameBodyHeader', () => { it('Precondition: decodeNonFrameBodyHeader readPos must be within the byte length of the buffer given.', () => { const headerInfo = { messageHeader: { - contentType: ContentType.NO_FRAMING + contentType: ContentType.NO_FRAMING, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any const buffer = fixtures.basicNonFrameHeader() - expect(() => decodeNonFrameBodyHeader(buffer, headerInfo, buffer.byteLength + 1)).to.throw() + expect(() => + decodeNonFrameBodyHeader(buffer, headerInfo, buffer.byteLength + 1) + ).to.throw() expect(() => decodeNonFrameBodyHeader(buffer, headerInfo, -1)).to.throw() }) it('ArrayBuffer for a Uint8Array or Buffer may be larger than the Uint8Array or Buffer that it is a view over is.', () => { const headerInfo = { messageHeader: { - contentType: ContentType.NO_FRAMING + contentType: ContentType.NO_FRAMING, }, algorithmSuite: { ivLength: 12, - tagLength: 16 - } + tagLength: 16, + }, } as any /* Create a Uint8Array that has an a valid FrameHeader but is proceeded by "invalid" bytes. */ - const buff = concatBuffers(new Uint8Array(5), fixtures.basicNonFrameHeader()) + const buff = concatBuffers( + new Uint8Array(5), + fixtures.basicNonFrameHeader() + ) const shouldFail = decodeNonFrameBodyHeader(buff, headerInfo, 0) if (!shouldFail) throw new Error('failure') expect(shouldFail.iv).to.not.eql(fixtures.basicFrameIV()) @@ -532,7 +589,11 @@ describe('decodeNonFrameBodyHeader', () => { /* Given this I can use this to construct a new view of part of the * ArrayBuffer to simulate a large ArrayBuffer that is sliced * into parts for efficiency. */ - const sharingArrayBuffer = new Uint8Array(buff.buffer, 5, buff.byteLength - 5) + const sharingArrayBuffer = new Uint8Array( + buff.buffer, + 5, + buff.byteLength - 5 + ) const test = decodeNonFrameBodyHeader(sharingArrayBuffer, headerInfo, 0) if (!test) throw new Error('failure') expect(test.iv).to.eql(fixtures.basicFrameIV()) diff --git a/modules/serialize/test/deserialize_factory.test.ts b/modules/serialize/test/deserialize_factory.test.ts index 3ba5ae75a..81ad21b7b 100644 --- a/modules/serialize/test/deserialize_factory.test.ts +++ b/modules/serialize/test/deserialize_factory.test.ts @@ -6,51 +6,72 @@ import { expect } from 'chai' import { deserializeFactory } from '../src/deserialize_factory' import { concatBuffers } from '../src' -import { WebCryptoAlgorithmSuite, EncryptedDataKey } from '@aws-crypto/material-management' +import { + WebCryptoAlgorithmSuite, + EncryptedDataKey, +} from '@aws-crypto/material-management' import * as fixtures from './fixtures' const toUtf8 = (input: Uint8Array) => Buffer.from(input).toString() describe('deserializeFactory:decodeEncryptionContext', () => { it('returns context object', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const contextSection = fixtures.basicEncryptionContext() const test = decodeEncryptionContext(contextSection.slice(2)) - expect(test).to.have.property('some') - .and.to.eql('public') - expect(test).to.have.property('information') + expect(test).to.have.property('some').and.to.eql('public') + expect(test) + .to.have.property('information') .and.to.eql('\u00bd + \u00bc = \u00be') }) it('Check for early return (Postcondition): The case of 0 length is defined as an empty object.', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const test = decodeEncryptionContext(new Uint8Array(0)) expect(test).to.be.deep.equal({}) }) it('Postcondition: Since the encryption context has a length, it must have pairs.', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const badContextSection = fixtures.missingDataEncryptionContext().slice(2) expect(() => decodeEncryptionContext(badContextSection)).to.throw() }) it('Postcondition: The byte length of the encodedEncryptionContext must match the readPos.', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const badContextSection = fixtures.tooMuchDataEncryptionContext().slice(2) expect(() => decodeEncryptionContext(badContextSection)).to.throw() }) it('Postcondition: The number of keys in the encryptionContext must match the pairsCount.', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const badContextSection = fixtures.duplicateKeysEncryptionContext().slice(2) expect(() => decodeEncryptionContext(badContextSection)).to.throw() }) it('ArrayBuffer for a Uint8Array or Buffer may be larger than the Uint8Array or Buffer that it is a view over is.', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) /* Create a Uint8Array that has an a valid FrameHeader but is proceeded by "invalid" bytes. (the Length part) */ const buff = fixtures.basicEncryptionContext() @@ -58,58 +79,78 @@ describe('deserializeFactory:decodeEncryptionContext', () => { /* Given this I can use this to construct a new view of part of the * ArrayBuffer to simulate a large ArrayBuffer that is sliced * into parts for efficiency. */ - const sharingArrayBuffer = new Uint8Array(buff.buffer, 2, buff.byteLength - 2) + const sharingArrayBuffer = new Uint8Array( + buff.buffer, + 2, + buff.byteLength - 2 + ) const test = decodeEncryptionContext(sharingArrayBuffer) - expect(test).to.have.property('some') - .and.to.eql('public') - expect(test).to.have.property('information') + expect(test).to.have.property('some').and.to.eql('public') + expect(test) + .to.have.property('information') .and.to.eql('\u00bd + \u00bc = \u00be') }) it('Keys may be properties of Object.prototype, decodeEncryptionContext has to succeed', () => { - const { decodeEncryptionContext } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { decodeEncryptionContext } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) /* hasOwnProperty test vector */ - const encryptionContext = fixtures.hasOwnPropertyEncryptionContext().slice(2) + const encryptionContext = fixtures + .hasOwnPropertyEncryptionContext() + .slice(2) const test = decodeEncryptionContext(encryptionContext) - expect(test).to.have.property('hasOwnProperty') - .and.to.eql('arbitraryValue') + expect(test).to.have.property('hasOwnProperty').and.to.eql('arbitraryValue') }) }) describe('deserializeFactory:deserializeEncryptedDataKeys', () => { it('return EncryptedDataKey info', () => { - const { deserializeEncryptedDataKeys } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeEncryptedDataKeys } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const buffer = fixtures.encryptedDataKey() const test = deserializeEncryptedDataKeys(buffer, 0) if (!test) throw new Error('fail') - expect(test).to.have.property('encryptedDataKeys') + expect(test) + .to.have.property('encryptedDataKeys') .and.to.be.an('Array') .and.to.have.lengthOf(2) - expect(test).to.have.property('readPos') - .and.to.eql(buffer.byteLength) + expect(test).to.have.property('readPos').and.to.eql(buffer.byteLength) const { encryptedDataKeys } = test expect(encryptedDataKeys[0]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[0].providerInfo).to.eql('firstKey') expect(encryptedDataKeys[0].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[0].rawInfo).to.deep.equal(new Uint8Array([ 102, 105, 114, 115, 116, 75, 101, 121 ])) - expect(encryptedDataKeys[0].encryptedDataKey) - .to.deep.equal(new Uint8Array([1, 2, 3, 4, 5])) + expect(encryptedDataKeys[0].rawInfo).to.deep.equal( + new Uint8Array([102, 105, 114, 115, 116, 75, 101, 121]) + ) + expect(encryptedDataKeys[0].encryptedDataKey).to.deep.equal( + new Uint8Array([1, 2, 3, 4, 5]) + ) expect(encryptedDataKeys[1]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[1].providerInfo).to.eql('secondKey') expect(encryptedDataKeys[1].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[1].rawInfo).to.deep.equal(new Uint8Array([ 115, 101, 99, 111, 110, 100, 75, 101, 121 ])) - expect(encryptedDataKeys[1].encryptedDataKey) - .to.deep.equal(new Uint8Array([6, 7, 8, 9, 0])) + expect(encryptedDataKeys[1].rawInfo).to.deep.equal( + new Uint8Array([115, 101, 99, 111, 110, 100, 75, 101, 121]) + ) + expect(encryptedDataKeys[1].encryptedDataKey).to.deep.equal( + new Uint8Array([6, 7, 8, 9, 0]) + ) }) it(`Check for early return (Postcondition): Need to have at least Uint16 (2) bytes of data. Check for early return (Postcondition): readElement will return false if there is not enough data.`, () => { - const { deserializeEncryptedDataKeys } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeEncryptedDataKeys } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const buffer = fixtures.encryptedDataKey() // By testing every buffer size, we check every boundary condition for "not enough data" @@ -120,43 +161,60 @@ describe('deserializeFactory:deserializeEncryptedDataKeys', () => { }) it('Precondition: There must be at least 1 EncryptedDataKey element.', () => { - const { deserializeEncryptedDataKeys } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeEncryptedDataKeys } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const buffer = new Uint8Array(2) expect(() => deserializeEncryptedDataKeys(buffer, 0)).to.throw() }) it('Precondition: startPos must be within the byte length of the buffer given.', () => { - const { deserializeEncryptedDataKeys } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeEncryptedDataKeys } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const buffer = new Uint8Array(10) - expect(() => deserializeEncryptedDataKeys(buffer, buffer.byteLength + 1)).to.throw() + expect(() => + deserializeEncryptedDataKeys(buffer, buffer.byteLength + 1) + ).to.throw() expect(() => deserializeEncryptedDataKeys(buffer, -1)).to.throw() }) it('ArrayBuffer for a Uint8Array or Buffer may be larger than the Uint8Array or Buffer that it is a view over is.', () => { /* Create a Uint8Array that has an a valid FrameHeader but is proceeded by "invalid" bytes. */ - const { deserializeEncryptedDataKeys } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeEncryptedDataKeys } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const buffer = concatBuffers(new Uint8Array(5), fixtures.encryptedDataKey()) expect(() => deserializeEncryptedDataKeys(buffer, 0)).to.throw() // Now we verify that the if we read from after the "invalid" section everything is OK. const verify = deserializeEncryptedDataKeys(buffer, 5) - expect(verify).to.have.property('encryptedDataKeys') + expect(verify) + .to.have.property('encryptedDataKeys') .and.to.be.an('Array') .and.to.have.lengthOf(2) - expect(verify).to.have.property('readPos') - .and.to.eql(buffer.byteLength) + expect(verify).to.have.property('readPos').and.to.eql(buffer.byteLength) /* Given this I can use this to construct a new view of part of the * ArrayBuffer to simulate a large ArrayBuffer that is sliced * into parts for efficiency. */ - const sharingArrayBuffer = new Uint8Array(buffer.buffer, 5, buffer.byteLength - 5) + const sharingArrayBuffer = new Uint8Array( + buffer.buffer, + 5, + buffer.byteLength - 5 + ) const test = deserializeEncryptedDataKeys(sharingArrayBuffer, 0) if (!test) throw new Error('fail') - expect(test).to.have.property('encryptedDataKeys') + expect(test) + .to.have.property('encryptedDataKeys') .and.to.be.an('Array') .and.to.have.lengthOf(2) - expect(test).to.have.property('readPos') + expect(test) + .to.have.property('readPos') .and.to.eql(sharingArrayBuffer.byteLength) const { encryptedDataKeys } = test @@ -164,57 +222,61 @@ describe('deserializeFactory:deserializeEncryptedDataKeys', () => { expect(encryptedDataKeys[0]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[0].providerInfo).to.eql('firstKey') expect(encryptedDataKeys[0].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[0].encryptedDataKey) - .to.deep.equal(new Uint8Array([1, 2, 3, 4, 5])) + expect(encryptedDataKeys[0].encryptedDataKey).to.deep.equal( + new Uint8Array([1, 2, 3, 4, 5]) + ) expect(encryptedDataKeys[1]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[1].providerInfo).to.eql('secondKey') expect(encryptedDataKeys[1].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[1].encryptedDataKey) - .to.deep.equal(new Uint8Array([6, 7, 8, 9, 0])) + expect(encryptedDataKeys[1].encryptedDataKey).to.deep.equal( + new Uint8Array([6, 7, 8, 9, 0]) + ) }) }) describe('deserializeFactory:deserializeMessageHeader', () => { it('return header information with context', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const basicMessageHeader = fixtures.basicMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) - const buffer = concatBuffers( - basicMessageHeader, - headerIv, - headerAuthTag - ) + const buffer = concatBuffers(basicMessageHeader, headerIv, headerAuthTag) const test = deserializeMessageHeader(buffer) if (!test) throw new Error('fail') - expect(test).to.have.property('headerLength') + expect(test) + .to.have.property('headerLength') .and.to.deep.equal(basicMessageHeader.byteLength) - expect(test).to.have.property('rawHeader') + expect(test) + .to.have.property('rawHeader') .and.to.deep.equal(basicMessageHeader) - expect(test).to.have.property('headerIv') - .and.to.deep.equal(headerIv) - expect(test).to.have.property('headerAuthTag') + expect(test).to.have.property('headerIv').and.to.deep.equal(headerIv) + expect(test) + .to.have.property('headerAuthTag') .and.to.deep.equal(headerAuthTag) - expect(test).to.have.property('algorithmSuite') + expect(test) + .to.have.property('algorithmSuite') .and.to.be.instanceOf(WebCryptoAlgorithmSuite) expect(test.algorithmSuite.id).to.eql(0x0014) const { messageHeader } = test - expect(messageHeader).to.have.property('version') - .and.to.eql(1) - expect(messageHeader).to.have.property('type') - .and.to.eql(128) - expect(messageHeader).to.have.property('suiteId') - .and.to.eql(0x0014) - expect(messageHeader).to.have.property('messageId') + expect(messageHeader).to.have.property('version').and.to.eql(1) + expect(messageHeader).to.have.property('type').and.to.eql(128) + expect(messageHeader).to.have.property('suiteId').and.to.eql(0x0014) + expect(messageHeader) + .to.have.property('messageId') .and.to.deep.equal(new Uint8Array(16).fill(3)) - expect(messageHeader).to.have.property('encryptionContext') + expect(messageHeader) + .to.have.property('encryptionContext') .and.to.deep.equal({ some: 'public', information: '½ + ¼ = ¾' }) - expect(messageHeader).to.have.property('encryptedDataKeys') + expect(messageHeader) + .to.have.property('encryptedDataKeys') .and.to.be.an('Array') .and.to.have.lengthOf(2) @@ -223,36 +285,34 @@ describe('deserializeFactory:deserializeMessageHeader', () => { expect(encryptedDataKeys[0]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[0].providerInfo).to.eql('firstKey') expect(encryptedDataKeys[0].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[0].encryptedDataKey) - .to.deep.equal(new Uint8Array([1, 2, 3, 4, 5])) + expect(encryptedDataKeys[0].encryptedDataKey).to.deep.equal( + new Uint8Array([1, 2, 3, 4, 5]) + ) expect(encryptedDataKeys[1]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[1].providerInfo).to.eql('secondKey') expect(encryptedDataKeys[1].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[1].encryptedDataKey) - .to.deep.equal(new Uint8Array([6, 7, 8, 9, 0])) - - expect(messageHeader).to.have.property('contentType') - .and.to.eql(2) - expect(messageHeader).to.have.property('headerIvLength') - .and.to.eql(12) - expect(messageHeader).to.have.property('frameLength') - .and.to.eql(4096) + expect(encryptedDataKeys[1].encryptedDataKey).to.deep.equal( + new Uint8Array([6, 7, 8, 9, 0]) + ) + + expect(messageHeader).to.have.property('contentType').and.to.eql(2) + expect(messageHeader).to.have.property('headerIvLength').and.to.eql(12) + expect(messageHeader).to.have.property('frameLength').and.to.eql(4096) }) it(`Check for early return (Postcondition): Not Enough Data. Need to have at least 22 bytes of data to begin parsing. Check for early return (Postcondition): Not Enough Data. Need to have all of the context in bytes before we can parse the next section. Check for early return (Postcondition): Not Enough Data. deserializeEncryptedDataKeys will return false if it does not have enough data. Check for early return (Postcondition): Not Enough Data. Need to have the remaining fixed length data to parse. `, () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const basicMessageHeader = fixtures.basicMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) - const buffer = concatBuffers( - basicMessageHeader, - headerIv, - headerAuthTag - ) + const buffer = concatBuffers(basicMessageHeader, headerIv, headerAuthTag) // By testing every buffer size, we check every boundary condition for "not enough data" for (let i = 0; buffer.byteLength > i; i++) { @@ -262,7 +322,10 @@ describe('deserializeFactory:deserializeMessageHeader', () => { }) it('return header information without context', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const zeroByteEncryptionContextMessageHeader = fixtures.zeroByteEncryptionContextMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) @@ -274,32 +337,35 @@ describe('deserializeFactory:deserializeMessageHeader', () => { const test = deserializeMessageHeader(buffer) if (!test) throw new Error('fail') - expect(test).to.have.property('headerLength') + expect(test) + .to.have.property('headerLength') .and.to.deep.equal(zeroByteEncryptionContextMessageHeader.byteLength) - expect(test).to.have.property('rawHeader') + expect(test) + .to.have.property('rawHeader') .and.to.deep.equal(zeroByteEncryptionContextMessageHeader) - expect(test).to.have.property('headerIv') - .and.to.deep.equal(headerIv) - expect(test).to.have.property('headerAuthTag') + expect(test).to.have.property('headerIv').and.to.deep.equal(headerIv) + expect(test) + .to.have.property('headerAuthTag') .and.to.deep.equal(headerAuthTag) - expect(test).to.have.property('algorithmSuite') + expect(test) + .to.have.property('algorithmSuite') .and.to.be.instanceOf(WebCryptoAlgorithmSuite) expect(test.algorithmSuite.id).to.eql(0x0014) const { messageHeader } = test - expect(messageHeader).to.have.property('version') - .and.to.eql(1) - expect(messageHeader).to.have.property('type') - .and.to.eql(128) - expect(messageHeader).to.have.property('suiteId') - .and.to.eql(0x0014) - expect(messageHeader).to.have.property('messageId') + expect(messageHeader).to.have.property('version').and.to.eql(1) + expect(messageHeader).to.have.property('type').and.to.eql(128) + expect(messageHeader).to.have.property('suiteId').and.to.eql(0x0014) + expect(messageHeader) + .to.have.property('messageId') .and.to.deep.equal(new Uint8Array(16).fill(3)) - expect(messageHeader).to.have.property('encryptionContext') + expect(messageHeader) + .to.have.property('encryptionContext') .and.to.deep.equal({}) - expect(messageHeader).to.have.property('encryptedDataKeys') + expect(messageHeader) + .to.have.property('encryptedDataKeys') .and.to.be.an('Array') .and.to.have.lengthOf(2) @@ -308,25 +374,27 @@ describe('deserializeFactory:deserializeMessageHeader', () => { expect(encryptedDataKeys[0]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[0].providerInfo).to.eql('firstKey') expect(encryptedDataKeys[0].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[0].encryptedDataKey) - .to.deep.equal(new Uint8Array([1, 2, 3, 4, 5])) + expect(encryptedDataKeys[0].encryptedDataKey).to.deep.equal( + new Uint8Array([1, 2, 3, 4, 5]) + ) expect(encryptedDataKeys[1]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[1].providerInfo).to.eql('secondKey') expect(encryptedDataKeys[1].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[1].encryptedDataKey) - .to.deep.equal(new Uint8Array([6, 7, 8, 9, 0])) - - expect(messageHeader).to.have.property('contentType') - .and.to.eql(2) - expect(messageHeader).to.have.property('headerIvLength') - .and.to.eql(12) - expect(messageHeader).to.have.property('frameLength') - .and.to.eql(4096) + expect(encryptedDataKeys[1].encryptedDataKey).to.deep.equal( + new Uint8Array([6, 7, 8, 9, 0]) + ) + + expect(messageHeader).to.have.property('contentType').and.to.eql(2) + expect(messageHeader).to.have.property('headerIvLength').and.to.eql(12) + expect(messageHeader).to.have.property('frameLength').and.to.eql(4096) }) it('Header without context should stream correctly i.e not return data when not enough is given.', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const zeroByteEncryptionContextMessageHeader = fixtures.zeroByteEncryptionContextMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) @@ -343,7 +411,10 @@ describe('deserializeFactory:deserializeMessageHeader', () => { }) it('ArrayBuffer for a Uint8Array or Buffer may be larger than the Uint8Array or Buffer that it is a view over is.', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const basicMessageHeader = fixtures.basicMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) @@ -360,36 +431,43 @@ describe('deserializeFactory:deserializeMessageHeader', () => { /* Given this I can use this to construct a new view of part of the * ArrayBuffer to simulate a large ArrayBuffer that is sliced * into parts for efficiency. */ - const sharingArrayBuffer = new Uint8Array(buffer.buffer, 5, buffer.byteLength - 5) + const sharingArrayBuffer = new Uint8Array( + buffer.buffer, + 5, + buffer.byteLength - 5 + ) const test = deserializeMessageHeader(sharingArrayBuffer) if (!test) throw new Error('fail') - expect(test).to.have.property('headerLength') + expect(test) + .to.have.property('headerLength') .and.to.deep.equal(basicMessageHeader.byteLength) - expect(test).to.have.property('rawHeader') + expect(test) + .to.have.property('rawHeader') .and.to.deep.equal(basicMessageHeader) - expect(test).to.have.property('headerIv') - .and.to.deep.equal(headerIv) - expect(test).to.have.property('headerAuthTag') + expect(test).to.have.property('headerIv').and.to.deep.equal(headerIv) + expect(test) + .to.have.property('headerAuthTag') .and.to.deep.equal(headerAuthTag) - expect(test).to.have.property('algorithmSuite') + expect(test) + .to.have.property('algorithmSuite') .and.to.be.instanceOf(WebCryptoAlgorithmSuite) expect(test.algorithmSuite.id).to.eql(0x0014) const { messageHeader } = test - expect(messageHeader).to.have.property('version') - .and.to.eql(1) - expect(messageHeader).to.have.property('type') - .and.to.eql(128) - expect(messageHeader).to.have.property('suiteId') - .and.to.eql(0x0014) - expect(messageHeader).to.have.property('messageId') + expect(messageHeader).to.have.property('version').and.to.eql(1) + expect(messageHeader).to.have.property('type').and.to.eql(128) + expect(messageHeader).to.have.property('suiteId').and.to.eql(0x0014) + expect(messageHeader) + .to.have.property('messageId') .and.to.deep.equal(new Uint8Array(16).fill(3)) - expect(messageHeader).to.have.property('encryptionContext') + expect(messageHeader) + .to.have.property('encryptionContext') .and.to.deep.equal({ some: 'public', information: '½ + ¼ = ¾' }) - expect(messageHeader).to.have.property('encryptedDataKeys') + expect(messageHeader) + .to.have.property('encryptedDataKeys') .and.to.be.an('Array') .and.to.have.lengthOf(2) @@ -398,38 +476,54 @@ describe('deserializeFactory:deserializeMessageHeader', () => { expect(encryptedDataKeys[0]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[0].providerInfo).to.eql('firstKey') expect(encryptedDataKeys[0].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[0].encryptedDataKey) - .to.deep.equal(new Uint8Array([1, 2, 3, 4, 5])) + expect(encryptedDataKeys[0].encryptedDataKey).to.deep.equal( + new Uint8Array([1, 2, 3, 4, 5]) + ) expect(encryptedDataKeys[1]).and.to.be.instanceOf(EncryptedDataKey) expect(encryptedDataKeys[1].providerInfo).to.eql('secondKey') expect(encryptedDataKeys[1].providerId).to.eql('½ + ¼ = ¾') - expect(encryptedDataKeys[1].encryptedDataKey) - .to.deep.equal(new Uint8Array([6, 7, 8, 9, 0])) - - expect(messageHeader).to.have.property('contentType') - .and.to.eql(2) - expect(messageHeader).to.have.property('headerIvLength') - .and.to.eql(12) - expect(messageHeader).to.have.property('frameLength') - .and.to.eql(4096) + expect(encryptedDataKeys[1].encryptedDataKey).to.deep.equal( + new Uint8Array([6, 7, 8, 9, 0]) + ) + + expect(messageHeader).to.have.property('contentType').and.to.eql(2) + expect(messageHeader).to.have.property('headerIvLength').and.to.eql(12) + expect(messageHeader).to.have.property('frameLength').and.to.eql(4096) }) it('Precondition: version and type must be the required values.', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) - expect(() => deserializeMessageHeader(fixtures.versionNotValidMessageHeader())).to.throw('Malformed Header') - expect(() => deserializeMessageHeader(fixtures.typeNotValidMessageHeader())).to.throw('Malformed Header') - expect(() => deserializeMessageHeader(fixtures.base64MessageHeader())).to.throw('Malformed Header: This blob may be base64 encoded.') + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) + expect(() => + deserializeMessageHeader(fixtures.versionNotValidMessageHeader()) + ).to.throw('Malformed Header') + expect(() => + deserializeMessageHeader(fixtures.typeNotValidMessageHeader()) + ).to.throw('Malformed Header') + expect(() => + deserializeMessageHeader(fixtures.base64MessageHeader()) + ).to.throw('Malformed Header: This blob may be base64 encoded.') }) it('Precondition: suiteId must match supported algorithm suite', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const suiteIdNotValidMessageHeader = fixtures.suiteIdNotValidMessageHeader() - expect(() => deserializeMessageHeader(suiteIdNotValidMessageHeader)).to.throw('Unsupported algorithm suite.') + expect(() => + deserializeMessageHeader(suiteIdNotValidMessageHeader) + ).to.throw('Unsupported algorithm suite.') }) it('Postcondition: reservedBytes are defined as 0,0,0,0', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const reservedBytesNoZeroMessageHeader = fixtures.reservedBytesNoZeroMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) @@ -442,7 +536,10 @@ describe('deserializeFactory:deserializeMessageHeader', () => { }) it('Postcondition: The headerIvLength must match the algorithm suite specification.', () => { - const { deserializeMessageHeader } = deserializeFactory(toUtf8, WebCryptoAlgorithmSuite) + const { deserializeMessageHeader } = deserializeFactory( + toUtf8, + WebCryptoAlgorithmSuite + ) const reservedBytesNoZeroMessageHeader = fixtures.ivLengthMismatchMessageHeader() const headerIv = new Uint8Array(12).fill(1) const headerAuthTag = new Uint8Array(16).fill(2) diff --git a/modules/serialize/test/ecdsa_signatures.test.ts b/modules/serialize/test/ecdsa_signatures.test.ts index ad56a7c19..58eb16760 100644 --- a/modules/serialize/test/ecdsa_signatures.test.ts +++ b/modules/serialize/test/ecdsa_signatures.test.ts @@ -5,7 +5,10 @@ import { expect } from 'chai' import { der2raw, raw2der } from '../src/ecdsa_signature' -import { WebCryptoAlgorithmSuite, AlgorithmSuiteIdentifier } from '@aws-crypto/material-management' +import { + WebCryptoAlgorithmSuite, + AlgorithmSuiteIdentifier, +} from '@aws-crypto/material-management' /* * This turns out the be very tricky. @@ -110,11 +113,216 @@ v.update(dataToSign) const isVerified = v.verify(publicPem, derSignature) */ -const validSuite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256) -const rawSignature = new Uint8Array([22, 77, 187, 192, 175, 104, 2, 240, 55, 2, 6, 138, 103, 148, 214, 240, 244, 65, 224, 254, 60, 52, 218, 22, 250, 245, 216, 228, 151, 151, 220, 234, 125, 9, 97, 8, 132, 123, 79, 193, 216, 207, 214, 0, 73, 183, 149, 173, 26, 173, 251, 132, 140, 139, 44, 122, 11, 50, 163, 105, 138, 221, 223, 29]) -const derSignature = new Uint8Array([48, 68, 2, 32, 22, 77, 187, 192, 175, 104, 2, 240, 55, 2, 6, 138, 103, 148, 214, 240, 244, 65, 224, 254, 60, 52, 218, 22, 250, 245, 216, 228, 151, 151, 220, 234, 2, 32, 125, 9, 97, 8, 132, 123, 79, 193, 216, 207, 214, 0, 73, 183, 149, 173, 26, 173, 251, 132, 140, 139, 44, 122, 11, 50, 163, 105, 138, 221, 223, 29]) +const validSuite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 +) +const rawSignature = new Uint8Array([ + 22, + 77, + 187, + 192, + 175, + 104, + 2, + 240, + 55, + 2, + 6, + 138, + 103, + 148, + 214, + 240, + 244, + 65, + 224, + 254, + 60, + 52, + 218, + 22, + 250, + 245, + 216, + 228, + 151, + 151, + 220, + 234, + 125, + 9, + 97, + 8, + 132, + 123, + 79, + 193, + 216, + 207, + 214, + 0, + 73, + 183, + 149, + 173, + 26, + 173, + 251, + 132, + 140, + 139, + 44, + 122, + 11, + 50, + 163, + 105, + 138, + 221, + 223, + 29, +]) +const derSignature = new Uint8Array([ + 48, + 68, + 2, + 32, + 22, + 77, + 187, + 192, + 175, + 104, + 2, + 240, + 55, + 2, + 6, + 138, + 103, + 148, + 214, + 240, + 244, + 65, + 224, + 254, + 60, + 52, + 218, + 22, + 250, + 245, + 216, + 228, + 151, + 151, + 220, + 234, + 2, + 32, + 125, + 9, + 97, + 8, + 132, + 123, + 79, + 193, + 216, + 207, + 214, + 0, + 73, + 183, + 149, + 173, + 26, + 173, + 251, + 132, + 140, + 139, + 44, + 122, + 11, + 50, + 163, + 105, + 138, + 221, + 223, + 29, +]) -const invalidLengthRawSignature = new Uint8Array([0, 22, 77, 187, 192, 175, 104, 2, 240, 55, 2, 6, 138, 103, 148, 214, 240, 244, 65, 224, 254, 60, 52, 218, 22, 250, 245, 216, 228, 151, 151, 220, 234, 125, 9, 97, 8, 132, 123, 79, 193, 216, 207, 214, 0, 73, 183, 149, 173, 26, 173, 251, 132, 140, 139, 44, 122, 11, 50, 163, 105, 138, 221, 223, 29, 0]) +const invalidLengthRawSignature = new Uint8Array([ + 0, + 22, + 77, + 187, + 192, + 175, + 104, + 2, + 240, + 55, + 2, + 6, + 138, + 103, + 148, + 214, + 240, + 244, + 65, + 224, + 254, + 60, + 52, + 218, + 22, + 250, + 245, + 216, + 228, + 151, + 151, + 220, + 234, + 125, + 9, + 97, + 8, + 132, + 123, + 79, + 193, + 216, + 207, + 214, + 0, + 73, + 183, + 149, + 173, + 26, + 173, + 251, + 132, + 140, + 139, + 44, + 122, + 11, + 50, + 163, + 105, + 138, + 221, + 223, + 29, + 0, +]) /* // All signatures should be verified with this public key (spki in bytes) @@ -139,34 +347,1241 @@ function test() { * and padding of r and s. */ // length == 102 -const derSigNoPadding = new Uint8Array([48, 100, 2, 48, 125, 32, 154, 168, 112, 11, 187, 171, 135, 119, 83, 66, 69, 164, 226, 80, 39, 176, 112, 210, 72, 159, 201, 242, 110, 212, 158, 170, 99, 155, 80, 29, 99, 77, 158, 81, 170, 46, 116, 246, 137, 197, 82, 112, 70, 36, 196, 49, 2, 48, 117, 43, 254, 192, 131, 207, 80, 1, 152, 238, 154, 139, 42, 81, 244, 230, 42, 114, 137, 98, 127, 86, 166, 26, 172, 80, 132, 251, 97, 249, 4, 39, 47, 250, 132, 44, 187, 235, 197, 157, 56, 216, 39, 130, 69, 46, 185, 150]) -const rawSigNoPadding = new Uint8Array([125, 32, 154, 168, 112, 11, 187, 171, 135, 119, 83, 66, 69, 164, 226, 80, 39, 176, 112, 210, 72, 159, 201, 242, 110, 212, 158, 170, 99, 155, 80, 29, 99, 77, 158, 81, 170, 46, 116, 246, 137, 197, 82, 112, 70, 36, 196, 49, 117, 43, 254, 192, 131, 207, 80, 1, 152, 238, 154, 139, 42, 81, 244, 230, 42, 114, 137, 98, 127, 86, 166, 26, 172, 80, 132, 251, 97, 249, 4, 39, 47, 250, 132, 44, 187, 235, 197, 157, 56, 216, 39, 130, 69, 46, 185, 150]) +const derSigNoPadding = new Uint8Array([ + 48, + 100, + 2, + 48, + 125, + 32, + 154, + 168, + 112, + 11, + 187, + 171, + 135, + 119, + 83, + 66, + 69, + 164, + 226, + 80, + 39, + 176, + 112, + 210, + 72, + 159, + 201, + 242, + 110, + 212, + 158, + 170, + 99, + 155, + 80, + 29, + 99, + 77, + 158, + 81, + 170, + 46, + 116, + 246, + 137, + 197, + 82, + 112, + 70, + 36, + 196, + 49, + 2, + 48, + 117, + 43, + 254, + 192, + 131, + 207, + 80, + 1, + 152, + 238, + 154, + 139, + 42, + 81, + 244, + 230, + 42, + 114, + 137, + 98, + 127, + 86, + 166, + 26, + 172, + 80, + 132, + 251, + 97, + 249, + 4, + 39, + 47, + 250, + 132, + 44, + 187, + 235, + 197, + 157, + 56, + 216, + 39, + 130, + 69, + 46, + 185, + 150, +]) +const rawSigNoPadding = new Uint8Array([ + 125, + 32, + 154, + 168, + 112, + 11, + 187, + 171, + 135, + 119, + 83, + 66, + 69, + 164, + 226, + 80, + 39, + 176, + 112, + 210, + 72, + 159, + 201, + 242, + 110, + 212, + 158, + 170, + 99, + 155, + 80, + 29, + 99, + 77, + 158, + 81, + 170, + 46, + 116, + 246, + 137, + 197, + 82, + 112, + 70, + 36, + 196, + 49, + 117, + 43, + 254, + 192, + 131, + 207, + 80, + 1, + 152, + 238, + 154, + 139, + 42, + 81, + 244, + 230, + 42, + 114, + 137, + 98, + 127, + 86, + 166, + 26, + 172, + 80, + 132, + 251, + 97, + 249, + 4, + 39, + 47, + 250, + 132, + 44, + 187, + 235, + 197, + 157, + 56, + 216, + 39, + 130, + 69, + 46, + 185, + 150, +]) // length == 103, r is padded -const derSigRPadded = new Uint8Array([48, 101, 2, 49, 0, 163, 81, 253, 131, 61, 166, 239, 242, 68, 133, 70, 219, 243, 67, 220, 94, 57, 115, 92, 119, 17, 93, 152, 78, 78, 177, 110, 48, 164, 12, 53, 146, 223, 8, 57, 108, 177, 237, 187, 165, 39, 162, 214, 193, 112, 220, 132, 13, 2, 48, 10, 2, 53, 95, 195, 68, 6, 79, 110, 220, 215, 130, 204, 182, 125, 44, 47, 198, 226, 17, 115, 207, 22, 89, 113, 18, 90, 63, 0, 105, 104, 221, 159, 156, 17, 168, 95, 96, 254, 88, 45, 120, 223, 180, 12, 44, 118, 18]) -const rawSigRPadded = new Uint8Array([163, 81, 253, 131, 61, 166, 239, 242, 68, 133, 70, 219, 243, 67, 220, 94, 57, 115, 92, 119, 17, 93, 152, 78, 78, 177, 110, 48, 164, 12, 53, 146, 223, 8, 57, 108, 177, 237, 187, 165, 39, 162, 214, 193, 112, 220, 132, 13, 10, 2, 53, 95, 195, 68, 6, 79, 110, 220, 215, 130, 204, 182, 125, 44, 47, 198, 226, 17, 115, 207, 22, 89, 113, 18, 90, 63, 0, 105, 104, 221, 159, 156, 17, 168, 95, 96, 254, 88, 45, 120, 223, 180, 12, 44, 118, 18]) +const derSigRPadded = new Uint8Array([ + 48, + 101, + 2, + 49, + 0, + 163, + 81, + 253, + 131, + 61, + 166, + 239, + 242, + 68, + 133, + 70, + 219, + 243, + 67, + 220, + 94, + 57, + 115, + 92, + 119, + 17, + 93, + 152, + 78, + 78, + 177, + 110, + 48, + 164, + 12, + 53, + 146, + 223, + 8, + 57, + 108, + 177, + 237, + 187, + 165, + 39, + 162, + 214, + 193, + 112, + 220, + 132, + 13, + 2, + 48, + 10, + 2, + 53, + 95, + 195, + 68, + 6, + 79, + 110, + 220, + 215, + 130, + 204, + 182, + 125, + 44, + 47, + 198, + 226, + 17, + 115, + 207, + 22, + 89, + 113, + 18, + 90, + 63, + 0, + 105, + 104, + 221, + 159, + 156, + 17, + 168, + 95, + 96, + 254, + 88, + 45, + 120, + 223, + 180, + 12, + 44, + 118, + 18, +]) +const rawSigRPadded = new Uint8Array([ + 163, + 81, + 253, + 131, + 61, + 166, + 239, + 242, + 68, + 133, + 70, + 219, + 243, + 67, + 220, + 94, + 57, + 115, + 92, + 119, + 17, + 93, + 152, + 78, + 78, + 177, + 110, + 48, + 164, + 12, + 53, + 146, + 223, + 8, + 57, + 108, + 177, + 237, + 187, + 165, + 39, + 162, + 214, + 193, + 112, + 220, + 132, + 13, + 10, + 2, + 53, + 95, + 195, + 68, + 6, + 79, + 110, + 220, + 215, + 130, + 204, + 182, + 125, + 44, + 47, + 198, + 226, + 17, + 115, + 207, + 22, + 89, + 113, + 18, + 90, + 63, + 0, + 105, + 104, + 221, + 159, + 156, + 17, + 168, + 95, + 96, + 254, + 88, + 45, + 120, + 223, + 180, + 12, + 44, + 118, + 18, +]) // length == 103, s is padded -const derSigSPadded = new Uint8Array([48, 101, 2, 48, 13, 237, 65, 195, 0, 118, 121, 114, 12, 187, 102, 24, 62, 8, 42, 43, 27, 18, 27, 123, 222, 46, 84, 53, 255, 198, 169, 180, 206, 77, 60, 3, 171, 209, 129, 25, 245, 157, 197, 128, 191, 153, 226, 52, 170, 3, 93, 180, 2, 49, 0, 191, 191, 7, 215, 111, 31, 5, 75, 245, 134, 50, 255, 118, 224, 243, 133, 233, 162, 55, 22, 203, 124, 69, 231, 1, 190, 191, 175, 158, 82, 80, 168, 172, 29, 97, 13, 141, 126, 184, 238, 159, 214, 213, 92, 114, 94, 61, 82]) -const rawSigSPadded = new Uint8Array([13, 237, 65, 195, 0, 118, 121, 114, 12, 187, 102, 24, 62, 8, 42, 43, 27, 18, 27, 123, 222, 46, 84, 53, 255, 198, 169, 180, 206, 77, 60, 3, 171, 209, 129, 25, 245, 157, 197, 128, 191, 153, 226, 52, 170, 3, 93, 180, 191, 191, 7, 215, 111, 31, 5, 75, 245, 134, 50, 255, 118, 224, 243, 133, 233, 162, 55, 22, 203, 124, 69, 231, 1, 190, 191, 175, 158, 82, 80, 168, 172, 29, 97, 13, 141, 126, 184, 238, 159, 214, 213, 92, 114, 94, 61, 82]) +const derSigSPadded = new Uint8Array([ + 48, + 101, + 2, + 48, + 13, + 237, + 65, + 195, + 0, + 118, + 121, + 114, + 12, + 187, + 102, + 24, + 62, + 8, + 42, + 43, + 27, + 18, + 27, + 123, + 222, + 46, + 84, + 53, + 255, + 198, + 169, + 180, + 206, + 77, + 60, + 3, + 171, + 209, + 129, + 25, + 245, + 157, + 197, + 128, + 191, + 153, + 226, + 52, + 170, + 3, + 93, + 180, + 2, + 49, + 0, + 191, + 191, + 7, + 215, + 111, + 31, + 5, + 75, + 245, + 134, + 50, + 255, + 118, + 224, + 243, + 133, + 233, + 162, + 55, + 22, + 203, + 124, + 69, + 231, + 1, + 190, + 191, + 175, + 158, + 82, + 80, + 168, + 172, + 29, + 97, + 13, + 141, + 126, + 184, + 238, + 159, + 214, + 213, + 92, + 114, + 94, + 61, + 82, +]) +const rawSigSPadded = new Uint8Array([ + 13, + 237, + 65, + 195, + 0, + 118, + 121, + 114, + 12, + 187, + 102, + 24, + 62, + 8, + 42, + 43, + 27, + 18, + 27, + 123, + 222, + 46, + 84, + 53, + 255, + 198, + 169, + 180, + 206, + 77, + 60, + 3, + 171, + 209, + 129, + 25, + 245, + 157, + 197, + 128, + 191, + 153, + 226, + 52, + 170, + 3, + 93, + 180, + 191, + 191, + 7, + 215, + 111, + 31, + 5, + 75, + 245, + 134, + 50, + 255, + 118, + 224, + 243, + 133, + 233, + 162, + 55, + 22, + 203, + 124, + 69, + 231, + 1, + 190, + 191, + 175, + 158, + 82, + 80, + 168, + 172, + 29, + 97, + 13, + 141, + 126, + 184, + 238, + 159, + 214, + 213, + 92, + 114, + 94, + 61, + 82, +]) // length == 104 both r and s are padded -const derSigBothSandRPadded = new Uint8Array([48, 102, 2, 49, 0, 161, 31, 228, 163, 249, 149, 236, 238, 15, 140, 163, 28, 152, 199, 168, 83, 187, 60, 79, 26, 71, 243, 120, 0, 44, 200, 217, 82, 162, 181, 168, 194, 181, 56, 20, 193, 213, 40, 112, 59, 13, 254, 55, 177, 231, 189, 128, 71, 2, 49, 0, 241, 232, 224, 60, 113, 203, 248, 143, 34, 63, 98, 221, 156, 143, 58, 106, 169, 169, 63, 126, 103, 145, 63, 246, 255, 32, 74, 11, 197, 255, 13, 244, 105, 188, 157, 210, 200, 36, 140, 218, 1, 115, 99, 255, 212, 71, 156, 38]) -const rawSigBothSandRPadded = new Uint8Array([161, 31, 228, 163, 249, 149, 236, 238, 15, 140, 163, 28, 152, 199, 168, 83, 187, 60, 79, 26, 71, 243, 120, 0, 44, 200, 217, 82, 162, 181, 168, 194, 181, 56, 20, 193, 213, 40, 112, 59, 13, 254, 55, 177, 231, 189, 128, 71, 241, 232, 224, 60, 113, 203, 248, 143, 34, 63, 98, 221, 156, 143, 58, 106, 169, 169, 63, 126, 103, 145, 63, 246, 255, 32, 74, 11, 197, 255, 13, 244, 105, 188, 157, 210, 200, 36, 140, 218, 1, 115, 99, 255, 212, 71, 156, 38]) +const derSigBothSandRPadded = new Uint8Array([ + 48, + 102, + 2, + 49, + 0, + 161, + 31, + 228, + 163, + 249, + 149, + 236, + 238, + 15, + 140, + 163, + 28, + 152, + 199, + 168, + 83, + 187, + 60, + 79, + 26, + 71, + 243, + 120, + 0, + 44, + 200, + 217, + 82, + 162, + 181, + 168, + 194, + 181, + 56, + 20, + 193, + 213, + 40, + 112, + 59, + 13, + 254, + 55, + 177, + 231, + 189, + 128, + 71, + 2, + 49, + 0, + 241, + 232, + 224, + 60, + 113, + 203, + 248, + 143, + 34, + 63, + 98, + 221, + 156, + 143, + 58, + 106, + 169, + 169, + 63, + 126, + 103, + 145, + 63, + 246, + 255, + 32, + 74, + 11, + 197, + 255, + 13, + 244, + 105, + 188, + 157, + 210, + 200, + 36, + 140, + 218, + 1, + 115, + 99, + 255, + 212, + 71, + 156, + 38, +]) +const rawSigBothSandRPadded = new Uint8Array([ + 161, + 31, + 228, + 163, + 249, + 149, + 236, + 238, + 15, + 140, + 163, + 28, + 152, + 199, + 168, + 83, + 187, + 60, + 79, + 26, + 71, + 243, + 120, + 0, + 44, + 200, + 217, + 82, + 162, + 181, + 168, + 194, + 181, + 56, + 20, + 193, + 213, + 40, + 112, + 59, + 13, + 254, + 55, + 177, + 231, + 189, + 128, + 71, + 241, + 232, + 224, + 60, + 113, + 203, + 248, + 143, + 34, + 63, + 98, + 221, + 156, + 143, + 58, + 106, + 169, + 169, + 63, + 126, + 103, + 145, + 63, + 246, + 255, + 32, + 74, + 11, + 197, + 255, + 13, + 244, + 105, + 188, + 157, + 210, + 200, + 36, + 140, + 218, + 1, + 115, + 99, + 255, + 212, + 71, + 156, + 38, +]) /* This vector has the "first byte" of r === 128. * This means that the "first bit" of r === 1. * This means the DER signature is padded. */ -const derSigRonBoundary = new Uint8Array([48, 102, 2, 49, 0, 128, 193, 160, 46, 142, 254, 87, 100, 216, 114, 75, 154, 209, 17, 184, 155, 141, 178, 118, 99, 34, 161, 229, 195, 144, 1, 183, 41, 165, 115, 107, 123, 234, 39, 90, 43, 247, 108, 227, 88, 144, 107, 230, 39, 103, 213, 174, 206, 2, 49, 0, 209, 70, 36, 78, 124, 248, 10, 77, 80, 102, 88, 38, 166, 138, 237, 192, 93, 189, 17, 157, 57, 203, 245, 93, 178, 19, 206, 31, 13, 117, 4, 241, 176, 107, 169, 23, 39, 71, 127, 32, 210, 157, 82, 115, 163, 177, 42, 74]) -const rawSigRonBoundary = new Uint8Array([128, 193, 160, 46, 142, 254, 87, 100, 216, 114, 75, 154, 209, 17, 184, 155, 141, 178, 118, 99, 34, 161, 229, 195, 144, 1, 183, 41, 165, 115, 107, 123, 234, 39, 90, 43, 247, 108, 227, 88, 144, 107, 230, 39, 103, 213, 174, 206, 209, 70, 36, 78, 124, 248, 10, 77, 80, 102, 88, 38, 166, 138, 237, 192, 93, 189, 17, 157, 57, 203, 245, 93, 178, 19, 206, 31, 13, 117, 4, 241, 176, 107, 169, 23, 39, 71, 127, 32, 210, 157, 82, 115, 163, 177, 42, 74]) +const derSigRonBoundary = new Uint8Array([ + 48, + 102, + 2, + 49, + 0, + 128, + 193, + 160, + 46, + 142, + 254, + 87, + 100, + 216, + 114, + 75, + 154, + 209, + 17, + 184, + 155, + 141, + 178, + 118, + 99, + 34, + 161, + 229, + 195, + 144, + 1, + 183, + 41, + 165, + 115, + 107, + 123, + 234, + 39, + 90, + 43, + 247, + 108, + 227, + 88, + 144, + 107, + 230, + 39, + 103, + 213, + 174, + 206, + 2, + 49, + 0, + 209, + 70, + 36, + 78, + 124, + 248, + 10, + 77, + 80, + 102, + 88, + 38, + 166, + 138, + 237, + 192, + 93, + 189, + 17, + 157, + 57, + 203, + 245, + 93, + 178, + 19, + 206, + 31, + 13, + 117, + 4, + 241, + 176, + 107, + 169, + 23, + 39, + 71, + 127, + 32, + 210, + 157, + 82, + 115, + 163, + 177, + 42, + 74, +]) +const rawSigRonBoundary = new Uint8Array([ + 128, + 193, + 160, + 46, + 142, + 254, + 87, + 100, + 216, + 114, + 75, + 154, + 209, + 17, + 184, + 155, + 141, + 178, + 118, + 99, + 34, + 161, + 229, + 195, + 144, + 1, + 183, + 41, + 165, + 115, + 107, + 123, + 234, + 39, + 90, + 43, + 247, + 108, + 227, + 88, + 144, + 107, + 230, + 39, + 103, + 213, + 174, + 206, + 209, + 70, + 36, + 78, + 124, + 248, + 10, + 77, + 80, + 102, + 88, + 38, + 166, + 138, + 237, + 192, + 93, + 189, + 17, + 157, + 57, + 203, + 245, + 93, + 178, + 19, + 206, + 31, + 13, + 117, + 4, + 241, + 176, + 107, + 169, + 23, + 39, + 71, + 127, + 32, + 210, + 157, + 82, + 115, + 163, + 177, + 42, + 74, +]) /* This vector has the "first byte" of s === 128. * This means that the "first bit" of s === 1. * This means the DER signature is padded. */ -const derSigSonBoundary = new Uint8Array([48, 101, 2, 48, 99, 9, 32, 95, 74, 230, 183, 174, 87, 124, 144, 130, 171, 98, 39, 162, 23, 207, 58, 218, 73, 183, 190, 173, 107, 46, 130, 60, 185, 45, 245, 81, 57, 191, 60, 41, 6, 8, 68, 241, 221, 25, 122, 145, 25, 229, 148, 158, 2, 49, 0, 128, 50, 250, 23, 18, 25, 233, 203, 214, 199, 87, 201, 51, 187, 231, 99, 99, 114, 101, 252, 197, 48, 94, 2, 1, 12, 154, 225, 237, 112, 63, 95, 149, 14, 159, 190, 177, 241, 121, 75, 133, 77, 148, 78, 11, 34, 215, 58]) -const rawSigSonBoundary = new Uint8Array([99, 9, 32, 95, 74, 230, 183, 174, 87, 124, 144, 130, 171, 98, 39, 162, 23, 207, 58, 218, 73, 183, 190, 173, 107, 46, 130, 60, 185, 45, 245, 81, 57, 191, 60, 41, 6, 8, 68, 241, 221, 25, 122, 145, 25, 229, 148, 158, 128, 50, 250, 23, 18, 25, 233, 203, 214, 199, 87, 201, 51, 187, 231, 99, 99, 114, 101, 252, 197, 48, 94, 2, 1, 12, 154, 225, 237, 112, 63, 95, 149, 14, 159, 190, 177, 241, 121, 75, 133, 77, 148, 78, 11, 34, 215, 58]) +const derSigSonBoundary = new Uint8Array([ + 48, + 101, + 2, + 48, + 99, + 9, + 32, + 95, + 74, + 230, + 183, + 174, + 87, + 124, + 144, + 130, + 171, + 98, + 39, + 162, + 23, + 207, + 58, + 218, + 73, + 183, + 190, + 173, + 107, + 46, + 130, + 60, + 185, + 45, + 245, + 81, + 57, + 191, + 60, + 41, + 6, + 8, + 68, + 241, + 221, + 25, + 122, + 145, + 25, + 229, + 148, + 158, + 2, + 49, + 0, + 128, + 50, + 250, + 23, + 18, + 25, + 233, + 203, + 214, + 199, + 87, + 201, + 51, + 187, + 231, + 99, + 99, + 114, + 101, + 252, + 197, + 48, + 94, + 2, + 1, + 12, + 154, + 225, + 237, + 112, + 63, + 95, + 149, + 14, + 159, + 190, + 177, + 241, + 121, + 75, + 133, + 77, + 148, + 78, + 11, + 34, + 215, + 58, +]) +const rawSigSonBoundary = new Uint8Array([ + 99, + 9, + 32, + 95, + 74, + 230, + 183, + 174, + 87, + 124, + 144, + 130, + 171, + 98, + 39, + 162, + 23, + 207, + 58, + 218, + 73, + 183, + 190, + 173, + 107, + 46, + 130, + 60, + 185, + 45, + 245, + 81, + 57, + 191, + 60, + 41, + 6, + 8, + 68, + 241, + 221, + 25, + 122, + 145, + 25, + 229, + 148, + 158, + 128, + 50, + 250, + 23, + 18, + 25, + 233, + 203, + 214, + 199, + 87, + 201, + 51, + 187, + 231, + 99, + 99, + 114, + 101, + 252, + 197, + 48, + 94, + 2, + 1, + 12, + 154, + 225, + 237, + 112, + 63, + 95, + 149, + 14, + 159, + 190, + 177, + 241, + 121, + 75, + 133, + 77, + 148, + 78, + 11, + 34, + 215, + 58, +]) describe('der2raw', () => { it('transform to raw signature', () => { @@ -175,7 +1590,9 @@ describe('der2raw', () => { }) it('Precondition: Do not attempt to RAW format if the suite does not support signing.', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(() => der2raw(derSignature, suite)).to.throw() }) }) @@ -187,16 +1604,22 @@ describe('raw2der', () => { }) it('Precondition: Do not attempt to DER format if the suite does not support signing.', () => { - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16 + ) expect(() => raw2der(rawSignature, suite)).to.throw() }) + const suite = new WebCryptoAlgorithmSuite( + AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + ) + it('Precondition: The total raw signature length is twice the key length bytes.', () => { - expect(() => raw2der(invalidLengthRawSignature, suite)).to.throw('Malformed signature.') + expect(() => raw2der(invalidLengthRawSignature, suite)).to.throw( + 'Malformed signature.' + ) }) - const suite = new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384) - it('transform to der signature with no padding', () => { expect(raw2der(rawSigNoPadding, suite)).to.deep.equal(derSigNoPadding) }) @@ -207,7 +1630,9 @@ describe('raw2der', () => { expect(raw2der(rawSigSPadded, suite)).to.deep.equal(derSigSPadded) }) it('transform to der signature with both r and s padded', () => { - expect(raw2der(rawSigBothSandRPadded, suite)).to.deep.equal(derSigBothSandRPadded) + expect(raw2der(rawSigBothSandRPadded, suite)).to.deep.equal( + derSigBothSandRPadded + ) }) it('transform to der signature with with r padded, but r is on the padding boundary', () => { expect(raw2der(rawSigRonBoundary, suite)).to.deep.equal(derSigRonBoundary) diff --git a/modules/serialize/test/fixtures.ts b/modules/serialize/test/fixtures.ts index c26f0a865..a0b613996 100644 --- a/modules/serialize/test/fixtures.ts +++ b/modules/serialize/test/fixtures.ts @@ -3,108 +3,1831 @@ /* eslint-env mocha */ -export function basicMessageHeader () { - return new Uint8Array([ 1, 128, 0, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 0, 0, 0, 12, 0, 0, 16, 0 ]) +export function basicMessageHeader() { + return new Uint8Array([ + 1, + 128, + 0, + 20, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 16, + 0, + ]) } -export function zeroByteEncryptionContextMessageHeader () { - return new Uint8Array([ 1, 128, 0, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 0, // see here, 0,0 for context length, but _no_ element count - 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 0, 0, 0, 12, 0, 0, 16, 0 ]) +export function zeroByteEncryptionContextMessageHeader() { + return new Uint8Array([ + 1, + 128, + 0, + 20, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 0, // see here, 0,0 for context length, but _no_ element count + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 16, + 0, + ]) } -export function suiteIdNotValidMessageHeader () { - return new Uint8Array([ 1, 128, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 0, 0, 0, 12, 0, 0, 16, 0 ]) +export function suiteIdNotValidMessageHeader() { + return new Uint8Array([ + 1, + 128, + 0, + 0, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 16, + 0, + ]) } -export function versionNotValidMessageHeader () { - return new Uint8Array([ 256, 128, 0, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 0, 0, 0, 12, 0, 0, 16, 0 ]) +export function versionNotValidMessageHeader() { + return new Uint8Array([ + 256, + 128, + 0, + 20, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 16, + 0, + ]) } -export function typeNotValidMessageHeader () { - return new Uint8Array([ 1, 256, 0, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 0, 0, 0, 12, 0, 0, 16, 0 ]) +export function typeNotValidMessageHeader() { + return new Uint8Array([ + 1, + 256, + 0, + 20, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 16, + 0, + ]) } -export function base64MessageHeader () { - return new Uint8Array([65, 89, 65, 65, 70, 65, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 65, 75, 119, 65, 67, 65, 65, 116, 112, 98, 109, 90, 118, 99, 109, 49, 104, 100, 71, 108, 118, 98, 103, 65, 77, 119, 114, 48, 103, 75, 121, 68, 67, 118, 67, 65, 57, 73, 77, 75, 43, 65, 65, 82, 122, 98, 50, 49, 108, 65, 65, 90, 119, 100, 87, 74, 115, 97, 87, 77, 65, 65, 103, 65, 77, 119, 114, 48, 103, 75, 121, 68, 67, 118, 67, 65, 57, 73, 77, 75, 43, 65, 65, 104, 109, 97, 88, 74, 122, 100, 69, 116, 108, 101, 81, 65, 70, 65, 81, 73, 68, 66, 65, 85, 65, 68, 77, 75, 57, 73, 67, 115, 103, 119, 114, 119, 103, 80, 83, 68, 67, 118, 103, 65, 74, 99, 50, 86, 106, 98, 50, 53, 107, 83, 50, 86, 53, 65, 65, 85, 71, 66, 119, 103, 74, 65, 65, 73, 65, 65, 65, 65, 65, 68, 65, 65, 65, 69, 65, 65, 61]) +export function base64MessageHeader() { + return new Uint8Array([ + 65, + 89, + 65, + 65, + 70, + 65, + 77, + 68, + 65, + 119, + 77, + 68, + 65, + 119, + 77, + 68, + 65, + 119, + 77, + 68, + 65, + 119, + 77, + 68, + 65, + 119, + 77, + 65, + 75, + 119, + 65, + 67, + 65, + 65, + 116, + 112, + 98, + 109, + 90, + 118, + 99, + 109, + 49, + 104, + 100, + 71, + 108, + 118, + 98, + 103, + 65, + 77, + 119, + 114, + 48, + 103, + 75, + 121, + 68, + 67, + 118, + 67, + 65, + 57, + 73, + 77, + 75, + 43, + 65, + 65, + 82, + 122, + 98, + 50, + 49, + 108, + 65, + 65, + 90, + 119, + 100, + 87, + 74, + 115, + 97, + 87, + 77, + 65, + 65, + 103, + 65, + 77, + 119, + 114, + 48, + 103, + 75, + 121, + 68, + 67, + 118, + 67, + 65, + 57, + 73, + 77, + 75, + 43, + 65, + 65, + 104, + 109, + 97, + 88, + 74, + 122, + 100, + 69, + 116, + 108, + 101, + 81, + 65, + 70, + 65, + 81, + 73, + 68, + 66, + 65, + 85, + 65, + 68, + 77, + 75, + 57, + 73, + 67, + 115, + 103, + 119, + 114, + 119, + 103, + 80, + 83, + 68, + 67, + 118, + 103, + 65, + 74, + 99, + 50, + 86, + 106, + 98, + 50, + 53, + 107, + 83, + 50, + 86, + 53, + 65, + 65, + 85, + 71, + 66, + 119, + 103, + 74, + 65, + 65, + 73, + 65, + 65, + 65, + 65, + 65, + 68, + 65, + 65, + 65, + 69, + 65, + 65, + 61, + ]) } -export function reservedBytesNoZeroMessageHeader () { - return new Uint8Array([ 1, 128, 0, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 1, 0, 0, 12, 0, 0, 16, 0 ]) +export function reservedBytesNoZeroMessageHeader() { + return new Uint8Array([ + 1, + 128, + 0, + 20, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 1, + 0, + 0, + 12, + 0, + 0, + 16, + 0, + ]) } -export function ivLengthMismatchMessageHeader () { - return new Uint8Array([ 1, 128, 0, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0, 2, 0, 0, 0, 0, 8, 0, 0, 16, 0 ]) +export function ivLengthMismatchMessageHeader() { + return new Uint8Array([ + 1, + 128, + 0, + 20, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + 2, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 16, + 0, + ]) } -export function basicFrameHeader () { +export function basicFrameHeader() { return new Uint8Array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) } -export function invalidSequenceNumberFrameHeader () { +export function invalidSequenceNumberFrameHeader() { return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) } -export function finalFrameHeader () { - return new Uint8Array([255, 255, 255, 255, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 231]) +export function finalFrameHeader() { + return new Uint8Array([ + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 3, + 231, + ]) } -export function finalFrameHeaderZeroBytes () { - return new Uint8Array([255, 255, 255, 255, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]) +export function finalFrameHeaderZeroBytes() { + return new Uint8Array([ + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + ]) } -export function invalidSequenceEndFinalFrameHeader () { - return new Uint8Array([0, 255, 255, 255, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 231]) +export function invalidSequenceEndFinalFrameHeader() { + return new Uint8Array([ + 0, + 255, + 255, + 255, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 3, + 231, + ]) } -export function invalidSequenceNumberFinalFrameHeader () { - return new Uint8Array([255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 231]) +export function invalidSequenceNumberFinalFrameHeader() { + return new Uint8Array([ + 255, + 255, + 255, + 255, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 3, + 231, + ]) } -export function basicNonFrameHeader () { - return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) +export function basicNonFrameHeader() { + return new Uint8Array([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]) } -export function basicEncryptionContext () { - return new Uint8Array([ 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99 ]) +export function basicEncryptionContext() { + return new Uint8Array([ + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + ]) } -export function missingDataEncryptionContext () { - return new Uint8Array([ 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108 ]) +export function missingDataEncryptionContext() { + return new Uint8Array([ + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + ]) } -export function tooMuchDataEncryptionContext () { - return new Uint8Array([ 0, 43, 0, 2, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0 ]) +export function tooMuchDataEncryptionContext() { + return new Uint8Array([ + 0, + 43, + 0, + 2, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + ]) } -export function duplicateKeysEncryptionContext () { - return new Uint8Array([ 0, 43, 0, 4, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99, 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99 ]) +export function duplicateKeysEncryptionContext() { + return new Uint8Array([ + 0, + 43, + 0, + 4, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + ]) } -export function hasOwnPropertyEncryptionContext () { - return new Uint8Array([ 0, 34, 0, 1, 0, 14, 104, 97, 115, 79, 119, 110, 80, 114, 111, 112, 101, 114, 116, 121, 0, 14, 97, 114, 98, 105, 116, 114, 97, 114, 121, 86, 97, 108, 117, 101 ]) +export function hasOwnPropertyEncryptionContext() { + return new Uint8Array([ + 0, + 34, + 0, + 1, + 0, + 14, + 104, + 97, + 115, + 79, + 119, + 110, + 80, + 114, + 111, + 112, + 101, + 114, + 116, + 121, + 0, + 14, + 97, + 114, + 98, + 105, + 116, + 114, + 97, + 114, + 121, + 86, + 97, + 108, + 117, + 101, + ]) } -export function basicFrameIV () { +export function basicFrameIV() { return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) } -export function basicNonFrameIV () { +export function basicNonFrameIV() { return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) } -export function headerAuthIV () { +export function headerAuthIV() { return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) } -export function encryptedDataKey () { - return new Uint8Array([ 0, 2, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 8, 102, 105, 114, 115, 116, 75, 101, 121, 0, 5, 1, 2, 3, 4, 5, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190, 0, 9, 115, 101, 99, 111, 110, 100, 75, 101, 121, 0, 5, 6, 7, 8, 9, 0 ]) +export function encryptedDataKey() { + return new Uint8Array([ + 0, + 2, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 8, + 102, + 105, + 114, + 115, + 116, + 75, + 101, + 121, + 0, + 5, + 1, + 2, + 3, + 4, + 5, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + 0, + 9, + 115, + 101, + 99, + 111, + 110, + 100, + 75, + 101, + 121, + 0, + 5, + 6, + 7, + 8, + 9, + 0, + ]) } -export function ecdsaP256Signature () { - return new Uint8Array([48, 68, 2, 32, 22, 77, 187, 192, 175, 104, 2, 240, 55, 2, 6, 138, 103, 148, 214, 240, 244, 65, 224, 254, 60, 52, 218, 22, 250, 245, 216, 228, 151, 151, 220, 234, 2, 32, 125, 9, 97, 8, 132, 123, 79, 193, 216, 207, 214, 0, 73, 183, 149, 173, 26, 173, 251, 132, 140, 139, 44, 122, 11, 50, 163, 105, 138, 221, 223, 29]) +export function ecdsaP256Signature() { + return new Uint8Array([ + 48, + 68, + 2, + 32, + 22, + 77, + 187, + 192, + 175, + 104, + 2, + 240, + 55, + 2, + 6, + 138, + 103, + 148, + 214, + 240, + 244, + 65, + 224, + 254, + 60, + 52, + 218, + 22, + 250, + 245, + 216, + 228, + 151, + 151, + 220, + 234, + 2, + 32, + 125, + 9, + 97, + 8, + 132, + 123, + 79, + 193, + 216, + 207, + 214, + 0, + 73, + 183, + 149, + 173, + 26, + 173, + 251, + 132, + 140, + 139, + 44, + 122, + 11, + 50, + 163, + 105, + 138, + 221, + 223, + 29, + ]) } -export function ecdsaP256SignatureInfo () { - return new Uint8Array([0, 70, 48, 68, 2, 32, 22, 77, 187, 192, 175, 104, 2, 240, 55, 2, 6, 138, 103, 148, 214, 240, 244, 65, 224, 254, 60, 52, 218, 22, 250, 245, 216, 228, 151, 151, 220, 234, 2, 32, 125, 9, 97, 8, 132, 123, 79, 193, 216, 207, 214, 0, 73, 183, 149, 173, 26, 173, 251, 132, 140, 139, 44, 122, 11, 50, 163, 105, 138, 221, 223, 29]) +export function ecdsaP256SignatureInfo() { + return new Uint8Array([ + 0, + 70, + 48, + 68, + 2, + 32, + 22, + 77, + 187, + 192, + 175, + 104, + 2, + 240, + 55, + 2, + 6, + 138, + 103, + 148, + 214, + 240, + 244, + 65, + 224, + 254, + 60, + 52, + 218, + 22, + 250, + 245, + 216, + 228, + 151, + 151, + 220, + 234, + 2, + 32, + 125, + 9, + 97, + 8, + 132, + 123, + 79, + 193, + 216, + 207, + 214, + 0, + 73, + 183, + 149, + 173, + 26, + 173, + 251, + 132, + 140, + 139, + 44, + 122, + 11, + 50, + 163, + 105, + 138, + 221, + 223, + 29, + ]) } diff --git a/modules/serialize/test/kdf_info.test.ts b/modules/serialize/test/kdf_info.test.ts index 205508a0a..495695e50 100644 --- a/modules/serialize/test/kdf_info.test.ts +++ b/modules/serialize/test/kdf_info.test.ts @@ -14,6 +14,8 @@ describe('kdfInfo', () => { expect(test).to.instanceof(Uint8Array) expect(test.byteLength).to.eql(18) - expect(test).to.deep.equal(new Uint8Array([0, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])) + expect(test).to.deep.equal( + new Uint8Array([0, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) + ) }) }) diff --git a/modules/serialize/test/read_elements.test.ts b/modules/serialize/test/read_elements.test.ts index e29ad9b69..4c2b83f97 100644 --- a/modules/serialize/test/read_elements.test.ts +++ b/modules/serialize/test/read_elements.test.ts @@ -9,44 +9,62 @@ import { concatBuffers } from '../src/concat_buffers' import { Buffer } from 'buffer' import * as fixtures from './fixtures' -function randomNat (limit : number) : number { +function randomNat(limit: number): number { return Math.floor(Math.random() * limit) } describe('readElements', () => { it('should be able to handle multiple elements containing multiple fields without padding', () => { const utf8DataStrings = [ - 'here', 'is', 'some', 'utf8', 'information', '\u00bd + \u00bc = \u00be' + 'here', + 'is', + 'some', + 'utf8', + 'information', + '\u00bd + \u00bc = \u00be', ] - const buffData = utf8DataStrings.map(str => new Uint8Array([...Buffer.from(str)])) - const buff = concatBuffers(...buffData.map(bufStr => { - const len = Buffer.alloc(2) - len.writeUInt16BE(bufStr.byteLength, 0) - return concatBuffers(len, bufStr) - })) + const buffData = utf8DataStrings.map( + (str) => new Uint8Array([...Buffer.from(str)]) + ) + const buff = concatBuffers( + ...buffData.map((bufStr) => { + const len = Buffer.alloc(2) + len.writeUInt16BE(bufStr.byteLength, 0) + return concatBuffers(len, bufStr) + }) + ) /* The elements in the buffer can be arranged in several ways. * For example, we can think of them as six elements with one * field each, or as three elements with two fields each. */ - const dimensions = [[1, 6], [2, 3], [3, 2], [6, 1]] + const dimensions = [ + [1, 6], + [2, 3], + [3, 2], + [6, 1], + ] dimensions.map(([elementCount, fieldsPerElement]) => { const info = readElements(elementCount, fieldsPerElement, buff) if (info === false) throw new Error('Fail') - let elements = info.elements + const elements = info.elements expect(elements).to.be.instanceof(Array) expect(elements.length).to.eql(elementCount) for (let eCount = 0; eCount < elementCount; eCount++) { - let element = info.elements[eCount] + const element = info.elements[eCount] expect(element).to.be.instanceof(Array) expect(element.length).to.eql(fieldsPerElement) for (let fCount = 0; fCount < fieldsPerElement; fCount++) { - let field = element[fCount] - expect(field).to.deep.equal(buffData[eCount * fieldsPerElement + fCount]) - expect(Buffer.from(field).toString()).to.deep.equal(utf8DataStrings[eCount * fieldsPerElement + fCount]) + const field = element[fCount] + expect(field).to.deep.equal( + buffData[eCount * fieldsPerElement + fCount] + ) + expect(Buffer.from(field).toString()).to.deep.equal( + utf8DataStrings[eCount * fieldsPerElement + fCount] + ) } } @@ -57,41 +75,68 @@ describe('readElements', () => { it('should be able to handle multiple elements containing multiple fields with various padding', () => { let numberOfRuns = 16 const maxPaddingLength = 1024 - const utf8DataStrings = [ 'here', 'is', 'some', 'utf8', 'information', '\u00bd + \u00bc = \u00be' ] - const buffData = utf8DataStrings.map(str => new Uint8Array([...Buffer.from(str)])) - const mainBuffer = concatBuffers(...buffData.map(bufStr => { - const len = Buffer.alloc(2) - len.writeUInt16BE(bufStr.byteLength, 0) - return concatBuffers(len, bufStr) - })) + const utf8DataStrings = [ + 'here', + 'is', + 'some', + 'utf8', + 'information', + '\u00bd + \u00bc = \u00be', + ] + const buffData = utf8DataStrings.map( + (str) => new Uint8Array([...Buffer.from(str)]) + ) + const mainBuffer = concatBuffers( + ...buffData.map((bufStr) => { + const len = Buffer.alloc(2) + len.writeUInt16BE(bufStr.byteLength, 0) + return concatBuffers(len, bufStr) + }) + ) - const dimensions = [[1, 6], [2, 3], [3, 2], [6, 1]] + const dimensions = [ + [1, 6], + [2, 3], + [3, 2], + [6, 1], + ] while (numberOfRuns--) { - let leftPadding = Buffer.alloc(randomNat(maxPaddingLength)) - let rightPadding = Buffer.alloc(randomNat(maxPaddingLength)) - let buff = concatBuffers(leftPadding, mainBuffer, rightPadding) + const leftPadding = Buffer.alloc(randomNat(maxPaddingLength)) + const rightPadding = Buffer.alloc(randomNat(maxPaddingLength)) + const buff = concatBuffers(leftPadding, mainBuffer, rightPadding) dimensions.map(([elementCount, fieldsPerElement]) => { - const info = readElements(elementCount, fieldsPerElement, buff, leftPadding.byteLength) + const info = readElements( + elementCount, + fieldsPerElement, + buff, + leftPadding.byteLength + ) if (info === false) throw new Error('Fail') - let elements = info.elements + const elements = info.elements expect(elements).to.be.instanceof(Array) expect(elements.length).to.eql(elementCount) for (let eCount = 0; eCount < elementCount; eCount++) { - let element = info.elements[eCount] + const element = info.elements[eCount] expect(element).to.be.instanceof(Array) expect(element.length).to.eql(fieldsPerElement) for (let fCount = 0; fCount < fieldsPerElement; fCount++) { - let field = element[fCount] - expect(field).to.deep.equal(buffData[eCount * fieldsPerElement + fCount]) - expect(Buffer.from(field).toString()).to.deep.equal(utf8DataStrings[eCount * fieldsPerElement + fCount]) + const field = element[fCount] + expect(field).to.deep.equal( + buffData[eCount * fieldsPerElement + fCount] + ) + expect(Buffer.from(field).toString()).to.deep.equal( + utf8DataStrings[eCount * fieldsPerElement + fCount] + ) } } - expect(info.readPos).to.eql(leftPadding.byteLength + mainBuffer.byteLength) + expect(info.readPos).to.eql( + leftPadding.byteLength + mainBuffer.byteLength + ) }) } }) @@ -111,14 +156,23 @@ describe('readElements', () => { it('Check for early return (Postcondition): Enough data must exist to read the Uint16 length value.; Check for early return (Postcondition): Enough data must exist length of the value.', () => { const utf8DataStrings = [ - 'here', 'is', 'some', 'utf8', 'information', '\u00bd + \u00bc = \u00be' + 'here', + 'is', + 'some', + 'utf8', + 'information', + '\u00bd + \u00bc = \u00be', ] - const buffData = utf8DataStrings.map(str => new Uint8Array([...Buffer.from(str)])) - const buff = concatBuffers(...buffData.map(bufStr => { - const len = Buffer.alloc(2) - len.writeUInt16BE(bufStr.byteLength, 0) - return concatBuffers(len, bufStr) - })) + const buffData = utf8DataStrings.map( + (str) => new Uint8Array([...Buffer.from(str)]) + ) + const buff = concatBuffers( + ...buffData.map((bufStr) => { + const len = Buffer.alloc(2) + len.writeUInt16BE(bufStr.byteLength, 0) + return concatBuffers(len, bufStr) + }) + ) /* Will return false when trying to read the length of the seventh element */ const infoFalse1 = readElements(1, 7, buff) @@ -141,7 +195,11 @@ describe('readElements', () => { /* Given this I can use this to construct a new view of part of the * ArrayBuffer to simulate a large ArrayBuffer that is sliced * into parts for efficiency. */ - const sharingArrayBuffer = new Uint8Array(buff.buffer, 4, buff.byteLength - 4) + const sharingArrayBuffer = new Uint8Array( + buff.buffer, + 4, + buff.byteLength - 4 + ) expect(readElements(4, 1, sharingArrayBuffer)).to.not.equal(false) }) }) diff --git a/modules/serialize/test/serialize_factory.test.ts b/modules/serialize/test/serialize_factory.test.ts index 55e1d634c..0a2b6da22 100644 --- a/modules/serialize/test/serialize_factory.test.ts +++ b/modules/serialize/test/serialize_factory.test.ts @@ -5,12 +5,18 @@ import { expect } from 'chai' import { serializeFactory } from '../src/serialize_factory' -import { SerializationVersion, ContentType, ObjectType } from '../src/identifiers' +import { + SerializationVersion, + ContentType, + ObjectType, +} from '../src/identifiers' import * as fixtures from './fixtures' describe('serializeFactory:frameIv', () => { it('should return a rational IV', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { frameIv } = serializeFactory(fromUtf8) const test = frameIv(12, 1) expect(test).to.be.instanceof(Uint8Array) @@ -19,7 +25,9 @@ describe('serializeFactory:frameIv', () => { }) it('Precondition: sequenceNumber must conform to the specification. i.e. 1 - (2^32 - 1)', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { frameIv } = serializeFactory(fromUtf8) expect(() => frameIv(12, 0)).to.throw() }) @@ -27,7 +35,9 @@ describe('serializeFactory:frameIv', () => { describe('serializeFactory:nonFramedBodyIv', () => { it('should return a rational IV', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { nonFramedBodyIv } = serializeFactory(fromUtf8) const test = nonFramedBodyIv(12) expect(test).to.be.instanceof(Uint8Array) @@ -38,7 +48,9 @@ describe('serializeFactory:nonFramedBodyIv', () => { describe('serializeFactory:headerAuthIv', () => { it('should return a rational IV', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { headerAuthIv } = serializeFactory(fromUtf8) const test = headerAuthIv(12) expect(test).to.be.instanceof(Uint8Array) @@ -49,7 +61,9 @@ describe('serializeFactory:headerAuthIv', () => { describe('serializeFactory:frameHeader', () => { it('should return a rational frameHeader', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { frameHeader, frameIv } = serializeFactory(fromUtf8) const sequenceNumber = 1 const iv = frameIv(12, sequenceNumber) @@ -62,7 +76,9 @@ describe('serializeFactory:frameHeader', () => { describe('serializeFactory:finalFrameHeader', () => { it('should return a rational finalFrameHeader', () => { - const fromUtf8 = () => { throw new Error('not used') } + const fromUtf8 = () => { + throw new Error('not used') + } const { finalFrameHeader, frameIv } = serializeFactory(fromUtf8) const sequenceNumber = 1 const iv = frameIv(12, sequenceNumber) @@ -77,21 +93,121 @@ describe('serializeFactory:encodeEncryptionContext', () => { it('should return rational byte array', () => { const fromUtf8 = (input: string) => Buffer.from(input) const { encodeEncryptionContext } = serializeFactory(fromUtf8) - const test = encodeEncryptionContext({ information: '\u00bd + \u00bc = \u00be', some: 'public' }) + const test = encodeEncryptionContext({ + information: '\u00bd + \u00bc = \u00be', + some: 'public', + }) expect(test).to.be.instanceof(Array) expect(test.length).to.eql(2) expect(test[0]).to.be.instanceof(Uint8Array) expect(test[1]).to.be.instanceof(Uint8Array) - expect(test[0]).to.deep.equal(new Uint8Array([ 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190 ])) - expect(test[1]).to.deep.equal(new Uint8Array([ 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99 ])) + expect(test[0]).to.deep.equal( + new Uint8Array([ + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + ]) + ) + expect(test[1]).to.deep.equal( + new Uint8Array([ + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + ]) + ) }) it('Precondition: The serialized encryption context entries must be sorted by UTF-8 key value.', () => { const fromUtf8 = (input: string) => Buffer.from(input) const { encodeEncryptionContext } = serializeFactory(fromUtf8) - const test = encodeEncryptionContext({ some: 'public', information: '\u00bd + \u00bc = \u00be' }) - expect(test[0]).to.deep.equal(new Uint8Array([ 0, 11, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 0, 12, 194, 189, 32, 43, 32, 194, 188, 32, 61, 32, 194, 190 ])) - expect(test[1]).to.deep.equal(new Uint8Array([ 0, 4, 115, 111, 109, 101, 0, 6, 112, 117, 98, 108, 105, 99 ])) + const test = encodeEncryptionContext({ + some: 'public', + information: '\u00bd + \u00bc = \u00be', + }) + expect(test[0]).to.deep.equal( + new Uint8Array([ + 0, + 11, + 105, + 110, + 102, + 111, + 114, + 109, + 97, + 116, + 105, + 111, + 110, + 0, + 12, + 194, + 189, + 32, + 43, + 32, + 194, + 188, + 32, + 61, + 32, + 194, + 190, + ]) + ) + expect(test[1]).to.deep.equal( + new Uint8Array([ + 0, + 4, + 115, + 111, + 109, + 101, + 0, + 6, + 112, + 117, + 98, + 108, + 105, + 99, + ]) + ) }) }) @@ -99,7 +215,10 @@ describe('serializeFactory:serializeEncryptionContext', () => { it('should return rational context bytes', () => { const fromUtf8 = (input: string) => Buffer.from(input) const { serializeEncryptionContext } = serializeFactory(fromUtf8) - const test = serializeEncryptionContext({ some: 'public', information: '\u00bd + \u00bc = \u00be' }) + const test = serializeEncryptionContext({ + some: 'public', + information: '\u00bd + \u00bc = \u00be', + }) expect(test).to.be.instanceof(Uint8Array) expect(test.byteLength).to.eql(45) @@ -121,8 +240,16 @@ describe('serializeFactory:serializeEncryptedDataKeys', () => { const fromUtf8 = (input: string) => Buffer.from(input) const { serializeEncryptedDataKeys } = serializeFactory(fromUtf8) const test = serializeEncryptedDataKeys([ - { providerInfo: 'firstKey', providerId: '\u00bd + \u00bc = \u00be', encryptedDataKey: new Uint8Array([1, 2, 3, 4, 5]) }, - { providerInfo: 'secondKey', providerId: '\u00bd + \u00bc = \u00be', encryptedDataKey: new Uint8Array([6, 7, 8, 9, 0]) } + { + providerInfo: 'firstKey', + providerId: '\u00bd + \u00bc = \u00be', + encryptedDataKey: new Uint8Array([1, 2, 3, 4, 5]), + }, + { + providerInfo: 'secondKey', + providerId: '\u00bd + \u00bc = \u00be', + encryptedDataKey: new Uint8Array([6, 7, 8, 9, 0]), + }, ]) expect(test).to.be.instanceof(Uint8Array) @@ -139,15 +266,43 @@ describe('serializeFactory:serializeMessageHeader', () => { version: SerializationVersion.V1, type: ObjectType.CUSTOMER_AE_DATA, suiteId: 0x0014, - messageId: new Uint8Array([ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ]), - encryptionContext: { some: 'public', information: '\u00bd + \u00bc = \u00be' }, + messageId: new Uint8Array([ + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + ]), + encryptionContext: { + some: 'public', + information: '\u00bd + \u00bc = \u00be', + }, encryptedDataKeys: [ - { providerInfo: 'firstKey', providerId: '\u00bd + \u00bc = \u00be', encryptedDataKey: new Uint8Array([1, 2, 3, 4, 5]) }, - { providerInfo: 'secondKey', providerId: '\u00bd + \u00bc = \u00be', encryptedDataKey: new Uint8Array([6, 7, 8, 9, 0]) } + { + providerInfo: 'firstKey', + providerId: '\u00bd + \u00bc = \u00be', + encryptedDataKey: new Uint8Array([1, 2, 3, 4, 5]), + }, + { + providerInfo: 'secondKey', + providerId: '\u00bd + \u00bc = \u00be', + encryptedDataKey: new Uint8Array([6, 7, 8, 9, 0]), + }, ], contentType: ContentType.FRAMED_DATA, headerIvLength: 12, - frameLength: 4096 + frameLength: 4096, }) expect(test).to.be.instanceof(Uint8Array) @@ -162,19 +317,46 @@ describe('serializeFactory:serializeMessageHeader', () => { version: SerializationVersion.V1, type: ObjectType.CUSTOMER_AE_DATA, suiteId: 0x0014, - messageId: new Uint8Array([ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ]), + messageId: new Uint8Array([ + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + ]), encryptionContext: {}, encryptedDataKeys: [ - { providerInfo: 'firstKey', providerId: '\u00bd + \u00bc = \u00be', encryptedDataKey: new Uint8Array([1, 2, 3, 4, 5]) }, - { providerInfo: 'secondKey', providerId: '\u00bd + \u00bc = \u00be', encryptedDataKey: new Uint8Array([6, 7, 8, 9, 0]) } + { + providerInfo: 'firstKey', + providerId: '\u00bd + \u00bc = \u00be', + encryptedDataKey: new Uint8Array([1, 2, 3, 4, 5]), + }, + { + providerInfo: 'secondKey', + providerId: '\u00bd + \u00bc = \u00be', + encryptedDataKey: new Uint8Array([6, 7, 8, 9, 0]), + }, ], contentType: ContentType.FRAMED_DATA, headerIvLength: 12, - frameLength: 4096 + frameLength: 4096, }) expect(test).to.be.instanceof(Uint8Array) expect(test.byteLength).to.eql(97) - expect(test).to.deep.equal(fixtures.zeroByteEncryptionContextMessageHeader()) + expect(test).to.deep.equal( + fixtures.zeroByteEncryptionContextMessageHeader() + ) }) }) diff --git a/modules/serialize/test/signature_info.test.ts b/modules/serialize/test/signature_info.test.ts index 5267b93e3..42d7c3ee5 100644 --- a/modules/serialize/test/signature_info.test.ts +++ b/modules/serialize/test/signature_info.test.ts @@ -4,7 +4,10 @@ /* eslint-env mocha */ import { expect } from 'chai' -import { serializeSignatureInfo, deserializeSignature } from '../src/signature_info' +import { + serializeSignatureInfo, + deserializeSignature, +} from '../src/signature_info' import * as fixtures from './fixtures' describe('serializeSignatureInfo', () => { diff --git a/modules/web-crypto-backend/test/backend-factory.test.ts b/modules/web-crypto-backend/test/backend-factory.test.ts index 5962ffc68..dcbdd5f7d 100644 --- a/modules/web-crypto-backend/test/backend-factory.test.ts +++ b/modules/web-crypto-backend/test/backend-factory.test.ts @@ -12,7 +12,7 @@ import { windowRequiresFallback, webCryptoBackendFactory, getNonZeroByteBackend, - getZeroByteSubtle + getZeroByteSubtle, } from '../src/backend-factory' import * as browserWindow from '@aws-sdk/util-locate-window' @@ -27,19 +27,27 @@ describe('pluckSubtleCrypto', () => { }) it('return subtle object', () => { - const test = pluckSubtleCrypto(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) - expect(test === fixtures.fakeWindowWebCryptoSupportsZeroByteGCM.crypto.subtle).to.equal(true) + const test = pluckSubtleCrypto( + fixtures.fakeWindowWebCryptoSupportsZeroByteGCM + ) + expect( + test === fixtures.fakeWindowWebCryptoSupportsZeroByteGCM.crypto.subtle + ).to.equal(true) }) }) describe('windowRequiresFallback', () => { it('returns false', async () => { - const test = await windowRequiresFallback(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) + const test = await windowRequiresFallback( + fixtures.fakeWindowWebCryptoSupportsZeroByteGCM + ) expect(test).to.eql(false) }) it('returns true', async () => { - const test = await windowRequiresFallback(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) + const test = await windowRequiresFallback( + fixtures.fakeWindowWebCryptoZeroByteEncryptFail + ) expect(test).to.eql(true) }) }) @@ -48,10 +56,16 @@ describe('webCryptoBackendFactory', () => { describe('configureFallback', () => { it('returns a valid and configured fallback.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowNoWebCrypto) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowNoWebCrypto) - const { configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowNoWebCrypto) - const test = await configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) + const { configureFallback } = webCryptoBackendFactory( + fixtures.fakeWindowNoWebCrypto + ) + const test = await configureFallback( + fixtures.subtleFallbackSupportsZeroByteGCM + ) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -60,10 +74,16 @@ describe('webCryptoBackendFactory', () => { it('Precondition: If a fallback is not required, do not configure one.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) - - const { configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) - const test = await configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) + + const { configureFallback } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoSupportsZeroByteGCM + ) + const test = await configureFallback( + fixtures.subtleFallbackSupportsZeroByteGCM + ) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -72,12 +92,18 @@ describe('webCryptoBackendFactory', () => { it('Precondition: Can not reconfigure fallback.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) - const { configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoOnlyRandomSource) + const { configureFallback } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoOnlyRandomSource + ) await configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) - expect(configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM)).to.rejectedWith(Error) + await expect( + configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) + ).to.rejectedWith(Error) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -85,11 +111,17 @@ describe('webCryptoBackendFactory', () => { it('Precondition: Fallback must look like it supports the required operations.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) - const { configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoOnlyRandomSource) + const { configureFallback } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoOnlyRandomSource + ) - expect(configureFallback(fixtures.subtleFallbackNoWebCrypto)).to.rejectedWith(Error) + await expect( + configureFallback(fixtures.subtleFallbackNoWebCrypto) + ).to.rejectedWith(Error) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -97,11 +129,17 @@ describe('webCryptoBackendFactory', () => { it('Postcondition: The fallback must specifically support ZeroByteGCM.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) - const { configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoOnlyRandomSource) + const { configureFallback } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoOnlyRandomSource + ) - expect(configureFallback(fixtures.subtleFallbackZeroByteEncryptFail)).to.rejectedWith(Error) + await expect( + configureFallback(fixtures.subtleFallbackZeroByteEncryptFail) + ).to.rejectedWith(Error) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -111,22 +149,34 @@ describe('webCryptoBackendFactory', () => { describe('getWebCryptoBackend', () => { it('getWebCryptoBackend returns subtle and randomValues', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) - const { getWebCryptoBackend } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM) + const { getWebCryptoBackend } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoSupportsZeroByteGCM + ) const test = await getWebCryptoBackend() // @ts-ignore browserWindow.locateWindow = locateWindow - expect(test).to.have.property('subtle').and.to.eql(fixtures.fakeWindowWebCryptoSupportsZeroByteGCM.crypto.subtle) + expect(test) + .to.have.property('subtle') + .and.to.eql( + fixtures.fakeWindowWebCryptoSupportsZeroByteGCM.crypto.subtle + ) expect(test).to.have.property('randomValues') }) it('Precondition: Access to a secure random source is required.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowNoWebCrypto) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowNoWebCrypto) - const { getWebCryptoBackend } = webCryptoBackendFactory(fixtures.fakeWindowNoWebCrypto) + const { getWebCryptoBackend } = webCryptoBackendFactory( + fixtures.fakeWindowNoWebCrypto + ) await expect(getWebCryptoBackend()).to.rejectedWith(Error) // @ts-ignore @@ -135,9 +185,13 @@ describe('webCryptoBackendFactory', () => { it('Postcondition: If no SubtleCrypto exists, a fallback must configured.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) - const { getWebCryptoBackend } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoOnlyRandomSource) + const { getWebCryptoBackend } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoOnlyRandomSource + ) await expect(getWebCryptoBackend()).to.rejectedWith(Error) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -145,9 +199,13 @@ describe('webCryptoBackendFactory', () => { it('Postcondition: If a a subtle backend exists and a fallback is required, one must be configured.', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) - const { getWebCryptoBackend } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) + const { getWebCryptoBackend } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoZeroByteEncryptFail + ) await expect(getWebCryptoBackend()).to.rejectedWith(Error) // @ts-ignore browserWindow.locateWindow = locateWindow @@ -155,30 +213,56 @@ describe('webCryptoBackendFactory', () => { it('getWebCryptoBackend returns configured fallback subtle and randomValues', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) - - const { getWebCryptoBackend, configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoOnlyRandomSource) - configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoOnlyRandomSource) + + const { + getWebCryptoBackend, + configureFallback, + } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoOnlyRandomSource) + // This is intentionally frustrating. + // By not waiting for the config, + // I _also_ test its ability to await the configuration. + configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) // eslint-disable-line @typescript-eslint/no-floating-promises const test = await getWebCryptoBackend() // @ts-ignore browserWindow.locateWindow = locateWindow - expect(test).to.have.property('subtle').and.to.eql(fixtures.subtleFallbackSupportsZeroByteGCM) + expect(test) + .to.have.property('subtle') + .and.to.eql(fixtures.subtleFallbackSupportsZeroByteGCM) expect(test).to.have.property('randomValues') }) it('getWebCryptoBackend returns MixedSupportWebCryptoBackend', async () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) - - const { getWebCryptoBackend, configureFallback } = webCryptoBackendFactory(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) - configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowWebCryptoZeroByteEncryptFail) + + const { + getWebCryptoBackend, + configureFallback, + } = webCryptoBackendFactory( + fixtures.fakeWindowWebCryptoZeroByteEncryptFail + ) + // This is intentionally frustrating. + // By not waiting for the config, + // I _also_ test its ability to await the configuration. + configureFallback(fixtures.subtleFallbackSupportsZeroByteGCM) // eslint-disable-line @typescript-eslint/no-floating-promises const test = await getWebCryptoBackend() // @ts-ignore browserWindow.locateWindow = locateWindow - expect(test).to.have.property('nonZeroByteSubtle').and.to.eql(fixtures.fakeWindowWebCryptoZeroByteEncryptFail.crypto.subtle) - expect(test).to.have.property('zeroByteSubtle').and.to.eql(fixtures.subtleFallbackSupportsZeroByteGCM) + expect(test) + .to.have.property('nonZeroByteSubtle') + .and.to.eql( + fixtures.fakeWindowWebCryptoZeroByteEncryptFail.crypto.subtle + ) + expect(test) + .to.have.property('zeroByteSubtle') + .and.to.eql(fixtures.subtleFallbackSupportsZeroByteGCM) expect(test).to.have.property('randomValues') }) }) @@ -186,8 +270,12 @@ describe('webCryptoBackendFactory', () => { describe('getNonZeroByteBackend', () => { it('gets a subtle backend', () => { - const test = getNonZeroByteBackend(fixtures.subtleFallbackSupportsZeroByteGCM) - expect(test === fixtures.subtleFallbackSupportsZeroByteGCM.subtle).to.equal(true) + const test = getNonZeroByteBackend( + fixtures.subtleFallbackSupportsZeroByteGCM + ) + expect(test === fixtures.subtleFallbackSupportsZeroByteGCM.subtle).to.equal( + true + ) }) it('Precondition: A backend must be passed to get a non zero byte backend.', () => { @@ -198,7 +286,9 @@ describe('getNonZeroByteBackend', () => { describe('getZeroByteSubtle', () => { it('gets a subtle backend', () => { const test = getZeroByteSubtle(fixtures.subtleFallbackSupportsZeroByteGCM) - expect(test === fixtures.subtleFallbackSupportsZeroByteGCM.subtle).to.equal(true) + expect(test === fixtures.subtleFallbackSupportsZeroByteGCM.subtle).to.equal( + true + ) }) it('Precondition: A backend must be passed to get a zero byte backend.', () => { diff --git a/modules/web-crypto-backend/test/fixtures.ts b/modules/web-crypto-backend/test/fixtures.ts index 93597a01b..edddc884f 100644 --- a/modules/web-crypto-backend/test/fixtures.ts +++ b/modules/web-crypto-backend/test/fixtures.ts @@ -5,84 +5,140 @@ export const fakeWindowWebCryptoSupportsZeroByteGCM: Window = { crypto: { getRandomValues: () => {}, subtle: { - async decrypt () { return {} as any }, - async digest () { return {} as any }, - async encrypt () { + async decrypt() { + return {} as any + }, + async digest() { + return {} as any + }, + async encrypt() { // Mock a valid default tagLength // so we support zero byte encryption... return { byteLength: 16 } as any }, - async exportKey () { return {} as any }, - async generateKey () { return {} as any }, - async importKey () { return {} as any }, - async sign () { return {} as any }, - async verify () { return {} as any } - } - } + async exportKey() { + return {} as any + }, + async generateKey() { + return {} as any + }, + async importKey() { + return {} as any + }, + async sign() { + return {} as any + }, + async verify() { + return {} as any + }, + }, + }, } as any export const fakeWindowWebCryptoZeroByteEncryptFail: Window = { crypto: { getRandomValues: () => {}, subtle: { - async decrypt () { return {} as any }, - async digest () { return {} as any }, - async encrypt (...args: any[]) { - const [,, data] = args + async decrypt() { + return {} as any + }, + async digest() { + return {} as any + }, + async encrypt(...args: any[]) { + const [, , data] = args if (data.byteLength === 0) { throw new Error('Does not support') } else { return {} as any } }, - async exportKey () { return {} as any }, - async generateKey () { return {} as any }, - async importKey () { return {} as any }, - async sign () { return {} as any }, - async verify () { return {} as any } - } - } + async exportKey() { + return {} as any + }, + async generateKey() { + return {} as any + }, + async importKey() { + return {} as any + }, + async sign() { + return {} as any + }, + async verify() { + return {} as any + }, + }, + }, } as any export const fakeWindowWebCryptoOnlyRandomSource: Window = { crypto: { - getRandomValues: () => {} - } + getRandomValues: () => {}, + }, } as any export const fakeWindowNoWebCrypto: Window = {} as any export const subtleFallbackSupportsZeroByteGCM = { - async decrypt () { return {} as any }, - async digest () { return {} as any }, - async encrypt () { + async decrypt() { + return {} as any + }, + async digest() { + return {} as any + }, + async encrypt() { // Mock a valid default tagLength // so we support zero byte encryption... return { byteLength: 16 } as any }, - async exportKey () { return {} as any }, - async generateKey () { return {} as any }, - async importKey () { return {} as any }, - async sign () { return {} as any }, - async verify () { return {} as any } + async exportKey() { + return {} as any + }, + async generateKey() { + return {} as any + }, + async importKey() { + return {} as any + }, + async sign() { + return {} as any + }, + async verify() { + return {} as any + }, } as any export const subtleFallbackZeroByteEncryptFail = { - async decrypt () { return {} as any }, - async digest () { return {} as any }, - async encrypt (...args: any[]) { - const [,, data] = args + async decrypt() { + return {} as any + }, + async digest() { + return {} as any + }, + async encrypt(...args: any[]) { + const [, , data] = args if (data.byteLength === 0) { throw new Error('Does not support') } else { return {} as any } }, - async exportKey () { return {} as any }, - async generateKey () { return {} as any }, - async importKey () { return {} as any }, - async sign () { return {} as any }, - async verify () { return {} as any } + async exportKey() { + return {} as any + }, + async generateKey() { + return {} as any + }, + async importKey() { + return {} as any + }, + async sign() { + return {} as any + }, + async verify() { + return {} as any + }, } as any export const subtleFallbackNoWebCrypto = {} as any @@ -93,7 +149,7 @@ export const fakeWindowIE11OnComplete = { return values.fill(1) }, subtle: { - decrypt () { + decrypt() { const obj = {} as any setTimeout(() => { obj.result = true @@ -101,7 +157,7 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - digest () { + digest() { const obj = {} as any setTimeout(() => { obj.result = true @@ -109,7 +165,7 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - encrypt () { + encrypt() { const obj = {} as any setTimeout(() => { obj.result = true @@ -117,7 +173,7 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - exportKey () { + exportKey() { const obj = {} as any setTimeout(() => { obj.result = true @@ -125,7 +181,7 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - generateKey () { + generateKey() { const obj = {} as any setTimeout(() => { obj.result = true @@ -133,7 +189,7 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - importKey () { + importKey() { const obj = {} as any setTimeout(() => { obj.result = true @@ -141,7 +197,7 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - sign () { + sign() { const obj = {} as any setTimeout(() => { obj.result = true @@ -149,17 +205,17 @@ export const fakeWindowIE11OnComplete = { }) return obj }, - verify () { + verify() { const obj = {} as any setTimeout(() => { obj.result = true obj.oncomplete() }) return obj - } - } + }, + }, }, - MSInputMethodContext: {} as any + MSInputMethodContext: {} as any, } as any export const fakeWindowIE11OnError = { @@ -168,63 +224,63 @@ export const fakeWindowIE11OnError = { return values.fill(1) }, subtle: { - decrypt () { + decrypt() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - digest () { + digest() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - encrypt () { + encrypt() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - exportKey () { + exportKey() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - generateKey () { + generateKey() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - importKey () { + importKey() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - sign () { + sign() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj }, - verify () { + verify() { const obj = {} as any setTimeout(() => { obj.onerror(new Error('stub error')) }) return obj - } - } + }, + }, }, - MSInputMethodContext: {} as any + MSInputMethodContext: {} as any, } as any diff --git a/modules/web-crypto-backend/test/promisify-ms-crypto.test.ts b/modules/web-crypto-backend/test/promisify-ms-crypto.test.ts index c342a0ec5..7c420478f 100644 --- a/modules/web-crypto-backend/test/promisify-ms-crypto.test.ts +++ b/modules/web-crypto-backend/test/promisify-ms-crypto.test.ts @@ -16,8 +16,12 @@ const { expect } = chai * because the promisify code is all the same. */ describe('promisifyMsSubtleCrypto', () => { - const backendComplete = promisifyMsSubtleCrypto(fixtures.fakeWindowIE11OnComplete.msCrypto.subtle) - const backendError = promisifyMsSubtleCrypto(fixtures.fakeWindowIE11OnError.msCrypto.subtle) + const backendComplete = promisifyMsSubtleCrypto( + fixtures.fakeWindowIE11OnComplete.msCrypto.subtle + ) + const backendError = promisifyMsSubtleCrypto( + fixtures.fakeWindowIE11OnError.msCrypto.subtle + ) it('backendComplete:decrypt', async () => { // @ts-ignore These methods are stubs, ignore ts errors @@ -25,8 +29,8 @@ describe('promisifyMsSubtleCrypto', () => { expect(test).to.equal(true) }) - it('backendError:decrypt', () => { + it('backendError:decrypt', async () => { // @ts-ignore These methods are stubs, ignore ts errors - expect(backendError.decrypt()).to.rejectedWith(Error) + await expect(backendError.decrypt()).to.rejectedWith(Error) }) }) diff --git a/modules/web-crypto-backend/test/synchronous_random_values.test.ts b/modules/web-crypto-backend/test/synchronous_random_values.test.ts index 9e338cdd2..937daf527 100644 --- a/modules/web-crypto-backend/test/synchronous_random_values.test.ts +++ b/modules/web-crypto-backend/test/synchronous_random_values.test.ts @@ -18,7 +18,9 @@ describe('synchronousRandomValues', () => { it('should return msCrypto random values', () => { const { locateWindow } = browserWindow - sinon.stub(browserWindow, 'locateWindow').returns(fixtures.fakeWindowIE11OnComplete) + sinon + .stub(browserWindow, 'locateWindow') + .returns(fixtures.fakeWindowIE11OnComplete) const test = synchronousRandomValues(5) expect(test).to.be.instanceOf(Uint8Array) diff --git a/package.json b/package.json index e08c22778..117de0857 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "clean": "npm run clear-build-cache && lerna clean", "clear-build-cache": "rimraf ./modules/*/build/*", "lint": "run-s lint-*", - "lint-eslint": "npx eslint modules/**/src/*.ts", - "lint-prettier": "prettier -c modules/**/src/*.ts", + "lint-eslint": "npx eslint modules/**/src/*.ts modules/**/test/**/*.ts", + "lint-prettier": "prettier -c modules/**/src/*.ts modules/**/test/**/*.ts", "build-node": "tsc -b tsconfig.json", "build-browser": "tsc -b tsconfig.module.json", "build": "run-s build-*",