Skip to content

Commit

Permalink
fix: Encrypt name to result (#211)
Browse files Browse the repository at this point in the history
Javascript stimulates named parameters with objects.
The previous version used `ciphertext` to denote
the usable result from a call to `encrypt`.
However, this caused some cogitative load.
Ciphertext is used to denote encrypted data,
however the result of a call to `encrypt` in not _only_ encrypted data.
The AWS Encryption SDK uses envelop encryption,
so the result of a call to `encrypt` include not only the encrypted data,
but also, the encrypted data keys, metadata, and the encryption context.
By returning both the `messageHeader` *and* the `ciphertext`
users are confused about what exactly was *in* `ciphertext`.
This is compounded by returning `messageHeader`
which is just a parsed version of the header
that is already returned by the result of `encrypt`

The named parameter is now call `result`.
This makes it clear that this is the important return value from `encrypt`
that is the only value needed for `decrypt`.
  • Loading branch information
seebees authored Sep 16, 2019
1 parent c50dfa1 commit 03061d1
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 71 deletions.
10 changes: 5 additions & 5 deletions modules/encrypt-browser/src/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface EncryptInput {

export interface EncryptResult {
messageHeader: MessageHeader
ciphertext: Uint8Array
result: Uint8Array
}

export async function encrypt (
Expand Down Expand Up @@ -145,7 +145,7 @@ export async function encrypt (
bodyContent.push(frameHeader, cipherBufferAndAuthTag)
}

const ciphertext = concatBuffers(
const result = concatBuffers(
header,
headerAuthIv,
headerAuthTag,
Expand All @@ -155,11 +155,11 @@ export async function encrypt (
dispose()

if (typeof subtleSign === 'function') {
const signatureArrayBuffer = await subtleSign(ciphertext)
const signatureArrayBuffer = await subtleSign(result)
const derSignature = raw2der(new Uint8Array(signatureArrayBuffer), material.suite)
const signatureInfo = serializeSignatureInfo(derSignature)
return { ciphertext: concatBuffers(ciphertext, signatureInfo), messageHeader }
return { result: concatBuffers(result, signatureInfo), messageHeader }
} else {
return { ciphertext, messageHeader }
return { result: result, messageHeader }
}
}
12 changes: 6 additions & 6 deletions modules/encrypt-browser/test/encrypt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('encrypt structural testing', () => {
const encryptionContext = { simple: 'context' }

const plaintext = fromUtf8('asdf')
const { ciphertext, 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.
Expand All @@ -82,7 +82,7 @@ describe('encrypt structural testing', () => {
expect(messageHeader.encryptedDataKeys).lengthOf(1)
expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk)

const messageInfo = deserializeMessageHeader(ciphertext)
const messageInfo = deserializeMessageHeader(result)
if (!messageInfo) throw new Error('I should never see this error')

expect(messageHeader).to.deep.equal(messageInfo.messageHeader)
Expand All @@ -96,9 +96,9 @@ describe('encrypt structural testing', () => {
it('can fully parse a framed message', async () => {
const plaintext = fromUtf8('asdf')
const frameLength = 1
const { ciphertext } = await encrypt(keyRing, plaintext, { frameLength })
const { result } = await encrypt(keyRing, plaintext, { frameLength })

const headerInfo = deserializeMessageHeader(ciphertext)
const headerInfo = deserializeMessageHeader(result)
if (!headerInfo) throw new Error('this should never happen')

const tagLength = headerInfo.algorithmSuite.tagLength / 8
Expand All @@ -107,7 +107,7 @@ describe('encrypt structural testing', () => {
let bodyHeader: any
// for every frame...
for (; i < 4; i++) {
bodyHeader = decodeBodyHeader(ciphertext, headerInfo, readPos)
bodyHeader = decodeBodyHeader(result, headerInfo, readPos)
if (!bodyHeader) throw new Error('this should never happen')
readPos = bodyHeader.readPos + bodyHeader.contentLength + tagLength
}
Expand All @@ -117,7 +117,7 @@ describe('encrypt structural testing', () => {

// This implicitly tests that I have consumed all the data,
// because otherwise the footer section will be too large
const footerSection = ciphertext.slice(readPos)
const footerSection = result.slice(readPos)
// This will throw if it does not deserialize correctly
deserializeSignature(footerSection)
})
Expand Down
8 changes: 4 additions & 4 deletions modules/encrypt-node/src/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface EncryptInput extends EncryptStreamInput {
}

export interface EncryptOutput {
ciphertext: Buffer
result: Buffer
messageHeader: MessageHeader
}

Expand All @@ -29,11 +29,11 @@ export async function encrypt (
const stream = encryptStream(cmm, op)
const { encoding } = op

const ciphertext: Buffer[] = []
const result: Buffer[] = []
let messageHeader: MessageHeader|false = false
stream
.once('MessageHeader', header => { messageHeader = header })
.on('data', (chunk: Buffer) => ciphertext.push(chunk))
.on('data', (chunk: Buffer) => result.push(chunk))

// This will check both Uint8Array|Buffer
if (plaintext instanceof Uint8Array) {
Expand All @@ -50,7 +50,7 @@ export async function encrypt (
if (!messageHeader) throw new Error('Unknown format')

return {
ciphertext: Buffer.concat(ciphertext),
result: Buffer.concat(result),
messageHeader
}
}
Expand Down
24 changes: 12 additions & 12 deletions modules/encrypt-node/test/encrypt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ describe('encrypt structural testing', () => {
const suiteId = AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16

const plaintext = 'asdf'
const { ciphertext, 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({})
expect(messageHeader.encryptedDataKeys).lengthOf(1)
expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk)

const messageInfo = deserializeMessageHeader(ciphertext)
const messageInfo = deserializeMessageHeader(result)
if (!messageInfo) throw new Error('I should never see this error')

expect(messageHeader).to.deep.equal(messageInfo.messageHeader)
Expand All @@ -95,7 +95,7 @@ describe('encrypt structural testing', () => {
const encryptionContext = { simple: 'context' }

const plaintext = Buffer.from('asdf')
const { ciphertext, 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.
Expand All @@ -104,7 +104,7 @@ describe('encrypt structural testing', () => {
expect(messageHeader.encryptedDataKeys).lengthOf(1)
expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk)

const messageInfo = deserializeMessageHeader(ciphertext)
const messageInfo = deserializeMessageHeader(result)
if (!messageInfo) throw new Error('I should never see this error')

expect(messageHeader).to.deep.equal(messageInfo.messageHeader)
Expand All @@ -120,7 +120,7 @@ describe('encrypt structural testing', () => {
next(null, 'asdf')
})

const { ciphertext, 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.
Expand All @@ -129,7 +129,7 @@ describe('encrypt structural testing', () => {
expect(messageHeader.encryptedDataKeys).lengthOf(1)
expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk)

const messageInfo = deserializeMessageHeader(ciphertext)
const messageInfo = deserializeMessageHeader(result)
if (!messageInfo) throw new Error('I should never see this error')

expect(messageHeader).to.deep.equal(messageInfo.messageHeader)
Expand Down Expand Up @@ -172,7 +172,7 @@ describe('encrypt structural testing', () => {

if (!messageHeader) throw new Error('I should never see this error')

const ciphertext = Buffer.concat(buffer)
const result = Buffer.concat(buffer)

/* The default algorithm suite will add a signature key to the context.
* So I only check that the passed context elements exist.
Expand All @@ -181,7 +181,7 @@ describe('encrypt structural testing', () => {
expect(messageHeader.encryptedDataKeys).lengthOf(1)
expect(messageHeader.encryptedDataKeys[0]).to.deep.equal(edk)

const messageInfo = deserializeMessageHeader(ciphertext)
const messageInfo = deserializeMessageHeader(result)
if (!messageInfo) throw new Error('I should never see this error')

expect(messageHeader).to.deep.equal(messageInfo.messageHeader)
Expand All @@ -195,9 +195,9 @@ describe('encrypt structural testing', () => {
it('can fully parse a framed message', async () => {
const plaintext = 'asdf'
const frameLength = 1
const { ciphertext } = await encrypt(keyRing, plaintext, { frameLength })
const { result } = await encrypt(keyRing, plaintext, { frameLength })

const headerInfo = deserializeMessageHeader(ciphertext)
const headerInfo = deserializeMessageHeader(result)
if (!headerInfo) throw new Error('this should never happen')

const tagLength = headerInfo.algorithmSuite.tagLength / 8
Expand All @@ -206,7 +206,7 @@ describe('encrypt structural testing', () => {
let bodyHeader: any
// for every frame...
for (; i < 5; i++) {
bodyHeader = decodeBodyHeader(ciphertext, headerInfo, readPos)
bodyHeader = decodeBodyHeader(result, headerInfo, readPos)
if (!bodyHeader) throw new Error('this should never happen')
readPos = bodyHeader.readPos + bodyHeader.contentLength + tagLength
}
Expand All @@ -216,7 +216,7 @@ describe('encrypt structural testing', () => {

// This implicitly tests that I have consumed all the data,
// because otherwise the footer section will be too large
const footerSection = ciphertext.slice(readPos)
const footerSection = result.slice(readPos)
// This will throw if it does not deserialize correctly
deserializeSignature(footerSection)
})
Expand Down
12 changes: 6 additions & 6 deletions modules/example-browser/src/aes_simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,22 @@ import { toBase64 } from '@aws-sdk/util-base64-browser'
const plainText = new Uint8Array([1, 2, 3, 4, 5])

/* Encrypt the data. */
const { ciphertext } = await encrypt(keyring, plainText, { encryptionContext: context })
const { result } = await encrypt(keyring, plainText, { encryptionContext: context })

/* Log the plain text
* only for testing and to show that it works.
*/
console.log('plainText:', plainText)
document.write('</br>plainText:' + plainText + '</br>')

/* Log the base64-encoded ciphertext
/* Log the base64-encoded result
* so that you can try decrypting it with another AWS Encryption SDK implementation.
*/
const ciphertextBase64 = toBase64(ciphertext)
console.log(ciphertextBase64)
document.write(ciphertextBase64)
const resultBase64 = toBase64(result)
console.log(resultBase64)
document.write(resultBase64)

const { plaintext, messageHeader } = await decrypt(keyring, ciphertext)
const { plaintext, messageHeader } = await decrypt(keyring, result)

/* Grab the encryption context so you can verify it. */
const { encryptionContext } = messageHeader
Expand Down
12 changes: 6 additions & 6 deletions modules/example-browser/src/kms_simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,22 @@ declare const AWS_CREDENTIALS: {accessKeyId: string, secretAccessKey:string }
const plainText = new Uint8Array([1, 2, 3, 4, 5])

/* Encrypt the data. */
const { ciphertext } = await encrypt(keyring, plainText, { encryptionContext: context })
const { result } = await encrypt(keyring, plainText, { encryptionContext: context })

/* Log the plain text
* only for testing and to show that it works.
*/
console.log('plainText:', plainText)
document.write('</br>plainText:' + plainText + '</br>')

/* Log the base64-encoded ciphertext
/* Log the base64-encoded result
* so that you can try decrypting it with another AWS Encryption SDK implementation.
*/
const ciphertextBase64 = toBase64(ciphertext)
console.log(ciphertextBase64)
document.write(ciphertextBase64)
const resultBase64 = toBase64(result)
console.log(resultBase64)
document.write(resultBase64)

const { plaintext, messageHeader } = await decrypt(keyring, ciphertext)
const { plaintext, messageHeader } = await decrypt(keyring, result)

/* Grab the encryption context so you can verify it. */
const { encryptionContext } = messageHeader
Expand Down
16 changes: 8 additions & 8 deletions modules/example-browser/src/multi_keyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,29 +122,29 @@ declare const AWS_CREDENTIALS: {accessKeyId: string, secretAccessKey:string }
const plainText = new Uint8Array([1, 2, 3, 4, 5])

/* Encrypt the data. */
const { ciphertext } = await encrypt(keyring, plainText, { encryptionContext: context })
const { result } = await encrypt(keyring, plainText, { encryptionContext: context })

/* Log the plain text
* only for testing and to show that it works.
*/
console.log('plainText:', plainText)
document.write('</br>plainText:' + plainText + '</br>')

/* Log the base64-encoded ciphertext
/* Log the base64-encoded result
* so that you can try decrypting it with another AWS Encryption SDK implementation.
*/
const ciphertextBase64 = toBase64(ciphertext)
console.log(ciphertextBase64)
document.write(ciphertextBase64)
const resultBase64 = toBase64(result)
console.log(resultBase64)
document.write(resultBase64)

/* Decrypt the data.
* This decrypt call could be done with **any** of the 3 keyrings.
* Here we use the multi-keyring, but
* decrypt(kmsKeyring, ciphertext)
* decrypt(aesKeyring, ciphertext)
* decrypt(kmsKeyring, result)
* decrypt(aesKeyring, result)
* would both work as well.
*/
const { plaintext, messageHeader } = await decrypt(keyring, ciphertext)
const { plaintext, messageHeader } = await decrypt(keyring, result)

/* Grab the encryption context so you can verify it. */
const { encryptionContext } = messageHeader
Expand Down
12 changes: 6 additions & 6 deletions modules/example-browser/src/rsa_simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,22 @@ import { toBase64 } from '@aws-sdk/util-base64-browser'
const plainText = new Uint8Array([1, 2, 3, 4, 5])

/* Encrypt the data. */
const { ciphertext } = await encrypt(keyring, plainText, { encryptionContext: context })
const { result } = await encrypt(keyring, plainText, { encryptionContext: context })

/* Log the plain text
* only for testing and to show that it works.
*/
console.log('plainText:', plainText)
document.write('</br>plainText:' + plainText + '</br>')

/* Log the base64-encoded ciphertext
/* Log the base64-encoded result
* so that you can try decrypting it with another AWS Encryption SDK implementation.
*/
const ciphertextBase64 = toBase64(ciphertext)
console.log(ciphertextBase64)
document.write(ciphertextBase64)
const resultBase64 = toBase64(result)
console.log(resultBase64)
document.write(resultBase64)

const { plaintext, messageHeader } = await decrypt(keyring, ciphertext)
const { plaintext, messageHeader } = await decrypt(keyring, result)

/* Grab the encryption context so you can verify it. */
const { encryptionContext } = messageHeader
Expand Down
6 changes: 3 additions & 3 deletions modules/example-node/src/aes_simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ export async function aesTest () {
const cleartext = 'asdf'

/* Encrypt the data. */
const { ciphertext } = await encrypt(keyring, cleartext, { encryptionContext: context })
const { result } = await encrypt(keyring, cleartext, { encryptionContext: context })
/* Decrypt the data. */
const { plaintext, messageHeader } = await decrypt(keyring, ciphertext)
const { plaintext, messageHeader } = await decrypt(keyring, result)

/* Grab the encryption context so you can verify it. */
const { encryptionContext } = messageHeader
Expand All @@ -78,5 +78,5 @@ export async function aesTest () {
})

/* Return the values so the code can be tested. */
return { plaintext, ciphertext, cleartext }
return { plaintext, result, cleartext }
}
6 changes: 3 additions & 3 deletions modules/example-node/src/kms_simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ export async function kmsSimpleTest () {
const cleartext = 'asdf'

/* Encrypt the data. */
const { ciphertext } = await encrypt(keyring, cleartext, { encryptionContext: context })
const { result } = await encrypt(keyring, cleartext, { encryptionContext: context })

/* Decrypt the data. */
const { plaintext, messageHeader } = await decrypt(keyring, ciphertext)
const { plaintext, messageHeader } = await decrypt(keyring, result)

/* Grab the encryption context so you can verify it. */
const { encryptionContext } = messageHeader
Expand All @@ -74,5 +74,5 @@ export async function kmsSimpleTest () {
})

/* Return the values so the code can be tested. */
return { plaintext, ciphertext, cleartext, messageHeader }
return { plaintext, result, cleartext, messageHeader }
}
Loading

0 comments on commit 03061d1

Please sign in to comment.