Skip to content

Commit 66e63b5

Browse files
texastonyseebees
andauthored
feat(node): support node v16 (#741)
Regenerated the Package lock with Node 16, NPM 8. Added CI testing for Node 16. Encapsulated Crypto's Sign(er) and Verify to prevent breaking changes. Implemented and used Catchable to catch unkown. TS upgrade introduced TS bug when recognizing arguments to SubtleCrypto's ImportKey. Introduced function and note to help it resolve the issue. Co-authored-by: seebees <[email protected]>
1 parent 6ba9add commit 66e63b5

File tree

30 files changed

+19466
-7207
lines changed

30 files changed

+19466
-7207
lines changed

buildspec.yml

+16
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,24 @@ batch:
99
image: aws/codebuild/standard:5.0
1010
- identifier: testNodejs12
1111
buildspec: codebuild/nodejs12.yml
12+
env:
13+
image: aws/codebuild/standard:5.0
1214
- identifier: testNodejs14
1315
buildspec: codebuild/nodejs14.yml
1416
env:
1517
image: aws/codebuild/standard:5.0
18+
- identifier: testNodejs16
19+
buildspec: codebuild/nodejs16.yml
20+
env:
21+
image: aws/codebuild/standard:5.0
1622
- identifier: testBrowser
1723
buildspec: codebuild/browser.yml
24+
env:
25+
image: aws/codebuild/standard:5.0
1826
- identifier: compliance
1927
buildspec: codebuild/compliance.yml
28+
env:
29+
image: aws/codebuild/standard:5.0
2030
- identifier: testVectorsNodejsLatest
2131
buildspec: codebuild/test_vectors/nodejs_latest.yml
2232
env:
@@ -25,10 +35,16 @@ batch:
2535
image: aws/codebuild/standard:5.0
2636
- identifier: testVectorsNodejs12
2737
buildspec: codebuild/test_vectors/nodejs12.yml
38+
env:
39+
image: aws/codebuild/standard:5.0
2840
- identifier: testVectorsNodejs14
2941
buildspec: codebuild/test_vectors/nodejs14.yml
3042
env:
3143
image: aws/codebuild/standard:5.0
44+
- identifier: testVectorsNodejs16
45+
buildspec: codebuild/test_vectors/nodejs16.yml
46+
env:
47+
image: aws/codebuild/standard:5.0
3248
- identifier: testVectorsBrowser
3349
buildspec: codebuild/test_vectors/browser.yml
3450
env:

codebuild/nodejs16.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: 0.2
2+
3+
env:
4+
variables:
5+
NODE_OPTIONS: "--max-old-space-size=4096"
6+
7+
phases:
8+
install:
9+
commands:
10+
- n 16
11+
- node -v
12+
- npm -v
13+
- npm ci --unsafe-perm
14+
- npm run build
15+
build:
16+
commands:
17+
- npm -v
18+
- node -v
19+
- npm run coverage-node

codebuild/test_vectors/nodejs16.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
version: 0.2
2+
3+
env:
4+
variables:
5+
NODE_OPTIONS: "--max-old-space-size=4096"
6+
NPM_CONFIG_UNSAFE_PERM: true
7+
8+
phases:
9+
install:
10+
commands:
11+
- n 16
12+
- node -v
13+
- npm -v
14+
- npm ci --unsafe-perm
15+
- npm run build
16+
build:
17+
commands:
18+
- npm -v
19+
- node -v
20+
- npm run verdaccio-publish
21+
- npm run verdaccio-node-decrypt
22+
- npm run verdaccio-node-encrypt

modules/decrypt-node/src/verify_stream.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ export class VerifyStream extends PortableTransformWithType {
8080
if (verify) {
8181
const { rawHeader, headerAuth, messageHeader } = headerInfo
8282
const { headerIv, headerAuthTag } = headerAuth
83-
verify.update(rawHeader)
83+
verify.update(<Buffer>rawHeader)
8484
verify.update(
85-
serializeMessageHeaderAuth({
85+
<Buffer>serializeMessageHeaderAuth({
8686
headerIv,
8787
headerAuthTag,
8888
messageHeader,
@@ -263,7 +263,7 @@ export class VerifyStream extends PortableTransformWithType {
263263
return super.push(chunk, encoding)
264264
}
265265

266-
_flush(callback: (err?: Error) => void) {
266+
_flush(callback: (err?: Error | any | unknown) => void) {
267267
const { finalAuthTagReceived } = this._verifyState
268268
/* Precondition: All ciphertext MUST have been received.
269269
* The verify stream has ended,

modules/example-browser/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434
"karma-chrome-launcher": "^3.1.0",
3535
"karma-coverage-istanbul-reporter": "^3.0.3",
3636
"karma-mocha": "2.0.1",
37-
"karma-webpack": "^4.0.2",
37+
"karma-webpack": "^5.0.0",
3838
"ts-loader": "9.2.5",
3939
"ts-node": "^10.2.1",
4040
"tslib": "^2.2.0",
4141
"typescript": "^4.0.2",
42-
"webpack": "^4.42.1",
42+
"webpack": "^5.42.0",
4343
"webpack-cli": "4.6.0"
4444
},
4545
"main": "./build/main/src/index.js",

modules/integration-browser/src/integration.encrypt.test.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,15 @@ function aTest(testName: string, decryptOracle: string) {
5959
const body = await response.arrayBuffer()
6060
needs(response.ok, `Failed to decrypt: ${toUtf8(body)}`)
6161
expect(plainText).toEqual(new Uint8Array(body))
62-
} catch (e) {
63-
if (!notSupportedMessages.includes(e.message)) throw e
62+
} catch (err) {
63+
needs(
64+
err instanceof Error,
65+
`Thrown object must be an error but was ${typeof err}`
66+
)
67+
needs(
68+
notSupportedMessages.includes(err.message),
69+
`Error message should be in notSupportedMessages but was ${err.message}`
70+
)
6471
}
6572
})
6673
}

modules/integration-browser/src/testDecryptFixture.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
MultiKeyringWebCrypto,
77
WebCryptoMaterialsManager,
88
DecryptResult,
9+
needs,
910
} from '@aws-crypto/client-browser'
1011
import {
1112
DecryptionFixture,
@@ -69,14 +70,17 @@ export async function testPositiveDecryptFixture(
6970
) {
7071
return { result: true, name }
7172
}
72-
// noinspection ExceptionCaughtLocallyJS
73+
/* If the actual plaintext does not match the expected plaintext,*/
7374
throw new Error(
7475
expectedNotActualPlaintextMessage +
7576
`\n expected plaintext: ${expectedPlainText}` +
7677
`\n actual plaintext: ${decryptResult.plaintext}`
7778
)
7879
} catch (err) {
80+
/* it FAILED with err.message as expectedNotActualPlaintextMessage */
7981
return { result: false, name, err }
82+
//By catching the err and returning it above, we also satisfy:
83+
/* If the decryption is NOT supported, FAILED with err.message in notSupportedDecryptMessages */
8084
}
8185
}
8286

@@ -96,10 +100,18 @@ export async function testNegativeDecryptFixture(
96100
const cmm = await _getCmm(keyInfos)
97101
decryptResult = await _decrypt(cmm, cipher)
98102
} catch (err) {
99-
if (notSupportedDecryptMessages.includes(err.message))
103+
needs(
104+
err instanceof Error,
105+
`Thrown object must be an error but was ${typeof err}`
106+
)
107+
if (notSupportedDecryptMessages.includes(err.message)) {
108+
/* If the decryption is NOT supported, FAILED with err.message in notSupportedDecryptMessages */
100109
return { result: false, name, err: err }
110+
}
111+
/* If it is a negative test, and it throws an error outside of notSupportedDecryptMessages, it PASSED.*/
101112
return { result: true, name }
102113
}
114+
/* If it is a negative test, and it does not throw an error, it FAILED */
103115
return {
104116
result: false,
105117
name,

modules/integration-node/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
"@aws-crypto/integration-vectors": "file:../integration-vectors",
2121
"@types/got": "^9.6.9",
2222
"@types/stream-to-promise": "^2.2.0",
23-
"@types/yargs": "^15.0.3",
23+
"@types/yargs": "^17.0.1",
2424
"got": "^11.8.0",
2525
"stream-to-promise": "^3.0.0",
2626
"tslib": "^2.3.0",
27-
"yargs": "^17.1.0"
27+
"yargs": "^17.0.1"
2828
},
2929
"sideEffects": false,
3030
"main": "./build/main/src/index.js",

modules/integration-node/src/cli.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const cli = yargs
8080
tolerateFailures,
8181
testName,
8282
concurrency,
83-
} = argv
83+
} = await argv
8484
/* I set the result to 1 so that if I fall through the exit condition is a failure */
8585
let result = 1
8686
if (command === 'decrypt') {

modules/integration-node/src/decrypt_materials_manager_node.ts

+12-21
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import {
5-
needs,
5+
buildAwsKmsMrkAwareDiscoveryMultiKeyringNode,
6+
buildAwsKmsMrkAwareStrictMultiKeyringNode,
67
KeyringNode,
7-
MultiKeyringNode,
88
KmsKeyringNode,
9+
MultiKeyringNode,
10+
needs,
11+
oaepHashSupported,
912
RawAesKeyringNode,
10-
WrappingSuiteIdentifier,
1113
RawAesWrappingSuiteIdentifier,
1214
RawRsaKeyringNode,
13-
oaepHashSupported,
14-
buildAwsKmsMrkAwareStrictMultiKeyringNode,
15-
buildAwsKmsMrkAwareDiscoveryMultiKeyringNode,
15+
WrappingSuiteIdentifier,
1616
} from '@aws-crypto/client-node'
1717
import {
18-
RsaKeyInfo,
18+
AESKey,
1919
AesKeyInfo,
20+
buildGetKeyring,
21+
KeyInfoTuple,
22+
KMSKey,
2023
KmsKeyInfo,
21-
KmsMrkAwareKeyInfo,
2224
KmsMrkAwareDiscoveryKeyInfo,
25+
KmsMrkAwareKeyInfo,
2326
RSAKey,
24-
AESKey,
25-
KMSKey,
26-
KeyInfoTuple,
27-
buildGetKeyring,
27+
RsaKeyInfo,
2828
} from '@aws-crypto/integration-vectors'
2929
import { constants } from 'crypto'
3030

@@ -117,12 +117,3 @@ export function rsaPadding(keyInfo: RsaKeyInfo) {
117117
needs(oaepHashSupported || oaepHash === 'sha1', 'Not supported at this time.')
118118
return { padding, oaepHash }
119119
}
120-
121-
export class NotSupported extends Error {
122-
code: string
123-
constructor(message?: string) {
124-
super(message)
125-
Object.setPrototypeOf(this, NotSupported.prototype)
126-
this.code = 'NOT_SUPPORTED'
127-
}
128-
}

modules/integration-vectors/src/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export interface TestVectorResult {
6161
name: string
6262
result: boolean
6363
description?: string
64-
err?: Error
64+
err?: Error | string | any
6565
}
6666

6767
export interface StreamEntry extends Entry {

modules/kms-keyring/src/kms_keyring.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
readOnlyProperty,
1717
unwrapDataKey,
1818
Newable,
19+
Catchable,
1920
} from '@aws-crypto/material-management'
2021
import {
2122
KMS_PROVIDER_ID,
@@ -243,7 +244,7 @@ export function KmsKeyringClass<
243244
*/
244245
const decryptableEDKs = encryptedDataKeys.filter(filterEDKs(keyIds, this))
245246

246-
const cmkErrors: Error[] = []
247+
const cmkErrors: Catchable[] = []
247248

248249
for (const edk of decryptableEDKs) {
249250
let dataKey: RequiredDecryptResponse | false = false
@@ -259,7 +260,7 @@ export function KmsKeyringClass<
259260
* If the caller does not have access they may have access
260261
* through another Keyring.
261262
*/
262-
cmkErrors.push(e)
263+
cmkErrors.push({ errPlus: e })
263264
}
264265

265266
/* Check for early return (Postcondition): clientProvider may not return a client. */
@@ -300,7 +301,7 @@ export function KmsKeyringClass<
300301
material.hasValidKey() ||
301302
(!material.hasValidKey() && !cmkErrors.length),
302303
cmkErrors.reduce(
303-
(m, e, i) => `${m} Error #${i + 1} \n ${e.stack} \n`,
304+
(m, e, i) => `${m} Error #${i + 1} \n ${e.errPlus.stack} \n`,
304305
'Unable to decrypt data key and one or more KMS CMKs had an error. \n '
305306
)
306307
)

modules/kms-keyring/src/kms_mrk_discovery_keyring.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
readOnlyProperty,
1414
SupportedAlgorithmSuites,
1515
Newable,
16+
Catchable,
1617
} from '@aws-crypto/material-management'
1718
import {
1819
constructArnInOtherRegion,
@@ -170,7 +171,7 @@ export function AwsKmsMrkAwareSymmetricDiscoveryKeyringClass<
170171
//# The set of encrypted data keys MUST first be filtered to match this
171172
//# keyring's configuration.
172173
const decryptableEDKs = encryptedDataKeys.filter(filterEDKs(this))
173-
const cmkErrors: Error[] = []
174+
const cmkErrors: Catchable[] = []
174175

175176
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-region-discovery-keyring.txt#2.8
176177
//# For each encrypted data key in the filtered set, one at a time, the
@@ -253,7 +254,7 @@ export function AwsKmsMrkAwareSymmetricDiscoveryKeyringClass<
253254
//# If the response does not satisfies these requirements then an error
254255
//# is collected and the next encrypted data key in the filtered set MUST
255256
//# be attempted.
256-
cmkErrors.push(e)
257+
cmkErrors.push({ errPlus: e })
257258
}
258259
}
259260
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-region-discovery-keyring.txt#2.8
@@ -266,7 +267,7 @@ export function AwsKmsMrkAwareSymmetricDiscoveryKeyringClass<
266267
`Unable to decrypt data key${
267268
!decryptableEDKs.length ? ': No EDKs supplied' : ''
268269
}.`,
269-
...cmkErrors.map((e, i) => `Error #${i + 1} \n${e.stack}`),
270+
...cmkErrors.map((e, i) => `Error #${i + 1} \n${e.errPlus.stack}`),
270271
].join('\n')
271272
)
272273
return material

modules/kms-keyring/src/kms_mrk_keyring.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
readOnlyProperty,
1616
unwrapDataKey,
1717
Newable,
18+
Catchable,
1819
} from '@aws-crypto/material-management'
1920
import {
2021
KMS_PROVIDER_ID,
@@ -274,7 +275,7 @@ export function AwsKmsMrkAwareSymmetricKeyringClass<
274275
//# keyring's configuration.
275276
const decryptableEDKs = encryptedDataKeys.filter(filterEDKs(keyId))
276277

277-
const cmkErrors: Error[] = []
278+
const cmkErrors: Catchable[] = []
278279

279280
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.8
280281
//# For each encrypted data key in the filtered set, one at a time, the
@@ -344,7 +345,7 @@ export function AwsKmsMrkAwareSymmetricKeyringClass<
344345
//# If the response does not satisfies these requirements then an error
345346
//# MUST be collected and the next encrypted data key in the filtered set
346347
//# MUST be attempted.
347-
cmkErrors.push(e)
348+
cmkErrors.push({ errPlus: e })
348349
}
349350
}
350351

@@ -358,7 +359,7 @@ export function AwsKmsMrkAwareSymmetricKeyringClass<
358359
`Unable to decrypt data key${
359360
!decryptableEDKs.length ? ': No EDKs supplied' : ''
360361
}.`,
361-
...cmkErrors.map((e, i) => `Error #${i + 1} \n${e.stack}`),
362+
...cmkErrors.map((e, i) => `Error #${i + 1} \n${e.errPlus.stack}`),
362363
].join('\n')
363364
)
364365

modules/material-management-node/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export {
2222
KeyringTrace,
2323
KeyringTraceFlag,
2424
needs,
25+
NotSupported,
2526
KeyringNode,
2627
MultiKeyringNode,
2728
immutableBaseClass,

0 commit comments

Comments
 (0)