tedious 16.1.0 → 16.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/all-headers.js +1 -2
- package/lib/all-headers.js.map +1 -0
- package/lib/always-encrypted/aead-aes-256-cbc-hmac-algorithm.js +9 -31
- package/lib/always-encrypted/aead-aes-256-cbc-hmac-algorithm.js.map +1 -0
- package/lib/always-encrypted/aead-aes-256-cbc-hmac-encryption-key.js +9 -24
- package/lib/always-encrypted/aead-aes-256-cbc-hmac-encryption-key.js.map +1 -0
- package/lib/always-encrypted/cek-entry.js +8 -12
- package/lib/always-encrypted/cek-entry.js.map +1 -0
- package/lib/always-encrypted/get-parameter-encryption-metadata.js +2 -24
- package/lib/always-encrypted/get-parameter-encryption-metadata.js.map +1 -0
- package/lib/always-encrypted/key-crypto.js +5 -30
- package/lib/always-encrypted/key-crypto.js.map +1 -0
- package/lib/always-encrypted/keystore-provider-azure-key-vault.js +11 -72
- package/lib/always-encrypted/keystore-provider-azure-key-vault.js.map +1 -0
- package/lib/always-encrypted/symmetric-key-cache.js +2 -13
- package/lib/always-encrypted/symmetric-key-cache.js.map +1 -0
- package/lib/always-encrypted/symmetric-key.js +3 -8
- package/lib/always-encrypted/symmetric-key.js.map +1 -0
- package/lib/always-encrypted/types.js +19 -27
- package/lib/always-encrypted/types.js.map +1 -0
- package/lib/always-encrypted/utils.js +2 -6
- package/lib/always-encrypted/utils.js.map +1 -0
- package/lib/bulk-load-payload.js +7 -15
- package/lib/bulk-load-payload.js.map +1 -0
- package/lib/bulk-load.js +58 -131
- package/lib/bulk-load.js.map +1 -0
- package/lib/collation.js +7 -15
- package/lib/collation.js.map +1 -0
- package/lib/connection.js +297 -536
- package/lib/connection.js.map +1 -0
- package/lib/connector.js +6 -37
- package/lib/connector.js.map +1 -0
- package/lib/data-type.js +2 -43
- package/lib/data-type.js.map +1 -0
- package/lib/data-types/bigint.js +1 -15
- package/lib/data-types/bigint.js.map +1 -0
- package/lib/data-types/binary.js +1 -12
- package/lib/data-types/binary.js.map +1 -0
- package/lib/data-types/bit.js +1 -11
- package/lib/data-types/bit.js.map +1 -0
- package/lib/data-types/bitn.js +1 -7
- package/lib/data-types/bitn.js.map +1 -0
- package/lib/data-types/char.js +1 -20
- package/lib/data-types/char.js.map +1 -0
- package/lib/data-types/date.js +1 -15
- package/lib/data-types/date.js.map +1 -0
- package/lib/data-types/datetime.js +3 -20
- package/lib/data-types/datetime.js.map +1 -0
- package/lib/data-types/datetime2.js +1 -26
- package/lib/data-types/datetime2.js.map +1 -0
- package/lib/data-types/datetimen.js +1 -7
- package/lib/data-types/datetimen.js.map +1 -0
- package/lib/data-types/datetimeoffset.js +1 -23
- package/lib/data-types/datetimeoffset.js.map +1 -0
- package/lib/data-types/decimal.js +1 -18
- package/lib/data-types/decimal.js.map +1 -0
- package/lib/data-types/decimaln.js +1 -7
- package/lib/data-types/decimaln.js.map +1 -0
- package/lib/data-types/float.js +1 -13
- package/lib/data-types/float.js.map +1 -0
- package/lib/data-types/floatn.js +1 -7
- package/lib/data-types/floatn.js.map +1 -0
- package/lib/data-types/image.js +1 -10
- package/lib/data-types/image.js.map +1 -0
- package/lib/data-types/int.js +1 -14
- package/lib/data-types/int.js.map +1 -0
- package/lib/data-types/intn.js +1 -7
- package/lib/data-types/intn.js.map +1 -0
- package/lib/data-types/money.js +1 -12
- package/lib/data-types/money.js.map +1 -0
- package/lib/data-types/moneyn.js +1 -7
- package/lib/data-types/moneyn.js.map +1 -0
- package/lib/data-types/nchar.js +1 -14
- package/lib/data-types/nchar.js.map +1 -0
- package/lib/data-types/ntext.js +1 -10
- package/lib/data-types/ntext.js.map +1 -0
- package/lib/data-types/null.js +1 -7
- package/lib/data-types/null.js.map +1 -0
- package/lib/data-types/numeric.js +1 -18
- package/lib/data-types/numeric.js.map +1 -0
- package/lib/data-types/numericn.js +1 -7
- package/lib/data-types/numericn.js.map +1 -0
- package/lib/data-types/nvarchar.js +1 -22
- package/lib/data-types/nvarchar.js.map +1 -0
- package/lib/data-types/real.js +1 -13
- package/lib/data-types/real.js.map +1 -0
- package/lib/data-types/smalldatetime.js +1 -14
- package/lib/data-types/smalldatetime.js.map +1 -0
- package/lib/data-types/smallint.js +1 -14
- package/lib/data-types/smallint.js.map +1 -0
- package/lib/data-types/smallmoney.js +1 -13
- package/lib/data-types/smallmoney.js.map +1 -0
- package/lib/data-types/sql-variant.js +1 -6
- package/lib/data-types/sql-variant.js.map +1 -0
- package/lib/data-types/text.js +1 -18
- package/lib/data-types/text.js.map +1 -0
- package/lib/data-types/time.js +1 -22
- package/lib/data-types/time.js.map +1 -0
- package/lib/data-types/tinyint.js +1 -14
- package/lib/data-types/tinyint.js.map +1 -0
- package/lib/data-types/tvp.js +11 -27
- package/lib/data-types/tvp.js.map +1 -0
- package/lib/data-types/udt.js +1 -7
- package/lib/data-types/udt.js.map +1 -0
- package/lib/data-types/uniqueidentifier.js +1 -11
- package/lib/data-types/uniqueidentifier.js.map +1 -0
- package/lib/data-types/varbinary.js +1 -22
- package/lib/data-types/varbinary.js.map +1 -0
- package/lib/data-types/varchar.js +1 -23
- package/lib/data-types/varchar.js.map +1 -0
- package/lib/data-types/xml.js +1 -7
- package/lib/data-types/xml.js.map +1 -0
- package/lib/debug.js +4 -16
- package/lib/debug.js.map +1 -0
- package/lib/errors/abort-error.js +2 -5
- package/lib/errors/abort-error.js.map +1 -0
- package/lib/errors/timeout-error.js +2 -5
- package/lib/errors/timeout-error.js.map +1 -0
- package/lib/errors.js +10 -16
- package/lib/errors.js.map +1 -0
- package/lib/guid-parser.js +1 -7
- package/lib/guid-parser.js.map +1 -0
- package/lib/incoming-message-stream.js +9 -29
- package/lib/incoming-message-stream.js.map +1 -0
- package/lib/instance-lookup.js +3 -34
- package/lib/instance-lookup.js.map +1 -0
- package/lib/library.js +1 -1
- package/lib/library.js.map +1 -0
- package/lib/login7-payload.js +99 -100
- package/lib/login7-payload.js.map +1 -0
- package/lib/message-io.js +17 -45
- package/lib/message-io.js.map +1 -0
- package/lib/message.js +4 -8
- package/lib/message.js.map +1 -0
- package/lib/metadata-parser.js +1 -22
- package/lib/metadata-parser.js.map +1 -0
- package/lib/ntlm-payload.js +2 -22
- package/lib/ntlm-payload.js.map +1 -0
- package/lib/ntlm.js +1 -4
- package/lib/ntlm.js.map +1 -0
- package/lib/outgoing-message-stream.js +12 -21
- package/lib/outgoing-message-stream.js.map +1 -0
- package/lib/packet.js +2 -47
- package/lib/packet.js.map +1 -0
- package/lib/prelogin-payload.js +11 -54
- package/lib/prelogin-payload.js.map +1 -0
- package/lib/request.js +88 -66
- package/lib/request.js.map +1 -0
- package/lib/rpcrequest-payload.js +13 -34
- package/lib/rpcrequest-payload.js.map +1 -0
- package/lib/sender.js +1 -24
- package/lib/sender.js.map +1 -0
- package/lib/special-stored-procedure.js +1 -1
- package/lib/special-stored-procedure.js.map +1 -0
- package/lib/sqlbatch-payload.js +5 -18
- package/lib/sqlbatch-payload.js.map +1 -0
- package/lib/tds-versions.js +3 -3
- package/lib/tds-versions.js.map +1 -0
- package/lib/tedious.js +1 -12
- package/lib/tedious.js.map +1 -0
- package/lib/token/colmetadata-token-parser.js +1 -17
- package/lib/token/colmetadata-token-parser.js.map +1 -0
- package/lib/token/done-token-parser.js +2 -8
- package/lib/token/done-token-parser.js.map +1 -0
- package/lib/token/env-change-token-parser.js +7 -28
- package/lib/token/env-change-token-parser.js.map +1 -0
- package/lib/token/feature-ext-ack-parser.js +1 -10
- package/lib/token/feature-ext-ack-parser.js.map +1 -0
- package/lib/token/fedauth-info-parser.js +2 -10
- package/lib/token/fedauth-info-parser.js.map +1 -0
- package/lib/token/handler.js +39 -149
- package/lib/token/handler.js.map +1 -0
- package/lib/token/infoerror-token-parser.js +1 -5
- package/lib/token/infoerror-token-parser.js.map +1 -0
- package/lib/token/loginack-token-parser.js +1 -6
- package/lib/token/loginack-token-parser.js.map +1 -0
- package/lib/token/nbcrow-token-parser.js +2 -15
- package/lib/token/nbcrow-token-parser.js.map +1 -0
- package/lib/token/order-token-parser.js +2 -7
- package/lib/token/order-token-parser.js.map +1 -0
- package/lib/token/returnstatus-token-parser.js +2 -4
- package/lib/token/returnstatus-token-parser.js.map +1 -0
- package/lib/token/returnvalue-token-parser.js +4 -9
- package/lib/token/returnvalue-token-parser.js.map +1 -0
- package/lib/token/row-token-parser.js +2 -11
- package/lib/token/row-token-parser.js.map +1 -0
- package/lib/token/sspi-token-parser.js +1 -5
- package/lib/token/sspi-token-parser.js.map +1 -0
- package/lib/token/stream-parser.js +24 -86
- package/lib/token/stream-parser.js.map +1 -0
- package/lib/token/token-stream-parser.js +4 -13
- package/lib/token/token-stream-parser.js.map +1 -0
- package/lib/token/token.js +88 -168
- package/lib/token/token.js.map +1 -0
- package/lib/tracking-buffer/writable-tracking-buffer.js +20 -60
- package/lib/tracking-buffer/writable-tracking-buffer.js.map +1 -0
- package/lib/transaction.js +9 -33
- package/lib/transaction.js.map +1 -0
- package/lib/transient-error-lookup.js +1 -4
- package/lib/transient-error-lookup.js.map +1 -0
- package/lib/utils/with-timeout.js +1 -9
- package/lib/utils/with-timeout.js.map +1 -0
- package/lib/value-parser.js +1 -143
- package/lib/value-parser.js.map +1 -0
- package/package.json +27 -71
|
@@ -4,94 +4,72 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.validateAndGetEncryptionAlgorithmName = exports.encryptWithKey = exports.decryptWithKey = exports.decryptSymmetricKey = void 0;
|
|
7
|
-
|
|
8
7
|
var _symmetricKeyCache = require("./symmetric-key-cache");
|
|
9
|
-
|
|
10
8
|
var _aeadAes256CbcHmacAlgorithm = require("./aead-aes-256-cbc-hmac-algorithm");
|
|
11
|
-
|
|
12
9
|
var _aeadAes256CbcHmacEncryptionKey = require("./aead-aes-256-cbc-hmac-encryption-key");
|
|
13
|
-
|
|
14
10
|
// This code is based on the `mssql-jdbc` library published under the conditions of MIT license.
|
|
15
11
|
// Copyright (c) 2019 Microsoft Corporation
|
|
12
|
+
|
|
16
13
|
const validateAndGetEncryptionAlgorithmName = (cipherAlgorithmId, cipherAlgorithmName) => {
|
|
17
14
|
if (cipherAlgorithmId !== 2) {
|
|
18
15
|
throw new Error('Custom cipher algorithm not supported.');
|
|
19
16
|
}
|
|
20
|
-
|
|
21
17
|
return _aeadAes256CbcHmacAlgorithm.algorithmName;
|
|
22
18
|
};
|
|
23
|
-
|
|
24
19
|
exports.validateAndGetEncryptionAlgorithmName = validateAndGetEncryptionAlgorithmName;
|
|
25
|
-
|
|
26
20
|
const encryptWithKey = async (plaintext, md, options) => {
|
|
27
21
|
if (!options.trustedServerNameAE) {
|
|
28
22
|
throw new Error('Server name should not be null in EncryptWithKey');
|
|
29
23
|
}
|
|
30
|
-
|
|
31
24
|
if (!md.cipherAlgorithm) {
|
|
32
25
|
await decryptSymmetricKey(md, options);
|
|
33
26
|
}
|
|
34
|
-
|
|
35
27
|
if (!md.cipherAlgorithm) {
|
|
36
28
|
throw new Error('Cipher Algorithm should not be null in EncryptWithKey');
|
|
37
29
|
}
|
|
38
|
-
|
|
39
30
|
const cipherText = md.cipherAlgorithm.encryptData(plaintext);
|
|
40
|
-
|
|
41
31
|
if (!cipherText) {
|
|
42
32
|
throw new Error('Internal error. Ciphertext value cannot be null.');
|
|
43
33
|
}
|
|
44
|
-
|
|
45
34
|
return cipherText;
|
|
46
35
|
};
|
|
47
|
-
|
|
48
36
|
exports.encryptWithKey = encryptWithKey;
|
|
49
|
-
|
|
50
37
|
const decryptWithKey = (cipherText, md, options) => {
|
|
51
38
|
if (!options.trustedServerNameAE) {
|
|
52
39
|
throw new Error('Server name should not be null in DecryptWithKey');
|
|
53
|
-
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// if (!md.cipherAlgorithm) {
|
|
54
43
|
// await decryptSymmetricKey(md, options);
|
|
55
44
|
// }
|
|
56
45
|
|
|
57
|
-
|
|
58
46
|
if (!md.cipherAlgorithm) {
|
|
59
47
|
throw new Error('Cipher Algorithm should not be null in DecryptWithKey');
|
|
60
48
|
}
|
|
61
|
-
|
|
62
49
|
const plainText = md.cipherAlgorithm.decryptData(cipherText);
|
|
63
|
-
|
|
64
50
|
if (!plainText) {
|
|
65
51
|
throw new Error('Internal error. Plaintext value cannot be null.');
|
|
66
52
|
}
|
|
67
|
-
|
|
68
53
|
return plainText;
|
|
69
54
|
};
|
|
70
|
-
|
|
71
55
|
exports.decryptWithKey = decryptWithKey;
|
|
72
|
-
|
|
73
56
|
const decryptSymmetricKey = async (md, options) => {
|
|
74
57
|
if (!md) {
|
|
75
58
|
throw new Error('md should not be null in DecryptSymmetricKey.');
|
|
76
59
|
}
|
|
77
|
-
|
|
78
60
|
if (!md.cekEntry) {
|
|
79
61
|
throw new Error('md.EncryptionInfo should not be null in DecryptSymmetricKey.');
|
|
80
62
|
}
|
|
81
|
-
|
|
82
63
|
if (!md.cekEntry.columnEncryptionKeyValues) {
|
|
83
64
|
throw new Error('md.EncryptionInfo.ColumnEncryptionKeyValues should not be null in DecryptSymmetricKey.');
|
|
84
65
|
}
|
|
85
|
-
|
|
86
66
|
let symKey;
|
|
87
67
|
let encryptionKeyInfoChosen;
|
|
88
68
|
const CEKValues = md.cekEntry.columnEncryptionKeyValues;
|
|
89
69
|
let lastError;
|
|
90
|
-
|
|
91
70
|
for (const CEKValue of CEKValues) {
|
|
92
71
|
try {
|
|
93
72
|
symKey = await (0, _symmetricKeyCache.getKey)(CEKValue, options);
|
|
94
|
-
|
|
95
73
|
if (symKey) {
|
|
96
74
|
encryptionKeyInfoChosen = CEKValue;
|
|
97
75
|
break;
|
|
@@ -100,7 +78,6 @@ const decryptSymmetricKey = async (md, options) => {
|
|
|
100
78
|
lastError = error;
|
|
101
79
|
}
|
|
102
80
|
}
|
|
103
|
-
|
|
104
81
|
if (!symKey) {
|
|
105
82
|
if (lastError) {
|
|
106
83
|
throw lastError;
|
|
@@ -108,12 +85,10 @@ const decryptSymmetricKey = async (md, options) => {
|
|
|
108
85
|
throw new Error('Exception while decryption of encrypted column encryption key.');
|
|
109
86
|
}
|
|
110
87
|
}
|
|
111
|
-
|
|
112
88
|
const algorithmName = validateAndGetEncryptionAlgorithmName(md.cipherAlgorithmId, md.cipherAlgorithmName);
|
|
113
89
|
const cipherAlgorithm = new _aeadAes256CbcHmacAlgorithm.AeadAes256CbcHmac256Algorithm(new _aeadAes256CbcHmacEncryptionKey.AeadAes256CbcHmac256EncryptionKey(symKey.rootKey, algorithmName), md.encryptionType);
|
|
114
90
|
md.cipherAlgorithm = cipherAlgorithm;
|
|
115
91
|
md.encryptionKeyInfo = encryptionKeyInfoChosen;
|
|
116
92
|
};
|
|
117
|
-
|
|
118
93
|
exports.decryptSymmetricKey = decryptSymmetricKey;
|
|
119
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
94
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3ltbWV0cmljS2V5Q2FjaGUiLCJyZXF1aXJlIiwiX2FlYWRBZXMyNTZDYmNIbWFjQWxnb3JpdGhtIiwiX2FlYWRBZXMyNTZDYmNIbWFjRW5jcnlwdGlvbktleSIsInZhbGlkYXRlQW5kR2V0RW5jcnlwdGlvbkFsZ29yaXRobU5hbWUiLCJjaXBoZXJBbGdvcml0aG1JZCIsImNpcGhlckFsZ29yaXRobU5hbWUiLCJFcnJvciIsImFsZ29yaXRobU5hbWUiLCJleHBvcnRzIiwiZW5jcnlwdFdpdGhLZXkiLCJwbGFpbnRleHQiLCJtZCIsIm9wdGlvbnMiLCJ0cnVzdGVkU2VydmVyTmFtZUFFIiwiY2lwaGVyQWxnb3JpdGhtIiwiZGVjcnlwdFN5bW1ldHJpY0tleSIsImNpcGhlclRleHQiLCJlbmNyeXB0RGF0YSIsImRlY3J5cHRXaXRoS2V5IiwicGxhaW5UZXh0IiwiZGVjcnlwdERhdGEiLCJjZWtFbnRyeSIsImNvbHVtbkVuY3J5cHRpb25LZXlWYWx1ZXMiLCJzeW1LZXkiLCJlbmNyeXB0aW9uS2V5SW5mb0Nob3NlbiIsIkNFS1ZhbHVlcyIsImxhc3RFcnJvciIsIkNFS1ZhbHVlIiwiZ2V0S2V5IiwiZXJyb3IiLCJBZWFkQWVzMjU2Q2JjSG1hYzI1NkFsZ29yaXRobSIsIkFlYWRBZXMyNTZDYmNIbWFjMjU2RW5jcnlwdGlvbktleSIsInJvb3RLZXkiLCJlbmNyeXB0aW9uVHlwZSIsImVuY3J5cHRpb25LZXlJbmZvIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Fsd2F5cy1lbmNyeXB0ZWQva2V5LWNyeXB0by50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGlzIGNvZGUgaXMgYmFzZWQgb24gdGhlIGBtc3NxbC1qZGJjYCBsaWJyYXJ5IHB1Ymxpc2hlZCB1bmRlciB0aGUgY29uZGl0aW9ucyBvZiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCAoYykgMjAxOSBNaWNyb3NvZnQgQ29ycG9yYXRpb25cblxuaW1wb3J0IHsgQ3J5cHRvTWV0YWRhdGEsIEVuY3J5cHRpb25LZXlJbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBJbnRlcm5hbENvbm5lY3Rpb25PcHRpb25zIGFzIENvbm5lY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vY29ubmVjdGlvbic7XG5pbXBvcnQgU3ltbWV0cmljS2V5IGZyb20gJy4vc3ltbWV0cmljLWtleSc7XG5pbXBvcnQgeyBnZXRLZXkgfSBmcm9tICcuL3N5bW1ldHJpYy1rZXktY2FjaGUnO1xuaW1wb3J0IHsgQWVhZEFlczI1NkNiY0htYWMyNTZBbGdvcml0aG0sIGFsZ29yaXRobU5hbWUgfSBmcm9tICcuL2FlYWQtYWVzLTI1Ni1jYmMtaG1hYy1hbGdvcml0aG0nO1xuaW1wb3J0IHsgQWVhZEFlczI1NkNiY0htYWMyNTZFbmNyeXB0aW9uS2V5IH0gZnJvbSAnLi9hZWFkLWFlcy0yNTYtY2JjLWhtYWMtZW5jcnlwdGlvbi1rZXknO1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVBbmRHZXRFbmNyeXB0aW9uQWxnb3JpdGhtTmFtZSA9IChjaXBoZXJBbGdvcml0aG1JZDogbnVtYmVyLCBjaXBoZXJBbGdvcml0aG1OYW1lPzogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKGNpcGhlckFsZ29yaXRobUlkICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDdXN0b20gY2lwaGVyIGFsZ29yaXRobSBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG5cbiAgcmV0dXJuIGFsZ29yaXRobU5hbWU7XG59O1xuXG5leHBvcnQgY29uc3QgZW5jcnlwdFdpdGhLZXkgPSBhc3luYyAocGxhaW50ZXh0OiBCdWZmZXIsIG1kOiBDcnlwdG9NZXRhZGF0YSwgb3B0aW9uczogQ29ubmVjdGlvbk9wdGlvbnMpOiBQcm9taXNlPEJ1ZmZlcj4gPT4ge1xuICBpZiAoIW9wdGlvbnMudHJ1c3RlZFNlcnZlck5hbWVBRSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2VydmVyIG5hbWUgc2hvdWxkIG5vdCBiZSBudWxsIGluIEVuY3J5cHRXaXRoS2V5Jyk7XG4gIH1cblxuICBpZiAoIW1kLmNpcGhlckFsZ29yaXRobSkge1xuICAgIGF3YWl0IGRlY3J5cHRTeW1tZXRyaWNLZXkobWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgaWYgKCFtZC5jaXBoZXJBbGdvcml0aG0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NpcGhlciBBbGdvcml0aG0gc2hvdWxkIG5vdCBiZSBudWxsIGluIEVuY3J5cHRXaXRoS2V5Jyk7XG4gIH1cblxuICBjb25zdCBjaXBoZXJUZXh0OiBCdWZmZXIgPSBtZC5jaXBoZXJBbGdvcml0aG0uZW5jcnlwdERhdGEocGxhaW50ZXh0KTtcblxuICBpZiAoIWNpcGhlclRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGVycm9yLiBDaXBoZXJ0ZXh0IHZhbHVlIGNhbm5vdCBiZSBudWxsLicpO1xuICB9XG5cbiAgcmV0dXJuIGNpcGhlclRleHQ7XG59O1xuXG5leHBvcnQgY29uc3QgZGVjcnlwdFdpdGhLZXkgPSAoY2lwaGVyVGV4dDogQnVmZmVyLCBtZDogQ3J5cHRvTWV0YWRhdGEsIG9wdGlvbnM6IENvbm5lY3Rpb25PcHRpb25zKTogQnVmZmVyID0+IHtcbiAgaWYgKCFvcHRpb25zLnRydXN0ZWRTZXJ2ZXJOYW1lQUUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZlciBuYW1lIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0V2l0aEtleScpO1xuICB9XG5cbiAgLy8gaWYgKCFtZC5jaXBoZXJBbGdvcml0aG0pIHtcbiAgLy8gICBhd2FpdCBkZWNyeXB0U3ltbWV0cmljS2V5KG1kLCBvcHRpb25zKTtcbiAgLy8gfVxuXG4gIGlmICghbWQuY2lwaGVyQWxnb3JpdGhtKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDaXBoZXIgQWxnb3JpdGhtIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0V2l0aEtleScpO1xuICB9XG5cbiAgY29uc3QgcGxhaW5UZXh0OiBCdWZmZXIgPSBtZC5jaXBoZXJBbGdvcml0aG0uZGVjcnlwdERhdGEoY2lwaGVyVGV4dCk7XG5cbiAgaWYgKCFwbGFpblRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGVycm9yLiBQbGFpbnRleHQgdmFsdWUgY2Fubm90IGJlIG51bGwuJyk7XG4gIH1cblxuICByZXR1cm4gcGxhaW5UZXh0O1xufTtcblxuZXhwb3J0IGNvbnN0IGRlY3J5cHRTeW1tZXRyaWNLZXkgPSBhc3luYyAobWQ6IENyeXB0b01ldGFkYXRhLCBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIW1kKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZCBzaG91bGQgbm90IGJlIG51bGwgaW4gRGVjcnlwdFN5bW1ldHJpY0tleS4nKTtcbiAgfVxuXG4gIGlmICghbWQuY2VrRW50cnkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21kLkVuY3J5cHRpb25JbmZvIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0U3ltbWV0cmljS2V5LicpO1xuICB9XG5cbiAgaWYgKCFtZC5jZWtFbnRyeS5jb2x1bW5FbmNyeXB0aW9uS2V5VmFsdWVzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZC5FbmNyeXB0aW9uSW5mby5Db2x1bW5FbmNyeXB0aW9uS2V5VmFsdWVzIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0U3ltbWV0cmljS2V5LicpO1xuICB9XG5cbiAgbGV0IHN5bUtleTogU3ltbWV0cmljS2V5IHwgdW5kZWZpbmVkO1xuICBsZXQgZW5jcnlwdGlvbktleUluZm9DaG9zZW46IEVuY3J5cHRpb25LZXlJbmZvIHwgdW5kZWZpbmVkO1xuICBjb25zdCBDRUtWYWx1ZXM6IEVuY3J5cHRpb25LZXlJbmZvW10gPSBtZC5jZWtFbnRyeS5jb2x1bW5FbmNyeXB0aW9uS2V5VmFsdWVzO1xuICBsZXQgbGFzdEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcblxuICBmb3IgKGNvbnN0IENFS1ZhbHVlIG9mIENFS1ZhbHVlcykge1xuICAgIHRyeSB7XG4gICAgICBzeW1LZXkgPSBhd2FpdCBnZXRLZXkoQ0VLVmFsdWUsIG9wdGlvbnMpO1xuICAgICAgaWYgKHN5bUtleSkge1xuICAgICAgICBlbmNyeXB0aW9uS2V5SW5mb0Nob3NlbiA9IENFS1ZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBsYXN0RXJyb3IgPSBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBpZiAoIXN5bUtleSkge1xuICAgIGlmIChsYXN0RXJyb3IpIHtcbiAgICAgIHRocm93IGxhc3RFcnJvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeGNlcHRpb24gd2hpbGUgZGVjcnlwdGlvbiBvZiBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5LicpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGFsZ29yaXRobU5hbWUgPSB2YWxpZGF0ZUFuZEdldEVuY3J5cHRpb25BbGdvcml0aG1OYW1lKG1kLmNpcGhlckFsZ29yaXRobUlkLCBtZC5jaXBoZXJBbGdvcml0aG1OYW1lKTtcbiAgY29uc3QgY2lwaGVyQWxnb3JpdGhtID0gbmV3IEFlYWRBZXMyNTZDYmNIbWFjMjU2QWxnb3JpdGhtKG5ldyBBZWFkQWVzMjU2Q2JjSG1hYzI1NkVuY3J5cHRpb25LZXkoc3ltS2V5LnJvb3RLZXksIGFsZ29yaXRobU5hbWUpLCBtZC5lbmNyeXB0aW9uVHlwZSk7XG5cbiAgbWQuY2lwaGVyQWxnb3JpdGhtID0gY2lwaGVyQWxnb3JpdGhtO1xuICBtZC5lbmNyeXB0aW9uS2V5SW5mbyA9IGVuY3J5cHRpb25LZXlJbmZvQ2hvc2VuIGFzIEVuY3J5cHRpb25LZXlJbmZvO1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBTUEsSUFBQUEsa0JBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLDJCQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSwrQkFBQSxHQUFBRixPQUFBO0FBUkE7QUFD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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-crypto.js","names":["_symmetricKeyCache","require","_aeadAes256CbcHmacAlgorithm","_aeadAes256CbcHmacEncryptionKey","validateAndGetEncryptionAlgorithmName","cipherAlgorithmId","cipherAlgorithmName","Error","algorithmName","exports","encryptWithKey","plaintext","md","options","trustedServerNameAE","cipherAlgorithm","decryptSymmetricKey","cipherText","encryptData","decryptWithKey","plainText","decryptData","cekEntry","columnEncryptionKeyValues","symKey","encryptionKeyInfoChosen","CEKValues","lastError","CEKValue","getKey","error","AeadAes256CbcHmac256Algorithm","AeadAes256CbcHmac256EncryptionKey","rootKey","encryptionType","encryptionKeyInfo"],"sources":["../../src/always-encrypted/key-crypto.ts"],"sourcesContent":["// This code is based on the `mssql-jdbc` library published under the conditions of MIT license.\n// Copyright (c) 2019 Microsoft Corporation\n\nimport { CryptoMetadata, EncryptionKeyInfo } from './types';\nimport { InternalConnectionOptions as ConnectionOptions } from '../connection';\nimport SymmetricKey from './symmetric-key';\nimport { getKey } from './symmetric-key-cache';\nimport { AeadAes256CbcHmac256Algorithm, algorithmName } from './aead-aes-256-cbc-hmac-algorithm';\nimport { AeadAes256CbcHmac256EncryptionKey } from './aead-aes-256-cbc-hmac-encryption-key';\n\nexport const validateAndGetEncryptionAlgorithmName = (cipherAlgorithmId: number, cipherAlgorithmName?: string): string => {\n if (cipherAlgorithmId !== 2) {\n throw new Error('Custom cipher algorithm not supported.');\n }\n\n return algorithmName;\n};\n\nexport const encryptWithKey = async (plaintext: Buffer, md: CryptoMetadata, options: ConnectionOptions): Promise<Buffer> => {\n if (!options.trustedServerNameAE) {\n throw new Error('Server name should not be null in EncryptWithKey');\n }\n\n if (!md.cipherAlgorithm) {\n await decryptSymmetricKey(md, options);\n }\n\n if (!md.cipherAlgorithm) {\n throw new Error('Cipher Algorithm should not be null in EncryptWithKey');\n }\n\n const cipherText: Buffer = md.cipherAlgorithm.encryptData(plaintext);\n\n if (!cipherText) {\n throw new Error('Internal error. Ciphertext value cannot be null.');\n }\n\n return cipherText;\n};\n\nexport const decryptWithKey = (cipherText: Buffer, md: CryptoMetadata, options: ConnectionOptions): Buffer => {\n if (!options.trustedServerNameAE) {\n throw new Error('Server name should not be null in DecryptWithKey');\n }\n\n // if (!md.cipherAlgorithm) {\n // await decryptSymmetricKey(md, options);\n // }\n\n if (!md.cipherAlgorithm) {\n throw new Error('Cipher Algorithm should not be null in DecryptWithKey');\n }\n\n const plainText: Buffer = md.cipherAlgorithm.decryptData(cipherText);\n\n if (!plainText) {\n throw new Error('Internal error. Plaintext value cannot be null.');\n }\n\n return plainText;\n};\n\nexport const decryptSymmetricKey = async (md: CryptoMetadata, options: ConnectionOptions): Promise<void> => {\n if (!md) {\n throw new Error('md should not be null in DecryptSymmetricKey.');\n }\n\n if (!md.cekEntry) {\n throw new Error('md.EncryptionInfo should not be null in DecryptSymmetricKey.');\n }\n\n if (!md.cekEntry.columnEncryptionKeyValues) {\n throw new Error('md.EncryptionInfo.ColumnEncryptionKeyValues should not be null in DecryptSymmetricKey.');\n }\n\n let symKey: SymmetricKey | undefined;\n let encryptionKeyInfoChosen: EncryptionKeyInfo | undefined;\n const CEKValues: EncryptionKeyInfo[] = md.cekEntry.columnEncryptionKeyValues;\n let lastError: Error | undefined;\n\n for (const CEKValue of CEKValues) {\n try {\n symKey = await getKey(CEKValue, options);\n if (symKey) {\n encryptionKeyInfoChosen = CEKValue;\n break;\n }\n } catch (error: any) {\n lastError = error;\n }\n }\n\n if (!symKey) {\n if (lastError) {\n throw lastError;\n } else {\n throw new Error('Exception while decryption of encrypted column encryption key.');\n }\n }\n\n const algorithmName = validateAndGetEncryptionAlgorithmName(md.cipherAlgorithmId, md.cipherAlgorithmName);\n const cipherAlgorithm = new AeadAes256CbcHmac256Algorithm(new AeadAes256CbcHmac256EncryptionKey(symKey.rootKey, algorithmName), md.encryptionType);\n\n md.cipherAlgorithm = cipherAlgorithm;\n md.encryptionKeyInfo = encryptionKeyInfoChosen as EncryptionKeyInfo;\n};\n"],"mappings":"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"}
|
|
@@ -4,68 +4,55 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.ColumnEncryptionAzureKeyVaultProvider = void 0;
|
|
7
|
-
|
|
8
7
|
var _identity = require("@azure/identity");
|
|
9
|
-
|
|
10
8
|
var _keyvaultKeys = require("@azure/keyvault-keys");
|
|
11
|
-
|
|
12
9
|
var _crypto = require("crypto");
|
|
13
|
-
|
|
14
10
|
var _url = require("url");
|
|
15
|
-
|
|
16
11
|
// This code is based on the `mssql-jdbc` library published under the conditions of MIT license.
|
|
17
12
|
// Copyright (c) 2019 Microsoft Corporation
|
|
13
|
+
|
|
18
14
|
class ColumnEncryptionAzureKeyVaultProvider {
|
|
15
|
+
name;
|
|
16
|
+
url;
|
|
17
|
+
rsaEncryptionAlgorithmWithOAEPForAKV;
|
|
18
|
+
firstVersion;
|
|
19
|
+
credentials;
|
|
20
|
+
azureKeyVaultDomainName;
|
|
21
|
+
keyClient;
|
|
19
22
|
constructor(clientId, clientKey, tenantId) {
|
|
20
|
-
this.name = void 0;
|
|
21
|
-
this.url = void 0;
|
|
22
|
-
this.rsaEncryptionAlgorithmWithOAEPForAKV = void 0;
|
|
23
|
-
this.firstVersion = void 0;
|
|
24
|
-
this.credentials = void 0;
|
|
25
|
-
this.azureKeyVaultDomainName = void 0;
|
|
26
|
-
this.keyClient = void 0;
|
|
27
23
|
this.name = 'AZURE_KEY_VAULT';
|
|
28
24
|
this.azureKeyVaultDomainName = 'vault.azure.net';
|
|
29
25
|
this.rsaEncryptionAlgorithmWithOAEPForAKV = 'RSA-OAEP';
|
|
30
26
|
this.firstVersion = Buffer.from([0x01]);
|
|
31
27
|
this.credentials = new _identity.ClientSecretCredential(tenantId, clientId, clientKey);
|
|
32
28
|
}
|
|
33
|
-
|
|
34
29
|
async decryptColumnEncryptionKey(masterKeyPath, encryptionAlgorithm, encryptedColumnEncryptionKey) {
|
|
35
30
|
if (!encryptedColumnEncryptionKey) {
|
|
36
31
|
throw new Error('Internal error. Encrypted column encryption key cannot be null.');
|
|
37
32
|
}
|
|
38
|
-
|
|
39
33
|
if (encryptedColumnEncryptionKey.length === 0) {
|
|
40
34
|
throw new Error('Internal error. Empty encrypted column encryption key specified.');
|
|
41
35
|
}
|
|
42
|
-
|
|
43
36
|
encryptionAlgorithm = this.validateEncryptionAlgorithm(encryptionAlgorithm);
|
|
44
37
|
const masterKey = await this.getMasterKey(masterKeyPath);
|
|
45
38
|
const keySizeInBytes = this.getAKVKeySize(masterKey);
|
|
46
39
|
const cryptoClient = this.createCryptoClient(masterKey);
|
|
47
|
-
|
|
48
40
|
if (encryptedColumnEncryptionKey[0] !== this.firstVersion[0]) {
|
|
49
41
|
throw new Error(`Specified encrypted column encryption key contains an invalid encryption algorithm version ${Buffer.from([encryptedColumnEncryptionKey[0]]).toString('hex')}. Expected version is ${Buffer.from([this.firstVersion[0]]).toString('hex')}.`);
|
|
50
42
|
}
|
|
51
|
-
|
|
52
43
|
let currentIndex = this.firstVersion.length;
|
|
53
44
|
const keyPathLength = encryptedColumnEncryptionKey.readInt16LE(currentIndex);
|
|
54
45
|
currentIndex += 2;
|
|
55
46
|
const cipherTextLength = encryptedColumnEncryptionKey.readInt16LE(currentIndex);
|
|
56
47
|
currentIndex += 2;
|
|
57
48
|
currentIndex += keyPathLength;
|
|
58
|
-
|
|
59
49
|
if (cipherTextLength !== keySizeInBytes) {
|
|
60
50
|
throw new Error(`The specified encrypted column encryption key's ciphertext length: ${cipherTextLength} does not match the ciphertext length: ${keySizeInBytes} when using column master key (Azure Key Vault key) in ${masterKeyPath}. The encrypted column encryption key may be corrupt, or the specified Azure Key Vault key path may be incorrect.`);
|
|
61
51
|
}
|
|
62
|
-
|
|
63
52
|
const signatureLength = encryptedColumnEncryptionKey.length - currentIndex - cipherTextLength;
|
|
64
|
-
|
|
65
53
|
if (signatureLength !== keySizeInBytes) {
|
|
66
54
|
throw new Error(`The specified encrypted column encryption key's signature length: ${signatureLength} does not match the signature length: ${keySizeInBytes} when using column master key (Azure Key Vault key) in ${masterKeyPath}. The encrypted column encryption key may be corrupt, or the specified Azure Key Vault key path may be incorrect.`);
|
|
67
55
|
}
|
|
68
|
-
|
|
69
56
|
const cipherText = Buffer.alloc(cipherTextLength);
|
|
70
57
|
encryptedColumnEncryptionKey.copy(cipherText, 0, currentIndex, currentIndex + cipherTextLength);
|
|
71
58
|
currentIndex += cipherTextLength;
|
|
@@ -76,30 +63,23 @@ class ColumnEncryptionAzureKeyVaultProvider {
|
|
|
76
63
|
const messageDigest = (0, _crypto.createHash)('sha256');
|
|
77
64
|
messageDigest.update(hash);
|
|
78
65
|
const dataToVerify = messageDigest.digest();
|
|
79
|
-
|
|
80
66
|
if (!dataToVerify) {
|
|
81
67
|
throw new Error('Hash should not be null while decrypting encrypted column encryption key.');
|
|
82
68
|
}
|
|
83
|
-
|
|
84
69
|
const verifyKey = await cryptoClient.verify('RS256', dataToVerify, signature);
|
|
85
|
-
|
|
86
70
|
if (!verifyKey.result) {
|
|
87
71
|
throw new Error(`The specified encrypted column encryption key signature does not match the signature computed with the column master key (Asymmetric key in Azure Key Vault) in ${masterKeyPath}. The encrypted column encryption key may be corrupt, or the specified path may be incorrect.`);
|
|
88
72
|
}
|
|
89
|
-
|
|
90
73
|
const decryptedCEK = await this.azureKeyVaultUnWrap(cryptoClient, encryptionAlgorithm, cipherText);
|
|
91
74
|
return decryptedCEK;
|
|
92
75
|
}
|
|
93
|
-
|
|
94
76
|
async encryptColumnEncryptionKey(masterKeyPath, encryptionAlgorithm, columnEncryptionKey) {
|
|
95
77
|
if (!columnEncryptionKey) {
|
|
96
78
|
throw new Error('Column encryption key cannot be null.');
|
|
97
79
|
}
|
|
98
|
-
|
|
99
80
|
if (columnEncryptionKey.length === 0) {
|
|
100
81
|
throw new Error('Empty column encryption key specified.');
|
|
101
82
|
}
|
|
102
|
-
|
|
103
83
|
encryptionAlgorithm = this.validateEncryptionAlgorithm(encryptionAlgorithm);
|
|
104
84
|
const masterKey = await this.getMasterKey(masterKeyPath);
|
|
105
85
|
const keySizeInBytes = this.getAKVKeySize(masterKey);
|
|
@@ -113,11 +93,9 @@ class ColumnEncryptionAzureKeyVaultProvider {
|
|
|
113
93
|
const cipherTextLength = Buffer.alloc(2);
|
|
114
94
|
cipherTextLength[0] = cipherText.length & 0xff;
|
|
115
95
|
cipherTextLength[1] = cipherText.length >> 8 & 0xff;
|
|
116
|
-
|
|
117
96
|
if (cipherText.length !== keySizeInBytes) {
|
|
118
97
|
throw new Error('CipherText length does not match the RSA key size.');
|
|
119
98
|
}
|
|
120
|
-
|
|
121
99
|
const dataToHash = Buffer.alloc(version.length + keyPathLength.length + cipherTextLength.length + masterKeyPathBytes.length + cipherText.length);
|
|
122
100
|
let destinationPosition = version.length;
|
|
123
101
|
version.copy(dataToHash, 0, 0, version.length);
|
|
@@ -132,17 +110,13 @@ class ColumnEncryptionAzureKeyVaultProvider {
|
|
|
132
110
|
messageDigest.update(dataToHash);
|
|
133
111
|
const dataToSign = messageDigest.digest();
|
|
134
112
|
const signedHash = await this.azureKeyVaultSignedHashedData(cryptoClient, dataToSign);
|
|
135
|
-
|
|
136
113
|
if (signedHash.length !== keySizeInBytes) {
|
|
137
114
|
throw new Error('Signed hash length does not match the RSA key size.');
|
|
138
115
|
}
|
|
139
|
-
|
|
140
116
|
const verifyKey = await cryptoClient.verify('RS256', dataToSign, signedHash);
|
|
141
|
-
|
|
142
117
|
if (!verifyKey.result) {
|
|
143
118
|
throw new Error('Invalid signature of the encrypted column encryption key computed.');
|
|
144
119
|
}
|
|
145
|
-
|
|
146
120
|
const encryptedColumnEncryptionKeyLength = version.length + cipherTextLength.length + keyPathLength.length + cipherText.length + masterKeyPathBytes.length + signedHash.length;
|
|
147
121
|
const encryptedColumnEncryptionKey = Buffer.alloc(encryptedColumnEncryptionKeyLength);
|
|
148
122
|
let currentIndex = 0;
|
|
@@ -159,66 +133,53 @@ class ColumnEncryptionAzureKeyVaultProvider {
|
|
|
159
133
|
signedHash.copy(encryptedColumnEncryptionKey, currentIndex, 0, signedHash.length);
|
|
160
134
|
return encryptedColumnEncryptionKey;
|
|
161
135
|
}
|
|
162
|
-
|
|
163
136
|
async getMasterKey(masterKeyPath) {
|
|
164
137
|
if (!masterKeyPath) {
|
|
165
138
|
throw new Error('Master key path cannot be null or undefined');
|
|
166
139
|
}
|
|
167
|
-
|
|
168
140
|
const keyParts = this.parsePath(masterKeyPath);
|
|
169
141
|
this.createKeyClient(keyParts.vaultUrl);
|
|
170
142
|
return await this.keyClient.getKey(keyParts.name, keyParts.version ? {
|
|
171
143
|
version: keyParts.version
|
|
172
144
|
} : {});
|
|
173
145
|
}
|
|
174
|
-
|
|
175
146
|
createKeyClient(keyVaultUrl) {
|
|
176
147
|
if (!keyVaultUrl) {
|
|
177
148
|
throw new Error('Cannot create key client with null or undefined keyVaultUrl');
|
|
178
149
|
}
|
|
179
|
-
|
|
180
150
|
if (!this.keyClient) {
|
|
181
151
|
this.url = keyVaultUrl;
|
|
182
152
|
this.keyClient = new _keyvaultKeys.KeyClient(keyVaultUrl, this.credentials);
|
|
183
153
|
}
|
|
184
154
|
}
|
|
185
|
-
|
|
186
155
|
createCryptoClient(masterKey) {
|
|
187
156
|
if (!masterKey) {
|
|
188
157
|
throw new Error('Cannot create CryptographyClient with null or undefined masterKey');
|
|
189
158
|
}
|
|
190
|
-
|
|
191
159
|
return new _keyvaultKeys.CryptographyClient(masterKey, this.credentials);
|
|
192
160
|
}
|
|
193
|
-
|
|
194
161
|
parsePath(masterKeyPath) {
|
|
195
162
|
if (!masterKeyPath || masterKeyPath.trim() === '') {
|
|
196
163
|
throw new Error('Azure Key Vault key path cannot be null.');
|
|
197
164
|
}
|
|
198
|
-
|
|
199
165
|
let baseUri;
|
|
200
|
-
|
|
201
166
|
try {
|
|
202
167
|
baseUri = (0, _url.parse)(masterKeyPath, true, true);
|
|
203
168
|
} catch {
|
|
204
169
|
throw new Error(`Invalid keys identifier: ${masterKeyPath}. Not a valid URI`);
|
|
205
170
|
}
|
|
206
|
-
|
|
207
171
|
if (!baseUri.hostname || !baseUri.hostname.toLowerCase().endsWith(this.azureKeyVaultDomainName)) {
|
|
208
172
|
throw new Error(`Invalid Azure Key Vault key path specified: ${masterKeyPath}.`);
|
|
209
|
-
}
|
|
210
|
-
|
|
173
|
+
}
|
|
211
174
|
|
|
175
|
+
// Path is of the form '/collection/name[/version]'
|
|
212
176
|
const segments = (baseUri.pathname || '').split('/');
|
|
213
|
-
|
|
214
177
|
if (segments.length !== 3 && segments.length !== 4) {
|
|
215
178
|
throw new Error(`Invalid keys identifier: ${masterKeyPath}. Bad number of segments: ${segments.length}`);
|
|
216
179
|
}
|
|
217
|
-
|
|
218
180
|
if ('keys' !== segments[1]) {
|
|
219
181
|
throw new Error(`Invalid keys identifier: ${masterKeyPath}. segment [1] should be "keys", found "${segments[1]}"`);
|
|
220
182
|
}
|
|
221
|
-
|
|
222
183
|
const vaultUrl = `${baseUri.protocol}//${baseUri.host}`;
|
|
223
184
|
const name = segments[2];
|
|
224
185
|
const version = segments.length === 4 ? segments[3] : undefined;
|
|
@@ -228,88 +189,66 @@ class ColumnEncryptionAzureKeyVaultProvider {
|
|
|
228
189
|
version
|
|
229
190
|
};
|
|
230
191
|
}
|
|
231
|
-
|
|
232
192
|
async azureKeyVaultSignedHashedData(cryptoClient, dataToSign) {
|
|
233
193
|
if (!cryptoClient) {
|
|
234
194
|
throw new Error('Azure KVS Crypto Client is not defined.');
|
|
235
195
|
}
|
|
236
|
-
|
|
237
196
|
const signedData = await cryptoClient.sign('RS256', dataToSign);
|
|
238
197
|
return Buffer.from(signedData.result);
|
|
239
198
|
}
|
|
240
|
-
|
|
241
199
|
async azureKeyVaultWrap(cryptoClient, encryptionAlgorithm, columnEncryptionKey) {
|
|
242
200
|
if (!cryptoClient) {
|
|
243
201
|
throw new Error('Azure KVS Crypto Client is not defined.');
|
|
244
202
|
}
|
|
245
|
-
|
|
246
203
|
if (!columnEncryptionKey) {
|
|
247
204
|
throw new Error('Column encryption key cannot be null.');
|
|
248
205
|
}
|
|
249
|
-
|
|
250
206
|
const wrappedKey = await cryptoClient.wrapKey(encryptionAlgorithm, columnEncryptionKey);
|
|
251
207
|
return Buffer.from(wrappedKey.result);
|
|
252
208
|
}
|
|
253
|
-
|
|
254
209
|
async azureKeyVaultUnWrap(cryptoClient, encryptionAlgorithm, encryptedColumnEncryptionKey) {
|
|
255
210
|
if (!cryptoClient) {
|
|
256
211
|
throw new Error('Azure KVS Crypto Client is not defined.');
|
|
257
212
|
}
|
|
258
|
-
|
|
259
213
|
if (!encryptionAlgorithm) {
|
|
260
214
|
throw new Error('Encryption Algorithm cannot be null or undefined');
|
|
261
215
|
}
|
|
262
|
-
|
|
263
216
|
if (!encryptedColumnEncryptionKey) {
|
|
264
217
|
throw new Error('Encrypted column encryption key cannot be null.');
|
|
265
218
|
}
|
|
266
|
-
|
|
267
219
|
if (encryptedColumnEncryptionKey.length === 0) {
|
|
268
220
|
throw new Error('Encrypted Column Encryption Key length should not be zero.');
|
|
269
221
|
}
|
|
270
|
-
|
|
271
222
|
const unwrappedKey = await cryptoClient.unwrapKey(encryptionAlgorithm, encryptedColumnEncryptionKey);
|
|
272
223
|
return Buffer.from(unwrappedKey.result);
|
|
273
224
|
}
|
|
274
|
-
|
|
275
225
|
getAKVKeySize(retrievedKey) {
|
|
276
226
|
if (!retrievedKey) {
|
|
277
227
|
throw new Error('Retrieved key cannot be null or undefined');
|
|
278
228
|
}
|
|
279
|
-
|
|
280
229
|
const key = retrievedKey.key;
|
|
281
|
-
|
|
282
230
|
if (!key) {
|
|
283
231
|
throw new Error(`Key does not exist ${retrievedKey.name}`);
|
|
284
232
|
}
|
|
285
|
-
|
|
286
233
|
const kty = key && key.kty && key.kty.toString().toUpperCase();
|
|
287
|
-
|
|
288
234
|
if (!kty || 'RSA'.localeCompare(kty, 'en') !== 0) {
|
|
289
235
|
throw new Error(`Cannot use a non-RSA key: ${kty}.`);
|
|
290
236
|
}
|
|
291
|
-
|
|
292
237
|
const keyLength = key && key.n && key.n.length;
|
|
293
238
|
return keyLength || 0;
|
|
294
239
|
}
|
|
295
|
-
|
|
296
240
|
validateEncryptionAlgorithm(encryptionAlgorithm) {
|
|
297
241
|
if (!encryptionAlgorithm) {
|
|
298
242
|
throw new Error('Key encryption algorithm cannot be null.');
|
|
299
243
|
}
|
|
300
|
-
|
|
301
244
|
if ('RSA_OAEP'.localeCompare(encryptionAlgorithm.toUpperCase(), 'en') === 0) {
|
|
302
245
|
encryptionAlgorithm = 'RSA-OAEP';
|
|
303
246
|
}
|
|
304
|
-
|
|
305
247
|
if (this.rsaEncryptionAlgorithmWithOAEPForAKV.localeCompare(encryptionAlgorithm.trim().toUpperCase(), 'en') !== 0) {
|
|
306
248
|
throw new Error(`Invalid key encryption algorithm specified: ${encryptionAlgorithm}. Expected value: ${this.rsaEncryptionAlgorithmWithOAEPForAKV}.`);
|
|
307
249
|
}
|
|
308
|
-
|
|
309
250
|
return encryptionAlgorithm;
|
|
310
251
|
}
|
|
311
|
-
|
|
312
252
|
}
|
|
313
|
-
|
|
314
253
|
exports.ColumnEncryptionAzureKeyVaultProvider = ColumnEncryptionAzureKeyVaultProvider;
|
|
315
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDb2x1bW5FbmNyeXB0aW9uQXp1cmVLZXlWYXVsdFByb3ZpZGVyIiwiY29uc3RydWN0b3IiLCJjbGllbnRJZCIsImNsaWVudEtleSIsInRlbmFudElkIiwibmFtZSIsInVybCIsInJzYUVuY3J5cHRpb25BbGdvcml0aG1XaXRoT0FFUEZvckFLViIsImZpcnN0VmVyc2lvbiIsImNyZWRlbnRpYWxzIiwiYXp1cmVLZXlWYXVsdERvbWFpbk5hbWUiLCJrZXlDbGllbnQiLCJCdWZmZXIiLCJmcm9tIiwiQ2xpZW50U2VjcmV0Q3JlZGVudGlhbCIsImRlY3J5cHRDb2x1bW5FbmNyeXB0aW9uS2V5IiwibWFzdGVyS2V5UGF0aCIsImVuY3J5cHRpb25BbGdvcml0aG0iLCJlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5IiwiRXJyb3IiLCJsZW5ndGgiLCJ2YWxpZGF0ZUVuY3J5cHRpb25BbGdvcml0aG0iLCJtYXN0ZXJLZXkiLCJnZXRNYXN0ZXJLZXkiLCJrZXlTaXplSW5CeXRlcyIsImdldEFLVktleVNpemUiLCJjcnlwdG9DbGllbnQiLCJjcmVhdGVDcnlwdG9DbGllbnQiLCJ0b1N0cmluZyIsImN1cnJlbnRJbmRleCIsImtleVBhdGhMZW5ndGgiLCJyZWFkSW50MTZMRSIsImNpcGhlclRleHRMZW5ndGgiLCJzaWduYXR1cmVMZW5ndGgiLCJjaXBoZXJUZXh0IiwiYWxsb2MiLCJjb3B5Iiwic2lnbmF0dXJlIiwiaGFzaCIsIm1lc3NhZ2VEaWdlc3QiLCJ1cGRhdGUiLCJkYXRhVG9WZXJpZnkiLCJkaWdlc3QiLCJ2ZXJpZnlLZXkiLCJ2ZXJpZnkiLCJyZXN1bHQiLCJkZWNyeXB0ZWRDRUsiLCJhenVyZUtleVZhdWx0VW5XcmFwIiwiZW5jcnlwdENvbHVtbkVuY3J5cHRpb25LZXkiLCJjb2x1bW5FbmNyeXB0aW9uS2V5IiwidmVyc2lvbiIsIm1hc3RlcktleVBhdGhCeXRlcyIsInRvTG93ZXJDYXNlIiwiYXp1cmVLZXlWYXVsdFdyYXAiLCJkYXRhVG9IYXNoIiwiZGVzdGluYXRpb25Qb3NpdGlvbiIsImRhdGFUb1NpZ24iLCJzaWduZWRIYXNoIiwiYXp1cmVLZXlWYXVsdFNpZ25lZEhhc2hlZERhdGEiLCJlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5TGVuZ3RoIiwia2V5UGFydHMiLCJwYXJzZVBhdGgiLCJjcmVhdGVLZXlDbGllbnQiLCJ2YXVsdFVybCIsImdldEtleSIsImtleVZhdWx0VXJsIiwiS2V5Q2xpZW50IiwiQ3J5cHRvZ3JhcGh5Q2xpZW50IiwidHJpbSIsImJhc2VVcmkiLCJob3N0bmFtZSIsImVuZHNXaXRoIiwic2VnbWVudHMiLCJwYXRobmFtZSIsInNwbGl0IiwicHJvdG9jb2wiLCJob3N0IiwidW5kZWZpbmVkIiwic2lnbmVkRGF0YSIsInNpZ24iLCJ3cmFwcGVkS2V5Iiwid3JhcEtleSIsInVud3JhcHBlZEtleSIsInVud3JhcEtleSIsInJldHJpZXZlZEtleSIsImtleSIsImt0eSIsInRvVXBwZXJDYXNlIiwibG9jYWxlQ29tcGFyZSIsImtleUxlbmd0aCIsIm4iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvYWx3YXlzLWVuY3J5cHRlZC9rZXlzdG9yZS1wcm92aWRlci1henVyZS1rZXktdmF1bHQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBjb2RlIGlzIGJhc2VkIG9uIHRoZSBgbXNzcWwtamRiY2AgbGlicmFyeSBwdWJsaXNoZWQgdW5kZXIgdGhlIGNvbmRpdGlvbnMgb2YgTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTkgTWljcm9zb2Z0IENvcnBvcmF0aW9uXG5cbmltcG9ydCB7IENsaWVudFNlY3JldENyZWRlbnRpYWwgfSBmcm9tICdAYXp1cmUvaWRlbnRpdHknO1xuaW1wb3J0IHsgQ3J5cHRvZ3JhcGh5Q2xpZW50LCBLZXlXcmFwQWxnb3JpdGhtLCBLZXlDbGllbnQsIEtleVZhdWx0S2V5IH0gZnJvbSAnQGF6dXJlL2tleXZhdWx0LWtleXMnO1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gJ3VybCc7XG5cbmludGVyZmFjZSBQYXJzZWRLZXlQYXRoIHtcbiAgdmF1bHRVcmw6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICB2ZXJzaW9uPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgY2xhc3MgQ29sdW1uRW5jcnlwdGlvbkF6dXJlS2V5VmF1bHRQcm92aWRlciB7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgdXJsOiB1bmRlZmluZWQgfCBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcnNhRW5jcnlwdGlvbkFsZ29yaXRobVdpdGhPQUVQRm9yQUtWOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmlyc3RWZXJzaW9uOiBCdWZmZXI7XG4gIHByaXZhdGUgY3JlZGVudGlhbHM6IENsaWVudFNlY3JldENyZWRlbnRpYWw7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXp1cmVLZXlWYXVsdERvbWFpbk5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSBrZXlDbGllbnQ6IHVuZGVmaW5lZCB8IEtleUNsaWVudDtcblxuICBjb25zdHJ1Y3RvcihjbGllbnRJZDogc3RyaW5nLCBjbGllbnRLZXk6IHN0cmluZywgdGVuYW50SWQ6IHN0cmluZykge1xuICAgIHRoaXMubmFtZSA9ICdBWlVSRV9LRVlfVkFVTFQnO1xuICAgIHRoaXMuYXp1cmVLZXlWYXVsdERvbWFpbk5hbWUgPSAndmF1bHQuYXp1cmUubmV0JztcbiAgICB0aGlzLnJzYUVuY3J5cHRpb25BbGdvcml0aG1XaXRoT0FFUEZvckFLViA9ICdSU0EtT0FFUCc7XG4gICAgdGhpcy5maXJzdFZlcnNpb24gPSBCdWZmZXIuZnJvbShbMHgwMV0pO1xuICAgIHRoaXMuY3JlZGVudGlhbHMgPSBuZXcgQ2xpZW50U2VjcmV0Q3JlZGVudGlhbCh0ZW5hbnRJZCwgY2xpZW50SWQsIGNsaWVudEtleSk7XG4gIH1cblxuICBhc3luYyBkZWNyeXB0Q29sdW1uRW5jcnlwdGlvbktleShtYXN0ZXJLZXlQYXRoOiBzdHJpbmcsIGVuY3J5cHRpb25BbGdvcml0aG06IHN0cmluZywgZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleTogQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBpZiAoIWVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgZXJyb3IuIEVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgY2Fubm90IGJlIG51bGwuJyk7XG4gICAgfVxuXG4gICAgaWYgKGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGVycm9yLiBFbXB0eSBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IHNwZWNpZmllZC4nKTtcbiAgICB9XG5cbiAgICBlbmNyeXB0aW9uQWxnb3JpdGhtID0gdGhpcy52YWxpZGF0ZUVuY3J5cHRpb25BbGdvcml0aG0oZW5jcnlwdGlvbkFsZ29yaXRobSk7XG5cbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmdldE1hc3RlcktleShtYXN0ZXJLZXlQYXRoKTtcblxuICAgIGNvbnN0IGtleVNpemVJbkJ5dGVzID0gdGhpcy5nZXRBS1ZLZXlTaXplKG1hc3RlcktleSk7XG5cbiAgICBjb25zdCBjcnlwdG9DbGllbnQgPSB0aGlzLmNyZWF0ZUNyeXB0b0NsaWVudChtYXN0ZXJLZXkpO1xuXG4gICAgaWYgKGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXlbMF0gIT09IHRoaXMuZmlyc3RWZXJzaW9uWzBdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNwZWNpZmllZCBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IGNvbnRhaW5zIGFuIGludmFsaWQgZW5jcnlwdGlvbiBhbGdvcml0aG0gdmVyc2lvbiAke0J1ZmZlci5mcm9tKFtlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5WzBdXSkudG9TdHJpbmcoJ2hleCcpfS4gRXhwZWN0ZWQgdmVyc2lvbiBpcyAke0J1ZmZlci5mcm9tKFt0aGlzLmZpcnN0VmVyc2lvblswXV0pLnRvU3RyaW5nKCdoZXgnKX0uYCk7XG4gICAgfVxuXG4gICAgbGV0IGN1cnJlbnRJbmRleCA9IHRoaXMuZmlyc3RWZXJzaW9uLmxlbmd0aDtcbiAgICBjb25zdCBrZXlQYXRoTGVuZ3RoOiBudW1iZXIgPSBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LnJlYWRJbnQxNkxFKGN1cnJlbnRJbmRleCk7XG5cbiAgICBjdXJyZW50SW5kZXggKz0gMjtcblxuICAgIGNvbnN0IGNpcGhlclRleHRMZW5ndGg6IG51bWJlciA9IGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkucmVhZEludDE2TEUoY3VycmVudEluZGV4KTtcblxuICAgIGN1cnJlbnRJbmRleCArPSAyO1xuXG4gICAgY3VycmVudEluZGV4ICs9IGtleVBhdGhMZW5ndGg7XG5cbiAgICBpZiAoY2lwaGVyVGV4dExlbmd0aCAhPT0ga2V5U2l6ZUluQnl0ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHNwZWNpZmllZCBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5J3MgY2lwaGVydGV4dCBsZW5ndGg6ICR7Y2lwaGVyVGV4dExlbmd0aH0gZG9lcyBub3QgbWF0Y2ggdGhlIGNpcGhlcnRleHQgbGVuZ3RoOiAke2tleVNpemVJbkJ5dGVzfSB3aGVuIHVzaW5nIGNvbHVtbiBtYXN0ZXIga2V5IChBenVyZSBLZXkgVmF1bHQga2V5KSBpbiAke21hc3RlcktleVBhdGh9LiBUaGUgZW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSBtYXkgYmUgY29ycnVwdCwgb3IgdGhlIHNwZWNpZmllZCBBenVyZSBLZXkgVmF1bHQga2V5IHBhdGggbWF5IGJlIGluY29ycmVjdC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBzaWduYXR1cmVMZW5ndGg6IG51bWJlciA9IGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkubGVuZ3RoIC0gY3VycmVudEluZGV4IC0gY2lwaGVyVGV4dExlbmd0aDtcblxuICAgIGlmIChzaWduYXR1cmVMZW5ndGggIT09IGtleVNpemVJbkJ5dGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBzcGVjaWZpZWQgZW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSdzIHNpZ25hdHVyZSBsZW5ndGg6ICR7c2lnbmF0dXJlTGVuZ3RofSBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIGxlbmd0aDogJHtrZXlTaXplSW5CeXRlc30gd2hlbiB1c2luZyBjb2x1bW4gbWFzdGVyIGtleSAoQXp1cmUgS2V5IFZhdWx0IGtleSkgaW4gJHttYXN0ZXJLZXlQYXRofS4gVGhlIGVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgbWF5IGJlIGNvcnJ1cHQsIG9yIHRoZSBzcGVjaWZpZWQgQXp1cmUgS2V5IFZhdWx0IGtleSBwYXRoIG1heSBiZSBpbmNvcnJlY3QuYCk7XG4gICAgfVxuXG4gICAgY29uc3QgY2lwaGVyVGV4dCA9IEJ1ZmZlci5hbGxvYyhjaXBoZXJUZXh0TGVuZ3RoKTtcbiAgICBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LmNvcHkoY2lwaGVyVGV4dCwgMCwgY3VycmVudEluZGV4LCBjdXJyZW50SW5kZXggKyBjaXBoZXJUZXh0TGVuZ3RoKTtcbiAgICBjdXJyZW50SW5kZXggKz0gY2lwaGVyVGV4dExlbmd0aDtcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IEJ1ZmZlci5hbGxvYyhzaWduYXR1cmVMZW5ndGgpO1xuICAgIGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkuY29weShzaWduYXR1cmUsIDAsIGN1cnJlbnRJbmRleCwgY3VycmVudEluZGV4ICsgc2lnbmF0dXJlTGVuZ3RoKTtcblxuICAgIGNvbnN0IGhhc2ggPSBCdWZmZXIuYWxsb2MoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5sZW5ndGggLSBzaWduYXR1cmUubGVuZ3RoKTtcbiAgICBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LmNvcHkoaGFzaCwgMCwgMCwgZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5sZW5ndGggLSBzaWduYXR1cmUubGVuZ3RoKTtcblxuICAgIGNvbnN0IG1lc3NhZ2VEaWdlc3QgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKTtcbiAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShoYXNoKTtcblxuICAgIGNvbnN0IGRhdGFUb1ZlcmlmeTogQnVmZmVyID0gbWVzc2FnZURpZ2VzdC5kaWdlc3QoKTtcblxuICAgIGlmICghZGF0YVRvVmVyaWZ5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0hhc2ggc2hvdWxkIG5vdCBiZSBudWxsIHdoaWxlIGRlY3J5cHRpbmcgZW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJpZnlLZXkgPSBhd2FpdCBjcnlwdG9DbGllbnQudmVyaWZ5KCdSUzI1NicsIGRhdGFUb1ZlcmlmeSwgc2lnbmF0dXJlKTtcbiAgICBpZiAoIXZlcmlmeUtleS5yZXN1bHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHNwZWNpZmllZCBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIGNvbXB1dGVkIHdpdGggdGhlIGNvbHVtbiBtYXN0ZXIga2V5IChBc3ltbWV0cmljIGtleSBpbiBBenVyZSBLZXkgVmF1bHQpIGluICR7bWFzdGVyS2V5UGF0aH0uIFRoZSBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IG1heSBiZSBjb3JydXB0LCBvciB0aGUgc3BlY2lmaWVkIHBhdGggbWF5IGJlIGluY29ycmVjdC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRDRUs6IEJ1ZmZlciA9IGF3YWl0IHRoaXMuYXp1cmVLZXlWYXVsdFVuV3JhcChjcnlwdG9DbGllbnQsIGVuY3J5cHRpb25BbGdvcml0aG0sIGNpcGhlclRleHQpO1xuXG4gICAgcmV0dXJuIGRlY3J5cHRlZENFSztcbiAgfVxuXG4gIGFzeW5jIGVuY3J5cHRDb2x1bW5FbmNyeXB0aW9uS2V5KG1hc3RlcktleVBhdGg6IHN0cmluZywgZW5jcnlwdGlvbkFsZ29yaXRobTogc3RyaW5nLCBjb2x1bW5FbmNyeXB0aW9uS2V5OiBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGlmICghY29sdW1uRW5jcnlwdGlvbktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb2x1bW4gZW5jcnlwdGlvbiBrZXkgY2Fubm90IGJlIG51bGwuJyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbHVtbkVuY3J5cHRpb25LZXkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VtcHR5IGNvbHVtbiBlbmNyeXB0aW9uIGtleSBzcGVjaWZpZWQuJyk7XG4gICAgfVxuXG4gICAgZW5jcnlwdGlvbkFsZ29yaXRobSA9IHRoaXMudmFsaWRhdGVFbmNyeXB0aW9uQWxnb3JpdGhtKGVuY3J5cHRpb25BbGdvcml0aG0pO1xuXG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5nZXRNYXN0ZXJLZXkobWFzdGVyS2V5UGF0aCk7XG5cbiAgICBjb25zdCBrZXlTaXplSW5CeXRlcyA9IHRoaXMuZ2V0QUtWS2V5U2l6ZShtYXN0ZXJLZXkpO1xuXG4gICAgY29uc3QgY3J5cHRvQ2xpZW50ID0gdGhpcy5jcmVhdGVDcnlwdG9DbGllbnQobWFzdGVyS2V5KTtcblxuICAgIGNvbnN0IHZlcnNpb24gPSBCdWZmZXIuZnJvbShbdGhpcy5maXJzdFZlcnNpb25bMF1dKTtcblxuICAgIGNvbnN0IG1hc3RlcktleVBhdGhCeXRlczogQnVmZmVyID0gQnVmZmVyLmZyb20obWFzdGVyS2V5UGF0aC50b0xvd2VyQ2FzZSgpLCAndXRmOCcpO1xuXG4gICAgY29uc3Qga2V5UGF0aExlbmd0aDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDIpO1xuXG4gICAga2V5UGF0aExlbmd0aFswXSA9IG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGggJiAweGZmO1xuICAgIGtleVBhdGhMZW5ndGhbMV0gPSBtYXN0ZXJLZXlQYXRoQnl0ZXMubGVuZ3RoID4+IDggJiAweGZmO1xuXG4gICAgY29uc3QgY2lwaGVyVGV4dDogQnVmZmVyID0gYXdhaXQgdGhpcy5henVyZUtleVZhdWx0V3JhcChjcnlwdG9DbGllbnQsIGVuY3J5cHRpb25BbGdvcml0aG0sIGNvbHVtbkVuY3J5cHRpb25LZXkpO1xuXG4gICAgY29uc3QgY2lwaGVyVGV4dExlbmd0aDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDIpO1xuXG4gICAgY2lwaGVyVGV4dExlbmd0aFswXSA9IGNpcGhlclRleHQubGVuZ3RoICYgMHhmZjtcbiAgICBjaXBoZXJUZXh0TGVuZ3RoWzFdID0gY2lwaGVyVGV4dC5sZW5ndGggPj4gOCAmIDB4ZmY7XG5cbiAgICBpZiAoY2lwaGVyVGV4dC5sZW5ndGggIT09IGtleVNpemVJbkJ5dGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NpcGhlclRleHQgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIHRoZSBSU0Ega2V5IHNpemUuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YVRvSGFzaDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKHZlcnNpb24ubGVuZ3RoICsga2V5UGF0aExlbmd0aC5sZW5ndGggKyBjaXBoZXJUZXh0TGVuZ3RoLmxlbmd0aCArIG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGggKyBjaXBoZXJUZXh0Lmxlbmd0aCk7XG4gICAgbGV0IGRlc3RpbmF0aW9uUG9zaXRpb246IG51bWJlciA9IHZlcnNpb24ubGVuZ3RoO1xuICAgIHZlcnNpb24uY29weShkYXRhVG9IYXNoLCAwLCAwLCB2ZXJzaW9uLmxlbmd0aCk7XG5cbiAgICBrZXlQYXRoTGVuZ3RoLmNvcHkoZGF0YVRvSGFzaCwgZGVzdGluYXRpb25Qb3NpdGlvbiwgMCwga2V5UGF0aExlbmd0aC5sZW5ndGgpO1xuICAgIGRlc3RpbmF0aW9uUG9zaXRpb24gKz0ga2V5UGF0aExlbmd0aC5sZW5ndGg7XG5cbiAgICBjaXBoZXJUZXh0TGVuZ3RoLmNvcHkoZGF0YVRvSGFzaCwgZGVzdGluYXRpb25Qb3NpdGlvbiwgMCwgY2lwaGVyVGV4dExlbmd0aC5sZW5ndGgpO1xuICAgIGRlc3RpbmF0aW9uUG9zaXRpb24gKz0gY2lwaGVyVGV4dExlbmd0aC5sZW5ndGg7XG5cbiAgICBtYXN0ZXJLZXlQYXRoQnl0ZXMuY29weShkYXRhVG9IYXNoLCBkZXN0aW5hdGlvblBvc2l0aW9uLCAwLCBtYXN0ZXJLZXlQYXRoQnl0ZXMubGVuZ3RoKTtcbiAgICBkZXN0aW5hdGlvblBvc2l0aW9uICs9IG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGg7XG5cbiAgICBjaXBoZXJUZXh0LmNvcHkoZGF0YVRvSGFzaCwgZGVzdGluYXRpb25Qb3NpdGlvbiwgMCwgY2lwaGVyVGV4dC5sZW5ndGgpO1xuXG4gICAgY29uc3QgbWVzc2FnZURpZ2VzdCA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpO1xuXG4gICAgbWVzc2FnZURpZ2VzdC51cGRhdGUoZGF0YVRvSGFzaCk7XG5cbiAgICBjb25zdCBkYXRhVG9TaWduOiBCdWZmZXIgPSBtZXNzYWdlRGlnZXN0LmRpZ2VzdCgpO1xuXG4gICAgY29uc3Qgc2lnbmVkSGFzaDogQnVmZmVyID0gYXdhaXQgdGhpcy5henVyZUtleVZhdWx0U2lnbmVkSGFzaGVkRGF0YShjcnlwdG9DbGllbnQsIGRhdGFUb1NpZ24pO1xuICAgIGlmIChzaWduZWRIYXNoLmxlbmd0aCAhPT0ga2V5U2l6ZUluQnl0ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2lnbmVkIGhhc2ggbGVuZ3RoIGRvZXMgbm90IG1hdGNoIHRoZSBSU0Ega2V5IHNpemUuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdmVyaWZ5S2V5ID0gYXdhaXQgY3J5cHRvQ2xpZW50LnZlcmlmeSgnUlMyNTYnLCBkYXRhVG9TaWduLCBzaWduZWRIYXNoKTtcblxuICAgIGlmICghdmVyaWZ5S2V5LnJlc3VsdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBvZiB0aGUgZW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSBjb21wdXRlZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5TGVuZ3RoOiBudW1iZXIgPSB2ZXJzaW9uLmxlbmd0aCArIGNpcGhlclRleHRMZW5ndGgubGVuZ3RoICsga2V5UGF0aExlbmd0aC5sZW5ndGggKyBjaXBoZXJUZXh0Lmxlbmd0aCArIG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGggKyBzaWduZWRIYXNoLmxlbmd0aDtcbiAgICBjb25zdCBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5OiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleUxlbmd0aCk7XG5cbiAgICBsZXQgY3VycmVudEluZGV4ID0gMDtcbiAgICB2ZXJzaW9uLmNvcHkoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleSwgY3VycmVudEluZGV4LCAwLCB2ZXJzaW9uLmxlbmd0aCk7XG4gICAgY3VycmVudEluZGV4ICs9IHZlcnNpb24ubGVuZ3RoO1xuXG4gICAga2V5UGF0aExlbmd0aC5jb3B5KGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXksIGN1cnJlbnRJbmRleCwgMCwga2V5UGF0aExlbmd0aC5sZW5ndGgpO1xuICAgIGN1cnJlbnRJbmRleCArPSBrZXlQYXRoTGVuZ3RoLmxlbmd0aDtcblxuICAgIGNpcGhlclRleHRMZW5ndGguY29weShlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LCBjdXJyZW50SW5kZXgsIDAsIGNpcGhlclRleHRMZW5ndGgubGVuZ3RoKTtcbiAgICBjdXJyZW50SW5kZXggKz0gY2lwaGVyVGV4dExlbmd0aC5sZW5ndGg7XG5cbiAgICBtYXN0ZXJLZXlQYXRoQnl0ZXMuY29weShlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LCBjdXJyZW50SW5kZXgsIDAsIG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGgpO1xuICAgIGN1cnJlbnRJbmRleCArPSBtYXN0ZXJLZXlQYXRoQnl0ZXMubGVuZ3RoO1xuXG4gICAgY2lwaGVyVGV4dC5jb3B5KGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXksIGN1cnJlbnRJbmRleCwgMCwgY2lwaGVyVGV4dC5sZW5ndGgpO1xuICAgIGN1cnJlbnRJbmRleCArPSBjaXBoZXJUZXh0Lmxlbmd0aDtcblxuICAgIHNpZ25lZEhhc2guY29weShlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LCBjdXJyZW50SW5kZXgsIDAsIHNpZ25lZEhhc2gubGVuZ3RoKTtcblxuICAgIHJldHVybiBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRNYXN0ZXJLZXkobWFzdGVyS2V5UGF0aDogc3RyaW5nKTogUHJvbWlzZTxLZXlWYXVsdEtleT4ge1xuICAgIGlmICghbWFzdGVyS2V5UGF0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYXN0ZXIga2V5IHBhdGggY2Fubm90IGJlIG51bGwgb3IgdW5kZWZpbmVkJyk7XG4gICAgfVxuICAgIGNvbnN0IGtleVBhcnRzID0gdGhpcy5wYXJzZVBhdGgobWFzdGVyS2V5UGF0aCk7XG5cbiAgICB0aGlzLmNyZWF0ZUtleUNsaWVudChrZXlQYXJ0cy52YXVsdFVybCk7XG5cbiAgICByZXR1cm4gYXdhaXQgKHRoaXMua2V5Q2xpZW50IGFzIEtleUNsaWVudCkuZ2V0S2V5KGtleVBhcnRzLm5hbWUsIGtleVBhcnRzLnZlcnNpb24gPyB7IHZlcnNpb246IGtleVBhcnRzLnZlcnNpb24gfSA6IHt9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlS2V5Q2xpZW50KGtleVZhdWx0VXJsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIWtleVZhdWx0VXJsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBjcmVhdGUga2V5IGNsaWVudCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkIGtleVZhdWx0VXJsJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5rZXlDbGllbnQpIHtcbiAgICAgIHRoaXMudXJsID0ga2V5VmF1bHRVcmw7XG4gICAgICB0aGlzLmtleUNsaWVudCA9IG5ldyBLZXlDbGllbnQoa2V5VmF1bHRVcmwsIHRoaXMuY3JlZGVudGlhbHMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ3J5cHRvQ2xpZW50KG1hc3RlcktleTogS2V5VmF1bHRLZXkpOiBDcnlwdG9ncmFwaHlDbGllbnQge1xuICAgIGlmICghbWFzdGVyS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBjcmVhdGUgQ3J5cHRvZ3JhcGh5Q2xpZW50IHdpdGggbnVsbCBvciB1bmRlZmluZWQgbWFzdGVyS2V5Jyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQ3J5cHRvZ3JhcGh5Q2xpZW50KG1hc3RlcktleSwgdGhpcy5jcmVkZW50aWFscyk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlUGF0aChtYXN0ZXJLZXlQYXRoOiBzdHJpbmcpOiBQYXJzZWRLZXlQYXRoIHtcbiAgICBpZiAoIW1hc3RlcktleVBhdGggfHwgbWFzdGVyS2V5UGF0aC50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F6dXJlIEtleSBWYXVsdCBrZXkgcGF0aCBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICB9XG5cbiAgICBsZXQgYmFzZVVyaTtcbiAgICB0cnkge1xuICAgICAgYmFzZVVyaSA9IHBhcnNlKG1hc3RlcktleVBhdGgsIHRydWUsIHRydWUpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGtleXMgaWRlbnRpZmllcjogJHttYXN0ZXJLZXlQYXRofS4gTm90IGEgdmFsaWQgVVJJYCk7XG4gICAgfVxuXG4gICAgaWYgKCFiYXNlVXJpLmhvc3RuYW1lIHx8ICFiYXNlVXJpLmhvc3RuYW1lLnRvTG93ZXJDYXNlKCkuZW5kc1dpdGgodGhpcy5henVyZUtleVZhdWx0RG9tYWluTmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBBenVyZSBLZXkgVmF1bHQga2V5IHBhdGggc3BlY2lmaWVkOiAke21hc3RlcktleVBhdGh9LmApO1xuICAgIH1cblxuICAgIC8vIFBhdGggaXMgb2YgdGhlIGZvcm0gJy9jb2xsZWN0aW9uL25hbWVbL3ZlcnNpb25dJ1xuICAgIGNvbnN0IHNlZ21lbnRzID0gKGJhc2VVcmkucGF0aG5hbWUgfHwgJycpLnNwbGl0KCcvJyk7XG4gICAgaWYgKHNlZ21lbnRzLmxlbmd0aCAhPT0gMyAmJiBzZWdtZW50cy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQga2V5cyBpZGVudGlmaWVyOiAke21hc3RlcktleVBhdGh9LiBCYWQgbnVtYmVyIG9mIHNlZ21lbnRzOiAke3NlZ21lbnRzLmxlbmd0aH1gXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICgna2V5cycgIT09IHNlZ21lbnRzWzFdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGtleXMgaWRlbnRpZmllcjogJHttYXN0ZXJLZXlQYXRofS4gc2VnbWVudCBbMV0gc2hvdWxkIGJlIFwia2V5c1wiLCBmb3VuZCBcIiR7c2VnbWVudHNbMV19XCJgXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHZhdWx0VXJsID0gYCR7YmFzZVVyaS5wcm90b2NvbH0vLyR7YmFzZVVyaS5ob3N0fWA7XG4gICAgY29uc3QgbmFtZSA9IHNlZ21lbnRzWzJdO1xuICAgIGNvbnN0IHZlcnNpb24gPSBzZWdtZW50cy5sZW5ndGggPT09IDQgPyBzZWdtZW50c1szXSA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4ge1xuICAgICAgdmF1bHRVcmwsXG4gICAgICBuYW1lLFxuICAgICAgdmVyc2lvblxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGF6dXJlS2V5VmF1bHRTaWduZWRIYXNoZWREYXRhKGNyeXB0b0NsaWVudDogQ3J5cHRvZ3JhcGh5Q2xpZW50LCBkYXRhVG9TaWduOiBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGlmICghY3J5cHRvQ2xpZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F6dXJlIEtWUyBDcnlwdG8gQ2xpZW50IGlzIG5vdCBkZWZpbmVkLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHNpZ25lZERhdGEgPSBhd2FpdCBjcnlwdG9DbGllbnQuc2lnbignUlMyNTYnLCBkYXRhVG9TaWduKTtcblxuICAgIHJldHVybiBCdWZmZXIuZnJvbShzaWduZWREYXRhLnJlc3VsdCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGF6dXJlS2V5VmF1bHRXcmFwKGNyeXB0b0NsaWVudDogQ3J5cHRvZ3JhcGh5Q2xpZW50LCBlbmNyeXB0aW9uQWxnb3JpdGhtOiBzdHJpbmcsIGNvbHVtbkVuY3J5cHRpb25LZXk6IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgaWYgKCFjcnlwdG9DbGllbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXp1cmUgS1ZTIENyeXB0byBDbGllbnQgaXMgbm90IGRlZmluZWQuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFjb2x1bW5FbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbHVtbiBlbmNyeXB0aW9uIGtleSBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB3cmFwcGVkS2V5ID0gYXdhaXQgY3J5cHRvQ2xpZW50LndyYXBLZXkoZW5jcnlwdGlvbkFsZ29yaXRobSBhcyBLZXlXcmFwQWxnb3JpdGhtLCBjb2x1bW5FbmNyeXB0aW9uS2V5KTtcblxuICAgIHJldHVybiBCdWZmZXIuZnJvbSh3cmFwcGVkS2V5LnJlc3VsdCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGF6dXJlS2V5VmF1bHRVbldyYXAoY3J5cHRvQ2xpZW50OiBDcnlwdG9ncmFwaHlDbGllbnQsIGVuY3J5cHRpb25BbGdvcml0aG06IHN0cmluZywgZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleTogQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBpZiAoIWNyeXB0b0NsaWVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBenVyZSBLVlMgQ3J5cHRvIENsaWVudCBpcyBub3QgZGVmaW5lZC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWVuY3J5cHRpb25BbGdvcml0aG0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBBbGdvcml0aG0gY2Fubm90IGJlIG51bGwgb3IgdW5kZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCFlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgY2Fubm90IGJlIG51bGwuJyk7XG4gICAgfVxuXG4gICAgaWYgKGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuY3J5cHRlZCBDb2x1bW4gRW5jcnlwdGlvbiBLZXkgbGVuZ3RoIHNob3VsZCBub3QgYmUgemVyby4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB1bndyYXBwZWRLZXkgPSBhd2FpdCBjcnlwdG9DbGllbnQudW53cmFwS2V5KGVuY3J5cHRpb25BbGdvcml0aG0gYXMgS2V5V3JhcEFsZ29yaXRobSwgZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleSk7XG5cbiAgICByZXR1cm4gQnVmZmVyLmZyb20odW53cmFwcGVkS2V5LnJlc3VsdCk7XG4gIH1cblxuICBwcml2YXRlIGdldEFLVktleVNpemUocmV0cmlldmVkS2V5OiBLZXlWYXVsdEtleSk6IG51bWJlciB7XG4gICAgaWYgKCFyZXRyaWV2ZWRLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmV0cmlldmVkIGtleSBjYW5ub3QgYmUgbnVsbCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG4gICAgY29uc3Qga2V5ID0gcmV0cmlldmVkS2V5LmtleTtcblxuICAgIGlmICgha2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEtleSBkb2VzIG5vdCBleGlzdCAke3JldHJpZXZlZEtleS5uYW1lfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGt0eTogc3RyaW5nIHwgdW5kZWZpbmVkID0ga2V5ICYmIGtleS5rdHkgJiYga2V5Lmt0eS50b1N0cmluZygpLnRvVXBwZXJDYXNlKCk7XG5cbiAgICBpZiAoIWt0eSB8fCAnUlNBJy5sb2NhbGVDb21wYXJlKGt0eSwgJ2VuJykgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHVzZSBhIG5vbi1SU0Ega2V5OiAke2t0eX0uYCk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5TGVuZ3RoID0ga2V5ICYmIGtleS5uICYmIGtleS5uLmxlbmd0aDtcblxuICAgIHJldHVybiBrZXlMZW5ndGggfHwgMDtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVFbmNyeXB0aW9uQWxnb3JpdGhtKGVuY3J5cHRpb25BbGdvcml0aG06IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFlbmNyeXB0aW9uQWxnb3JpdGhtKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0tleSBlbmNyeXB0aW9uIGFsZ29yaXRobSBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICB9XG5cbiAgICBpZiAoJ1JTQV9PQUVQJy5sb2NhbGVDb21wYXJlKGVuY3J5cHRpb25BbGdvcml0aG0udG9VcHBlckNhc2UoKSwgJ2VuJykgPT09IDApIHtcbiAgICAgIGVuY3J5cHRpb25BbGdvcml0aG0gPSAnUlNBLU9BRVAnO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJzYUVuY3J5cHRpb25BbGdvcml0aG1XaXRoT0FFUEZvckFLVi5sb2NhbGVDb21wYXJlKGVuY3J5cHRpb25BbGdvcml0aG0udHJpbSgpLnRvVXBwZXJDYXNlKCksICdlbicpICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQga2V5IGVuY3J5cHRpb24gYWxnb3JpdGhtIHNwZWNpZmllZDogJHtlbmNyeXB0aW9uQWxnb3JpdGhtfS4gRXhwZWN0ZWQgdmFsdWU6ICR7dGhpcy5yc2FFbmNyeXB0aW9uQWxnb3JpdGhtV2l0aE9BRVBGb3JBS1Z9LmApO1xuICAgIH1cblxuICAgIHJldHVybiBlbmNyeXB0aW9uQWxnb3JpdGhtO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFHQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFOQTtBQUNBO0FBYU8sTUFBTUEscUNBQU4sQ0FBNEM7RUFTakRDLFdBQVcsQ0FBQ0MsUUFBRCxFQUFtQkMsU0FBbkIsRUFBc0NDLFFBQXRDLEVBQXdEO0lBQUEsS0FSbkRDLElBUW1EO0lBQUEsS0FQM0RDLEdBTzJEO0lBQUEsS0FObERDLG9DQU1rRDtJQUFBLEtBTGxEQyxZQUtrRDtJQUFBLEtBSjNEQyxXQUkyRDtJQUFBLEtBSGxEQyx1QkFHa0Q7SUFBQSxLQUYzREMsU0FFMkQ7SUFDakUsS0FBS04sSUFBTCxHQUFZLGlCQUFaO0lBQ0EsS0FBS0ssdUJBQUwsR0FBK0IsaUJBQS9CO0lBQ0EsS0FBS0gsb0NBQUwsR0FBNEMsVUFBNUM7SUFDQSxLQUFLQyxZQUFMLEdBQW9CSSxNQUFNLENBQUNDLElBQVAsQ0FBWSxDQUFDLElBQUQsQ0FBWixDQUFwQjtJQUNBLEtBQUtKLFdBQUwsR0FBbUIsSUFBSUssZ0NBQUosQ0FBMkJWLFFBQTNCLEVBQXFDRixRQUFyQyxFQUErQ0MsU0FBL0MsQ0FBbkI7RUFDRDs7RUFFK0IsTUFBMUJZLDBCQUEwQixDQUFDQyxhQUFELEVBQXdCQyxtQkFBeEIsRUFBcURDLDRCQUFyRCxFQUE0RztJQUMxSSxJQUFJLENBQUNBLDRCQUFMLEVBQW1DO01B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
|
|
254
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfaWRlbnRpdHkiLCJyZXF1aXJlIiwiX2tleXZhdWx0S2V5cyIsIl9jcnlwdG8iLCJfdXJsIiwiQ29sdW1uRW5jcnlwdGlvbkF6dXJlS2V5VmF1bHRQcm92aWRlciIsIm5hbWUiLCJ1cmwiLCJyc2FFbmNyeXB0aW9uQWxnb3JpdGhtV2l0aE9BRVBGb3JBS1YiLCJmaXJzdFZlcnNpb24iLCJjcmVkZW50aWFscyIsImF6dXJlS2V5VmF1bHREb21haW5OYW1lIiwia2V5Q2xpZW50IiwiY29uc3RydWN0b3IiLCJjbGllbnRJZCIsImNsaWVudEtleSIsInRlbmFudElkIiwiQnVmZmVyIiwiZnJvbSIsIkNsaWVudFNlY3JldENyZWRlbnRpYWwiLCJkZWNyeXB0Q29sdW1uRW5jcnlwdGlvbktleSIsIm1hc3RlcktleVBhdGgiLCJlbmNyeXB0aW9uQWxnb3JpdGhtIiwiZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleSIsIkVycm9yIiwibGVuZ3RoIiwidmFsaWRhdGVFbmNyeXB0aW9uQWxnb3JpdGhtIiwibWFzdGVyS2V5IiwiZ2V0TWFzdGVyS2V5Iiwia2V5U2l6ZUluQnl0ZXMiLCJnZXRBS1ZLZXlTaXplIiwiY3J5cHRvQ2xpZW50IiwiY3JlYXRlQ3J5cHRvQ2xpZW50IiwidG9TdHJpbmciLCJjdXJyZW50SW5kZXgiLCJrZXlQYXRoTGVuZ3RoIiwicmVhZEludDE2TEUiLCJjaXBoZXJUZXh0TGVuZ3RoIiwic2lnbmF0dXJlTGVuZ3RoIiwiY2lwaGVyVGV4dCIsImFsbG9jIiwiY29weSIsInNpZ25hdHVyZSIsImhhc2giLCJtZXNzYWdlRGlnZXN0IiwiY3JlYXRlSGFzaCIsInVwZGF0ZSIsImRhdGFUb1ZlcmlmeSIsImRpZ2VzdCIsInZlcmlmeUtleSIsInZlcmlmeSIsInJlc3VsdCIsImRlY3J5cHRlZENFSyIsImF6dXJlS2V5VmF1bHRVbldyYXAiLCJlbmNyeXB0Q29sdW1uRW5jcnlwdGlvbktleSIsImNvbHVtbkVuY3J5cHRpb25LZXkiLCJ2ZXJzaW9uIiwibWFzdGVyS2V5UGF0aEJ5dGVzIiwidG9Mb3dlckNhc2UiLCJhenVyZUtleVZhdWx0V3JhcCIsImRhdGFUb0hhc2giLCJkZXN0aW5hdGlvblBvc2l0aW9uIiwiZGF0YVRvU2lnbiIsInNpZ25lZEhhc2giLCJhenVyZUtleVZhdWx0U2lnbmVkSGFzaGVkRGF0YSIsImVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXlMZW5ndGgiLCJrZXlQYXJ0cyIsInBhcnNlUGF0aCIsImNyZWF0ZUtleUNsaWVudCIsInZhdWx0VXJsIiwiZ2V0S2V5Iiwia2V5VmF1bHRVcmwiLCJLZXlDbGllbnQiLCJDcnlwdG9ncmFwaHlDbGllbnQiLCJ0cmltIiwiYmFzZVVyaSIsInBhcnNlIiwiaG9zdG5hbWUiLCJlbmRzV2l0aCIsInNlZ21lbnRzIiwicGF0aG5hbWUiLCJzcGxpdCIsInByb3RvY29sIiwiaG9zdCIsInVuZGVmaW5lZCIsInNpZ25lZERhdGEiLCJzaWduIiwid3JhcHBlZEtleSIsIndyYXBLZXkiLCJ1bndyYXBwZWRLZXkiLCJ1bndyYXBLZXkiLCJyZXRyaWV2ZWRLZXkiLCJrZXkiLCJrdHkiLCJ0b1VwcGVyQ2FzZSIsImxvY2FsZUNvbXBhcmUiLCJrZXlMZW5ndGgiLCJuIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hbHdheXMtZW5jcnlwdGVkL2tleXN0b3JlLXByb3ZpZGVyLWF6dXJlLWtleS12YXVsdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGlzIGNvZGUgaXMgYmFzZWQgb24gdGhlIGBtc3NxbC1qZGJjYCBsaWJyYXJ5IHB1Ymxpc2hlZCB1bmRlciB0aGUgY29uZGl0aW9ucyBvZiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCAoYykgMjAxOSBNaWNyb3NvZnQgQ29ycG9yYXRpb25cblxuaW1wb3J0IHsgQ2xpZW50U2VjcmV0Q3JlZGVudGlhbCB9IGZyb20gJ0BhenVyZS9pZGVudGl0eSc7XG5pbXBvcnQgeyBDcnlwdG9ncmFwaHlDbGllbnQsIEtleVdyYXBBbGdvcml0aG0sIEtleUNsaWVudCwgS2V5VmF1bHRLZXkgfSBmcm9tICdAYXp1cmUva2V5dmF1bHQta2V5cyc7XG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IHBhcnNlIH0gZnJvbSAndXJsJztcblxuaW50ZXJmYWNlIFBhcnNlZEtleVBhdGgge1xuICB2YXVsdFVybDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIHZlcnNpb24/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBDb2x1bW5FbmNyeXB0aW9uQXp1cmVLZXlWYXVsdFByb3ZpZGVyIHtcbiAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSB1cmw6IHVuZGVmaW5lZCB8IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByc2FFbmNyeXB0aW9uQWxnb3JpdGhtV2l0aE9BRVBGb3JBS1Y6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBmaXJzdFZlcnNpb246IEJ1ZmZlcjtcbiAgcHJpdmF0ZSBjcmVkZW50aWFsczogQ2xpZW50U2VjcmV0Q3JlZGVudGlhbDtcbiAgcHJpdmF0ZSByZWFkb25seSBhenVyZUtleVZhdWx0RG9tYWluTmFtZTogc3RyaW5nO1xuICBwcml2YXRlIGtleUNsaWVudDogdW5kZWZpbmVkIHwgS2V5Q2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKGNsaWVudElkOiBzdHJpbmcsIGNsaWVudEtleTogc3RyaW5nLCB0ZW5hbnRJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5uYW1lID0gJ0FaVVJFX0tFWV9WQVVMVCc7XG4gICAgdGhpcy5henVyZUtleVZhdWx0RG9tYWluTmFtZSA9ICd2YXVsdC5henVyZS5uZXQnO1xuICAgIHRoaXMucnNhRW5jcnlwdGlvbkFsZ29yaXRobVdpdGhPQUVQRm9yQUtWID0gJ1JTQS1PQUVQJztcbiAgICB0aGlzLmZpcnN0VmVyc2lvbiA9IEJ1ZmZlci5mcm9tKFsweDAxXSk7XG4gICAgdGhpcy5jcmVkZW50aWFscyA9IG5ldyBDbGllbnRTZWNyZXRDcmVkZW50aWFsKHRlbmFudElkLCBjbGllbnRJZCwgY2xpZW50S2V5KTtcbiAgfVxuXG4gIGFzeW5jIGRlY3J5cHRDb2x1bW5FbmNyeXB0aW9uS2V5KG1hc3RlcktleVBhdGg6IHN0cmluZywgZW5jcnlwdGlvbkFsZ29yaXRobTogc3RyaW5nLCBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5OiBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGlmICghZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBlcnJvci4gRW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICB9XG5cbiAgICBpZiAoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgZXJyb3IuIEVtcHR5IGVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgc3BlY2lmaWVkLicpO1xuICAgIH1cblxuICAgIGVuY3J5cHRpb25BbGdvcml0aG0gPSB0aGlzLnZhbGlkYXRlRW5jcnlwdGlvbkFsZ29yaXRobShlbmNyeXB0aW9uQWxnb3JpdGhtKTtcblxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMuZ2V0TWFzdGVyS2V5KG1hc3RlcktleVBhdGgpO1xuXG4gICAgY29uc3Qga2V5U2l6ZUluQnl0ZXMgPSB0aGlzLmdldEFLVktleVNpemUobWFzdGVyS2V5KTtcblxuICAgIGNvbnN0IGNyeXB0b0NsaWVudCA9IHRoaXMuY3JlYXRlQ3J5cHRvQ2xpZW50KG1hc3RlcktleSk7XG5cbiAgICBpZiAoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleVswXSAhPT0gdGhpcy5maXJzdFZlcnNpb25bMF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU3BlY2lmaWVkIGVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgY29udGFpbnMgYW4gaW52YWxpZCBlbmNyeXB0aW9uIGFsZ29yaXRobSB2ZXJzaW9uICR7QnVmZmVyLmZyb20oW2VuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXlbMF1dKS50b1N0cmluZygnaGV4Jyl9LiBFeHBlY3RlZCB2ZXJzaW9uIGlzICR7QnVmZmVyLmZyb20oW3RoaXMuZmlyc3RWZXJzaW9uWzBdXSkudG9TdHJpbmcoJ2hleCcpfS5gKTtcbiAgICB9XG5cbiAgICBsZXQgY3VycmVudEluZGV4ID0gdGhpcy5maXJzdFZlcnNpb24ubGVuZ3RoO1xuICAgIGNvbnN0IGtleVBhdGhMZW5ndGg6IG51bWJlciA9IGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkucmVhZEludDE2TEUoY3VycmVudEluZGV4KTtcblxuICAgIGN1cnJlbnRJbmRleCArPSAyO1xuXG4gICAgY29uc3QgY2lwaGVyVGV4dExlbmd0aDogbnVtYmVyID0gZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5yZWFkSW50MTZMRShjdXJyZW50SW5kZXgpO1xuXG4gICAgY3VycmVudEluZGV4ICs9IDI7XG5cbiAgICBjdXJyZW50SW5kZXggKz0ga2V5UGF0aExlbmd0aDtcblxuICAgIGlmIChjaXBoZXJUZXh0TGVuZ3RoICE9PSBrZXlTaXplSW5CeXRlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgc3BlY2lmaWVkIGVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkncyBjaXBoZXJ0ZXh0IGxlbmd0aDogJHtjaXBoZXJUZXh0TGVuZ3RofSBkb2VzIG5vdCBtYXRjaCB0aGUgY2lwaGVydGV4dCBsZW5ndGg6ICR7a2V5U2l6ZUluQnl0ZXN9IHdoZW4gdXNpbmcgY29sdW1uIG1hc3RlciBrZXkgKEF6dXJlIEtleSBWYXVsdCBrZXkpIGluICR7bWFzdGVyS2V5UGF0aH0uIFRoZSBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IG1heSBiZSBjb3JydXB0LCBvciB0aGUgc3BlY2lmaWVkIEF6dXJlIEtleSBWYXVsdCBrZXkgcGF0aCBtYXkgYmUgaW5jb3JyZWN0LmApO1xuICAgIH1cblxuICAgIGNvbnN0IHNpZ25hdHVyZUxlbmd0aDogbnVtYmVyID0gZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5sZW5ndGggLSBjdXJyZW50SW5kZXggLSBjaXBoZXJUZXh0TGVuZ3RoO1xuXG4gICAgaWYgKHNpZ25hdHVyZUxlbmd0aCAhPT0ga2V5U2l6ZUluQnl0ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHNwZWNpZmllZCBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5J3Mgc2lnbmF0dXJlIGxlbmd0aDogJHtzaWduYXR1cmVMZW5ndGh9IGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgbGVuZ3RoOiAke2tleVNpemVJbkJ5dGVzfSB3aGVuIHVzaW5nIGNvbHVtbiBtYXN0ZXIga2V5IChBenVyZSBLZXkgVmF1bHQga2V5KSBpbiAke21hc3RlcktleVBhdGh9LiBUaGUgZW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSBtYXkgYmUgY29ycnVwdCwgb3IgdGhlIHNwZWNpZmllZCBBenVyZSBLZXkgVmF1bHQga2V5IHBhdGggbWF5IGJlIGluY29ycmVjdC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBjaXBoZXJUZXh0ID0gQnVmZmVyLmFsbG9jKGNpcGhlclRleHRMZW5ndGgpO1xuICAgIGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkuY29weShjaXBoZXJUZXh0LCAwLCBjdXJyZW50SW5kZXgsIGN1cnJlbnRJbmRleCArIGNpcGhlclRleHRMZW5ndGgpO1xuICAgIGN1cnJlbnRJbmRleCArPSBjaXBoZXJUZXh0TGVuZ3RoO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlID0gQnVmZmVyLmFsbG9jKHNpZ25hdHVyZUxlbmd0aCk7XG4gICAgZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5jb3B5KHNpZ25hdHVyZSwgMCwgY3VycmVudEluZGV4LCBjdXJyZW50SW5kZXggKyBzaWduYXR1cmVMZW5ndGgpO1xuXG4gICAgY29uc3QgaGFzaCA9IEJ1ZmZlci5hbGxvYyhlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5Lmxlbmd0aCAtIHNpZ25hdHVyZS5sZW5ndGgpO1xuICAgIGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkuY29weShoYXNoLCAwLCAwLCBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5Lmxlbmd0aCAtIHNpZ25hdHVyZS5sZW5ndGgpO1xuXG4gICAgY29uc3QgbWVzc2FnZURpZ2VzdCA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpO1xuICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKGhhc2gpO1xuXG4gICAgY29uc3QgZGF0YVRvVmVyaWZ5OiBCdWZmZXIgPSBtZXNzYWdlRGlnZXN0LmRpZ2VzdCgpO1xuXG4gICAgaWYgKCFkYXRhVG9WZXJpZnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSGFzaCBzaG91bGQgbm90IGJlIG51bGwgd2hpbGUgZGVjcnlwdGluZyBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5LicpO1xuICAgIH1cblxuICAgIGNvbnN0IHZlcmlmeUtleSA9IGF3YWl0IGNyeXB0b0NsaWVudC52ZXJpZnkoJ1JTMjU2JywgZGF0YVRvVmVyaWZ5LCBzaWduYXR1cmUpO1xuICAgIGlmICghdmVyaWZ5S2V5LnJlc3VsdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgc3BlY2lmaWVkIGVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgY29tcHV0ZWQgd2l0aCB0aGUgY29sdW1uIG1hc3RlciBrZXkgKEFzeW1tZXRyaWMga2V5IGluIEF6dXJlIEtleSBWYXVsdCkgaW4gJHttYXN0ZXJLZXlQYXRofS4gVGhlIGVuY3J5cHRlZCBjb2x1bW4gZW5jcnlwdGlvbiBrZXkgbWF5IGJlIGNvcnJ1cHQsIG9yIHRoZSBzcGVjaWZpZWQgcGF0aCBtYXkgYmUgaW5jb3JyZWN0LmApO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY3J5cHRlZENFSzogQnVmZmVyID0gYXdhaXQgdGhpcy5henVyZUtleVZhdWx0VW5XcmFwKGNyeXB0b0NsaWVudCwgZW5jcnlwdGlvbkFsZ29yaXRobSwgY2lwaGVyVGV4dCk7XG5cbiAgICByZXR1cm4gZGVjcnlwdGVkQ0VLO1xuICB9XG5cbiAgYXN5bmMgZW5jcnlwdENvbHVtbkVuY3J5cHRpb25LZXkobWFzdGVyS2V5UGF0aDogc3RyaW5nLCBlbmNyeXB0aW9uQWxnb3JpdGhtOiBzdHJpbmcsIGNvbHVtbkVuY3J5cHRpb25LZXk6IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgaWYgKCFjb2x1bW5FbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbHVtbiBlbmNyeXB0aW9uIGtleSBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICB9XG5cbiAgICBpZiAoY29sdW1uRW5jcnlwdGlvbktleS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRW1wdHkgY29sdW1uIGVuY3J5cHRpb24ga2V5IHNwZWNpZmllZC4nKTtcbiAgICB9XG5cbiAgICBlbmNyeXB0aW9uQWxnb3JpdGhtID0gdGhpcy52YWxpZGF0ZUVuY3J5cHRpb25BbGdvcml0aG0oZW5jcnlwdGlvbkFsZ29yaXRobSk7XG5cbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmdldE1hc3RlcktleShtYXN0ZXJLZXlQYXRoKTtcblxuICAgIGNvbnN0IGtleVNpemVJbkJ5dGVzID0gdGhpcy5nZXRBS1ZLZXlTaXplKG1hc3RlcktleSk7XG5cbiAgICBjb25zdCBjcnlwdG9DbGllbnQgPSB0aGlzLmNyZWF0ZUNyeXB0b0NsaWVudChtYXN0ZXJLZXkpO1xuXG4gICAgY29uc3QgdmVyc2lvbiA9IEJ1ZmZlci5mcm9tKFt0aGlzLmZpcnN0VmVyc2lvblswXV0pO1xuXG4gICAgY29uc3QgbWFzdGVyS2V5UGF0aEJ5dGVzOiBCdWZmZXIgPSBCdWZmZXIuZnJvbShtYXN0ZXJLZXlQYXRoLnRvTG93ZXJDYXNlKCksICd1dGY4Jyk7XG5cbiAgICBjb25zdCBrZXlQYXRoTGVuZ3RoOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoMik7XG5cbiAgICBrZXlQYXRoTGVuZ3RoWzBdID0gbWFzdGVyS2V5UGF0aEJ5dGVzLmxlbmd0aCAmIDB4ZmY7XG4gICAga2V5UGF0aExlbmd0aFsxXSA9IG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGggPj4gOCAmIDB4ZmY7XG5cbiAgICBjb25zdCBjaXBoZXJUZXh0OiBCdWZmZXIgPSBhd2FpdCB0aGlzLmF6dXJlS2V5VmF1bHRXcmFwKGNyeXB0b0NsaWVudCwgZW5jcnlwdGlvbkFsZ29yaXRobSwgY29sdW1uRW5jcnlwdGlvbktleSk7XG5cbiAgICBjb25zdCBjaXBoZXJUZXh0TGVuZ3RoOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoMik7XG5cbiAgICBjaXBoZXJUZXh0TGVuZ3RoWzBdID0gY2lwaGVyVGV4dC5sZW5ndGggJiAweGZmO1xuICAgIGNpcGhlclRleHRMZW5ndGhbMV0gPSBjaXBoZXJUZXh0Lmxlbmd0aCA+PiA4ICYgMHhmZjtcblxuICAgIGlmIChjaXBoZXJUZXh0Lmxlbmd0aCAhPT0ga2V5U2l6ZUluQnl0ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2lwaGVyVGV4dCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggdGhlIFJTQSBrZXkgc2l6ZS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhVG9IYXNoOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2ModmVyc2lvbi5sZW5ndGggKyBrZXlQYXRoTGVuZ3RoLmxlbmd0aCArIGNpcGhlclRleHRMZW5ndGgubGVuZ3RoICsgbWFzdGVyS2V5UGF0aEJ5dGVzLmxlbmd0aCArIGNpcGhlclRleHQubGVuZ3RoKTtcbiAgICBsZXQgZGVzdGluYXRpb25Qb3NpdGlvbjogbnVtYmVyID0gdmVyc2lvbi5sZW5ndGg7XG4gICAgdmVyc2lvbi5jb3B5KGRhdGFUb0hhc2gsIDAsIDAsIHZlcnNpb24ubGVuZ3RoKTtcblxuICAgIGtleVBhdGhMZW5ndGguY29weShkYXRhVG9IYXNoLCBkZXN0aW5hdGlvblBvc2l0aW9uLCAwLCBrZXlQYXRoTGVuZ3RoLmxlbmd0aCk7XG4gICAgZGVzdGluYXRpb25Qb3NpdGlvbiArPSBrZXlQYXRoTGVuZ3RoLmxlbmd0aDtcblxuICAgIGNpcGhlclRleHRMZW5ndGguY29weShkYXRhVG9IYXNoLCBkZXN0aW5hdGlvblBvc2l0aW9uLCAwLCBjaXBoZXJUZXh0TGVuZ3RoLmxlbmd0aCk7XG4gICAgZGVzdGluYXRpb25Qb3NpdGlvbiArPSBjaXBoZXJUZXh0TGVuZ3RoLmxlbmd0aDtcblxuICAgIG1hc3RlcktleVBhdGhCeXRlcy5jb3B5KGRhdGFUb0hhc2gsIGRlc3RpbmF0aW9uUG9zaXRpb24sIDAsIG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGgpO1xuICAgIGRlc3RpbmF0aW9uUG9zaXRpb24gKz0gbWFzdGVyS2V5UGF0aEJ5dGVzLmxlbmd0aDtcblxuICAgIGNpcGhlclRleHQuY29weShkYXRhVG9IYXNoLCBkZXN0aW5hdGlvblBvc2l0aW9uLCAwLCBjaXBoZXJUZXh0Lmxlbmd0aCk7XG5cbiAgICBjb25zdCBtZXNzYWdlRGlnZXN0ID0gY3JlYXRlSGFzaCgnc2hhMjU2Jyk7XG5cbiAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShkYXRhVG9IYXNoKTtcblxuICAgIGNvbnN0IGRhdGFUb1NpZ246IEJ1ZmZlciA9IG1lc3NhZ2VEaWdlc3QuZGlnZXN0KCk7XG5cbiAgICBjb25zdCBzaWduZWRIYXNoOiBCdWZmZXIgPSBhd2FpdCB0aGlzLmF6dXJlS2V5VmF1bHRTaWduZWRIYXNoZWREYXRhKGNyeXB0b0NsaWVudCwgZGF0YVRvU2lnbik7XG4gICAgaWYgKHNpZ25lZEhhc2gubGVuZ3RoICE9PSBrZXlTaXplSW5CeXRlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTaWduZWQgaGFzaCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggdGhlIFJTQSBrZXkgc2l6ZS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJpZnlLZXkgPSBhd2FpdCBjcnlwdG9DbGllbnQudmVyaWZ5KCdSUzI1NicsIGRhdGFUb1NpZ24sIHNpZ25lZEhhc2gpO1xuXG4gICAgaWYgKCF2ZXJpZnlLZXkucmVzdWx0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIG9mIHRoZSBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IGNvbXB1dGVkLicpO1xuICAgIH1cblxuICAgIGNvbnN0IGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXlMZW5ndGg6IG51bWJlciA9IHZlcnNpb24ubGVuZ3RoICsgY2lwaGVyVGV4dExlbmd0aC5sZW5ndGggKyBrZXlQYXRoTGVuZ3RoLmxlbmd0aCArIGNpcGhlclRleHQubGVuZ3RoICsgbWFzdGVyS2V5UGF0aEJ5dGVzLmxlbmd0aCArIHNpZ25lZEhhc2gubGVuZ3RoO1xuICAgIGNvbnN0IGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXk6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5TGVuZ3RoKTtcblxuICAgIGxldCBjdXJyZW50SW5kZXggPSAwO1xuICAgIHZlcnNpb24uY29weShlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5LCBjdXJyZW50SW5kZXgsIDAsIHZlcnNpb24ubGVuZ3RoKTtcbiAgICBjdXJyZW50SW5kZXggKz0gdmVyc2lvbi5sZW5ndGg7XG5cbiAgICBrZXlQYXRoTGVuZ3RoLmNvcHkoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleSwgY3VycmVudEluZGV4LCAwLCBrZXlQYXRoTGVuZ3RoLmxlbmd0aCk7XG4gICAgY3VycmVudEluZGV4ICs9IGtleVBhdGhMZW5ndGgubGVuZ3RoO1xuXG4gICAgY2lwaGVyVGV4dExlbmd0aC5jb3B5KGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXksIGN1cnJlbnRJbmRleCwgMCwgY2lwaGVyVGV4dExlbmd0aC5sZW5ndGgpO1xuICAgIGN1cnJlbnRJbmRleCArPSBjaXBoZXJUZXh0TGVuZ3RoLmxlbmd0aDtcblxuICAgIG1hc3RlcktleVBhdGhCeXRlcy5jb3B5KGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXksIGN1cnJlbnRJbmRleCwgMCwgbWFzdGVyS2V5UGF0aEJ5dGVzLmxlbmd0aCk7XG4gICAgY3VycmVudEluZGV4ICs9IG1hc3RlcktleVBhdGhCeXRlcy5sZW5ndGg7XG5cbiAgICBjaXBoZXJUZXh0LmNvcHkoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleSwgY3VycmVudEluZGV4LCAwLCBjaXBoZXJUZXh0Lmxlbmd0aCk7XG4gICAgY3VycmVudEluZGV4ICs9IGNpcGhlclRleHQubGVuZ3RoO1xuXG4gICAgc2lnbmVkSGFzaC5jb3B5KGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXksIGN1cnJlbnRJbmRleCwgMCwgc2lnbmVkSGFzaC5sZW5ndGgpO1xuXG4gICAgcmV0dXJuIGVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldE1hc3RlcktleShtYXN0ZXJLZXlQYXRoOiBzdHJpbmcpOiBQcm9taXNlPEtleVZhdWx0S2V5PiB7XG4gICAgaWYgKCFtYXN0ZXJLZXlQYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01hc3RlciBrZXkgcGF0aCBjYW5ub3QgYmUgbnVsbCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG4gICAgY29uc3Qga2V5UGFydHMgPSB0aGlzLnBhcnNlUGF0aChtYXN0ZXJLZXlQYXRoKTtcblxuICAgIHRoaXMuY3JlYXRlS2V5Q2xpZW50KGtleVBhcnRzLnZhdWx0VXJsKTtcblxuICAgIHJldHVybiBhd2FpdCAodGhpcy5rZXlDbGllbnQgYXMgS2V5Q2xpZW50KS5nZXRLZXkoa2V5UGFydHMubmFtZSwga2V5UGFydHMudmVyc2lvbiA/IHsgdmVyc2lvbjoga2V5UGFydHMudmVyc2lvbiB9IDoge30pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVLZXlDbGllbnQoa2V5VmF1bHRVcmw6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICgha2V5VmF1bHRVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNyZWF0ZSBrZXkgY2xpZW50IHdpdGggbnVsbCBvciB1bmRlZmluZWQga2V5VmF1bHRVcmwnKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmtleUNsaWVudCkge1xuICAgICAgdGhpcy51cmwgPSBrZXlWYXVsdFVybDtcbiAgICAgIHRoaXMua2V5Q2xpZW50ID0gbmV3IEtleUNsaWVudChrZXlWYXVsdFVybCwgdGhpcy5jcmVkZW50aWFscyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDcnlwdG9DbGllbnQobWFzdGVyS2V5OiBLZXlWYXVsdEtleSk6IENyeXB0b2dyYXBoeUNsaWVudCB7XG4gICAgaWYgKCFtYXN0ZXJLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNyZWF0ZSBDcnlwdG9ncmFwaHlDbGllbnQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCBtYXN0ZXJLZXknKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBDcnlwdG9ncmFwaHlDbGllbnQobWFzdGVyS2V5LCB0aGlzLmNyZWRlbnRpYWxzKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VQYXRoKG1hc3RlcktleVBhdGg6IHN0cmluZyk6IFBhcnNlZEtleVBhdGgge1xuICAgIGlmICghbWFzdGVyS2V5UGF0aCB8fCBtYXN0ZXJLZXlQYXRoLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXp1cmUgS2V5IFZhdWx0IGtleSBwYXRoIGNhbm5vdCBiZSBudWxsLicpO1xuICAgIH1cblxuICAgIGxldCBiYXNlVXJpO1xuICAgIHRyeSB7XG4gICAgICBiYXNlVXJpID0gcGFyc2UobWFzdGVyS2V5UGF0aCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQga2V5cyBpZGVudGlmaWVyOiAke21hc3RlcktleVBhdGh9LiBOb3QgYSB2YWxpZCBVUklgKTtcbiAgICB9XG5cbiAgICBpZiAoIWJhc2VVcmkuaG9zdG5hbWUgfHwgIWJhc2VVcmkuaG9zdG5hbWUudG9Mb3dlckNhc2UoKS5lbmRzV2l0aCh0aGlzLmF6dXJlS2V5VmF1bHREb21haW5OYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIEF6dXJlIEtleSBWYXVsdCBrZXkgcGF0aCBzcGVjaWZpZWQ6ICR7bWFzdGVyS2V5UGF0aH0uYCk7XG4gICAgfVxuXG4gICAgLy8gUGF0aCBpcyBvZiB0aGUgZm9ybSAnL2NvbGxlY3Rpb24vbmFtZVsvdmVyc2lvbl0nXG4gICAgY29uc3Qgc2VnbWVudHMgPSAoYmFzZVVyaS5wYXRobmFtZSB8fCAnJykuc3BsaXQoJy8nKTtcbiAgICBpZiAoc2VnbWVudHMubGVuZ3RoICE9PSAzICYmIHNlZ21lbnRzLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBrZXlzIGlkZW50aWZpZXI6ICR7bWFzdGVyS2V5UGF0aH0uIEJhZCBudW1iZXIgb2Ygc2VnbWVudHM6ICR7c2VnbWVudHMubGVuZ3RofWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCdrZXlzJyAhPT0gc2VnbWVudHNbMV0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQga2V5cyBpZGVudGlmaWVyOiAke21hc3RlcktleVBhdGh9LiBzZWdtZW50IFsxXSBzaG91bGQgYmUgXCJrZXlzXCIsIGZvdW5kIFwiJHtzZWdtZW50c1sxXX1cImBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgdmF1bHRVcmwgPSBgJHtiYXNlVXJpLnByb3RvY29sfS8vJHtiYXNlVXJpLmhvc3R9YDtcbiAgICBjb25zdCBuYW1lID0gc2VnbWVudHNbMl07XG4gICAgY29uc3QgdmVyc2lvbiA9IHNlZ21lbnRzLmxlbmd0aCA9PT0gNCA/IHNlZ21lbnRzWzNdIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB7XG4gICAgICB2YXVsdFVybCxcbiAgICAgIG5hbWUsXG4gICAgICB2ZXJzaW9uXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYXp1cmVLZXlWYXVsdFNpZ25lZEhhc2hlZERhdGEoY3J5cHRvQ2xpZW50OiBDcnlwdG9ncmFwaHlDbGllbnQsIGRhdGFUb1NpZ246IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgaWYgKCFjcnlwdG9DbGllbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXp1cmUgS1ZTIENyeXB0byBDbGllbnQgaXMgbm90IGRlZmluZWQuJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2lnbmVkRGF0YSA9IGF3YWl0IGNyeXB0b0NsaWVudC5zaWduKCdSUzI1NicsIGRhdGFUb1NpZ24pO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNpZ25lZERhdGEucmVzdWx0KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYXp1cmVLZXlWYXVsdFdyYXAoY3J5cHRvQ2xpZW50OiBDcnlwdG9ncmFwaHlDbGllbnQsIGVuY3J5cHRpb25BbGdvcml0aG06IHN0cmluZywgY29sdW1uRW5jcnlwdGlvbktleTogQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBpZiAoIWNyeXB0b0NsaWVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBenVyZSBLVlMgQ3J5cHRvIENsaWVudCBpcyBub3QgZGVmaW5lZC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWNvbHVtbkVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29sdW1uIGVuY3J5cHRpb24ga2V5IGNhbm5vdCBiZSBudWxsLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHdyYXBwZWRLZXkgPSBhd2FpdCBjcnlwdG9DbGllbnQud3JhcEtleShlbmNyeXB0aW9uQWxnb3JpdGhtIGFzIEtleVdyYXBBbGdvcml0aG0sIGNvbHVtbkVuY3J5cHRpb25LZXkpO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHdyYXBwZWRLZXkucmVzdWx0KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYXp1cmVLZXlWYXVsdFVuV3JhcChjcnlwdG9DbGllbnQ6IENyeXB0b2dyYXBoeUNsaWVudCwgZW5jcnlwdGlvbkFsZ29yaXRobTogc3RyaW5nLCBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5OiBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGlmICghY3J5cHRvQ2xpZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F6dXJlIEtWUyBDcnlwdG8gQ2xpZW50IGlzIG5vdCBkZWZpbmVkLicpO1xuICAgIH1cblxuICAgIGlmICghZW5jcnlwdGlvbkFsZ29yaXRobSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbmNyeXB0aW9uIEFsZ29yaXRobSBjYW5ub3QgYmUgbnVsbCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIWVuY3J5cHRlZENvbHVtbkVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGVkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICB9XG5cbiAgICBpZiAoZW5jcnlwdGVkQ29sdW1uRW5jcnlwdGlvbktleS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGVkIENvbHVtbiBFbmNyeXB0aW9uIEtleSBsZW5ndGggc2hvdWxkIG5vdCBiZSB6ZXJvLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHVud3JhcHBlZEtleSA9IGF3YWl0IGNyeXB0b0NsaWVudC51bndyYXBLZXkoZW5jcnlwdGlvbkFsZ29yaXRobSBhcyBLZXlXcmFwQWxnb3JpdGhtLCBlbmNyeXB0ZWRDb2x1bW5FbmNyeXB0aW9uS2V5KTtcblxuICAgIHJldHVybiBCdWZmZXIuZnJvbSh1bndyYXBwZWRLZXkucmVzdWx0KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QUtWS2V5U2l6ZShyZXRyaWV2ZWRLZXk6IEtleVZhdWx0S2V5KTogbnVtYmVyIHtcbiAgICBpZiAoIXJldHJpZXZlZEtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXRyaWV2ZWQga2V5IGNhbm5vdCBiZSBudWxsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCBrZXkgPSByZXRyaWV2ZWRLZXkua2V5O1xuXG4gICAgaWYgKCFrZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgS2V5IGRvZXMgbm90IGV4aXN0ICR7cmV0cmlldmVkS2V5Lm5hbWV9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qga3R5OiBzdHJpbmcgfCB1bmRlZmluZWQgPSBrZXkgJiYga2V5Lmt0eSAmJiBrZXkua3R5LnRvU3RyaW5nKCkudG9VcHBlckNhc2UoKTtcblxuICAgIGlmICgha3R5IHx8ICdSU0EnLmxvY2FsZUNvbXBhcmUoa3R5LCAnZW4nKSAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgdXNlIGEgbm9uLVJTQSBrZXk6ICR7a3R5fS5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlMZW5ndGggPSBrZXkgJiYga2V5Lm4gJiYga2V5Lm4ubGVuZ3RoO1xuXG4gICAgcmV0dXJuIGtleUxlbmd0aCB8fCAwO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUVuY3J5cHRpb25BbGdvcml0aG0oZW5jcnlwdGlvbkFsZ29yaXRobTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWVuY3J5cHRpb25BbGdvcml0aG0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignS2V5IGVuY3J5cHRpb24gYWxnb3JpdGhtIGNhbm5vdCBiZSBudWxsLicpO1xuICAgIH1cblxuICAgIGlmICgnUlNBX09BRVAnLmxvY2FsZUNvbXBhcmUoZW5jcnlwdGlvbkFsZ29yaXRobS50b1VwcGVyQ2FzZSgpLCAnZW4nKSA9PT0gMCkge1xuICAgICAgZW5jcnlwdGlvbkFsZ29yaXRobSA9ICdSU0EtT0FFUCc7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucnNhRW5jcnlwdGlvbkFsZ29yaXRobVdpdGhPQUVQRm9yQUtWLmxvY2FsZUNvbXBhcmUoZW5jcnlwdGlvbkFsZ29yaXRobS50cmltKCkudG9VcHBlckNhc2UoKSwgJ2VuJykgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBrZXkgZW5jcnlwdGlvbiBhbGdvcml0aG0gc3BlY2lmaWVkOiAke2VuY3J5cHRpb25BbGdvcml0aG19LiBFeHBlY3RlZCB2YWx1ZTogJHt0aGlzLnJzYUVuY3J5cHRpb25BbGdvcml0aG1XaXRoT0FFUEZvckFLVn0uYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVuY3J5cHRpb25BbGdvcml0aG07XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsSUFBQUEsU0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsYUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsSUFBQSxHQUFBSCxPQUFBO0FBTkE7QUFDQTs7QUFhTyxNQUFNSSxxQ0FBcUMsQ0FBQztFQUNqQ0MsSUFBSTtFQUNaQyxHQUFHO0VBQ01DLG9DQUFvQztFQUNwQ0MsWUFBWTtFQUNyQkMsV0FBVztFQUNGQyx1QkFBdUI7RUFDaENDLFNBQVM7RUFFakJDLFdBQVdBLENBQUNDLFFBQWdCLEVBQUVDLFNBQWlCLEVBQUVDLFFBQWdCLEVBQUU7SUFDakUsSUFBSSxDQUFDVixJQUFJLEdBQUcsaUJBQWlCO0lBQzdCLElBQUksQ0FBQ0ssdUJBQXVCLEdBQUcsaUJBQWlCO0lBQ2hELElBQUksQ0FBQ0gsb0NBQW9DLEdBQUcsVUFBVTtJQUN0RCxJQUFJLENBQUNDLFlBQVksR0FBR1EsTUFBTSxDQUFDQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxJQUFJLENBQUNSLFdBQVcsR0FBRyxJQUFJUyxn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
|