From 5f97432baf3721faa986b051c50781f53b659bd5 Mon Sep 17 00:00:00 2001 From: seebees Date: Mon, 15 Jul 2019 16:59:43 -0700 Subject: [PATCH 1/3] fix: frame length can not be 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolves #129 The other ESDK’s use frameLength === 0 to indicate non-framed content. The JS ESDK does not support encrypting non-framed content. A frameLength of 0 will crash the process. Add condition and test. --- modules/encrypt-browser/src/encrypt.ts | 8 +++++++- modules/encrypt-browser/test/encrypt.test.ts | 5 +++++ modules/encrypt-node/src/encrypt_stream.ts | 9 +++++++-- modules/encrypt-node/test/encrypt.test.ts | 5 +++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/modules/encrypt-browser/src/encrypt.ts b/modules/encrypt-browser/src/encrypt.ts index 33ef913e7..3a7d757b6 100644 --- a/modules/encrypt-browser/src/encrypt.ts +++ b/modules/encrypt-browser/src/encrypt.ts @@ -21,6 +21,7 @@ import { AlgorithmSuiteIdentifier, getEncryptHelper, KeyringWebCrypto, + needs, WebCryptoMaterialsManager // eslint-disable-line no-unused-vars } from '@aws-crypto/material-management-browser' import { @@ -35,7 +36,8 @@ import { serializeSignatureInfo, FRAME_LENGTH, MESSAGE_ID_LENGTH, - raw2der + raw2der, + Maximum } from '@aws-crypto/serialize' import { fromUtf8 } from '@aws-sdk/util-utf8-browser' import { getWebCryptoBackend } from '@aws-crypto/web-crypto-backend' @@ -60,6 +62,10 @@ export async function encrypt ( plaintext: Uint8Array, { suiteId, encryptionContext, frameLength = FRAME_LENGTH }: EncryptInput = {} ): Promise { + + /* Precondition: The frameLength must be less than the maximum frame size for browser encryption. */ + needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, 'frameLength out of bounds') + const backend = await getWebCryptoBackend() if (!backend) throw new Error('No supported crypto backend') diff --git a/modules/encrypt-browser/test/encrypt.test.ts b/modules/encrypt-browser/test/encrypt.test.ts index 229276fb1..3b2b4f625 100644 --- a/modules/encrypt-browser/test/encrypt.test.ts +++ b/modules/encrypt-browser/test/encrypt.test.ts @@ -85,4 +85,9 @@ describe('encrypt structural testing', () => { expect(messageHeader).to.deep.equal(messageInfo.messageHeader) }) + + it('Precondition: The frameLength must be less than the maximum frame size for browser encryption.', async () => { + const frameLength = 0 + expect(encrypt(keyRing, 'asdf', { frameLength })).to.rejectedWith(Error) + }) }) diff --git a/modules/encrypt-node/src/encrypt_stream.ts b/modules/encrypt-node/src/encrypt_stream.ts index 0d126d896..2be7b8b94 100644 --- a/modules/encrypt-node/src/encrypt_stream.ts +++ b/modules/encrypt-node/src/encrypt_stream.ts @@ -16,7 +16,8 @@ import { NodeDefaultCryptographicMaterialsManager, NodeAlgorithmSuite, AlgorithmSuiteIdentifier, // eslint-disable-line no-unused-vars KeyringNode, NodeEncryptionMaterial, getEncryptHelper, EncryptionContext, // eslint-disable-line no-unused-vars - NodeMaterialsManager // eslint-disable-line no-unused-vars + NodeMaterialsManager, // eslint-disable-line no-unused-vars + needs } from '@aws-crypto/material-management-node' import { getFramedEncryptStream } from './framed_encrypt_stream' import { SignatureStream } from './signature_stream' @@ -26,7 +27,8 @@ import { MessageHeader, // eslint-disable-line no-unused-vars serializeFactory, kdfInfo, ContentType, SerializationVersion, ObjectType, FRAME_LENGTH, - MESSAGE_ID_LENGTH + MESSAGE_ID_LENGTH, + Maximum } from '@aws-crypto/serialize' // @ts-ignore @@ -56,6 +58,9 @@ export function encryptStream ( ): Duplex { const { suiteId, context, frameLength = FRAME_LENGTH } = op + /* Precondition: The frameLength must be less than the maximum frame size Node.js stream. */ + needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, 'frameLength out of bounds') + /* If the cmm is a Keyring, wrap it with NodeDefaultCryptographicMaterialsManager. */ cmm = cmm instanceof KeyringNode ? new NodeDefaultCryptographicMaterialsManager(cmm) diff --git a/modules/encrypt-node/test/encrypt.test.ts b/modules/encrypt-node/test/encrypt.test.ts index f7d3c9318..aa42a4523 100644 --- a/modules/encrypt-node/test/encrypt.test.ts +++ b/modules/encrypt-node/test/encrypt.test.ts @@ -184,6 +184,11 @@ describe('encrypt structural testing', () => { expect(messageHeader).to.deep.equal(messageInfo.messageHeader) }) + + 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) + }) }) function finishedAsync (stream: any) { From ef69ccd20191f78246b8523e560e9225475da014 Mon Sep 17 00:00:00 2001 From: seebees Date: Tue, 16 Jul 2019 09:05:44 -0700 Subject: [PATCH 2/3] linit --- modules/encrypt-browser/src/encrypt.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/encrypt-browser/src/encrypt.ts b/modules/encrypt-browser/src/encrypt.ts index 3a7d757b6..257584815 100644 --- a/modules/encrypt-browser/src/encrypt.ts +++ b/modules/encrypt-browser/src/encrypt.ts @@ -62,7 +62,6 @@ export async function encrypt ( plaintext: Uint8Array, { suiteId, encryptionContext, frameLength = FRAME_LENGTH }: EncryptInput = {} ): Promise { - /* Precondition: The frameLength must be less than the maximum frame size for browser encryption. */ needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, 'frameLength out of bounds') From 3f91a93094b976f7a7d63c28cdfc6a55f5f22143 Mon Sep 17 00:00:00 2001 From: seebees Date: Tue, 16 Jul 2019 09:07:09 -0700 Subject: [PATCH 3/3] Add bounds to error message --- modules/encrypt-browser/src/encrypt.ts | 2 +- modules/encrypt-node/src/encrypt_stream.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/encrypt-browser/src/encrypt.ts b/modules/encrypt-browser/src/encrypt.ts index 257584815..8baf90f20 100644 --- a/modules/encrypt-browser/src/encrypt.ts +++ b/modules/encrypt-browser/src/encrypt.ts @@ -63,7 +63,7 @@ export async function encrypt ( { suiteId, encryptionContext, frameLength = FRAME_LENGTH }: EncryptInput = {} ): Promise { /* Precondition: The frameLength must be less than the maximum frame size for browser encryption. */ - needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, 'frameLength out of bounds') + needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, `frameLength out of bounds: 0 > frameLength >= ${Maximum.FRAME_SIZE}`) const backend = await getWebCryptoBackend() if (!backend) throw new Error('No supported crypto backend') diff --git a/modules/encrypt-node/src/encrypt_stream.ts b/modules/encrypt-node/src/encrypt_stream.ts index 2be7b8b94..1a48f293d 100644 --- a/modules/encrypt-node/src/encrypt_stream.ts +++ b/modules/encrypt-node/src/encrypt_stream.ts @@ -59,7 +59,7 @@ export function encryptStream ( const { suiteId, context, frameLength = FRAME_LENGTH } = op /* Precondition: The frameLength must be less than the maximum frame size Node.js stream. */ - needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, 'frameLength out of bounds') + needs(frameLength > 0 && Maximum.FRAME_SIZE >= frameLength, `frameLength out of bounds: 0 > frameLength >= ${Maximum.FRAME_SIZE}`) /* If the cmm is a Keyring, wrap it with NodeDefaultCryptographicMaterialsManager. */ cmm = cmm instanceof KeyringNode