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-*",