@cubist-labs/cubesigner-sdk-key-import 0.4.254 → 0.4.260

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.
@@ -1 +1 @@
1
- {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,GAAG,EACH,OAAO,EACP,GAAG,EACH,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AAiBpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA0LnD;;GAEG;AACH,qBAAa,WAAW;;IAOtB;;;;OAIG;gBACS,EAAE,EAAE,GAAG;IAoDnB;;;;;;;OAOG;IACU,eAAe,CAC1B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,gBAAgB,EAAE,EACxB,KAAK,CAAC,EAAE,yBAAyB,GAChC,OAAO,CAAC,GAAG,EAAE,CAAC;IAQjB;;;;;;;OAOG;IACU,mBAAmB,CAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,CAAC,EAAE,yBAAyB,GAChC,OAAO,CAAC,GAAG,EAAE,CAAC;CA+FlB"}
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,GAAG,EACH,OAAO,EACP,GAAG,EACH,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQnD;;GAEG;AACH,qBAAa,WAAW;;IAItB;;;;OAIG;gBACS,EAAE,EAAE,GAAG;IAmBnB;;;;;;;OAOG;IACU,eAAe,CAC1B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,gBAAgB,EAAE,EACxB,KAAK,CAAC,EAAE,yBAAyB,GAChC,OAAO,CAAC,GAAG,EAAE,CAAC;IAQjB;;;;;;;OAOG;IACU,mBAAmB,CAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,CAAC,EAAE,yBAAyB,GAChC,OAAO,CAAC,GAAG,EAAE,CAAC;CAgElB"}
package/dist/import.js CHANGED
@@ -10,143 +10,15 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _WrappedImportKey_instances, _WrappedImportKey_enclaveAttestation, _WrappedImportKey_enclaveSignature, _WrappedImportKey_verifyImportKey, _WrappedImportKey_signedData, _KeyImporter_instances, _KeyImporter_wrappedImportKey, _KeyImporter_subtleCrypto, _KeyImporter_publicKeyHandle, _KeyImporter_hpkeSuite, _KeyImporter_cs, _KeyImporter_getWrappedImportAndPubKey, _KeyImporter_getSubtleCrypto, _KeyImporter_importPackages, _KeyImporter_encrypt;
13
+ var _KeyImporter_instances, _KeyImporter_wrappedImportKey, _KeyImporter_cs, _KeyImporter_getWrappedImportKey, _KeyImporter_importPackages;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.KeyImporter = void 0;
16
16
  const cubesigner_sdk_1 = require("@cubist-labs/cubesigner-sdk");
17
- const core_1 = require("@hpke/core");
18
- const asn1_ecc_1 = require("@peculiar/asn1-ecc");
19
- const asn1_schema_1 = require("@peculiar/asn1-schema");
20
- const x509_1 = require("@peculiar/x509");
21
17
  const mnemonic_1 = require("./mnemonic");
22
18
  const raw_1 = require("./raw");
23
- const util_1 = require("./util");
24
- // domain-separation tag used when generating signing hash for import key
25
- const IMPORT_KEY_SIGNING_DST = new TextEncoder().encode("CUBESIGNER_EPHEMERAL_IMPORT_P384");
26
- // attestation document slack times
27
- const MAX_ATTESTATION_AGE_MINUTES = 15n;
28
- const MAX_ATTESTATION_FUTURE_MINUTES = 5n;
29
- const WIK_REFRESH_EARLY_MILLIS = 60000n;
30
- // OIDs for elliptic curve X509 certs
31
- const EC_PUBLIC_KEY = "1.2.840.10045.2.1";
32
- const NIST_P384 = "1.3.132.0.34";
19
+ const wrapped_import_key_1 = require("./wrapped_import_key");
33
20
  // Maximum number of keys to import in a single API call
34
21
  const MAX_IMPORTS_PER_API_CALL = 32n;
35
- // AWS Nitro Enclaves root CA certificate
36
- // https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip
37
- //
38
- // See the documentation about AWS Nitro Enclaves verification:
39
- // https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html
40
- const AWS_CA_CERT = "MIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYDVQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4MTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQLDANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEGBSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZEh8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkFR+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPWrfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6NIwLz3/Y=";
41
- // Cubist enclave-signing key. All valid attestations will have this
42
- // public key in PCR8.
43
- const CUBIST_EIF_SIGNING_PK = "2e6d0430c8b0b78316236d03cda2996449e24096b3f5b524031f12eeb5fc19a19db522a846e6240a5f36f26591890ac4";
44
- /**
45
- * The result of deserializing a CreateKeyImportKeyResponse
46
- */
47
- class WrappedImportKey {
48
- /**
49
- * Constructor. This is only called from `WrappedImportKey.createAndVerify()`.
50
- *
51
- * @param resp The response from CubeSigner
52
- */
53
- constructor(resp) {
54
- _WrappedImportKey_instances.add(this);
55
- _WrappedImportKey_enclaveAttestation.set(this, void 0);
56
- _WrappedImportKey_enclaveSignature.set(this, void 0);
57
- if (!resp.enclave_attestation || !resp.enclave_signature) {
58
- throw new Error("No attestation found in CreateKeyImportKeyResponse");
59
- }
60
- // parse the response
61
- this.publicKey = (0, cubesigner_sdk_1.decodeBase64)(resp.public_key);
62
- this.publicKeyBase64 = resp.public_key;
63
- this.skEnc = (0, cubesigner_sdk_1.decodeBase64)(resp.sk_enc);
64
- this.skEncBase64 = resp.sk_enc;
65
- this.dkEnc = (0, cubesigner_sdk_1.decodeBase64)(resp.dk_enc);
66
- this.dkEncBase64 = resp.dk_enc;
67
- __classPrivateFieldSet(this, _WrappedImportKey_enclaveAttestation, (0, cubesigner_sdk_1.decodeBase64)(resp.enclave_attestation), "f");
68
- __classPrivateFieldSet(this, _WrappedImportKey_enclaveSignature, (0, cubesigner_sdk_1.decodeBase64)(resp.enclave_signature), "f");
69
- this.expEpochSeconds = BigInt(resp.expires);
70
- // this array is updated in createAndVerify once verification succeeds
71
- this.verifiedHash = new Uint8Array(32);
72
- }
73
- /**
74
- * Create and verify an instance of this type
75
- *
76
- * @param resp The response from CubeSigner
77
- * @param subtle An instance of SubtleCrypto used for verification
78
- * @returns A newly constructed instance
79
- */
80
- static async createAndVerify(resp, subtle) {
81
- const ret = new WrappedImportKey(resp);
82
- const hash = await __classPrivateFieldGet(ret, _WrappedImportKey_instances, "m", _WrappedImportKey_verifyImportKey).call(ret, subtle);
83
- ret.verifiedHash.set(hash);
84
- return ret;
85
- }
86
- /**
87
- * Returns `true` if this WrappedImportKey needs to be refreshed.
88
- *
89
- * @returns True just if this key needs to be refreshed.
90
- */
91
- needsRefresh() {
92
- // force refresh if we're within WIK_REFRESH_EARLY_MILLIS of the expiration
93
- return (0, util_1.nowEpochMillis)() + WIK_REFRESH_EARLY_MILLIS > this.expEpochSeconds * 1000n;
94
- }
95
- }
96
- _WrappedImportKey_enclaveAttestation = new WeakMap(), _WrappedImportKey_enclaveSignature = new WeakMap(), _WrappedImportKey_instances = new WeakSet(), _WrappedImportKey_verifyImportKey =
97
- /**
98
- * Verify this wrapped import key.
99
- *
100
- * @param subtle An instance of SubtleCrypto used for verification
101
- * @returns The hash of the successfully verified wrapped import key
102
- */
103
- async function _WrappedImportKey_verifyImportKey(subtle) {
104
- // check expiration date
105
- if ((0, util_1.nowEpochMillis)() > this.expEpochSeconds * 1000n) {
106
- throw new Error("Import key is expired");
107
- }
108
- // make sure that there is an attestation
109
- if (!__classPrivateFieldGet(this, _WrappedImportKey_enclaveSignature, "f") || !__classPrivateFieldGet(this, _WrappedImportKey_enclaveAttestation, "f")) {
110
- throw new Error("No attestation found");
111
- }
112
- const signing_key = await verifyAttestationKey(__classPrivateFieldGet(this, _WrappedImportKey_enclaveAttestation, "f"));
113
- // we use subtlecrypto's impl of RSA-PSS verification
114
- const rsaPssKeyParams = {
115
- name: "RSA-PSS",
116
- hash: "SHA-256",
117
- };
118
- const pubkey = await subtle.importKey("spki", signing_key, rsaPssKeyParams, true, ["verify"]);
119
- const pubkeyAlg = pubkey.algorithm;
120
- // compute the signing hash and verify the signature
121
- const message = __classPrivateFieldGet(this, _WrappedImportKey_instances, "m", _WrappedImportKey_signedData).call(this);
122
- const mlen = Number(BigInt(pubkeyAlg.modulusLength) / 8n);
123
- const rsaPssParams = {
124
- name: "RSA-PSS",
125
- saltLength: mlen - 2 - 32,
126
- };
127
- if (await subtle.verify(rsaPssParams, pubkey, __classPrivateFieldGet(this, _WrappedImportKey_enclaveSignature, "f"), message)) {
128
- return new Uint8Array(await subtle.digest("SHA-256", message));
129
- }
130
- throw new Error("Import key signature verification failed");
131
- }, _WrappedImportKey_signedData = function _WrappedImportKey_signedData() {
132
- const parts = [
133
- // domain separation tag
134
- (0, util_1.toBigEndian)(BigInt(IMPORT_KEY_SIGNING_DST.length), 2),
135
- IMPORT_KEY_SIGNING_DST,
136
- // public key
137
- (0, util_1.toBigEndian)(BigInt(this.publicKey.length), 2),
138
- this.publicKey,
139
- // sk_enc
140
- (0, util_1.toBigEndian)(BigInt(this.skEnc.length), 2),
141
- this.skEnc,
142
- // dk_enc
143
- (0, util_1.toBigEndian)(BigInt(this.dkEnc.length), 2),
144
- this.dkEnc,
145
- // 8-byte big-endian expiration time in seconds since UNIX epoch
146
- (0, util_1.toBigEndian)(this.expEpochSeconds, 8),
147
- ];
148
- return (0, util_1.concatArrays)(parts);
149
- };
150
22
  /**
151
23
  * An import encryption key and the corresponding attestation document
152
24
  */
@@ -159,16 +31,8 @@ class KeyImporter {
159
31
  constructor(cs) {
160
32
  _KeyImporter_instances.add(this);
161
33
  _KeyImporter_wrappedImportKey.set(this, null);
162
- _KeyImporter_subtleCrypto.set(this, null);
163
- _KeyImporter_publicKeyHandle.set(this, null);
164
- _KeyImporter_hpkeSuite.set(this, void 0);
165
34
  _KeyImporter_cs.set(this, void 0);
166
35
  __classPrivateFieldSet(this, _KeyImporter_cs, cs, "f");
167
- __classPrivateFieldSet(this, _KeyImporter_hpkeSuite, new core_1.CipherSuite({
168
- kem: new core_1.DhkemP384HkdfSha384(),
169
- kdf: new core_1.HkdfSha384(),
170
- aead: new core_1.Aes256Gcm(),
171
- }), "f");
172
36
  }
173
37
  /**
174
38
  * Encrypts a set of mnemonics and imports them.
@@ -194,46 +58,20 @@ class KeyImporter {
194
58
  }
195
59
  }
196
60
  exports.KeyImporter = KeyImporter;
197
- _KeyImporter_wrappedImportKey = new WeakMap(), _KeyImporter_subtleCrypto = new WeakMap(), _KeyImporter_publicKeyHandle = new WeakMap(), _KeyImporter_hpkeSuite = new WeakMap(), _KeyImporter_cs = new WeakMap(), _KeyImporter_instances = new WeakSet(), _KeyImporter_getWrappedImportAndPubKey =
61
+ _KeyImporter_wrappedImportKey = new WeakMap(), _KeyImporter_cs = new WeakMap(), _KeyImporter_instances = new WeakSet(), _KeyImporter_getWrappedImportKey =
198
62
  /**
199
63
  * Check that the wrapped import key is unexpired and verified. Otherwise,
200
- * request a new one, verify it, and update the verified signing hash.
64
+ * request a new one and verify it.
201
65
  *
202
- * @returns The verified signing hash.
66
+ * @returns The current verified wrapped import key.
203
67
  */
204
- async function _KeyImporter_getWrappedImportAndPubKey() {
205
- if (!__classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f")) {
206
- // first time we load a WrappedImportKey, make sure the x509 crypto
207
- // provider is set correctly.
208
- x509_1.cryptoProvider.set(await (0, cubesigner_sdk_1.loadCrypto)());
209
- }
68
+ async function _KeyImporter_getWrappedImportKey() {
210
69
  if (!__classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f") || __classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f").needsRefresh()) {
211
- const kikResp = await __classPrivateFieldGet(this, _KeyImporter_cs, "f").createKeyImportKey();
212
- const subtle = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_getSubtleCrypto).call(this);
213
- const wik = await WrappedImportKey.createAndVerify(kikResp, subtle);
214
- // import the public key from the WrappedImportKey
215
- const p384Params = {
216
- name: "ECDH",
217
- namedCurve: "P-384",
218
- };
219
- __classPrivateFieldSet(this, _KeyImporter_publicKeyHandle, await subtle.importKey("raw", wik.publicKey, p384Params, true, []), "f");
220
- __classPrivateFieldSet(this, _KeyImporter_wrappedImportKey, wik, "f");
70
+ const resp = await __classPrivateFieldGet(this, _KeyImporter_cs, "f").createKeyImportKey();
71
+ const subtle = await (0, cubesigner_sdk_1.loadSubtleCrypto)();
72
+ __classPrivateFieldSet(this, _KeyImporter_wrappedImportKey, await wrapped_import_key_1.WrappedImportKey.createAndVerify(resp, subtle), "f");
221
73
  }
222
- return {
223
- wik: __classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f"),
224
- ipk: __classPrivateFieldGet(this, _KeyImporter_publicKeyHandle, "f"),
225
- };
226
- }, _KeyImporter_getSubtleCrypto =
227
- /**
228
- * Get or create an instance of SubtleCrypto.
229
- *
230
- * @returns The instance of SubtleCrypto.
231
- */
232
- async function _KeyImporter_getSubtleCrypto() {
233
- if (!__classPrivateFieldGet(this, _KeyImporter_subtleCrypto, "f")) {
234
- __classPrivateFieldSet(this, _KeyImporter_subtleCrypto, await (0, cubesigner_sdk_1.loadSubtleCrypto)(), "f");
235
- }
236
- return __classPrivateFieldGet(this, _KeyImporter_subtleCrypto, "f");
74
+ return __classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f");
237
75
  }, _KeyImporter_importPackages =
238
76
  /**
239
77
  * Encrypts a set of prepared key packages, and imports them.
@@ -251,118 +89,33 @@ async function _KeyImporter_importPackages(keyType, packages, props) {
251
89
  // we have retrieved it and that it hasn't expired. We do this here
252
90
  // for a couple reasons:
253
91
  //
254
- // - all encryptions in a give request must use the same import key, and
92
+ // - all encryptions in a given request must use the same import key, and
255
93
  //
256
94
  // - when importing a huge number of keys the import pubkey might expire
257
95
  // during the import, so we check for expiration before each request
258
- const { wik, ipk } = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_getWrappedImportAndPubKey).call(this);
259
- // next, encrypt this chunk of mnemonics
96
+ const wik = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_getWrappedImportKey).call(this);
97
+ // next, encrypt this chunk of packages
260
98
  const start = Number(MAX_IMPORTS_PER_API_CALL) * i;
261
99
  const end = Number(MAX_IMPORTS_PER_API_CALL) + start;
262
- const pkgsSlice = packages.slice(start, end);
263
100
  const key_material = [];
264
- for (const keyPkg of pkgsSlice) {
265
- const material = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_encrypt).call(this, keyPkg, wik.verifiedHash, ipk);
266
- key_material.push(material);
101
+ for (const keyPkg of packages.slice(start, end)) {
102
+ const { enc, ciphertext } = await wik.encrypt(keyPkg);
103
+ // We use an extension of HPKE that allows a salt value to be specified, but it is ok to
104
+ // use an empty salt if the import key is not reused
105
+ key_material.push({ salt: "", client_public_key: enc, ikm_enc: ciphertext });
267
106
  }
268
- // construct the request
107
+ // construct the request and send it
269
108
  const policy = props?.policy ?? null;
270
109
  const req = {
271
- public_key: wik.publicKeyBase64,
272
- sk_enc: wik.skEncBase64,
273
- dk_enc: wik.dkEncBase64,
274
- expires: Number(wik.expEpochSeconds),
110
+ ...wik.toImportKey(),
275
111
  key_type: keyType,
276
112
  key_material,
277
113
  ...props,
278
114
  policy,
279
115
  };
280
- // send it and append the result to the return value
281
116
  const resp = await __classPrivateFieldGet(this, _KeyImporter_cs, "f").importKeys(req);
282
117
  keys.push(...resp);
283
118
  }
284
119
  return keys;
285
- }, _KeyImporter_encrypt =
286
- /**
287
- * Encrypt to this wrapped import key. Stores the result in `this.encrypted_keys`
288
- *
289
- * @param data The data to encrypt
290
- * @param verifiedHash The verified signing hash of the wrapped import key to which to encrypt
291
- * @param pubkey The public key to encrypt to
292
- * @returns The encrypted key material
293
- */
294
- async function _KeyImporter_encrypt(data, verifiedHash, pubkey) {
295
- // set up the HPKE sender
296
- const sender = await __classPrivateFieldGet(this, _KeyImporter_hpkeSuite, "f").createSenderContext({
297
- recipientPublicKey: pubkey,
298
- info: verifiedHash,
299
- });
300
- // encrypt and construct the return value
301
- const senderCtext = await sender.seal(data);
302
- return {
303
- salt: "",
304
- client_public_key: (0, cubesigner_sdk_1.encodeToBase64)(sender.enc),
305
- ikm_enc: (0, cubesigner_sdk_1.encodeToBase64)(senderCtext),
306
- };
307
120
  };
308
- /**
309
- * Verifies the attestation key against the AWS Nitro Enclaves signing
310
- * key and returns the attested signing key.
311
- *
312
- * @param attBytes An attestation from an AWS nitro enclave
313
- * @returns The signing key that was attested, or null if verification failed
314
- */
315
- async function verifyAttestationKey(attBytes) {
316
- // cbor-x is being imported as ESM, so we must asynchronously import it here.
317
- // Because we only use that and auth0/cose here, we import both this way.
318
- const { Sign1 } = await import("@auth0/cose");
319
- const { decode: cborDecode } = await import("cbor-x");
320
- const att = Sign1.decode(attBytes);
321
- const attDoc = cborDecode(att.payload);
322
- // if there's no public key in this attestation, reject
323
- if (!attDoc.public_key) {
324
- throw new Error("Attestation did not include a signing public key");
325
- }
326
- // if PCR8 does not match the CubeSigner public key, reject
327
- const pcr8Data = attDoc.pcrs["8"];
328
- // slice(2) strips "0x" prefix; CUBIST_EIF_SIGNING_PK is bare hex
329
- if (!pcr8Data || CUBIST_EIF_SIGNING_PK !== (0, cubesigner_sdk_1.encodeToHex)(pcr8Data).slice(2)) {
330
- throw new Error("Attestation was not from an authorized enclave");
331
- }
332
- // check expiration date of attestation
333
- const latest = (0, util_1.nowEpochMillis)() + MAX_ATTESTATION_FUTURE_MINUTES * 60n * 1000n;
334
- const earliest = latest - (MAX_ATTESTATION_FUTURE_MINUTES + MAX_ATTESTATION_AGE_MINUTES) * 60n * 1000n;
335
- if (attDoc.timestamp < earliest || attDoc.timestamp > latest) {
336
- throw new Error("Attestation is expired");
337
- }
338
- // Verify certificate chain starting with AWS Nitro CA cert
339
- let parent = new x509_1.X509Certificate(AWS_CA_CERT);
340
- for (let i = 0; i < attDoc.cabundle.length; ++i) {
341
- const cert = new x509_1.X509Certificate(attDoc.cabundle[i]);
342
- if (!(await cert.verify(parent))) {
343
- throw new Error(`Attestation certificate chain failed at index ${i}`);
344
- }
345
- parent = cert;
346
- }
347
- const cert = new x509_1.X509Certificate(attDoc.certificate);
348
- if (!(await cert.verify(parent))) {
349
- throw new Error("Attestation certificate chain failed at leaf");
350
- }
351
- const pubkey = cert.publicKey;
352
- // make sure that we got the expected public key type
353
- const alg = new x509_1.AlgorithmProvider().toAsnAlgorithm(pubkey.algorithm);
354
- if (alg.algorithm != EC_PUBLIC_KEY) {
355
- // not the expected algorithm, i.e., elliptic curve signing
356
- throw new Error("Attestation contained unexpected signature algorithm");
357
- }
358
- const params = asn1_schema_1.AsnParser.parse(alg.parameters, asn1_ecc_1.ECParameters);
359
- if (!params.namedCurve || params.namedCurve !== NIST_P384) {
360
- // not the expected params, i.e., NIST P384
361
- throw new Error("Attestation contained unexpected signature algorithm");
362
- }
363
- // verify the cose signature with the key, which we verified against
364
- // the AWS Nitro CA certificate above
365
- await att.verify(await pubkey.export());
366
- return attDoc.public_key;
367
- }
368
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ltcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFTQSwrREFNb0M7QUFDcEMscUNBQXFGO0FBQ3JGLGlEQUFrRDtBQUNsRCx1REFBa0Q7QUFDbEQseUNBSXdCO0FBR3hCLHlDQUFtRDtBQUNuRCwrQkFBeUM7QUFDekMsaUNBQW1FO0FBRW5FLHlFQUF5RTtBQUN6RSxNQUFNLHNCQUFzQixHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7QUFFNUYsbUNBQW1DO0FBQ25DLE1BQU0sMkJBQTJCLEdBQUcsR0FBRyxDQUFDO0FBQ3hDLE1BQU0sOEJBQThCLEdBQUcsRUFBRSxDQUFDO0FBQzFDLE1BQU0sd0JBQXdCLEdBQUcsTUFBTyxDQUFDO0FBRXpDLHFDQUFxQztBQUNyQyxNQUFNLGFBQWEsR0FBRyxtQkFBbUIsQ0FBQztBQUMxQyxNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUM7QUFFakMsd0RBQXdEO0FBQ3hELE1BQU0sd0JBQXdCLEdBQUcsR0FBRyxDQUFDO0FBRXJDLHlDQUF5QztBQUN6Qyx5RUFBeUU7QUFDekUsRUFBRTtBQUNGLCtEQUErRDtBQUMvRCxvRUFBb0U7QUFDcEUsTUFBTSxXQUFXLEdBQ2YsMHNCQUEwc0IsQ0FBQztBQUU3c0Isb0VBQW9FO0FBQ3BFLHNCQUFzQjtBQUN0QixNQUFNLHFCQUFxQixHQUN6QixrR0FBa0csQ0FBQztBQUVyRzs7R0FFRztBQUNILE1BQU0sZ0JBQWdCO0lBZ0JwQjs7OztPQUlHO0lBQ0gsWUFBb0IsSUFBZ0M7O1FBUjNDLHVEQUFnQztRQUNoQyxxREFBOEI7UUFRckMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztR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REFBc0QsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyx1QkFBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVyxFQUFFLHVCQUFZLENBQUMsQ0FBQztJQUM5RCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFELDJDQUEyQztRQUMzQyxNQUFNLElBQUksS0FBSyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVELG9FQUFvRTtJQUNwRSxxQ0FBcUM7SUFDckMsTUFBTSxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFFeEMsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDO0FBQzNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7XG4gIENyZWF0ZUtleUltcG9ydEtleVJlc3BvbnNlLFxuICBJbXBvcnRLZXlSZXF1ZXN0LFxuICBJbXBvcnRLZXlSZXF1ZXN0TWF0ZXJpYWwsXG4gIEtleSxcbiAgS2V5VHlwZSxcbiAgT3JnLFxuICBJbXBvcnREZXJpdmVLZXlQcm9wZXJ0aWVzLFxufSBmcm9tIFwiQGN1YmlzdC1kZXYvY3ViZXNpZ25lci1zZGtcIjtcbmltcG9ydCB7XG4gIGxvYWRDcnlwdG8sXG4gIGxvYWRTdWJ0bGVDcnlwdG8sXG4gIGRlY29kZUJhc2U2NCxcbiAgZW5jb2RlVG9CYXNlNjQsXG4gIGVuY29kZVRvSGV4LFxufSBmcm9tIFwiQGN1YmlzdC1kZXYvY3ViZXNpZ25lci1zZGtcIjtcbmltcG9ydCB7IENpcGhlclN1aXRlLCBBZXMyNTZHY20sIEhrZGZTaGEzODQsIERoa2VtUDM4NEhrZGZTaGEzODQgfSBmcm9tIFwiQGhwa2UvY29yZVwiO1xuaW1wb3J0IHsgRUNQYXJhbWV0ZXJzIH0gZnJvbSBcIkBwZWN1bGlhci9hc24xLWVjY1wiO1xuaW1wb3J0IHsgQXNuUGFyc2VyIH0gZnJvbSBcIkBwZWN1bGlhci9hc24xLXNjaGVtYVwiO1xuaW1wb3J0IHtcbiAgQWxnb3JpdGhtUHJvdmlkZXIsXG4gIFg1MDlDZXJ0aWZpY2F0ZSxcbiAgY3J5cHRvUHJvdmlkZXIgYXMgeDUwOUNyeXB0b1Byb3ZpZGVyLFxufSBmcm9tIFwiQHBlY3VsaWFyL3g1MDlcIjtcblxuaW1wb3J0IHR5cGUgeyBNbmVtb25pY1RvSW1wb3J0IH0gZnJvbSBcIi4vbW5lbW9uaWNcIjtcbmltcG9ydCB7IG5ld01uZW1vbmljS2V5UGFja2FnZSB9IGZyb20gXCIuL21uZW1vbmljXCI7XG5pbXBvcnQgeyBuZXdSYXdLZXlQYWNrYWdlIH0gZnJvbSBcIi4vcmF3XCI7XG5pbXBvcnQgeyB0b0JpZ0VuZGlhbiwgY29uY2F0QXJyYXlzLCBub3dFcG9jaE1pbGxpcyB9IGZyb20gXCIuL3V0aWxcIjtcblxuLy8gZG9tYWluLXNlcGFyYXRpb24gdGFnIHVzZWQgd2hlbiBnZW5lcmF0aW5nIHNpZ25pbmcgaGFzaCBmb3IgaW1wb3J0IGtleVxuY29uc3QgSU1QT1JUX0tFWV9TSUdOSU5HX0RTVCA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShcIkNVQkVTSUdORVJfRVBIRU1FUkFMX0lNUE9SVF9QMzg0XCIpO1xuXG4vLyBhdHRlc3RhdGlvbiBkb2N1bWVudCBzbGFjayB0aW1lc1xuY29uc3QgTUFYX0FUVEVTVEFUSU9OX0FHRV9NSU5VVEVTID0gMTVuO1xuY29uc3QgTUFYX0FUVEVTVEFUSU9OX0ZVVFVSRV9NSU5VVEVTID0gNW47XG5jb25zdCBXSUtfUkVGUkVTSF9FQVJMWV9NSUxMSVMgPSA2MF8wMDBuO1xuXG4vLyBPSURzIGZvciBlbGxpcHRpYyBjdXJ2ZSBYNTA5IGNlcnRzXG5jb25zdCBFQ19QVUJMSUNfS0VZID0gXCIxLjIuODQwLjEwMDQ1LjIuMVwiO1xuY29uc3QgTklTVF9QMzg0ID0gXCIxLjMuMTMyLjAuMzRcIjtcblxuLy8gTWF4aW11bSBudW1iZXIgb2Yga2V5cyB0byBpbXBvcnQgaW4gYSBzaW5nbGUgQVBJIGNhbGxcbmNvbnN0IE1BWF9JTVBPUlRTX1BFUl9BUElfQ0FMTCA9IDMybjtcblxuLy8gQVdTIE5pdHJvIEVuY2xhdmVzIHJvb3QgQ0EgY2VydGlmaWNhdGVcbi8vIGh0dHBzOi8vYXdzLW5pdHJvLWVuY2xhdmVzLmFtYXpvbmF3cy5jb20vQVdTX05pdHJvRW5jbGF2ZXNfUm9vdC1HMS56aXBcbi8vXG4vLyBTZWUgdGhlIGRvY3VtZW50YXRpb24gYWJvdXQgQVdTIE5pdHJvIEVuY2xhdmVzIHZlcmlmaWNhdGlvbjpcbi8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbmNsYXZlcy9sYXRlc3QvdXNlci92ZXJpZnktcm9vdC5odG1sXG5jb25zdCBBV1NfQ0FfQ0VSVCA9XG4gIFwiTUlJQ0VUQ0NBWmFnQXdJQkFnSVJBUGt4ZFdnYmtLL2hIVWJNdE9UbitGWXdDZ1lJS29aSXpqMEVBd013U1RFTE1Ba0dBMVVFQmhNQ1ZWTXhEekFOQmdOVkJBb01Ca0Z0WVhwdmJqRU1NQW9HQTFVRUN3d0RRVmRUTVJzd0dRWURWUVFEREJKaGQzTXVibWwwY204dFpXNWpiR0YyWlhNd0hoY05NVGt4TURJNE1UTXlPREExV2hjTk5Ea3hNREk0TVRReU9EQTFXakJKTVFzd0NRWURWUVFHRXdKVlV6RVBNQTBHQTFVRUNnd0dRVzFoZW05dU1Rd3dDZ1lEVlFRTERBTkJWMU14R3pBWkJnTlZCQU1NRW1GM2N5NXVhWFJ5YnkxbGJtTnNZWFpsY3pCMk1CQUdCeXFHU000OUFnRUdCU3VCQkFBaUEySUFCUHdDVk91bUNNSHphSERpbXRxUXZrWTRNcEp6Ym9sTC8vWnkyWWxFUzFCUjVUU2tzZmJiNDhDOFdCb3l0N0YyQnc3ZUV0YWFQK29oRzJiblVzOTkwZDBKWDI4VGNQUVhDRVBaM0JBQkllVFBZd0VvQ1daRWg4bDVZb1F3VGNVLzlLTkNNRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVa0NXMURka0ZSK2VXdzViNmNwM1BtYW5mUzVZd0RnWURWUjBQQVFIL0JBUURBZ0dHTUFvR0NDcUdTTTQ5QkFNREEya0FNR1lDTVFDamZ5K1JvY205WHVlNFlud1dtTkpWQTQ0ZkEwUDVXMk9wWW93OU9ZQ1ZSYUVldkw4dU8xWFlydTV4dE1QV3JmTUNNUUNpODVzV0JiSndLS1hkUzZCcHRRRnVaYlQ3M28vZ0JoMXFVeGwvbk5yMTJVTzhZZndyNndQTGIrNk5Jd0x6My9ZPVwiO1xuXG4vLyBDdWJpc3QgZW5jbGF2ZS1zaWduaW5nIGtleS4gQWxsIHZhbGlkIGF0dGVzdGF0aW9ucyB3aWxsIGhhdmUgdGhpc1xuLy8gcHVibGljIGtleSBpbiBQQ1I4LlxuY29uc3QgQ1VCSVNUX0VJRl9TSUdOSU5HX1BLID1cbiAgXCIyZTZkMDQzMGM4YjBiNzgzMTYyMzZkMDNjZGEyOTk2NDQ5ZTI0MDk2YjNmNWI1MjQwMzFmMTJlZWI1ZmMxOWExOWRiNTIyYTg0NmU2MjQwYTVmMzZmMjY1OTE4OTBhYzRcIjtcblxuLyoqXG4gKiBUaGUgcmVzdWx0IG9mIGRlc2VyaWFsaXppbmcgYSBDcmVhdGVLZXlJbXBvcnRLZXlSZXNwb25zZVxuICovXG5jbGFzcyBXcmFwcGVkSW1wb3J0S2V5IHtcbiAgcmVhZG9ubHkgdmVyaWZpZWRIYXNoOiBVaW50OEFycmF5O1xuXG4gIHJlYWRvbmx5IHB1YmxpY0tleTogVWludDhBcnJheTtcbiAgcmVhZG9ubHkgcHVibGljS2V5QmFzZTY0OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgc2tFbmM6IFVpbnQ4QXJyYXk7XG4gIHJlYWRvbmx5IHNrRW5jQmFzZTY0OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgZGtFbmM6IFVpbnQ4QXJyYXk7XG4gIHJlYWRvbmx5IGRrRW5jQmFzZTY0OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgZXhwRXBvY2hTZWNvbmRzOiBiaWdpbnQ7XG4gIHJlYWRvbmx5ICNlbmNsYXZlQXR0ZXN0YXRpb246IFVpbnQ4QXJyYXk7XG4gIHJlYWRvbmx5ICNlbmNsYXZlU2lnbmF0dXJlOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci4gVGhpcyBpcyBvbmx5IGNhbGxlZCBmcm9tIGBXcmFwcGVkSW1wb3J0S2V5LmNyZWF0ZUFuZFZlcmlmeSgpYC5cbiAgICpcbiAgICogQHBhcmFtIHJlc3AgVGhlIHJlc3BvbnNlIGZyb20gQ3ViZVNpZ25lclxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihyZXNwOiBDcmVhdGVLZXlJbXBvcnRLZXlSZXNwb25zZSkge1xuICAgIGlmICghcmVzcC5lbmNsYXZlX2F0dGVzdGF0aW9uIHx8ICFyZXNwLmVuY2xhdmVfc2lnbmF0dXJlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBhdHRlc3RhdGlvbiBmb3VuZCBpbiBDcmVhdGVLZXlJbXBvcnRLZXlSZXNwb25zZVwiKTtcbiAgICB9XG5cbiAgICAvLyBwYXJzZSB0aGUgcmVzcG9uc2VcbiAgICB0aGlzLnB1YmxpY0tleSA9IGRlY29kZUJhc2U2NChyZXNwLnB1YmxpY19rZXkpO1xuICAgIHRoaXMucHVibGljS2V5QmFzZTY0ID0gcmVzcC5wdWJsaWNfa2V5O1xuXG4gICAgdGhpcy5za0VuYyA9IGRlY29kZUJhc2U2NChyZXNwLnNrX2VuYyk7XG4gICAgdGhpcy5za0VuY0Jhc2U2NCA9IHJlc3Auc2tfZW5jO1xuXG4gICAgdGhpcy5ka0VuYyA9IGRlY29kZUJhc2U2NChyZXNwLmRrX2VuYyk7XG4gICAgdGhpcy5ka0VuY0Jhc2U2NCA9IHJlc3AuZGtfZW5jO1xuXG4gICAgdGhpcy4jZW5jbGF2ZUF0dGVzdGF0aW9uID0gZGVjb2RlQmFzZTY0KHJlc3AuZW5jbGF2ZV9hdHRlc3RhdGlvbik7XG4gICAgdGhpcy4jZW5jbGF2ZVNpZ25hdHVyZSA9IGRlY29kZUJhc2U2NChyZXNwLmVuY2xhdmVfc2lnbmF0dXJlKTtcbiAgICB0aGlzLmV4cEVwb2NoU2Vjb25kcyA9IEJpZ0ludChyZXNwLmV4cGlyZXMpO1xuXG4gICAgLy8gdGhpcyBhcnJheSBpcyB1cGRhdGVkIGluIGNyZWF0ZUFuZFZlcmlmeSBvbmNlIHZlcmlmaWNhdGlvbiBzdWNjZWVkc1xuICAgIHRoaXMudmVyaWZpZWRIYXNoID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbmQgdmVyaWZ5IGFuIGluc3RhbmNlIG9mIHRoaXMgdHlwZVxuICAgKlxuICAgKiBAcGFyYW0gcmVzcCBUaGUgcmVzcG9uc2UgZnJvbSBDdWJlU2lnbmVyXG4gICAqIEBwYXJhbSBzdWJ0bGUgQW4gaW5zdGFuY2Ugb2YgU3VidGxlQ3J5cHRvIHVzZWQgZm9yIHZlcmlmaWNhdGlvblxuICAgKiBAcmV0dXJucyBBIG5ld2x5IGNvbnN0cnVjdGVkIGluc3RhbmNlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGNyZWF0ZUFuZFZlcmlmeShcbiAgICByZXNwOiBDcmVhdGVLZXlJbXBvcnRLZXlSZXNwb25zZSxcbiAgICBzdWJ0bGU6IFN1YnRsZUNyeXB0byxcbiAgKTogUHJvbWlzZTxXcmFwcGVkSW1wb3J0S2V5PiB7XG4gICAgY29uc3QgcmV0ID0gbmV3IFdyYXBwZWRJbXBvcnRLZXkocmVzcCk7XG4gICAgY29uc3QgaGFzaCA9IGF3YWl0IHJldC4jdmVyaWZ5SW1wb3J0S2V5KHN1YnRsZSk7XG4gICAgcmV0LnZlcmlmaWVkSGFzaC5zZXQoaGFzaCk7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgdGhpcyB3cmFwcGVkIGltcG9ydCBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBzdWJ0bGUgQW4gaW5zdGFuY2Ugb2YgU3VidGxlQ3J5cHRvIHVzZWQgZm9yIHZlcmlmaWNhdGlvblxuICAgKiBAcmV0dXJucyBUaGUgaGFzaCBvZiB0aGUgc3VjY2Vzc2Z1bGx5IHZlcmlmaWVkIHdyYXBwZWQgaW1wb3J0IGtleVxuICAgKi9cbiAgYXN5bmMgI3ZlcmlmeUltcG9ydEtleShzdWJ0bGU6IFN1YnRsZUNyeXB0byk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIC8vIGNoZWNrIGV4cGlyYXRpb24gZGF0ZVxuICAgIGlmIChub3dFcG9jaE1pbGxpcygpID4gdGhpcy5leHBFcG9jaFNlY29uZHMgKiAxMDAwbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW1wb3J0IGtleSBpcyBleHBpcmVkXCIpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZXJlIGlzIGFuIGF0dGVzdGF0aW9uXG4gICAgaWYgKCF0aGlzLiNlbmNsYXZlU2lnbmF0dXJlIHx8ICF0aGlzLiNlbmNsYXZlQXR0ZXN0YXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGF0dGVzdGF0aW9uIGZvdW5kXCIpO1xuICAgIH1cbiAgICBjb25zdCBzaWduaW5nX2tleSA9IGF3YWl0IHZlcmlmeUF0dGVzdGF0aW9uS2V5KHRoaXMuI2VuY2xhdmVBdHRlc3RhdGlvbik7XG5cbiAgICAvLyB3ZSB1c2Ugc3VidGxlY3J5cHRvJ3MgaW1wbCBvZiBSU0EtUFNTIHZlcmlmaWNhdGlvblxuICAgIGNvbnN0IHJzYVBzc0tleVBhcmFtcyA9IHtcbiAgICAgIG5hbWU6IFwiUlNBLVBTU1wiLFxuICAgICAgaGFzaDogXCJTSEEtMjU2XCIsXG4gICAgfTtcbiAgICBjb25zdCBwdWJrZXkgPSBhd2FpdCBzdWJ0bGUuaW1wb3J0S2V5KFwic3BraVwiLCBzaWduaW5nX2tleSwgcnNhUHNzS2V5UGFyYW1zLCB0cnVlLCBbXCJ2ZXJpZnlcIl0pO1xuICAgIGNvbnN0IHB1YmtleUFsZyA9IHB1YmtleS5hbGdvcml0aG0gYXMgdW5rbm93biBhcyB7IG1vZHVsdXNMZW5ndGg6IG51bWJlciB9O1xuXG4gICAgLy8gY29tcHV0ZSB0aGUgc2lnbmluZyBoYXNoIGFuZCB2ZXJpZnkgdGhlIHNpZ25hdHVyZVxuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLiNzaWduZWREYXRhKCk7XG4gICAgY29uc3QgbWxlbiA9IE51bWJlcihCaWdJbnQocHVia2V5QWxnLm1vZHVsdXNMZW5ndGgpIC8gOG4pO1xuICAgIGNvbnN0IHJzYVBzc1BhcmFtcyA9IHtcbiAgICAgIG5hbWU6IFwiUlNBLVBTU1wiLFxuICAgICAgc2FsdExlbmd0aDogbWxlbiAtIDIgLSAzMixcbiAgICB9O1xuXG4gICAgaWYgKGF3YWl0IHN1YnRsZS52ZXJpZnkocnNhUHNzUGFyYW1zLCBwdWJrZXksIHRoaXMuI2VuY2xhdmVTaWduYXR1cmUsIG1lc3NhZ2UpKSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgc3VidGxlLmRpZ2VzdChcIlNIQS0yNTZcIiwgbWVzc2FnZSkpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbXBvcnQga2V5IHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gZmFpbGVkXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYHRydWVgIGlmIHRoaXMgV3JhcHBlZEltcG9ydEtleSBuZWVkcyB0byBiZSByZWZyZXNoZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUganVzdCBpZiB0aGlzIGtleSBuZWVkcyB0byBiZSByZWZyZXNoZWQuXG4gICAqL1xuICBwdWJsaWMgbmVlZHNSZWZyZXNoKCk6IGJvb2xlYW4ge1xuICAgIC8vIGZvcmNlIHJlZnJlc2ggaWYgd2UncmUgd2l0aGluIFdJS19SRUZSRVNIX0VBUkxZX01JTExJUyBvZiB0aGUgZXhwaXJhdGlvblxuICAgIHJldHVybiBub3dFcG9jaE1pbGxpcygpICsgV0lLX1JFRlJFU0hfRUFSTFlfTUlMTElTID4gdGhpcy5leHBFcG9jaFNlY29uZHMgKiAxMDAwbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgc2lnbmluZyBoYXNoIGZvciBhIHdyYXBwZWQgaW1wb3J0IGtleVxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2lnbmluZyBoYXNoXG4gICAqL1xuICAjc2lnbmVkRGF0YSgpOiBVaW50OEFycmF5IHtcbiAgICBjb25zdCBwYXJ0czogVWludDhBcnJheVtdID0gW1xuICAgICAgLy8gZG9tYWluIHNlcGFyYXRpb24gdGFnXG4gICAgICB0b0JpZ0VuZGlhbihCaWdJbnQoSU1QT1JUX0tFWV9TSUdOSU5HX0RTVC5sZW5ndGgpLCAyKSxcbiAgICAgIElNUE9SVF9LRVlfU0lHTklOR19EU1QsXG5cbiAgICAgIC8vIHB1YmxpYyBrZXlcbiAgICAgIHRvQmlnRW5kaWFuKEJpZ0ludCh0aGlzLnB1YmxpY0tleS5sZW5ndGgpLCAyKSxcbiAgICAgIHRoaXMucHVibGljS2V5LFxuXG4gICAgICAvLyBza19lbmNcbiAgICAgIHRvQmlnRW5kaWFuKEJpZ0ludCh0aGlzLnNrRW5jLmxlbmd0aCksIDIpLFxuICAgICAgdGhpcy5za0VuYyxcblxuICAgICAgLy8gZGtfZW5jXG4gICAgICB0b0JpZ0VuZGlhbihCaWdJbnQodGhpcy5ka0VuYy5sZW5ndGgpLCAyKSxcbiAgICAgIHRoaXMuZGtFbmMsXG5cbiAgICAgIC8vIDgtYnl0ZSBiaWctZW5kaWFuIGV4cGlyYXRpb24gdGltZSBpbiBzZWNvbmRzIHNpbmNlIFVOSVggZXBvY2hcbiAgICAgIHRvQmlnRW5kaWFuKHRoaXMuZXhwRXBvY2hTZWNvbmRzLCA4KSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIGNvbmNhdEFycmF5cyhwYXJ0cyk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgcmV0dXJuIHZhbHVlIGZyb20gS2V5SW1wb3J0ZXIuI2dldFdyYXBwZWRJbXBvcnRBbmRQdWJLZXkoKVxuICovXG50eXBlIFdyYXBwZWRJbXBvcnRBbmRQdWJLZXkgPSB7XG4gIHdpazogV3JhcHBlZEltcG9ydEtleTtcbiAgaXBrOiBDcnlwdG9LZXk7XG59O1xuXG4vKipcbiAqIEFuIGltcG9ydCBlbmNyeXB0aW9uIGtleSBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgYXR0ZXN0YXRpb24gZG9jdW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEtleUltcG9ydGVyIHtcbiAgI3dyYXBwZWRJbXBvcnRLZXk6IG51bGwgfCBXcmFwcGVkSW1wb3J0S2V5ID0gbnVsbDtcbiAgI3N1YnRsZUNyeXB0bzogbnVsbCB8IFN1YnRsZUNyeXB0byA9IG51bGw7XG4gICNwdWJsaWNLZXlIYW5kbGU6IG51bGwgfCBDcnlwdG9LZXkgPSBudWxsO1xuICByZWFkb25seSAjaHBrZVN1aXRlOiBDaXBoZXJTdWl0ZTtcbiAgcmVhZG9ubHkgI2NzOiBPcmc7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBmcm9tIGEgQ3ViZVNpZ25lciBgT3JnYCBpbnN0YW5jZVxuICAgKlxuICAgKiBAcGFyYW0gY3MgQSBDdWJlU2lnbmVyIGBPcmdgIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihjczogT3JnKSB7XG4gICAgdGhpcy4jY3MgPSBjcztcbiAgICB0aGlzLiNocGtlU3VpdGUgPSBuZXcgQ2lwaGVyU3VpdGUoe1xuICAgICAga2VtOiBuZXcgRGhrZW1QMzg0SGtkZlNoYTM4NCgpLFxuICAgICAga2RmOiBuZXcgSGtkZlNoYTM4NCgpLFxuICAgICAgYWVhZDogbmV3IEFlczI1NkdjbSgpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHRoYXQgdGhlIHdyYXBwZWQgaW1wb3J0IGtleSBpcyB1bmV4cGlyZWQgYW5kIHZlcmlmaWVkLiBPdGhlcndpc2UsXG4gICAqIHJlcXVlc3QgYSBuZXcgb25lLCB2ZXJpZnkgaXQsIGFuZCB1cGRhdGUgdGhlIHZlcmlmaWVkIHNpZ25pbmcgaGFzaC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHZlcmlmaWVkIHNpZ25pbmcgaGFzaC5cbiAgICovXG4gIGFzeW5jICNnZXRXcmFwcGVkSW1wb3J0QW5kUHViS2V5KCk6IFByb21pc2U8V3JhcHBlZEltcG9ydEFuZFB1YktleT4ge1xuICAgIGlmICghdGhpcy4jd3JhcHBlZEltcG9ydEtleSkge1xuICAgICAgLy8gZmlyc3QgdGltZSB3ZSBsb2FkIGEgV3JhcHBlZEltcG9ydEtleSwgbWFrZSBzdXJlIHRoZSB4NTA5IGNyeXB0b1xuICAgICAgLy8gcHJvdmlkZXIgaXMgc2V0IGNvcnJlY3RseS5cbiAgICAgIHg1MDlDcnlwdG9Qcm92aWRlci5zZXQoYXdhaXQgbG9hZENyeXB0bygpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLiN3cmFwcGVkSW1wb3J0S2V5IHx8IHRoaXMuI3dyYXBwZWRJbXBvcnRLZXkubmVlZHNSZWZyZXNoKCkpIHtcbiAgICAgIGNvbnN0IGtpa1Jlc3AgPSBhd2FpdCB0aGlzLiNjcy5jcmVhdGVLZXlJbXBvcnRLZXkoKTtcbiAgICAgIGNvbnN0IHN1YnRsZSA9IGF3YWl0IHRoaXMuI2dldFN1YnRsZUNyeXB0bygpO1xuICAgICAgY29uc3Qgd2lrID0gYXdhaXQgV3JhcHBlZEltcG9ydEtleS5jcmVhdGVBbmRWZXJpZnkoa2lrUmVzcCwgc3VidGxlKTtcblxuICAgICAgLy8gaW1wb3J0IHRoZSBwdWJsaWMga2V5IGZyb20gdGhlIFdyYXBwZWRJbXBvcnRLZXlcbiAgICAgIGNvbnN0IHAzODRQYXJhbXMgPSB7XG4gICAgICAgIG5hbWU6IFwiRUNESFwiLFxuICAgICAgICBuYW1lZEN1cnZlOiBcIlAtMzg0XCIsXG4gICAgICB9O1xuICAgICAgdGhpcy4jcHVibGljS2V5SGFuZGxlID0gYXdhaXQgc3VidGxlLmltcG9ydEtleShcInJhd1wiLCB3aWsucHVibGljS2V5LCBwMzg0UGFyYW1zLCB0cnVlLCBbXSk7XG4gICAgICB0aGlzLiN3cmFwcGVkSW1wb3J0S2V5ID0gd2lrO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgd2lrOiB0aGlzLiN3cmFwcGVkSW1wb3J0S2V5LFxuICAgICAgaXBrOiB0aGlzLiNwdWJsaWNLZXlIYW5kbGUhLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IG9yIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBTdWJ0bGVDcnlwdG8uXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBpbnN0YW5jZSBvZiBTdWJ0bGVDcnlwdG8uXG4gICAqL1xuICBhc3luYyAjZ2V0U3VidGxlQ3J5cHRvKCk6IFByb21pc2U8U3VidGxlQ3J5cHRvPiB7XG4gICAgaWYgKCF0aGlzLiNzdWJ0bGVDcnlwdG8pIHtcbiAgICAgIHRoaXMuI3N1YnRsZUNyeXB0byA9IGF3YWl0IGxvYWRTdWJ0bGVDcnlwdG8oKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuI3N1YnRsZUNyeXB0bztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiBtbmVtb25pY3MgYW5kIGltcG9ydHMgdGhlbS5cbiAgICpcbiAgICogQHBhcmFtIGtleVR5cGUgVGhlIHR5cGUgb2Yga2V5IHRvIGltcG9ydFxuICAgKiBAcGFyYW0gbW5lcyBUaGUgbW5lbW9uaWNzIHRvIGltcG9ydCwgd2l0aCBvcHRpb25hbCBkZXJpdmF0aW9uIHBhdGhzIGFuZCBwYXNzd29yZHNcbiAgICogQHBhcmFtIHByb3BzIEFkZGl0aW9uYWwgb3B0aW9ucyBmb3IgaW1wb3J0XG4gICAqIEByZXR1cm5zIGBLZXlgIG9iamVjdHMgZm9yIGVhY2ggaW1wb3J0ZWQga2V5LlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGltcG9ydE1uZW1vbmljcyhcbiAgICBrZXlUeXBlOiBLZXlUeXBlLFxuICAgIG1uZXM6IE1uZW1vbmljVG9JbXBvcnRbXSxcbiAgICBwcm9wcz86IEltcG9ydERlcml2ZUtleVByb3BlcnRpZXMsXG4gICk6IFByb21pc2U8S2V5W10+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy4jaW1wb3J0UGFja2FnZXMoXG4gICAgICBrZXlUeXBlLFxuICAgICAgbW5lcy5tYXAoKG1uZSkgPT4gbmV3TW5lbW9uaWNLZXlQYWNrYWdlKG1uZSkpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiByYXcga2V5cyBhbmQgaW1wb3J0cyB0aGVtLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5VHlwZSBUaGUgdHlwZSBvZiBrZXkgdG8gaW1wb3J0XG4gICAqIEBwYXJhbSBzZWNyZXRzIFRoZSBzZWNyZXQga2V5cyB0byBpbXBvcnQuXG4gICAqIEBwYXJhbSBwcm9wcyBBZGRpdGlvbmFsIG9wdGlvbnMgZm9yIGltcG9ydFxuICAgKiBAcmV0dXJucyBgS2V5YCBvYmplY3RzIGZvciBlYWNoIGltcG9ydGVkIGtleS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbXBvcnRSYXdTZWNyZXRLZXlzKFxuICAgIGtleVR5cGU6IEtleVR5cGUsXG4gICAgc2VjcmV0czogVWludDhBcnJheVtdLFxuICAgIHByb3BzPzogSW1wb3J0RGVyaXZlS2V5UHJvcGVydGllcyxcbiAgKTogUHJvbWlzZTxLZXlbXT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLiNpbXBvcnRQYWNrYWdlcyhcbiAgICAgIGtleVR5cGUsXG4gICAgICBzZWNyZXRzLm1hcCgoc2VjKSA9PiBuZXdSYXdLZXlQYWNrYWdlKHNlYykpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiBwcmVwYXJlZCBrZXkgcGFja2FnZXMsIGFuZCBpbXBvcnRzIHRoZW0uXG4gICAqXG4gICAqIEBwYXJhbSBrZXlUeXBlIFRoZSB0eXBlIG9mIGtleSB0byBpbXBvcnRcbiAgICogQHBhcmFtIHBhY2thZ2VzIFRoZSBrZXkgcGFja2FnZXMgdG8gaW1wb3J0LlxuICAgKiBAcGFyYW0gcHJvcHMgQWRkaXRpb25hbCBvcHRpb25zIGZvciBpbXBvcnRcbiAgICogQHJldHVybnMgYEtleWAgb2JqZWN0cyBmb3IgZWFjaCBpbXBvcnRlZCBrZXkuXG4gICAqL1xuICBhc3luYyAjaW1wb3J0UGFja2FnZXMoXG4gICAga2V5VHlwZTogS2V5VHlwZSxcbiAgICBwYWNrYWdlczogVWludDhBcnJheVtdLFxuICAgIHByb3BzPzogSW1wb3J0RGVyaXZlS2V5UHJvcGVydGllcyxcbiAgKTogUHJvbWlzZTxLZXlbXT4ge1xuICAgIGNvbnN0IG5DaHVua3MgPSBOdW1iZXIoXG4gICAgICAoQmlnSW50KHBhY2thZ2VzLmxlbmd0aCkgKyBNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwgLSAxbikgLyBNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwsXG4gICAgKTtcbiAgICBjb25zdCBrZXlzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5DaHVua3M7ICsraSkge1xuICAgICAgLy8gZmlyc3QsIG1ha2Ugc3VyZSB0aGF0IHRoZSB3cmFwcGVkIGltcG9ydCBrZXkgaXMgdmFsaWQsIGkuZS4sIHRoYXRcbiAgICAgIC8vIHdlIGhhdmUgcmV0cmlldmVkIGl0IGFuZCB0aGF0IGl0IGhhc24ndCBleHBpcmVkLiBXZSBkbyB0aGlzIGhlcmVcbiAgICAgIC8vIGZvciBhIGNvdXBsZSByZWFzb25zOlxuICAgICAgLy9cbiAgICAgIC8vIC0gYWxsIGVuY3J5cHRpb25zIGluIGEgZ2l2ZSByZXF1ZXN0IG11c3QgdXNlIHRoZSBzYW1lIGltcG9ydCBrZXksIGFuZFxuICAgICAgLy9cbiAgICAgIC8vIC0gd2hlbiBpbXBvcnRpbmcgYSBodWdlIG51bWJlciBvZiBrZXlzIHRoZSBpbXBvcnQgcHVia2V5IG1pZ2h0IGV4cGlyZVxuICAgICAgLy8gICBkdXJpbmcgdGhlIGltcG9ydCwgc28gd2UgY2hlY2sgZm9yIGV4cGlyYXRpb24gYmVmb3JlIGVhY2ggcmVxdWVzdFxuICAgICAgY29uc3QgeyB3aWssIGlwayB9ID0gYXdhaXQgdGhpcy4jZ2V0V3JhcHBlZEltcG9ydEFuZFB1YktleSgpO1xuXG4gICAgICAvLyBuZXh0LCBlbmNyeXB0IHRoaXMgY2h1bmsgb2YgbW5lbW9uaWNzXG4gICAgICBjb25zdCBzdGFydCA9IE51bWJlcihNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwpICogaTtcbiAgICAgIGNvbnN0IGVuZCA9IE51bWJlcihNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwpICsgc3RhcnQ7XG4gICAgICBjb25zdCBwa2dzU2xpY2UgPSBwYWNrYWdlcy5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgIGNvbnN0IGtleV9tYXRlcmlhbCA9IFtdO1xuICAgICAgZm9yIChjb25zdCBrZXlQa2cgb2YgcGtnc1NsaWNlKSB7XG4gICAgICAgIGNvbnN0IG1hdGVyaWFsID0gYXdhaXQgdGhpcy4jZW5jcnlwdChrZXlQa2csIHdpay52ZXJpZmllZEhhc2gsIGlwayk7XG4gICAgICAgIGtleV9tYXRlcmlhbC5wdXNoKG1hdGVyaWFsKTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uc3RydWN0IHRoZSByZXF1ZXN0XG4gICAgICBjb25zdCBwb2xpY3kgPSBwcm9wcz8ucG9saWN5ID8/IG51bGw7XG4gICAgICBjb25zdCByZXE6IEltcG9ydEtleVJlcXVlc3QgPSB7XG4gICAgICAgIHB1YmxpY19rZXk6IHdpay5wdWJsaWNLZXlCYXNlNjQsXG4gICAgICAgIHNrX2VuYzogd2lrLnNrRW5jQmFzZTY0LFxuICAgICAgICBka19lbmM6IHdpay5ka0VuY0Jhc2U2NCxcbiAgICAgICAgZXhwaXJlczogTnVtYmVyKHdpay5leHBFcG9jaFNlY29uZHMpLFxuICAgICAgICBrZXlfdHlwZToga2V5VHlwZSxcbiAgICAgICAga2V5X21hdGVyaWFsLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgICAgcG9saWN5LFxuICAgICAgfTtcblxuICAgICAgLy8gc2VuZCBpdCBhbmQgYXBwZW5kIHRoZSByZXN1bHQgdG8gdGhlIHJldHVybiB2YWx1ZVxuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHRoaXMuI2NzLmltcG9ydEtleXMocmVxKTtcbiAgICAgIGtleXMucHVzaCguLi5yZXNwKTtcbiAgICB9XG5cbiAgICByZXR1cm4ga2V5cztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0IHRvIHRoaXMgd3JhcHBlZCBpbXBvcnQga2V5LiBTdG9yZXMgdGhlIHJlc3VsdCBpbiBgdGhpcy5lbmNyeXB0ZWRfa2V5c2BcbiAgICpcbiAgICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgdG8gZW5jcnlwdFxuICAgKiBAcGFyYW0gdmVyaWZpZWRIYXNoIFRoZSB2ZXJpZmllZCBzaWduaW5nIGhhc2ggb2YgdGhlIHdyYXBwZWQgaW1wb3J0IGtleSB0byB3aGljaCB0byBlbmNyeXB0XG4gICAqIEBwYXJhbSBwdWJrZXkgVGhlIHB1YmxpYyBrZXkgdG8gZW5jcnlwdCB0b1xuICAgKiBAcmV0dXJucyBUaGUgZW5jcnlwdGVkIGtleSBtYXRlcmlhbFxuICAgKi9cbiAgYXN5bmMgI2VuY3J5cHQoXG4gICAgZGF0YTogVWludDhBcnJheSxcbiAgICB2ZXJpZmllZEhhc2g6IFVpbnQ4QXJyYXksXG4gICAgcHVia2V5OiBDcnlwdG9LZXksXG4gICk6IFByb21pc2U8SW1wb3J0S2V5UmVxdWVzdE1hdGVyaWFsPiB7XG4gICAgLy8gc2V0IHVwIHRoZSBIUEtFIHNlbmRlclxuICAgIGNvbnN0IHNlbmRlciA9IGF3YWl0IHRoaXMuI2hwa2VTdWl0ZS5jcmVhdGVTZW5kZXJDb250ZXh0KHtcbiAgICAgIHJlY2lwaWVudFB1YmxpY0tleTogcHVia2V5LFxuICAgICAgaW5mbzogdmVyaWZpZWRIYXNoLFxuICAgIH0pO1xuXG4gICAgLy8gZW5jcnlwdCBhbmQgY29uc3RydWN0IHRoZSByZXR1cm4gdmFsdWVcbiAgICBjb25zdCBzZW5kZXJDdGV4dCA9IGF3YWl0IHNlbmRlci5zZWFsKGRhdGEpO1xuICAgIHJldHVybiB7XG4gICAgICBzYWx0OiBcIlwiLFxuICAgICAgY2xpZW50X3B1YmxpY19rZXk6IGVuY29kZVRvQmFzZTY0KHNlbmRlci5lbmMpLFxuICAgICAgaWttX2VuYzogZW5jb2RlVG9CYXNlNjQoc2VuZGVyQ3RleHQpLFxuICAgIH07XG4gIH1cbn1cblxuLypcbiAqIEFuIEFXUyBOaXRybyBhdHRlc3RhdGlvbiBkb2N1bWVudFxuICpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLW5pdHJvLWVuY2xhdmVzLW5zbS1hcGkvYmxvYi80Yjg1MWYzMDA2YzZmYTk4ZjIzZGNmZmIyY2JhMDNiMzlkZTliOGFmL3NyYy9hcGkvbW9kLnJzI0wyMDhcbiAqL1xudHlwZSBBdHRlc3RhdGlvbkRvYyA9IHtcbiAgbW9kdWxlX2lkOiBzdHJpbmc7XG4gIGRpZ2VzdDogXCJTSEEyNTZcIiB8IFwiU0hBMzg0XCIgfCBcIlNIQTUxMlwiO1xuICB0aW1lc3RhbXA6IGJpZ2ludDtcbiAgcGNyczogeyBbcGNyOiBzdHJpbmddOiBVaW50OEFycmF5IH07XG4gIGNlcnRpZmljYXRlOiBVaW50OEFycmF5O1xuICBjYWJ1bmRsZTogVWludDhBcnJheVtdO1xuICBwdWJsaWNfa2V5PzogVWludDhBcnJheTtcbiAgdXNlcl9kYXRhPzogVWludDhBcnJheTtcbiAgbm9uY2U/OiBVaW50OEFycmF5O1xufTtcblxuLyoqXG4gKiBWZXJpZmllcyB0aGUgYXR0ZXN0YXRpb24ga2V5IGFnYWluc3QgdGhlIEFXUyBOaXRybyBFbmNsYXZlcyBzaWduaW5nXG4gKiBrZXkgYW5kIHJldHVybnMgdGhlIGF0dGVzdGVkIHNpZ25pbmcga2V5LlxuICpcbiAqIEBwYXJhbSBhdHRCeXRlcyBBbiBhdHRlc3RhdGlvbiBmcm9tIGFuIEFXUyBuaXRybyBlbmNsYXZlXG4gKiBAcmV0dXJucyBUaGUgc2lnbmluZyBrZXkgdGhhdCB3YXMgYXR0ZXN0ZWQsIG9yIG51bGwgaWYgdmVyaWZpY2F0aW9uIGZhaWxlZFxuICovXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlBdHRlc3RhdGlvbktleShhdHRCeXRlczogVWludDhBcnJheSk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAvLyBjYm9yLXggaXMgYmVpbmcgaW1wb3J0ZWQgYXMgRVNNLCBzbyB3ZSBtdXN0IGFzeW5jaHJvbm91c2x5IGltcG9ydCBpdCBoZXJlLlxuICAvLyBCZWNhdXNlIHdlIG9ubHkgdXNlIHRoYXQgYW5kIGF1dGgwL2Nvc2UgaGVyZSwgd2UgaW1wb3J0IGJvdGggdGhpcyB3YXkuXG4gIGNvbnN0IHsgU2lnbjEgfSA9IGF3YWl0IGltcG9ydChcIkBhdXRoMC9jb3NlXCIpO1xuICBjb25zdCB7IGRlY29kZTogY2JvckRlY29kZSB9ID0gYXdhaXQgaW1wb3J0KFwiY2Jvci14XCIpO1xuXG4gIGNvbnN0IGF0dCA9IFNpZ24xLmRlY29kZShhdHRCeXRlcyk7XG4gIGNvbnN0IGF0dERvYyA9IGNib3JEZWNvZGUoYXR0LnBheWxvYWQpIGFzIEF0dGVzdGF0aW9uRG9jO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm8gcHVibGljIGtleSBpbiB0aGlzIGF0dGVzdGF0aW9uLCByZWplY3RcbiAgaWYgKCFhdHREb2MucHVibGljX2tleSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGVzdGF0aW9uIGRpZCBub3QgaW5jbHVkZSBhIHNpZ25pbmcgcHVibGljIGtleVwiKTtcbiAgfVxuXG4gIC8vIGlmIFBDUjggZG9lcyBub3QgbWF0Y2ggdGhlIEN1YmVTaWduZXIgcHVibGljIGtleSwgcmVqZWN0XG4gIGNvbnN0IHBjcjhEYXRhID0gYXR0RG9jLnBjcnNbXCI4XCJdO1xuICAvLyBzbGljZSgyKSBzdHJpcHMgXCIweFwiIHByZWZpeDsgQ1VCSVNUX0VJRl9TSUdOSU5HX1BLIGlzIGJhcmUgaGV4XG4gIGlmICghcGNyOERhdGEgfHwgQ1VCSVNUX0VJRl9TSUdOSU5HX1BLICE9PSBlbmNvZGVUb0hleChwY3I4RGF0YSkuc2xpY2UoMikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJBdHRlc3RhdGlvbiB3YXMgbm90IGZyb20gYW4gYXV0aG9yaXplZCBlbmNsYXZlXCIpO1xuICB9XG5cbiAgLy8gY2hlY2sgZXhwaXJhdGlvbiBkYXRlIG9mIGF0dGVzdGF0aW9uXG4gIGNvbnN0IGxhdGVzdCA9IG5vd0Vwb2NoTWlsbGlzKCkgKyBNQVhfQVRURVNUQVRJT05fRlVUVVJFX01JTlVURVMgKiA2MG4gKiAxMDAwbjtcbiAgY29uc3QgZWFybGllc3QgPVxuICAgIGxhdGVzdCAtIChNQVhfQVRURVNUQVRJT05fRlVUVVJFX01JTlVURVMgKyBNQVhfQVRURVNUQVRJT05fQUdFX01JTlVURVMpICogNjBuICogMTAwMG47XG4gIGlmIChhdHREb2MudGltZXN0YW1wIDwgZWFybGllc3QgfHwgYXR0RG9jLnRpbWVzdGFtcCA+IGxhdGVzdCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGVzdGF0aW9uIGlzIGV4cGlyZWRcIik7XG4gIH1cblxuICAvLyBWZXJpZnkgY2VydGlmaWNhdGUgY2hhaW4gc3RhcnRpbmcgd2l0aCBBV1MgTml0cm8gQ0EgY2VydFxuICBsZXQgcGFyZW50ID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZShBV1NfQ0FfQ0VSVCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0RG9jLmNhYnVuZGxlLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY2VydCA9IG5ldyBYNTA5Q2VydGlmaWNhdGUoYXR0RG9jLmNhYnVuZGxlW2ldKTtcbiAgICBpZiAoIShhd2FpdCBjZXJ0LnZlcmlmeShwYXJlbnQpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBdHRlc3RhdGlvbiBjZXJ0aWZpY2F0ZSBjaGFpbiBmYWlsZWQgYXQgaW5kZXggJHtpfWApO1xuICAgIH1cbiAgICBwYXJlbnQgPSBjZXJ0O1xuICB9XG4gIGNvbnN0IGNlcnQgPSBuZXcgWDUwOUNlcnRpZmljYXRlKGF0dERvYy5jZXJ0aWZpY2F0ZSk7XG4gIGlmICghKGF3YWl0IGNlcnQudmVyaWZ5KHBhcmVudCkpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXR0ZXN0YXRpb24gY2VydGlmaWNhdGUgY2hhaW4gZmFpbGVkIGF0IGxlYWZcIik7XG4gIH1cbiAgY29uc3QgcHVia2V5ID0gY2VydC5wdWJsaWNLZXk7XG5cbiAgLy8gbWFrZSBzdXJlIHRoYXQgd2UgZ290IHRoZSBleHBlY3RlZCBwdWJsaWMga2V5IHR5cGVcbiAgY29uc3QgYWxnID0gbmV3IEFsZ29yaXRobVByb3ZpZGVyKCkudG9Bc25BbGdvcml0aG0ocHVia2V5LmFsZ29yaXRobSk7XG4gIGlmIChhbGcuYWxnb3JpdGhtICE9IEVDX1BVQkxJQ19LRVkpIHtcbiAgICAvLyBub3QgdGhlIGV4cGVjdGVkIGFsZ29yaXRobSwgaS5lLiwgZWxsaXB0aWMgY3VydmUgc2lnbmluZ1xuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGVzdGF0aW9uIGNvbnRhaW5lZCB1bmV4cGVjdGVkIHNpZ25hdHVyZSBhbGdvcml0aG1cIik7XG4gIH1cbiAgY29uc3QgcGFyYW1zID0gQXNuUGFyc2VyLnBhcnNlKGFsZy5wYXJhbWV0ZXJzISwgRUNQYXJhbWV0ZXJzKTtcbiAgaWYgKCFwYXJhbXMubmFtZWRDdXJ2ZSB8fCBwYXJhbXMubmFtZWRDdXJ2ZSAhPT0gTklTVF9QMzg0KSB7XG4gICAgLy8gbm90IHRoZSBleHBlY3RlZCBwYXJhbXMsIGkuZS4sIE5JU1QgUDM4NFxuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGVzdGF0aW9uIGNvbnRhaW5lZCB1bmV4cGVjdGVkIHNpZ25hdHVyZSBhbGdvcml0aG1cIik7XG4gIH1cblxuICAvLyB2ZXJpZnkgdGhlIGNvc2Ugc2lnbmF0dXJlIHdpdGggdGhlIGtleSwgd2hpY2ggd2UgdmVyaWZpZWQgYWdhaW5zdFxuICAvLyB0aGUgQVdTIE5pdHJvIENBIGNlcnRpZmljYXRlIGFib3ZlXG4gIGF3YWl0IGF0dC52ZXJpZnkoYXdhaXQgcHVia2V5LmV4cG9ydCgpKTtcblxuICByZXR1cm4gYXR0RG9jLnB1YmxpY19rZXk7XG59XG4iXX0=
121
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ltcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFRQSwrREFBOEQ7QUFHOUQseUNBQW1EO0FBQ25ELCtCQUF5QztBQUN6Qyw2REFBd0Q7QUFFeEQsd0RBQXdEO0FBQ3hELE1BQU0sd0JBQXdCLEdBQUcsR0FBRyxDQUFDO0FBRXJDOztHQUVHO0FBQ0gsTUFBYSxXQUFXO0lBSXRCOzs7O09BSUc7SUFDSCxZQUFZLEVBQU87O1FBUm5CLHdDQUE2QyxJQUFJLEVBQUM7UUFDekMsa0NBQVM7UUFRaEIsdUJBQUEsSUFBSSxtQkFBTyxFQUFFLE1BQUEsQ0FBQztJQUNoQixDQUFDO0lBaUJEOzs7Ozs7O09BT0c7SUFDSSxLQUFLLENBQUMsZUFBZSxDQUMxQixPQUFnQixFQUNoQixJQUF3QixFQUN4QixLQUFpQztRQUVqQyxPQUFPLE1BQU0sdUJBQUEsSUFBSSwyREFBZ0IsTUFBcEIsSUFBSSxFQUNmLE9BQU8sRUFDUCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFBLGdDQUFxQixFQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQzdDLEtBQUssQ0FDTixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxLQUFLLENBQUMsbUJBQW1CLENBQzlCLE9BQWdCLEVBQ2hCLE9BQXFCLEVBQ3JCLEtBQWlDO1FBRWpDLE9BQU8sTUFBTSx1QkFBQSxJQUFJLDJEQUFnQixNQUFwQixJQUFJLEVBQ2YsT0FBTyxFQUNQLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUEsc0JBQWdCLEVBQUMsR0FBRyxDQUFDLENBQUMsRUFDM0MsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0NBMERGO0FBNUhELGtDQTRIQzs7QUEvR0M7Ozs7O0dBS0c7QUFDSCxLQUFLO0lBQ0gsSUFBSSxDQUFDLHVCQUFBLElBQUkscUNBQWtCLElBQUksdUJBQUEsSUFBSSxxQ0FBa0IsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDO1FBQ3JFLE1BQU0sSUFBSSxHQUFHLE1BQU0sdUJBQUEsSUFBSSx1QkFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLGlDQUFnQixHQUFFLENBQUM7UUFDeEMsdUJBQUEsSUFBSSxpQ0FBcUIsTUFBTSxxQ0FBZ0IsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFBLENBQUM7SUFDaEYsQ0FBQztJQUNELE9BQU8sdUJBQUEsSUFBSSxxQ0FBa0IsQ0FBQztBQUNoQyxDQUFDO0FBMENEOzs7Ozs7O0dBT0c7QUFDSCxLQUFLLHNDQUNILE9BQWdCLEVBQ2hCLFFBQXNCLEVBQ3RCLEtBQWlDO0lBRWpDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FDcEIsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLHdCQUF3QixHQUFHLEVBQUUsQ0FBQyxHQUFHLHdCQUF3QixDQUNyRixDQUFDO0lBQ0YsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRWhCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNqQyxvRUFBb0U7UUFDcEUsbUVBQW1FO1FBQ25FLHdCQUF3QjtRQUN4QixFQUFFO1FBQ0YseUVBQXlFO1FBQ3pFLEVBQUU7UUFDRix3RUFBd0U7UUFDeEUsc0VBQXNFO1FBQ3RFLE1BQU0sR0FBRyxHQUFHLE1BQU0sdUJBQUEsSUFBSSxnRUFBcUIsTUFBekIsSUFBSSxDQUF1QixDQUFDO1FBRTlDLHVDQUF1QztRQUN2QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUErQixFQUFFLENBQUM7UUFDcEQsS0FBSyxNQUFNLE1BQU0sSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2hELE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEdBQUcsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELHdGQUF3RjtZQUN4RixvREFBb0Q7WUFDcEQsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLENBQUM7UUFFRCxvQ0FBb0M7UUFDcEMsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUM7UUFDckMsTUFBTSxHQUFHLEdBQXFCO1lBQzVCLEdBQUcsR0FBRyxDQUFDLFdBQVcsRUFBRTtZQUNwQixRQUFRLEVBQUUsT0FBTztZQUNqQixZQUFZO1lBQ1osR0FBRyxLQUFLO1lBQ1IsTUFBTTtTQUNQLENBQUM7UUFFRixNQUFNLElBQUksR0FBRyxNQUFNLHVCQUFBLElBQUksdUJBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7XG4gIEltcG9ydEtleVJlcXVlc3QsXG4gIEltcG9ydEtleVJlcXVlc3RNYXRlcmlhbCxcbiAgS2V5LFxuICBLZXlUeXBlLFxuICBPcmcsXG4gIEltcG9ydERlcml2ZUtleVByb3BlcnRpZXMsXG59IGZyb20gXCJAY3ViaXN0LWRldi9jdWJlc2lnbmVyLXNka1wiO1xuaW1wb3J0IHsgbG9hZFN1YnRsZUNyeXB0byB9IGZyb20gXCJAY3ViaXN0LWRldi9jdWJlc2lnbmVyLXNka1wiO1xuXG5pbXBvcnQgdHlwZSB7IE1uZW1vbmljVG9JbXBvcnQgfSBmcm9tIFwiLi9tbmVtb25pY1wiO1xuaW1wb3J0IHsgbmV3TW5lbW9uaWNLZXlQYWNrYWdlIH0gZnJvbSBcIi4vbW5lbW9uaWNcIjtcbmltcG9ydCB7IG5ld1Jhd0tleVBhY2thZ2UgfSBmcm9tIFwiLi9yYXdcIjtcbmltcG9ydCB7IFdyYXBwZWRJbXBvcnRLZXkgfSBmcm9tIFwiLi93cmFwcGVkX2ltcG9ydF9rZXlcIjtcblxuLy8gTWF4aW11bSBudW1iZXIgb2Yga2V5cyB0byBpbXBvcnQgaW4gYSBzaW5nbGUgQVBJIGNhbGxcbmNvbnN0IE1BWF9JTVBPUlRTX1BFUl9BUElfQ0FMTCA9IDMybjtcblxuLyoqXG4gKiBBbiBpbXBvcnQgZW5jcnlwdGlvbiBrZXkgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGF0dGVzdGF0aW9uIGRvY3VtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBLZXlJbXBvcnRlciB7XG4gICN3cmFwcGVkSW1wb3J0S2V5OiBudWxsIHwgV3JhcHBlZEltcG9ydEtleSA9IG51bGw7XG4gIHJlYWRvbmx5ICNjczogT3JnO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgZnJvbSBhIEN1YmVTaWduZXIgYE9yZ2AgaW5zdGFuY2VcbiAgICpcbiAgICogQHBhcmFtIGNzIEEgQ3ViZVNpZ25lciBgT3JnYCBpbnN0YW5jZVxuICAgKi9cbiAgY29uc3RydWN0b3IoY3M6IE9yZykge1xuICAgIHRoaXMuI2NzID0gY3M7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhhdCB0aGUgd3JhcHBlZCBpbXBvcnQga2V5IGlzIHVuZXhwaXJlZCBhbmQgdmVyaWZpZWQuIE90aGVyd2lzZSxcbiAgICogcmVxdWVzdCBhIG5ldyBvbmUgYW5kIHZlcmlmeSBpdC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgdmVyaWZpZWQgd3JhcHBlZCBpbXBvcnQga2V5LlxuICAgKi9cbiAgYXN5bmMgI2dldFdyYXBwZWRJbXBvcnRLZXkoKTogUHJvbWlzZTxXcmFwcGVkSW1wb3J0S2V5PiB7XG4gICAgaWYgKCF0aGlzLiN3cmFwcGVkSW1wb3J0S2V5IHx8IHRoaXMuI3dyYXBwZWRJbXBvcnRLZXkubmVlZHNSZWZyZXNoKCkpIHtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCB0aGlzLiNjcy5jcmVhdGVLZXlJbXBvcnRLZXkoKTtcbiAgICAgIGNvbnN0IHN1YnRsZSA9IGF3YWl0IGxvYWRTdWJ0bGVDcnlwdG8oKTtcbiAgICAgIHRoaXMuI3dyYXBwZWRJbXBvcnRLZXkgPSBhd2FpdCBXcmFwcGVkSW1wb3J0S2V5LmNyZWF0ZUFuZFZlcmlmeShyZXNwLCBzdWJ0bGUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy4jd3JhcHBlZEltcG9ydEtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiBtbmVtb25pY3MgYW5kIGltcG9ydHMgdGhlbS5cbiAgICpcbiAgICogQHBhcmFtIGtleVR5cGUgVGhlIHR5cGUgb2Yga2V5IHRvIGltcG9ydFxuICAgKiBAcGFyYW0gbW5lcyBUaGUgbW5lbW9uaWNzIHRvIGltcG9ydCwgd2l0aCBvcHRpb25hbCBkZXJpdmF0aW9uIHBhdGhzIGFuZCBwYXNzd29yZHNcbiAgICogQHBhcmFtIHByb3BzIEFkZGl0aW9uYWwgb3B0aW9ucyBmb3IgaW1wb3J0XG4gICAqIEByZXR1cm5zIGBLZXlgIG9iamVjdHMgZm9yIGVhY2ggaW1wb3J0ZWQga2V5LlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGltcG9ydE1uZW1vbmljcyhcbiAgICBrZXlUeXBlOiBLZXlUeXBlLFxuICAgIG1uZXM6IE1uZW1vbmljVG9JbXBvcnRbXSxcbiAgICBwcm9wcz86IEltcG9ydERlcml2ZUtleVByb3BlcnRpZXMsXG4gICk6IFByb21pc2U8S2V5W10+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy4jaW1wb3J0UGFja2FnZXMoXG4gICAgICBrZXlUeXBlLFxuICAgICAgbW5lcy5tYXAoKG1uZSkgPT4gbmV3TW5lbW9uaWNLZXlQYWNrYWdlKG1uZSkpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiByYXcga2V5cyBhbmQgaW1wb3J0cyB0aGVtLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5VHlwZSBUaGUgdHlwZSBvZiBrZXkgdG8gaW1wb3J0XG4gICAqIEBwYXJhbSBzZWNyZXRzIFRoZSBzZWNyZXQga2V5cyB0byBpbXBvcnQuXG4gICAqIEBwYXJhbSBwcm9wcyBBZGRpdGlvbmFsIG9wdGlvbnMgZm9yIGltcG9ydFxuICAgKiBAcmV0dXJucyBgS2V5YCBvYmplY3RzIGZvciBlYWNoIGltcG9ydGVkIGtleS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbXBvcnRSYXdTZWNyZXRLZXlzKFxuICAgIGtleVR5cGU6IEtleVR5cGUsXG4gICAgc2VjcmV0czogVWludDhBcnJheVtdLFxuICAgIHByb3BzPzogSW1wb3J0RGVyaXZlS2V5UHJvcGVydGllcyxcbiAgKTogUHJvbWlzZTxLZXlbXT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLiNpbXBvcnRQYWNrYWdlcyhcbiAgICAgIGtleVR5cGUsXG4gICAgICBzZWNyZXRzLm1hcCgoc2VjKSA9PiBuZXdSYXdLZXlQYWNrYWdlKHNlYykpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiBwcmVwYXJlZCBrZXkgcGFja2FnZXMsIGFuZCBpbXBvcnRzIHRoZW0uXG4gICAqXG4gICAqIEBwYXJhbSBrZXlUeXBlIFRoZSB0eXBlIG9mIGtleSB0byBpbXBvcnRcbiAgICogQHBhcmFtIHBhY2thZ2VzIFRoZSBrZXkgcGFja2FnZXMgdG8gaW1wb3J0LlxuICAgKiBAcGFyYW0gcHJvcHMgQWRkaXRpb25hbCBvcHRpb25zIGZvciBpbXBvcnRcbiAgICogQHJldHVybnMgYEtleWAgb2JqZWN0cyBmb3IgZWFjaCBpbXBvcnRlZCBrZXkuXG4gICAqL1xuICBhc3luYyAjaW1wb3J0UGFja2FnZXMoXG4gICAga2V5VHlwZTogS2V5VHlwZSxcbiAgICBwYWNrYWdlczogVWludDhBcnJheVtdLFxuICAgIHByb3BzPzogSW1wb3J0RGVyaXZlS2V5UHJvcGVydGllcyxcbiAgKTogUHJvbWlzZTxLZXlbXT4ge1xuICAgIGNvbnN0IG5DaHVua3MgPSBOdW1iZXIoXG4gICAgICAoQmlnSW50KHBhY2thZ2VzLmxlbmd0aCkgKyBNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwgLSAxbikgLyBNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwsXG4gICAgKTtcbiAgICBjb25zdCBrZXlzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5DaHVua3M7ICsraSkge1xuICAgICAgLy8gZmlyc3QsIG1ha2Ugc3VyZSB0aGF0IHRoZSB3cmFwcGVkIGltcG9ydCBrZXkgaXMgdmFsaWQsIGkuZS4sIHRoYXRcbiAgICAgIC8vIHdlIGhhdmUgcmV0cmlldmVkIGl0IGFuZCB0aGF0IGl0IGhhc24ndCBleHBpcmVkLiBXZSBkbyB0aGlzIGhlcmVcbiAgICAgIC8vIGZvciBhIGNvdXBsZSByZWFzb25zOlxuICAgICAgLy9cbiAgICAgIC8vIC0gYWxsIGVuY3J5cHRpb25zIGluIGEgZ2l2ZW4gcmVxdWVzdCBtdXN0IHVzZSB0aGUgc2FtZSBpbXBvcnQga2V5LCBhbmRcbiAgICAgIC8vXG4gICAgICAvLyAtIHdoZW4gaW1wb3J0aW5nIGEgaHVnZSBudW1iZXIgb2Yga2V5cyB0aGUgaW1wb3J0IHB1YmtleSBtaWdodCBleHBpcmVcbiAgICAgIC8vICAgZHVyaW5nIHRoZSBpbXBvcnQsIHNvIHdlIGNoZWNrIGZvciBleHBpcmF0aW9uIGJlZm9yZSBlYWNoIHJlcXVlc3RcbiAgICAgIGNvbnN0IHdpayA9IGF3YWl0IHRoaXMuI2dldFdyYXBwZWRJbXBvcnRLZXkoKTtcblxuICAgICAgLy8gbmV4dCwgZW5jcnlwdCB0aGlzIGNodW5rIG9mIHBhY2thZ2VzXG4gICAgICBjb25zdCBzdGFydCA9IE51bWJlcihNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwpICogaTtcbiAgICAgIGNvbnN0IGVuZCA9IE51bWJlcihNQVhfSU1QT1JUU19QRVJfQVBJX0NBTEwpICsgc3RhcnQ7XG4gICAgICBjb25zdCBrZXlfbWF0ZXJpYWw6IEltcG9ydEtleVJlcXVlc3RNYXRlcmlhbFtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IGtleVBrZyBvZiBwYWNrYWdlcy5zbGljZShzdGFydCwgZW5kKSkge1xuICAgICAgICBjb25zdCB7IGVuYywgY2lwaGVydGV4dCB9ID0gYXdhaXQgd2lrLmVuY3J5cHQoa2V5UGtnKTtcbiAgICAgICAgLy8gV2UgdXNlIGFuIGV4dGVuc2lvbiBvZiBIUEtFIHRoYXQgYWxsb3dzIGEgc2FsdCB2YWx1ZSB0byBiZSBzcGVjaWZpZWQsIGJ1dCBpdCBpcyBvayB0b1xuICAgICAgICAvLyB1c2UgYW4gZW1wdHkgc2FsdCBpZiB0aGUgaW1wb3J0IGtleSBpcyBub3QgcmV1c2VkXG4gICAgICAgIGtleV9tYXRlcmlhbC5wdXNoKHsgc2FsdDogXCJcIiwgY2xpZW50X3B1YmxpY19rZXk6IGVuYywgaWttX2VuYzogY2lwaGVydGV4dCB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uc3RydWN0IHRoZSByZXF1ZXN0IGFuZCBzZW5kIGl0XG4gICAgICBjb25zdCBwb2xpY3kgPSBwcm9wcz8ucG9saWN5ID8/IG51bGw7XG4gICAgICBjb25zdCByZXE6IEltcG9ydEtleVJlcXVlc3QgPSB7XG4gICAgICAgIC4uLndpay50b0ltcG9ydEtleSgpLFxuICAgICAgICBrZXlfdHlwZToga2V5VHlwZSxcbiAgICAgICAga2V5X21hdGVyaWFsLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgICAgcG9saWN5LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHRoaXMuI2NzLmltcG9ydEtleXMocmVxKTtcbiAgICAgIGtleXMucHVzaCguLi5yZXNwKTtcbiAgICB9XG5cbiAgICByZXR1cm4ga2V5cztcbiAgfVxufVxuIl19
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { KeyImporter } from "./import";
2
2
  export { MnemonicToImport } from "./mnemonic";
3
+ export { encryptPolicySecret, EncryptedPolicySecret } from "./policy_secret";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.KeyImporter = void 0;
3
+ exports.encryptPolicySecret = exports.KeyImporter = void 0;
4
4
  var import_1 = require("./import");
5
5
  Object.defineProperty(exports, "KeyImporter", { enumerable: true, get: function () { return import_1.KeyImporter; } });
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXVDO0FBQTlCLHFHQUFBLFdBQVcsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IEtleUltcG9ydGVyIH0gZnJvbSBcIi4vaW1wb3J0XCI7XG5leHBvcnQgeyBNbmVtb25pY1RvSW1wb3J0IH0gZnJvbSBcIi4vbW5lbW9uaWNcIjtcbiJdfQ==
6
+ var policy_secret_1 = require("./policy_secret");
7
+ Object.defineProperty(exports, "encryptPolicySecret", { enumerable: true, get: function () { return policy_secret_1.encryptPolicySecret; } });
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXVDO0FBQTlCLHFHQUFBLFdBQVcsT0FBQTtBQUVwQixpREFBNkU7QUFBcEUsb0hBQUEsbUJBQW1CLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBLZXlJbXBvcnRlciB9IGZyb20gXCIuL2ltcG9ydFwiO1xuZXhwb3J0IHsgTW5lbW9uaWNUb0ltcG9ydCB9IGZyb20gXCIuL21uZW1vbmljXCI7XG5leHBvcnQgeyBlbmNyeXB0UG9saWN5U2VjcmV0LCBFbmNyeXB0ZWRQb2xpY3lTZWNyZXQgfSBmcm9tIFwiLi9wb2xpY3lfc2VjcmV0XCI7XG4iXX0=
@@ -0,0 +1,19 @@
1
+ import type { ApiClient, KeyImportKey, SecretValue } from "@cubist-labs/cubesigner-sdk";
2
+ /**
3
+ * The result of encrypting a policy secret value.
4
+ */
5
+ export type EncryptedPolicySecret = {
6
+ /** The encrypted secret value, for use in `SetPolicySecretRequest.value`. */
7
+ value: SecretValue;
8
+ /** The import key, for use in `SetPolicySecretRequest.import_key`. */
9
+ importKey: KeyImportKey;
10
+ };
11
+ /**
12
+ * Encrypt a policy secret value using a fresh policy import key.
13
+ *
14
+ * @param client The API client.
15
+ * @param plaintext The plaintext secret value to encrypt.
16
+ * @returns The encrypted secret value and the import key to include in the request.
17
+ */
18
+ export declare function encryptPolicySecret(client: ApiClient, plaintext: string): Promise<EncryptedPolicySecret>;
19
+ //# sourceMappingURL=policy_secret.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy_secret.d.ts","sourceRoot":"","sources":["../src/policy_secret.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAIvF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,6EAA6E;IAC7E,KAAK,EAAE,WAAW,CAAC;IACnB,sEAAsE;IACtE,SAAS,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC,CAahC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encryptPolicySecret = encryptPolicySecret;
4
+ const cubesigner_sdk_1 = require("@cubist-labs/cubesigner-sdk");
5
+ const wrapped_import_key_1 = require("./wrapped_import_key");
6
+ /**
7
+ * Encrypt a policy secret value using a fresh policy import key.
8
+ *
9
+ * @param client The API client.
10
+ * @param plaintext The plaintext secret value to encrypt.
11
+ * @returns The encrypted secret value and the import key to include in the request.
12
+ */
13
+ async function encryptPolicySecret(client, plaintext) {
14
+ const resp = await client.policyImportKeyCreate();
15
+ const subtle = await (0, cubesigner_sdk_1.loadSubtleCrypto)();
16
+ const wik = await wrapped_import_key_1.WrappedImportKey.createAndVerify(resp, subtle, null);
17
+ const { enc, ciphertext } = await wik.encrypt(new TextEncoder().encode(plaintext));
18
+ return {
19
+ // We use an extension of HPKE that allows a salt value to be specified, but it is ok to
20
+ // use an empty salt if the import key is not reused
21
+ value: { client_public_key: enc, encrypted_value: ciphertext, salt: "" },
22
+ importKey: wik.toImportKey(),
23
+ };
24
+ }
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5X3NlY3JldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wb2xpY3lfc2VjcmV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBcUJBLGtEQWdCQztBQXBDRCwrREFBOEQ7QUFDOUQsNkRBQXdEO0FBWXhEOzs7Ozs7R0FNRztBQUNJLEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsTUFBaUIsRUFDakIsU0FBaUI7SUFFakIsTUFBTSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUVsRCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsaUNBQWdCLEdBQUUsQ0FBQztJQUN4QyxNQUFNLEdBQUcsR0FBRyxNQUFNLHFDQUFnQixDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRXZFLE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEdBQUcsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDbkYsT0FBTztRQUNMLHdGQUF3RjtRQUN4RixvREFBb0Q7UUFDcEQsS0FBSyxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRTtRQUN4RSxTQUFTLEVBQUUsR0FBRyxDQUFDLFdBQVcsRUFBRTtLQUM3QixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQXBpQ2xpZW50LCBLZXlJbXBvcnRLZXksIFNlY3JldFZhbHVlIH0gZnJvbSBcIkBjdWJpc3QtZGV2L2N1YmVzaWduZXItc2RrXCI7XG5pbXBvcnQgeyBsb2FkU3VidGxlQ3J5cHRvIH0gZnJvbSBcIkBjdWJpc3QtZGV2L2N1YmVzaWduZXItc2RrXCI7XG5pbXBvcnQgeyBXcmFwcGVkSW1wb3J0S2V5IH0gZnJvbSBcIi4vd3JhcHBlZF9pbXBvcnRfa2V5XCI7XG5cbi8qKlxuICogVGhlIHJlc3VsdCBvZiBlbmNyeXB0aW5nIGEgcG9saWN5IHNlY3JldCB2YWx1ZS5cbiAqL1xuZXhwb3J0IHR5cGUgRW5jcnlwdGVkUG9saWN5U2VjcmV0ID0ge1xuICAvKiogVGhlIGVuY3J5cHRlZCBzZWNyZXQgdmFsdWUsIGZvciB1c2UgaW4gYFNldFBvbGljeVNlY3JldFJlcXVlc3QudmFsdWVgLiAqL1xuICB2YWx1ZTogU2VjcmV0VmFsdWU7XG4gIC8qKiBUaGUgaW1wb3J0IGtleSwgZm9yIHVzZSBpbiBgU2V0UG9saWN5U2VjcmV0UmVxdWVzdC5pbXBvcnRfa2V5YC4gKi9cbiAgaW1wb3J0S2V5OiBLZXlJbXBvcnRLZXk7XG59O1xuXG4vKipcbiAqIEVuY3J5cHQgYSBwb2xpY3kgc2VjcmV0IHZhbHVlIHVzaW5nIGEgZnJlc2ggcG9saWN5IGltcG9ydCBrZXkuXG4gKlxuICogQHBhcmFtIGNsaWVudCBUaGUgQVBJIGNsaWVudC5cbiAqIEBwYXJhbSBwbGFpbnRleHQgVGhlIHBsYWludGV4dCBzZWNyZXQgdmFsdWUgdG8gZW5jcnlwdC5cbiAqIEByZXR1cm5zIFRoZSBlbmNyeXB0ZWQgc2VjcmV0IHZhbHVlIGFuZCB0aGUgaW1wb3J0IGtleSB0byBpbmNsdWRlIGluIHRoZSByZXF1ZXN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jcnlwdFBvbGljeVNlY3JldChcbiAgY2xpZW50OiBBcGlDbGllbnQsXG4gIHBsYWludGV4dDogc3RyaW5nLFxuKTogUHJvbWlzZTxFbmNyeXB0ZWRQb2xpY3lTZWNyZXQ+IHtcbiAgY29uc3QgcmVzcCA9IGF3YWl0IGNsaWVudC5wb2xpY3lJbXBvcnRLZXlDcmVhdGUoKTtcblxuICBjb25zdCBzdWJ0bGUgPSBhd2FpdCBsb2FkU3VidGxlQ3J5cHRvKCk7XG4gIGNvbnN0IHdpayA9IGF3YWl0IFdyYXBwZWRJbXBvcnRLZXkuY3JlYXRlQW5kVmVyaWZ5KHJlc3AsIHN1YnRsZSwgbnVsbCk7XG5cbiAgY29uc3QgeyBlbmMsIGNpcGhlcnRleHQgfSA9IGF3YWl0IHdpay5lbmNyeXB0KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShwbGFpbnRleHQpKTtcbiAgcmV0dXJuIHtcbiAgICAvLyBXZSB1c2UgYW4gZXh0ZW5zaW9uIG9mIEhQS0UgdGhhdCBhbGxvd3MgYSBzYWx0IHZhbHVlIHRvIGJlIHNwZWNpZmllZCwgYnV0IGl0IGlzIG9rIHRvXG4gICAgLy8gdXNlIGFuIGVtcHR5IHNhbHQgaWYgdGhlIGltcG9ydCBrZXkgaXMgbm90IHJldXNlZFxuICAgIHZhbHVlOiB7IGNsaWVudF9wdWJsaWNfa2V5OiBlbmMsIGVuY3J5cHRlZF92YWx1ZTogY2lwaGVydGV4dCwgc2FsdDogXCJcIiB9LFxuICAgIGltcG9ydEtleTogd2lrLnRvSW1wb3J0S2V5KCksXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,63 @@
1
+ import { type CreateKeyImportKeyResponse, type CreatePolicyImportKeyResponse, type KeyImportKey as ImportKey } from "@cubist-labs/cubesigner-sdk";
2
+ export declare const IMPORT_KEY_SIGNING_DST: Uint8Array;
3
+ export declare const WIK_REFRESH_EARLY_MILLIS = 60000n;
4
+ /**
5
+ * An import-key response with enclave attestation, compatible with both
6
+ * `CreateKeyImportKeyResponse` and `CreatePolicyImportKeyResponse`.
7
+ */
8
+ export type ImportKeyResponse = CreateKeyImportKeyResponse & CreatePolicyImportKeyResponse;
9
+ /**
10
+ * A verified import key, usable for HPKE encryption.
11
+ */
12
+ export declare class WrappedImportKey {
13
+ #private;
14
+ /**
15
+ * Private constructor.
16
+ *
17
+ * @param resp The import key response from CubeSigner.
18
+ * @param suite The HPKE ciphersuite to use for encryption.
19
+ */
20
+ private constructor();
21
+ /**
22
+ * Create and verify a `WrappedImportKey` from an import-key response.
23
+ *
24
+ * @param resp The response from CubeSigner (key import or policy import).
25
+ * @param subtle A SubtleCrypto instance used for verification.
26
+ * @param pcr8Expect The expected PCR8 value (bare hex). If `null`, the PCR8 check is skipped.
27
+ * Defaults to the Cubist enclave signing key, which is correct for key imports.
28
+ * @returns A newly constructed, verified instance.
29
+ */
30
+ static createAndVerify(resp: ImportKeyResponse, subtle: SubtleCrypto, pcr8Expect?: string | null): Promise<WrappedImportKey>;
31
+ /**
32
+ * Returns `true` if this WrappedImportKey needs to be refreshed.
33
+ *
34
+ * @returns True just if this key needs to be refreshed.
35
+ */
36
+ needsRefresh(): boolean;
37
+ /**
38
+ * Encrypt `data` using HPKE to this import key.
39
+ *
40
+ * @param data The plaintext to encrypt.
41
+ * @returns The base64-encoded HPKE encapsulated key (`enc`) and ciphertext.
42
+ */
43
+ encrypt(data: Uint8Array): Promise<{
44
+ enc: string;
45
+ ciphertext: string;
46
+ }>;
47
+ /**
48
+ * Return the import key fields, for use in import requests.
49
+ *
50
+ * @returns The import key fields.
51
+ */
52
+ toImportKey(): ImportKey;
53
+ }
54
+ /**
55
+ * Verifies the attestation key against the AWS Nitro Enclaves signing
56
+ * key and returns the attested signing key.
57
+ *
58
+ * @param attBytes An attestation from an AWS nitro enclave.
59
+ * @param pcr8Expect If non-null, the expected value of PCR8 in the attestation.
60
+ * @returns The signing key that was attested.
61
+ */
62
+ export declare function verifyAttestationKey(attBytes: Uint8Array, pcr8Expect: string | null): Promise<Uint8Array>;
63
+ //# sourceMappingURL=wrapped_import_key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapped_import_key.d.ts","sourceRoot":"","sources":["../src/wrapped_import_key.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,YAAY,IAAI,SAAS,EAC/B,MAAM,4BAA4B,CAAC;AAYpC,eAAO,MAAM,sBAAsB,YAA+D,CAAC;AAGnG,eAAO,MAAM,wBAAwB,SAAU,CAAC;AAuBhD;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,0BAA0B,GAAG,6BAA6B,CAAC;AAE3F;;GAEG;AACH,qBAAa,gBAAgB;;IAU3B;;;;;OAKG;IACH,OAAO;IAUP;;;;;;;;OAQG;WACiB,eAAe,CACjC,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,YAAY,EACpB,UAAU,GAAE,MAAM,GAAG,IAA4B,GAChD,OAAO,CAAC,gBAAgB,CAAC;IA6C5B;;;;OAIG;IACI,YAAY,IAAI,OAAO;IAmC9B;;;;;OAKG;IACU,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAWpF;;;;OAIG;IACI,WAAW,IAAI,SAAS;CAQhC;AAmBD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,UAAU,EACpB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,UAAU,CAAC,CAkErB"}