/
decrypt_materials_manager_node.ts
106 lines (94 loc) · 3.78 KB
/
decrypt_materials_manager_node.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
/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
needs,
MultiKeyringNode,
KmsKeyringNode,
RawAesKeyringNode,
WrappingSuiteIdentifier, // eslint-disable-line no-unused-vars
RawAesWrappingSuiteIdentifier,
RawRsaKeyringNode
} from '@aws-crypto/client-node'
import {
RsaKeyInfo, // eslint-disable-line no-unused-vars
AesKeyInfo, // eslint-disable-line no-unused-vars
KmsKeyInfo, // eslint-disable-line no-unused-vars
RSAKey, // eslint-disable-line no-unused-vars
AESKey, // eslint-disable-line no-unused-vars
KMSKey, // eslint-disable-line no-unused-vars
KeyInfoTuple // eslint-disable-line no-unused-vars
} from './types'
import { constants } from 'crypto'
const Bits2RawAesWrappingSuiteIdentifier: {[key: number]: WrappingSuiteIdentifier} = {
128: RawAesWrappingSuiteIdentifier.AES128_GCM_IV12_TAG16_NO_PADDING,
192: RawAesWrappingSuiteIdentifier.AES192_GCM_IV12_TAG16_NO_PADDING,
256: RawAesWrappingSuiteIdentifier.AES256_GCM_IV12_TAG16_NO_PADDING
}
export function encryptMaterialsManagerNode (keyInfos: KeyInfoTuple[]) {
const [generator, ...children] = keyInfos.map(keyringNode)
return new MultiKeyringNode({ generator, children })
}
export function decryptMaterialsManagerNode (keyInfos: KeyInfoTuple[]) {
const children = keyInfos.map(keyringNode)
return new MultiKeyringNode({ children })
}
export function keyringNode ([ info, key ]: KeyInfoTuple) {
if (info.type === 'aws-kms' && key.type === 'aws-kms') {
return kmsKeyring(info, key)
}
if (info.type === 'raw' && info['encryption-algorithm'] === 'aes' && key.type === 'symmetric') {
return aesKeyring(info, key)
}
if (info.type === 'raw' && info['encryption-algorithm'] === 'rsa' && (key.type === 'public' || key.type === 'private')) {
return rsaKeyring(info, key)
}
throw new Error('Unsupported keyring type')
}
export function kmsKeyring (_keyInfo: KmsKeyInfo, key: KMSKey) {
const generatorKeyId = key['key-id']
return new KmsKeyringNode({ generatorKeyId })
}
export function aesKeyring (keyInfo:AesKeyInfo, key: AESKey) {
const keyName = key['key-id']
const keyNamespace = keyInfo['provider-id']
const { encoding, material } = key
const unencryptedMasterKey = Buffer.alloc(key.bits / 8, material, encoding)
const wrappingSuite = Bits2RawAesWrappingSuiteIdentifier[key.bits]
return new RawAesKeyringNode({ keyName, keyNamespace, unencryptedMasterKey, wrappingSuite })
}
export function rsaKeyring (keyInfo: RsaKeyInfo, key: RSAKey) {
const keyName = key['key-id']
const keyNamespace = keyInfo['provider-id']
const rsaKey = key.type === 'private'
? { privateKey: key.material }
: { publicKey: key.material }
const padding = rsaPadding(keyInfo)
return new RawRsaKeyringNode({ keyName, keyNamespace, rsaKey, padding })
}
export function rsaPadding (keyInfo: RsaKeyInfo) {
const paddingAlgorithm = keyInfo['padding-algorithm']
const paddingHash = keyInfo['padding-hash']
if (paddingAlgorithm === 'pkcs1') return constants.RSA_PKCS1_PADDING
needs(paddingHash === 'sha1', 'Not supported at this time.')
return constants.RSA_PKCS1_OAEP_PADDING
}
export class NotSupported extends Error {
code: string
constructor (message?: string) {
super(message)
Object.setPrototypeOf(this, NotSupported.prototype)
this.code = 'NOT_SUPPORTED'
}
}