-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathget_encrypt_test_iterator.ts
125 lines (113 loc) · 3.24 KB
/
get_encrypt_test_iterator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import {
EncryptManifestList,
KeyList,
KeyInfoTuple,
} from '@aws-crypto/integration-vectors'
import { randomBytes } from 'crypto'
import {
AlgorithmSuiteIdentifier,
EncryptionContext,
} from '@aws-crypto/client-node'
import { URL } from 'url'
import { readFileSync } from 'fs'
import got from 'got'
import { ZipFile } from 'yazl'
import {
KEYS_MANIFEST_NAME_FILENAME,
MANIFEST_PLAINTEXT_PATH,
} from './constants'
export async function getEncryptTestVectorIterator(
manifestFile: string,
keyFile: string,
manifestZip?: ZipFile
) {
const [manifest, keys]: [EncryptManifestList, KeyList] = await Promise.all([
getParsedJSON(manifestFile),
getParsedJSON(keyFile),
])
return _getEncryptTestVectorIterator(manifest, keys, manifestZip)
}
/* Just a simple more testable function */
export function _getEncryptTestVectorIterator(
{ tests, plaintexts }: EncryptManifestList,
keysManifest: KeyList,
manifestZip?: ZipFile
) {
if (manifestZip) {
// We assume that the keys manifest given for encrypt
// has all the keys required for decrypt.
manifestZip.addBuffer(
Buffer.from(JSON.stringify(keysManifest)),
`${KEYS_MANIFEST_NAME_FILENAME}`
)
}
const { keys } = keysManifest
const plaintextBytes: { [name: string]: Buffer } = {}
Object.keys(plaintexts).forEach((name) => {
plaintextBytes[name] = randomBytes(plaintexts[name])
if (manifestZip) {
manifestZip.addBuffer(
plaintextBytes[name],
`${MANIFEST_PLAINTEXT_PATH}${name}`
)
}
})
return (function* nextTest(): IterableIterator<EncryptTestVectorInfo> {
for (const [name, testInfo] of Object.entries(tests)) {
const {
plaintext,
'master-keys': masterKeys,
algorithm,
'frame-size': frameLength,
'encryption-context': encryptionContext,
} = testInfo
const keysInfo = masterKeys.map((keyInfo) => {
const key = keys[keyInfo.key]
if (!key) throw new Error(`no key for ${name}`)
return [keyInfo, key] as KeyInfoTuple
})
/* I'm expecting that the encrypt function will throw if this is not a supported AlgorithmSuiteIdentifier */
const suiteId = parseInt(algorithm, 16) as AlgorithmSuiteIdentifier
yield {
name,
keysInfo,
plainTextData: plaintextBytes[plaintext],
plaintextName: plaintext,
encryptOp: { suiteId, frameLength, encryptionContext },
}
}
})()
}
export interface EncryptTestVectorInfo {
name: string
keysInfo: KeyInfoTuple[]
plainTextData: Buffer
plaintextName: string
encryptOp: {
suiteId: AlgorithmSuiteIdentifier
frameLength: number
encryptionContext: EncryptionContext
}
}
async function getParsedJSON(thing: string) {
try {
const url = new URL(thing)
if (url.protocol === 'file:') {
return jsonAtPath(thing)
} else {
return jsonAtUrl(url)
}
} catch (ex) {
return jsonAtPath(thing)
}
}
async function jsonAtUrl(url: URL) {
const { body } = await got(url)
return JSON.parse(body)
}
function jsonAtPath(path: string) {
const json = readFileSync(path, { encoding: 'utf-8' })
return JSON.parse(json)
}