tedious 16.2.0 → 16.4.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.
Files changed (205) hide show
  1. package/lib/all-headers.js +1 -2
  2. package/lib/all-headers.js.map +1 -0
  3. package/lib/always-encrypted/aead-aes-256-cbc-hmac-algorithm.js +9 -31
  4. package/lib/always-encrypted/aead-aes-256-cbc-hmac-algorithm.js.map +1 -0
  5. package/lib/always-encrypted/aead-aes-256-cbc-hmac-encryption-key.js +9 -24
  6. package/lib/always-encrypted/aead-aes-256-cbc-hmac-encryption-key.js.map +1 -0
  7. package/lib/always-encrypted/cek-entry.js +8 -12
  8. package/lib/always-encrypted/cek-entry.js.map +1 -0
  9. package/lib/always-encrypted/get-parameter-encryption-metadata.js +2 -24
  10. package/lib/always-encrypted/get-parameter-encryption-metadata.js.map +1 -0
  11. package/lib/always-encrypted/key-crypto.js +5 -30
  12. package/lib/always-encrypted/key-crypto.js.map +1 -0
  13. package/lib/always-encrypted/keystore-provider-azure-key-vault.js +11 -72
  14. package/lib/always-encrypted/keystore-provider-azure-key-vault.js.map +1 -0
  15. package/lib/always-encrypted/symmetric-key-cache.js +2 -13
  16. package/lib/always-encrypted/symmetric-key-cache.js.map +1 -0
  17. package/lib/always-encrypted/symmetric-key.js +3 -8
  18. package/lib/always-encrypted/symmetric-key.js.map +1 -0
  19. package/lib/always-encrypted/types.js +19 -27
  20. package/lib/always-encrypted/types.js.map +1 -0
  21. package/lib/always-encrypted/utils.js +2 -6
  22. package/lib/always-encrypted/utils.js.map +1 -0
  23. package/lib/bulk-load-payload.js +7 -15
  24. package/lib/bulk-load-payload.js.map +1 -0
  25. package/lib/bulk-load.js +58 -131
  26. package/lib/bulk-load.js.map +1 -0
  27. package/lib/collation.js +7 -15
  28. package/lib/collation.js.map +1 -0
  29. package/lib/connection.js +307 -534
  30. package/lib/connection.js.map +1 -0
  31. package/lib/connector.js +6 -37
  32. package/lib/connector.js.map +1 -0
  33. package/lib/data-type.js +2 -43
  34. package/lib/data-type.js.map +1 -0
  35. package/lib/data-types/bigint.js +1 -15
  36. package/lib/data-types/bigint.js.map +1 -0
  37. package/lib/data-types/binary.js +1 -12
  38. package/lib/data-types/binary.js.map +1 -0
  39. package/lib/data-types/bit.js +1 -11
  40. package/lib/data-types/bit.js.map +1 -0
  41. package/lib/data-types/bitn.js +1 -7
  42. package/lib/data-types/bitn.js.map +1 -0
  43. package/lib/data-types/char.js +1 -20
  44. package/lib/data-types/char.js.map +1 -0
  45. package/lib/data-types/date.js +1 -15
  46. package/lib/data-types/date.js.map +1 -0
  47. package/lib/data-types/datetime.js +3 -20
  48. package/lib/data-types/datetime.js.map +1 -0
  49. package/lib/data-types/datetime2.js +1 -26
  50. package/lib/data-types/datetime2.js.map +1 -0
  51. package/lib/data-types/datetimen.js +1 -7
  52. package/lib/data-types/datetimen.js.map +1 -0
  53. package/lib/data-types/datetimeoffset.js +1 -23
  54. package/lib/data-types/datetimeoffset.js.map +1 -0
  55. package/lib/data-types/decimal.js +1 -18
  56. package/lib/data-types/decimal.js.map +1 -0
  57. package/lib/data-types/decimaln.js +1 -7
  58. package/lib/data-types/decimaln.js.map +1 -0
  59. package/lib/data-types/float.js +1 -13
  60. package/lib/data-types/float.js.map +1 -0
  61. package/lib/data-types/floatn.js +1 -7
  62. package/lib/data-types/floatn.js.map +1 -0
  63. package/lib/data-types/image.js +1 -10
  64. package/lib/data-types/image.js.map +1 -0
  65. package/lib/data-types/int.js +1 -14
  66. package/lib/data-types/int.js.map +1 -0
  67. package/lib/data-types/intn.js +1 -7
  68. package/lib/data-types/intn.js.map +1 -0
  69. package/lib/data-types/money.js +1 -12
  70. package/lib/data-types/money.js.map +1 -0
  71. package/lib/data-types/moneyn.js +1 -7
  72. package/lib/data-types/moneyn.js.map +1 -0
  73. package/lib/data-types/nchar.js +1 -14
  74. package/lib/data-types/nchar.js.map +1 -0
  75. package/lib/data-types/ntext.js +1 -10
  76. package/lib/data-types/ntext.js.map +1 -0
  77. package/lib/data-types/null.js +1 -7
  78. package/lib/data-types/null.js.map +1 -0
  79. package/lib/data-types/numeric.js +1 -18
  80. package/lib/data-types/numeric.js.map +1 -0
  81. package/lib/data-types/numericn.js +1 -7
  82. package/lib/data-types/numericn.js.map +1 -0
  83. package/lib/data-types/nvarchar.js +1 -22
  84. package/lib/data-types/nvarchar.js.map +1 -0
  85. package/lib/data-types/real.js +1 -13
  86. package/lib/data-types/real.js.map +1 -0
  87. package/lib/data-types/smalldatetime.js +1 -14
  88. package/lib/data-types/smalldatetime.js.map +1 -0
  89. package/lib/data-types/smallint.js +1 -14
  90. package/lib/data-types/smallint.js.map +1 -0
  91. package/lib/data-types/smallmoney.js +1 -13
  92. package/lib/data-types/smallmoney.js.map +1 -0
  93. package/lib/data-types/sql-variant.js +1 -6
  94. package/lib/data-types/sql-variant.js.map +1 -0
  95. package/lib/data-types/text.js +1 -18
  96. package/lib/data-types/text.js.map +1 -0
  97. package/lib/data-types/time.js +1 -22
  98. package/lib/data-types/time.js.map +1 -0
  99. package/lib/data-types/tinyint.js +1 -14
  100. package/lib/data-types/tinyint.js.map +1 -0
  101. package/lib/data-types/tvp.js +11 -27
  102. package/lib/data-types/tvp.js.map +1 -0
  103. package/lib/data-types/udt.js +1 -7
  104. package/lib/data-types/udt.js.map +1 -0
  105. package/lib/data-types/uniqueidentifier.js +1 -11
  106. package/lib/data-types/uniqueidentifier.js.map +1 -0
  107. package/lib/data-types/varbinary.js +1 -22
  108. package/lib/data-types/varbinary.js.map +1 -0
  109. package/lib/data-types/varchar.js +1 -23
  110. package/lib/data-types/varchar.js.map +1 -0
  111. package/lib/data-types/xml.js +1 -7
  112. package/lib/data-types/xml.js.map +1 -0
  113. package/lib/debug.js +4 -16
  114. package/lib/debug.js.map +1 -0
  115. package/lib/errors/abort-error.js +2 -5
  116. package/lib/errors/abort-error.js.map +1 -0
  117. package/lib/errors/timeout-error.js +2 -5
  118. package/lib/errors/timeout-error.js.map +1 -0
  119. package/lib/errors.js +10 -16
  120. package/lib/errors.js.map +1 -0
  121. package/lib/guid-parser.js +1 -7
  122. package/lib/guid-parser.js.map +1 -0
  123. package/lib/incoming-message-stream.js +9 -29
  124. package/lib/incoming-message-stream.js.map +1 -0
  125. package/lib/instance-lookup.js +3 -34
  126. package/lib/instance-lookup.js.map +1 -0
  127. package/lib/library.js +1 -1
  128. package/lib/library.js.map +1 -0
  129. package/lib/login7-payload.js +99 -100
  130. package/lib/login7-payload.js.map +1 -0
  131. package/lib/message-io.js +17 -45
  132. package/lib/message-io.js.map +1 -0
  133. package/lib/message.js +4 -8
  134. package/lib/message.js.map +1 -0
  135. package/lib/metadata-parser.js +1 -22
  136. package/lib/metadata-parser.js.map +1 -0
  137. package/lib/ntlm-payload.js +2 -22
  138. package/lib/ntlm-payload.js.map +1 -0
  139. package/lib/ntlm.js +1 -4
  140. package/lib/ntlm.js.map +1 -0
  141. package/lib/outgoing-message-stream.js +12 -21
  142. package/lib/outgoing-message-stream.js.map +1 -0
  143. package/lib/packet.js +2 -47
  144. package/lib/packet.js.map +1 -0
  145. package/lib/prelogin-payload.js +11 -54
  146. package/lib/prelogin-payload.js.map +1 -0
  147. package/lib/request.js +88 -66
  148. package/lib/request.js.map +1 -0
  149. package/lib/rpcrequest-payload.js +8 -35
  150. package/lib/rpcrequest-payload.js.map +1 -0
  151. package/lib/sender.js +1 -24
  152. package/lib/sender.js.map +1 -0
  153. package/lib/special-stored-procedure.js +1 -1
  154. package/lib/special-stored-procedure.js.map +1 -0
  155. package/lib/sqlbatch-payload.js +5 -18
  156. package/lib/sqlbatch-payload.js.map +1 -0
  157. package/lib/tds-versions.js +3 -3
  158. package/lib/tds-versions.js.map +1 -0
  159. package/lib/tedious.js +1 -12
  160. package/lib/tedious.js.map +1 -0
  161. package/lib/token/colmetadata-token-parser.js +1 -17
  162. package/lib/token/colmetadata-token-parser.js.map +1 -0
  163. package/lib/token/done-token-parser.js +2 -8
  164. package/lib/token/done-token-parser.js.map +1 -0
  165. package/lib/token/env-change-token-parser.js +7 -28
  166. package/lib/token/env-change-token-parser.js.map +1 -0
  167. package/lib/token/feature-ext-ack-parser.js +1 -10
  168. package/lib/token/feature-ext-ack-parser.js.map +1 -0
  169. package/lib/token/fedauth-info-parser.js +2 -10
  170. package/lib/token/fedauth-info-parser.js.map +1 -0
  171. package/lib/token/handler.js +39 -149
  172. package/lib/token/handler.js.map +1 -0
  173. package/lib/token/infoerror-token-parser.js +1 -5
  174. package/lib/token/infoerror-token-parser.js.map +1 -0
  175. package/lib/token/loginack-token-parser.js +1 -6
  176. package/lib/token/loginack-token-parser.js.map +1 -0
  177. package/lib/token/nbcrow-token-parser.js +2 -15
  178. package/lib/token/nbcrow-token-parser.js.map +1 -0
  179. package/lib/token/order-token-parser.js +2 -7
  180. package/lib/token/order-token-parser.js.map +1 -0
  181. package/lib/token/returnstatus-token-parser.js +2 -4
  182. package/lib/token/returnstatus-token-parser.js.map +1 -0
  183. package/lib/token/returnvalue-token-parser.js +4 -9
  184. package/lib/token/returnvalue-token-parser.js.map +1 -0
  185. package/lib/token/row-token-parser.js +2 -11
  186. package/lib/token/row-token-parser.js.map +1 -0
  187. package/lib/token/sspi-token-parser.js +1 -5
  188. package/lib/token/sspi-token-parser.js.map +1 -0
  189. package/lib/token/stream-parser.js +24 -86
  190. package/lib/token/stream-parser.js.map +1 -0
  191. package/lib/token/token-stream-parser.js +4 -13
  192. package/lib/token/token-stream-parser.js.map +1 -0
  193. package/lib/token/token.js +88 -168
  194. package/lib/token/token.js.map +1 -0
  195. package/lib/tracking-buffer/writable-tracking-buffer.js +20 -60
  196. package/lib/tracking-buffer/writable-tracking-buffer.js.map +1 -0
  197. package/lib/transaction.js +9 -33
  198. package/lib/transaction.js.map +1 -0
  199. package/lib/transient-error-lookup.js +1 -4
  200. package/lib/transient-error-lookup.js.map +1 -0
  201. package/lib/utils/with-timeout.js +1 -9
  202. package/lib/utils/with-timeout.js.map +1 -0
  203. package/lib/value-parser.js +1 -143
  204. package/lib/value-parser.js.map +1 -0
  205. 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
- } // if (!md.cipherAlgorithm) {
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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ2YWxpZGF0ZUFuZEdldEVuY3J5cHRpb25BbGdvcml0aG1OYW1lIiwiY2lwaGVyQWxnb3JpdGhtSWQiLCJjaXBoZXJBbGdvcml0aG1OYW1lIiwiRXJyb3IiLCJhbGdvcml0aG1OYW1lIiwiZW5jcnlwdFdpdGhLZXkiLCJwbGFpbnRleHQiLCJtZCIsIm9wdGlvbnMiLCJ0cnVzdGVkU2VydmVyTmFtZUFFIiwiY2lwaGVyQWxnb3JpdGhtIiwiZGVjcnlwdFN5bW1ldHJpY0tleSIsImNpcGhlclRleHQiLCJlbmNyeXB0RGF0YSIsImRlY3J5cHRXaXRoS2V5IiwicGxhaW5UZXh0IiwiZGVjcnlwdERhdGEiLCJjZWtFbnRyeSIsImNvbHVtbkVuY3J5cHRpb25LZXlWYWx1ZXMiLCJzeW1LZXkiLCJlbmNyeXB0aW9uS2V5SW5mb0Nob3NlbiIsIkNFS1ZhbHVlcyIsImxhc3RFcnJvciIsIkNFS1ZhbHVlIiwiZXJyb3IiLCJBZWFkQWVzMjU2Q2JjSG1hYzI1NkFsZ29yaXRobSIsIkFlYWRBZXMyNTZDYmNIbWFjMjU2RW5jcnlwdGlvbktleSIsInJvb3RLZXkiLCJlbmNyeXB0aW9uVHlwZSIsImVuY3J5cHRpb25LZXlJbmZvIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Fsd2F5cy1lbmNyeXB0ZWQva2V5LWNyeXB0by50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGlzIGNvZGUgaXMgYmFzZWQgb24gdGhlIGBtc3NxbC1qZGJjYCBsaWJyYXJ5IHB1Ymxpc2hlZCB1bmRlciB0aGUgY29uZGl0aW9ucyBvZiBNSVQgbGljZW5zZS5cbi8vIENvcHlyaWdodCAoYykgMjAxOSBNaWNyb3NvZnQgQ29ycG9yYXRpb25cblxuaW1wb3J0IHsgQ3J5cHRvTWV0YWRhdGEsIEVuY3J5cHRpb25LZXlJbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBJbnRlcm5hbENvbm5lY3Rpb25PcHRpb25zIGFzIENvbm5lY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vY29ubmVjdGlvbic7XG5pbXBvcnQgU3ltbWV0cmljS2V5IGZyb20gJy4vc3ltbWV0cmljLWtleSc7XG5pbXBvcnQgeyBnZXRLZXkgfSBmcm9tICcuL3N5bW1ldHJpYy1rZXktY2FjaGUnO1xuaW1wb3J0IHsgQWVhZEFlczI1NkNiY0htYWMyNTZBbGdvcml0aG0sIGFsZ29yaXRobU5hbWUgfSBmcm9tICcuL2FlYWQtYWVzLTI1Ni1jYmMtaG1hYy1hbGdvcml0aG0nO1xuaW1wb3J0IHsgQWVhZEFlczI1NkNiY0htYWMyNTZFbmNyeXB0aW9uS2V5IH0gZnJvbSAnLi9hZWFkLWFlcy0yNTYtY2JjLWhtYWMtZW5jcnlwdGlvbi1rZXknO1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVBbmRHZXRFbmNyeXB0aW9uQWxnb3JpdGhtTmFtZSA9IChjaXBoZXJBbGdvcml0aG1JZDogbnVtYmVyLCBjaXBoZXJBbGdvcml0aG1OYW1lPzogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKGNpcGhlckFsZ29yaXRobUlkICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDdXN0b20gY2lwaGVyIGFsZ29yaXRobSBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG5cbiAgcmV0dXJuIGFsZ29yaXRobU5hbWU7XG59O1xuXG5leHBvcnQgY29uc3QgZW5jcnlwdFdpdGhLZXkgPSBhc3luYyAocGxhaW50ZXh0OiBCdWZmZXIsIG1kOiBDcnlwdG9NZXRhZGF0YSwgb3B0aW9uczogQ29ubmVjdGlvbk9wdGlvbnMpOiBQcm9taXNlPEJ1ZmZlcj4gPT4ge1xuICBpZiAoIW9wdGlvbnMudHJ1c3RlZFNlcnZlck5hbWVBRSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2VydmVyIG5hbWUgc2hvdWxkIG5vdCBiZSBudWxsIGluIEVuY3J5cHRXaXRoS2V5Jyk7XG4gIH1cblxuICBpZiAoIW1kLmNpcGhlckFsZ29yaXRobSkge1xuICAgIGF3YWl0IGRlY3J5cHRTeW1tZXRyaWNLZXkobWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgaWYgKCFtZC5jaXBoZXJBbGdvcml0aG0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NpcGhlciBBbGdvcml0aG0gc2hvdWxkIG5vdCBiZSBudWxsIGluIEVuY3J5cHRXaXRoS2V5Jyk7XG4gIH1cblxuICBjb25zdCBjaXBoZXJUZXh0OiBCdWZmZXIgPSBtZC5jaXBoZXJBbGdvcml0aG0uZW5jcnlwdERhdGEocGxhaW50ZXh0KTtcblxuICBpZiAoIWNpcGhlclRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGVycm9yLiBDaXBoZXJ0ZXh0IHZhbHVlIGNhbm5vdCBiZSBudWxsLicpO1xuICB9XG5cbiAgcmV0dXJuIGNpcGhlclRleHQ7XG59O1xuXG5leHBvcnQgY29uc3QgZGVjcnlwdFdpdGhLZXkgPSAoY2lwaGVyVGV4dDogQnVmZmVyLCBtZDogQ3J5cHRvTWV0YWRhdGEsIG9wdGlvbnM6IENvbm5lY3Rpb25PcHRpb25zKTogQnVmZmVyID0+IHtcbiAgaWYgKCFvcHRpb25zLnRydXN0ZWRTZXJ2ZXJOYW1lQUUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZlciBuYW1lIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0V2l0aEtleScpO1xuICB9XG5cbiAgLy8gaWYgKCFtZC5jaXBoZXJBbGdvcml0aG0pIHtcbiAgLy8gICBhd2FpdCBkZWNyeXB0U3ltbWV0cmljS2V5KG1kLCBvcHRpb25zKTtcbiAgLy8gfVxuXG4gIGlmICghbWQuY2lwaGVyQWxnb3JpdGhtKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDaXBoZXIgQWxnb3JpdGhtIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0V2l0aEtleScpO1xuICB9XG5cbiAgY29uc3QgcGxhaW5UZXh0OiBCdWZmZXIgPSBtZC5jaXBoZXJBbGdvcml0aG0uZGVjcnlwdERhdGEoY2lwaGVyVGV4dCk7XG5cbiAgaWYgKCFwbGFpblRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGVycm9yLiBQbGFpbnRleHQgdmFsdWUgY2Fubm90IGJlIG51bGwuJyk7XG4gIH1cblxuICByZXR1cm4gcGxhaW5UZXh0O1xufTtcblxuZXhwb3J0IGNvbnN0IGRlY3J5cHRTeW1tZXRyaWNLZXkgPSBhc3luYyAobWQ6IENyeXB0b01ldGFkYXRhLCBvcHRpb25zOiBDb25uZWN0aW9uT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIW1kKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZCBzaG91bGQgbm90IGJlIG51bGwgaW4gRGVjcnlwdFN5bW1ldHJpY0tleS4nKTtcbiAgfVxuXG4gIGlmICghbWQuY2VrRW50cnkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21kLkVuY3J5cHRpb25JbmZvIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0U3ltbWV0cmljS2V5LicpO1xuICB9XG5cbiAgaWYgKCFtZC5jZWtFbnRyeS5jb2x1bW5FbmNyeXB0aW9uS2V5VmFsdWVzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZC5FbmNyeXB0aW9uSW5mby5Db2x1bW5FbmNyeXB0aW9uS2V5VmFsdWVzIHNob3VsZCBub3QgYmUgbnVsbCBpbiBEZWNyeXB0U3ltbWV0cmljS2V5LicpO1xuICB9XG5cbiAgbGV0IHN5bUtleTogU3ltbWV0cmljS2V5IHwgdW5kZWZpbmVkO1xuICBsZXQgZW5jcnlwdGlvbktleUluZm9DaG9zZW46IEVuY3J5cHRpb25LZXlJbmZvIHwgdW5kZWZpbmVkO1xuICBjb25zdCBDRUtWYWx1ZXM6IEVuY3J5cHRpb25LZXlJbmZvW10gPSBtZC5jZWtFbnRyeS5jb2x1bW5FbmNyeXB0aW9uS2V5VmFsdWVzO1xuICBsZXQgbGFzdEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcblxuICBmb3IgKGNvbnN0IENFS1ZhbHVlIG9mIENFS1ZhbHVlcykge1xuICAgIHRyeSB7XG4gICAgICBzeW1LZXkgPSBhd2FpdCBnZXRLZXkoQ0VLVmFsdWUsIG9wdGlvbnMpO1xuICAgICAgaWYgKHN5bUtleSkge1xuICAgICAgICBlbmNyeXB0aW9uS2V5SW5mb0Nob3NlbiA9IENFS1ZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBsYXN0RXJyb3IgPSBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBpZiAoIXN5bUtleSkge1xuICAgIGlmIChsYXN0RXJyb3IpIHtcbiAgICAgIHRocm93IGxhc3RFcnJvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeGNlcHRpb24gd2hpbGUgZGVjcnlwdGlvbiBvZiBlbmNyeXB0ZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5LicpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGFsZ29yaXRobU5hbWUgPSB2YWxpZGF0ZUFuZEdldEVuY3J5cHRpb25BbGdvcml0aG1OYW1lKG1kLmNpcGhlckFsZ29yaXRobUlkLCBtZC5jaXBoZXJBbGdvcml0aG1OYW1lKTtcbiAgY29uc3QgY2lwaGVyQWxnb3JpdGhtID0gbmV3IEFlYWRBZXMyNTZDYmNIbWFjMjU2QWxnb3JpdGhtKG5ldyBBZWFkQWVzMjU2Q2JjSG1hYzI1NkVuY3J5cHRpb25LZXkoc3ltS2V5LnJvb3RLZXksIGFsZ29yaXRobU5hbWUpLCBtZC5lbmNyeXB0aW9uVHlwZSk7XG5cbiAgbWQuY2lwaGVyQWxnb3JpdGhtID0gY2lwaGVyQWxnb3JpdGhtO1xuICBtZC5lbmNyeXB0aW9uS2V5SW5mbyA9IGVuY3J5cHRpb25LZXlJbmZvQ2hvc2VuIGFzIEVuY3J5cHRpb25LZXlJbmZvO1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQU1BOztBQUNBOztBQUNBOztBQVJBO0FBQ0E7QUFTTyxNQUFNQSxxQ0FBcUMsR0FBRyxDQUFDQyxpQkFBRCxFQUE0QkMsbUJBQTVCLEtBQXFFO0VBQ3hILElBQUlELGlCQUFpQixLQUFLLENBQTFCLEVBQTZCO0lBQzNCLE1BQU0sSUFBSUUsS0FBSixDQUFVLHdDQUFWLENBQU47RUFDRDs7RUFFRCxPQUFPQyx5Q0FBUDtBQUNELENBTk07Ozs7QUFRQSxNQUFNQyxj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
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
- } // Path is of the form '/collection/name[/version]'
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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