@cubist-labs/cubesigner-sdk-key-import 0.4.68-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -0
- package/dist/import.d.ts +23 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +333 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/mnemonic.d.ts +35 -0
- package/dist/mnemonic.d.ts.map +1 -0
- package/dist/mnemonic.js +93 -0
- package/dist/util.d.ts +22 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +49 -0
- package/package.json +39 -0
- package/src/import.ts +426 -0
- package/src/index.ts +2 -0
- package/src/mnemonic.ts +91 -0
- package/src/util.ts +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# CubeSigner key import
|
|
2
|
+
|
|
3
|
+
This library implements the client-side encryption used to import keys
|
|
4
|
+
into CubeSigner.
|
|
5
|
+
|
|
6
|
+
## WARNING
|
|
7
|
+
|
|
8
|
+
Importing keys using code running in an untrusted environment is **dangerous**
|
|
9
|
+
because that code must process secret key material. For example, importing
|
|
10
|
+
keys from a user's web browser is **very risky**: exposing secret keys
|
|
11
|
+
in browsers means that malicious web pages, advertisements, and extensions
|
|
12
|
+
may be able to steal your key. JS execution environments are also great
|
|
13
|
+
targets for side-channel attackers.
|
|
14
|
+
|
|
15
|
+
Whenever possible, Cubist strongly recommends generating keys using the
|
|
16
|
+
`createKey` API. We strongly recommend against using local keygen plus
|
|
17
|
+
import as a replacement for real disaster-recovery backup. Please contact
|
|
18
|
+
us if you have questions about or need help with disaster-recovery planning.
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import * as cs from "@cubist-labs/cubesigner-sdk";
|
|
24
|
+
import * as csFs from "@cubist-labs/cubesigner-sdk-fs-storage";
|
|
25
|
+
import { KeyImporter, type MnemonicToImport } from "@cubist-labs/cubesigner-sdk-key-import";
|
|
26
|
+
|
|
27
|
+
// create a CubeSigner client from credentials on-disk, which
|
|
28
|
+
// you can create by running `cs login` from the CLI.
|
|
29
|
+
const client = await cs.CubeSignerClient.create(csFs.defaultManagementSessionManager());
|
|
30
|
+
|
|
31
|
+
// create the key-importer instance
|
|
32
|
+
const keyImporter = new KeyImporter(client.org());
|
|
33
|
+
|
|
34
|
+
// mnemonics to import directly as EVM keys
|
|
35
|
+
const evmMnemonics: MnemonicToImport[] = [
|
|
36
|
+
{
|
|
37
|
+
mnemonic: "car split like parrot uphold faint amount alert inch bean priority custom auction denial reason oyster food duck horn top battle video seed company",
|
|
38
|
+
derivationPath: "m/44'/60'/0'/0/0",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
mnemonic: "force focus walnut scale barrel faint hotel fabric source because heavy provide bridge intact they receive stairs matter fetch family color happy slender accident",
|
|
42
|
+
derivationPath: "m/44'/60'/1'/0/0",
|
|
43
|
+
password: "bip39 passwords are silly",
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
// mnemonic to import directly as Bitcoin Segwit keys
|
|
47
|
+
const btcMnemonics: MnemonicToImport[] = [
|
|
48
|
+
{
|
|
49
|
+
mnemonic: "style goddess hair mountain open when train mail fly engage fork walnut end toe mail price priority ocean uncover immune spray person slogan avoid",
|
|
50
|
+
derivationPath: "m/84'/0'/0'/0/0",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
mnemonic: "marine airport maze doll note assume deliver second bus include deal escape detail friend letter captain glide actual resemble nation shell search elephant busy",
|
|
54
|
+
derivationPath: "m/84'/0'/9'/0/1",
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// import the keys
|
|
59
|
+
const evmKeys = await keyImporter.importMnemonics(cs.Secp256k1.Evm, evmMnemonics);
|
|
60
|
+
const btcKeys = await keyImporter.importMnemonics(cs.Secp256k1.Btc, btcMnemonics);
|
|
61
|
+
|
|
62
|
+
// If you want to derive many keys from the same mnemonic, you should import
|
|
63
|
+
// the bare mnemonic and use the `deriveKey` and/or `deriveKeys` methods to
|
|
64
|
+
// create keys.
|
|
65
|
+
const bareMnemonic: MnemonicToImport = {
|
|
66
|
+
mnemonic: "divide impact town typical inhale uncover rifle pet multiply idea long before debate apart pulse type need produce among pony attend cat injury ring",
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// First, import the bare mnemonic
|
|
70
|
+
const mnemonic = (await keyImporter.importMnemonics(cs.Mnemonic, [bareMnemonic]))[0];
|
|
71
|
+
|
|
72
|
+
// Then derive keys from it.
|
|
73
|
+
const deriveResponse = await org.deriveKey(cs.Secp256k1.Taproot, "m/86'/0'/3'/1/0", mnemonic.materialId);
|
|
74
|
+
const otherDeriveResponses = await org.deriveKeys(
|
|
75
|
+
cs.Secp256k1.Ava,
|
|
76
|
+
[
|
|
77
|
+
"m/1'/2'/3",
|
|
78
|
+
"m/4'/5/6",
|
|
79
|
+
"m/7/8'/9",
|
|
80
|
+
],
|
|
81
|
+
mnemonic.materialId,
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
# License
|
|
86
|
+
|
|
87
|
+
Copyright (C) 2024 Cubist, Inc. All rights reserved.
|
|
88
|
+
|
|
89
|
+
This library is licensed under the MIT and Apache-2.0 licenses.
|
|
90
|
+
See the [../../NOTICE] file for further information.
|
package/dist/import.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Key, KeyType, Org } from "@cubist-labs/cubesigner-sdk";
|
|
2
|
+
import type { MnemonicToImport } from "./mnemonic";
|
|
3
|
+
/**
|
|
4
|
+
* An import encryption key and the corresponding attestation document
|
|
5
|
+
*/
|
|
6
|
+
export declare class KeyImporter {
|
|
7
|
+
#private;
|
|
8
|
+
/**
|
|
9
|
+
* Construct from a CubeSigner `Org` instance
|
|
10
|
+
*
|
|
11
|
+
* @param { Org } cs A CubeSigner `Org` instance
|
|
12
|
+
*/
|
|
13
|
+
constructor(cs: Org);
|
|
14
|
+
/**
|
|
15
|
+
* Encrypts a set of mnemonics and imports them.
|
|
16
|
+
*
|
|
17
|
+
* @param { KeyType } keyType The type of key to import
|
|
18
|
+
* @param { MnemonicToImport[] } mnes The mnemonics to import, with optional derivation paths and passwords
|
|
19
|
+
* @return { Promise<Key[]> } `Key` objects for each imported key.
|
|
20
|
+
*/
|
|
21
|
+
importMnemonics(keyType: KeyType, mnes: MnemonicToImport[]): Promise<Key[]>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,GAAG,EACH,OAAO,EACP,GAAG,EACJ,MAAM,6BAA6B,CAAC;AAWrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAoLnD;;GAEG;AACH,qBAAa,WAAW;;IAOtB;;;;OAIG;gBACS,EAAE,EAAE,GAAG;IAoDnB;;;;;;OAMG;IACU,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAyEzF"}
|
package/dist/import.js
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
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
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
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_encrypt;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.KeyImporter = void 0;
|
|
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
|
+
const mnemonic_1 = require("./mnemonic");
|
|
22
|
+
const util_1 = require("./util");
|
|
23
|
+
// domain-separation tag used when generating signing hash for import key
|
|
24
|
+
const IMPORT_KEY_SIGNING_DST = new TextEncoder().encode("CUBESIGNER_EPHEMERAL_IMPORT_P384");
|
|
25
|
+
// attestation document slack times
|
|
26
|
+
const MAX_ATTESTATION_AGE_MINUTES = 15n;
|
|
27
|
+
const MAX_ATTESTATION_FUTURE_MINUTES = 5n;
|
|
28
|
+
const WIK_REFRESH_EARLY_MILLIS = 60000n;
|
|
29
|
+
// OIDs for elliptic curve X509 certs
|
|
30
|
+
const EC_PUBLIC_KEY = "1.2.840.10045.2.1";
|
|
31
|
+
const NIST_P384 = "1.3.132.0.34";
|
|
32
|
+
// Maximum number of keys to import in a single API call
|
|
33
|
+
const MAX_IMPORTS_PER_API_CALL = 32n;
|
|
34
|
+
// AWS Nitro Enclaves root CA certificate
|
|
35
|
+
// https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip
|
|
36
|
+
//
|
|
37
|
+
// See the documentation about AWS Nitro Enclaves verification:
|
|
38
|
+
// https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html
|
|
39
|
+
const AWS_CA_CERT = "MIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYDVQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4MTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQLDANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEGBSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZEh8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkFR+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPWrfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6NIwLz3/Y=";
|
|
40
|
+
/**
|
|
41
|
+
* The result of deserializing a CreateKeyImportKeyResponse
|
|
42
|
+
*/
|
|
43
|
+
class WrappedImportKey {
|
|
44
|
+
/**
|
|
45
|
+
* Constructor. This is only called from `WrappedImportKey.createAndVerify()`.
|
|
46
|
+
*
|
|
47
|
+
* @param { CreateKeyImportKeyResponse } resp The response from CubeSigner
|
|
48
|
+
*/
|
|
49
|
+
constructor(resp) {
|
|
50
|
+
_WrappedImportKey_instances.add(this);
|
|
51
|
+
_WrappedImportKey_enclaveAttestation.set(this, void 0);
|
|
52
|
+
_WrappedImportKey_enclaveSignature.set(this, void 0);
|
|
53
|
+
if (!resp.enclave_attestation || !resp.enclave_signature) {
|
|
54
|
+
throw new Error("No attestation found in CreateKeyImportKeyResponse");
|
|
55
|
+
}
|
|
56
|
+
// parse the response
|
|
57
|
+
this.publicKey = new Uint8Array(Buffer.from(resp.public_key, "base64"));
|
|
58
|
+
this.publicKeyBase64 = resp.public_key;
|
|
59
|
+
this.skEnc = new Uint8Array(Buffer.from(resp.sk_enc, "base64"));
|
|
60
|
+
this.skEncBase64 = resp.sk_enc;
|
|
61
|
+
this.dkEnc = new Uint8Array(Buffer.from(resp.dk_enc, "base64"));
|
|
62
|
+
this.dkEncBase64 = resp.dk_enc;
|
|
63
|
+
__classPrivateFieldSet(this, _WrappedImportKey_enclaveAttestation, new Uint8Array(Buffer.from(resp.enclave_attestation, "base64")), "f");
|
|
64
|
+
__classPrivateFieldSet(this, _WrappedImportKey_enclaveSignature, new Uint8Array(Buffer.from(resp.enclave_signature, "base64")), "f");
|
|
65
|
+
this.expEpochSeconds = BigInt(resp.expires);
|
|
66
|
+
// this array is updated in createAndVerify once verification succeeds
|
|
67
|
+
this.verifiedHash = new Uint8Array(32);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create and verify an instance of this type
|
|
71
|
+
*
|
|
72
|
+
* @param { CreateKeyImportKeyResponse } resp The response from CubeSigner
|
|
73
|
+
* @param { SubtleCrypto } subtle An instance of SubtleCrypto used for verification
|
|
74
|
+
* @return { Promise<WrappedImportKey> } A newly constructed instance
|
|
75
|
+
*/
|
|
76
|
+
static async createAndVerify(resp, subtle) {
|
|
77
|
+
const ret = new WrappedImportKey(resp);
|
|
78
|
+
const hash = await __classPrivateFieldGet(ret, _WrappedImportKey_instances, "m", _WrappedImportKey_verifyImportKey).call(ret, subtle);
|
|
79
|
+
ret.verifiedHash.set(hash);
|
|
80
|
+
return ret;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Returns `true` if this WrappedImportKey needs to be refreshed.
|
|
84
|
+
*
|
|
85
|
+
* @return { boolean } True just if this key needs to be refreshed.
|
|
86
|
+
*/
|
|
87
|
+
needsRefresh() {
|
|
88
|
+
// force refresh if we're within WIK_REFRESH_EARLY_MILLIS of the expiration
|
|
89
|
+
return (0, util_1.nowEpochMillis)() + WIK_REFRESH_EARLY_MILLIS > this.expEpochSeconds * 1000n;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
_WrappedImportKey_enclaveAttestation = new WeakMap(), _WrappedImportKey_enclaveSignature = new WeakMap(), _WrappedImportKey_instances = new WeakSet(), _WrappedImportKey_verifyImportKey =
|
|
93
|
+
/**
|
|
94
|
+
* Verify this wrapped import key.
|
|
95
|
+
*
|
|
96
|
+
* @param { SubtleCrypto } subtle An instance of SubtleCrypto used for verification
|
|
97
|
+
* @return { Promise<Uint8Array> } The hash of the successfully verified wrapped import key
|
|
98
|
+
*/
|
|
99
|
+
async function _WrappedImportKey_verifyImportKey(subtle) {
|
|
100
|
+
// check expiration date
|
|
101
|
+
if ((0, util_1.nowEpochMillis)() > this.expEpochSeconds * 1000n) {
|
|
102
|
+
throw new Error("Import key is expired");
|
|
103
|
+
}
|
|
104
|
+
// make sure that there is an attestation
|
|
105
|
+
if (!__classPrivateFieldGet(this, _WrappedImportKey_enclaveSignature, "f") || !__classPrivateFieldGet(this, _WrappedImportKey_enclaveAttestation, "f")) {
|
|
106
|
+
throw new Error("No attestation found");
|
|
107
|
+
}
|
|
108
|
+
const signing_key = await verifyAttestationKey(__classPrivateFieldGet(this, _WrappedImportKey_enclaveAttestation, "f"));
|
|
109
|
+
// we use subtlecrypto's impl of RSA-PSS verification
|
|
110
|
+
const rsaPssKeyParams = {
|
|
111
|
+
name: "RSA-PSS",
|
|
112
|
+
hash: "SHA-256",
|
|
113
|
+
};
|
|
114
|
+
const pubkey = await subtle.importKey("spki", signing_key, rsaPssKeyParams, true, ["verify"]);
|
|
115
|
+
const pubkeyAlg = pubkey.algorithm;
|
|
116
|
+
// compute the signing hash and verify the signature
|
|
117
|
+
const message = __classPrivateFieldGet(this, _WrappedImportKey_instances, "m", _WrappedImportKey_signedData).call(this);
|
|
118
|
+
const mlen = Number(BigInt(pubkeyAlg.modulusLength) / 8n);
|
|
119
|
+
const rsaPssParams = {
|
|
120
|
+
name: "RSA-PSS",
|
|
121
|
+
saltLength: mlen - 2 - 32,
|
|
122
|
+
};
|
|
123
|
+
if (await subtle.verify(rsaPssParams, pubkey, __classPrivateFieldGet(this, _WrappedImportKey_enclaveSignature, "f"), message)) {
|
|
124
|
+
return new Uint8Array(await subtle.digest("SHA-256", message));
|
|
125
|
+
}
|
|
126
|
+
throw new Error("Import key signature verification failed");
|
|
127
|
+
}, _WrappedImportKey_signedData = function _WrappedImportKey_signedData() {
|
|
128
|
+
const parts = [
|
|
129
|
+
// domain separation tag
|
|
130
|
+
(0, util_1.toBigEndian)(BigInt(IMPORT_KEY_SIGNING_DST.length), 2),
|
|
131
|
+
IMPORT_KEY_SIGNING_DST,
|
|
132
|
+
// public key
|
|
133
|
+
(0, util_1.toBigEndian)(BigInt(this.publicKey.length), 2),
|
|
134
|
+
this.publicKey,
|
|
135
|
+
// sk_enc
|
|
136
|
+
(0, util_1.toBigEndian)(BigInt(this.skEnc.length), 2),
|
|
137
|
+
this.skEnc,
|
|
138
|
+
// dk_enc
|
|
139
|
+
(0, util_1.toBigEndian)(BigInt(this.dkEnc.length), 2),
|
|
140
|
+
this.dkEnc,
|
|
141
|
+
// 8-byte big-endian expiration time in seconds since UNIX epoch
|
|
142
|
+
(0, util_1.toBigEndian)(this.expEpochSeconds, 8),
|
|
143
|
+
];
|
|
144
|
+
return (0, util_1.concatArrays)(parts);
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* An import encryption key and the corresponding attestation document
|
|
148
|
+
*/
|
|
149
|
+
class KeyImporter {
|
|
150
|
+
/**
|
|
151
|
+
* Construct from a CubeSigner `Org` instance
|
|
152
|
+
*
|
|
153
|
+
* @param { Org } cs A CubeSigner `Org` instance
|
|
154
|
+
*/
|
|
155
|
+
constructor(cs) {
|
|
156
|
+
_KeyImporter_instances.add(this);
|
|
157
|
+
_KeyImporter_wrappedImportKey.set(this, null);
|
|
158
|
+
_KeyImporter_subtleCrypto.set(this, null);
|
|
159
|
+
_KeyImporter_publicKeyHandle.set(this, null);
|
|
160
|
+
_KeyImporter_hpkeSuite.set(this, void 0);
|
|
161
|
+
_KeyImporter_cs.set(this, void 0);
|
|
162
|
+
__classPrivateFieldSet(this, _KeyImporter_cs, cs, "f");
|
|
163
|
+
__classPrivateFieldSet(this, _KeyImporter_hpkeSuite, new core_1.CipherSuite({
|
|
164
|
+
kem: new core_1.DhkemP384HkdfSha384(),
|
|
165
|
+
kdf: new core_1.HkdfSha384(),
|
|
166
|
+
aead: new core_1.Aes256Gcm(),
|
|
167
|
+
}), "f");
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Encrypts a set of mnemonics and imports them.
|
|
171
|
+
*
|
|
172
|
+
* @param { KeyType } keyType The type of key to import
|
|
173
|
+
* @param { MnemonicToImport[] } mnes The mnemonics to import, with optional derivation paths and passwords
|
|
174
|
+
* @return { Promise<Key[]> } `Key` objects for each imported key.
|
|
175
|
+
*/
|
|
176
|
+
async importMnemonics(keyType, mnes) {
|
|
177
|
+
const nChunks = Number((BigInt(mnes.length) + MAX_IMPORTS_PER_API_CALL - 1n) / MAX_IMPORTS_PER_API_CALL);
|
|
178
|
+
const keys = [];
|
|
179
|
+
for (let i = 0; i < nChunks; ++i) {
|
|
180
|
+
// first, make sure that the wrapped import key is valid, i.e., that
|
|
181
|
+
// we have retrieved it and that it hasn't expired. We do this here
|
|
182
|
+
// for a couple reasons:
|
|
183
|
+
//
|
|
184
|
+
// - all encryptions in a give request must use the same import key, and
|
|
185
|
+
//
|
|
186
|
+
// - when importing a huge number of keys the import pubkey might expire
|
|
187
|
+
// during the import, so we check for expiration before each request
|
|
188
|
+
const { wik, ipk } = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_getWrappedImportAndPubKey).call(this);
|
|
189
|
+
// next, encrypt this chunk of mnemonics
|
|
190
|
+
const start = Number(MAX_IMPORTS_PER_API_CALL) * i;
|
|
191
|
+
const end = Number(MAX_IMPORTS_PER_API_CALL) + start;
|
|
192
|
+
const mneSlice = mnes.slice(start, end);
|
|
193
|
+
const key_material = [];
|
|
194
|
+
for (const mne of mneSlice) {
|
|
195
|
+
const keyPkg = (0, mnemonic_1.newMnemonicKeyPackage)(mne);
|
|
196
|
+
const material = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_encrypt).call(this, keyPkg, wik.verifiedHash, ipk);
|
|
197
|
+
key_material.push(material);
|
|
198
|
+
}
|
|
199
|
+
// construct the request
|
|
200
|
+
const req = {
|
|
201
|
+
public_key: wik.publicKeyBase64,
|
|
202
|
+
sk_enc: wik.skEncBase64,
|
|
203
|
+
dk_enc: wik.dkEncBase64,
|
|
204
|
+
expires: Number(wik.expEpochSeconds),
|
|
205
|
+
key_type: keyType,
|
|
206
|
+
key_material,
|
|
207
|
+
};
|
|
208
|
+
// send it and append the result to the return value
|
|
209
|
+
const resp = await __classPrivateFieldGet(this, _KeyImporter_cs, "f").importKeys(req);
|
|
210
|
+
keys.push(...resp);
|
|
211
|
+
}
|
|
212
|
+
return keys;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.KeyImporter = KeyImporter;
|
|
216
|
+
_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 =
|
|
217
|
+
/**
|
|
218
|
+
* Check that the wrapped import key is unexpired and verified. Otherwise,
|
|
219
|
+
* request a new one, verify it, and update the verified signing hash.
|
|
220
|
+
*
|
|
221
|
+
* @return { Promise<[WrappedImportKey, CryptoKey]> } The verified signing hash.
|
|
222
|
+
*/
|
|
223
|
+
async function _KeyImporter_getWrappedImportAndPubKey() {
|
|
224
|
+
if (!__classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f")) {
|
|
225
|
+
// first time we load a WrappedImportKey, make sure the x509 crypto
|
|
226
|
+
// provider is set correctly.
|
|
227
|
+
x509_1.cryptoProvider.set(await (0, cubesigner_sdk_1.loadCrypto)());
|
|
228
|
+
}
|
|
229
|
+
if (!__classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f") || __classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f").needsRefresh()) {
|
|
230
|
+
const kikResp = await __classPrivateFieldGet(this, _KeyImporter_cs, "f").createKeyImportKey();
|
|
231
|
+
const subtle = await __classPrivateFieldGet(this, _KeyImporter_instances, "m", _KeyImporter_getSubtleCrypto).call(this);
|
|
232
|
+
const wik = await WrappedImportKey.createAndVerify(kikResp, subtle);
|
|
233
|
+
// import the public key from the WrappedImportKey
|
|
234
|
+
const p384Params = {
|
|
235
|
+
name: "ECDH",
|
|
236
|
+
namedCurve: "P-384",
|
|
237
|
+
};
|
|
238
|
+
__classPrivateFieldSet(this, _KeyImporter_publicKeyHandle, await subtle.importKey("raw", wik.publicKey, p384Params, true, []), "f");
|
|
239
|
+
__classPrivateFieldSet(this, _KeyImporter_wrappedImportKey, wik, "f");
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
wik: __classPrivateFieldGet(this, _KeyImporter_wrappedImportKey, "f"),
|
|
243
|
+
ipk: __classPrivateFieldGet(this, _KeyImporter_publicKeyHandle, "f"),
|
|
244
|
+
};
|
|
245
|
+
}, _KeyImporter_getSubtleCrypto =
|
|
246
|
+
/**
|
|
247
|
+
* Get or create an instance of SubtleCrypto.
|
|
248
|
+
*
|
|
249
|
+
* @return { SubtleCrypto } The instance of SubtleCrypto.
|
|
250
|
+
*/
|
|
251
|
+
async function _KeyImporter_getSubtleCrypto() {
|
|
252
|
+
if (!__classPrivateFieldGet(this, _KeyImporter_subtleCrypto, "f")) {
|
|
253
|
+
__classPrivateFieldSet(this, _KeyImporter_subtleCrypto, await (0, cubesigner_sdk_1.loadSubtleCrypto)(), "f");
|
|
254
|
+
}
|
|
255
|
+
return __classPrivateFieldGet(this, _KeyImporter_subtleCrypto, "f");
|
|
256
|
+
}, _KeyImporter_encrypt =
|
|
257
|
+
/**
|
|
258
|
+
* Encrypt to this wrapped import key. Stores the result in `this.encrypted_keys`
|
|
259
|
+
*
|
|
260
|
+
* @param { Uint8Array } data The data to encrypt
|
|
261
|
+
* @param { Uint8Array } verifiedHash The verified signing hash of the wrapped import key to which to encrypt
|
|
262
|
+
* @param { CryptoKey } pubkey The public key to encrypt to
|
|
263
|
+
* @return { Promise<ImportKeyRequestMaterial> } The encrypted key material
|
|
264
|
+
*/
|
|
265
|
+
async function _KeyImporter_encrypt(data, verifiedHash, pubkey) {
|
|
266
|
+
// set up the HPKE sender
|
|
267
|
+
const sender = await __classPrivateFieldGet(this, _KeyImporter_hpkeSuite, "f").createSenderContext({
|
|
268
|
+
recipientPublicKey: pubkey,
|
|
269
|
+
info: verifiedHash,
|
|
270
|
+
});
|
|
271
|
+
// encrypt and construct the return value
|
|
272
|
+
const senderCtext = await sender.seal(data);
|
|
273
|
+
return {
|
|
274
|
+
salt: "",
|
|
275
|
+
client_public_key: Buffer.from(sender.enc).toString("base64"),
|
|
276
|
+
ikm_enc: Buffer.from(senderCtext).toString("base64"),
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Verifies the attestation key against the AWS Nitro Enclaves signing
|
|
281
|
+
* key and returns the attested signing key.
|
|
282
|
+
*
|
|
283
|
+
* @param { Uint8Array } attBytes An attestation from an AWS nitro enclave
|
|
284
|
+
* @return { Promise<Uint8Array> } The signing key that was attested, or null if verification failed
|
|
285
|
+
*/
|
|
286
|
+
async function verifyAttestationKey(attBytes) {
|
|
287
|
+
// cbor-x is being imported as ESM, so we must asynchronously import it here.
|
|
288
|
+
// Because we only use that and auth0/cose here, we import both this way.
|
|
289
|
+
const { Sign1 } = await import("@auth0/cose");
|
|
290
|
+
const { decode: cborDecode } = await import("cbor-x");
|
|
291
|
+
const att = Sign1.decode(attBytes);
|
|
292
|
+
const attDoc = cborDecode(att.payload);
|
|
293
|
+
// check expiration date of attestation
|
|
294
|
+
const latest = (0, util_1.nowEpochMillis)() + MAX_ATTESTATION_FUTURE_MINUTES * 60n * 1000n;
|
|
295
|
+
const earliest = latest - (MAX_ATTESTATION_FUTURE_MINUTES + MAX_ATTESTATION_AGE_MINUTES) * 60n * 1000n;
|
|
296
|
+
if (attDoc.timestamp < earliest || attDoc.timestamp > latest) {
|
|
297
|
+
throw new Error("Attestation is expired");
|
|
298
|
+
}
|
|
299
|
+
// if there's no public key in this attestation, give up
|
|
300
|
+
if (!attDoc.public_key) {
|
|
301
|
+
throw new Error("Attestation did not include a signing public key");
|
|
302
|
+
}
|
|
303
|
+
// Verify certificate chain starting with AWS Nitro CA cert
|
|
304
|
+
let parent = new x509_1.X509Certificate(AWS_CA_CERT);
|
|
305
|
+
for (let i = 0; i < attDoc.cabundle.length; ++i) {
|
|
306
|
+
const cert = new x509_1.X509Certificate(attDoc.cabundle[i]);
|
|
307
|
+
if (!(await cert.verify(parent))) {
|
|
308
|
+
throw new Error(`Attestation certificate chain failed at index ${i}`);
|
|
309
|
+
}
|
|
310
|
+
parent = cert;
|
|
311
|
+
}
|
|
312
|
+
const cert = new x509_1.X509Certificate(attDoc.certificate);
|
|
313
|
+
if (!(await cert.verify(parent))) {
|
|
314
|
+
throw new Error("Attestation certificate chain failed at leaf");
|
|
315
|
+
}
|
|
316
|
+
const pubkey = cert.publicKey;
|
|
317
|
+
// make sure that we got the expected public key type
|
|
318
|
+
const alg = new x509_1.AlgorithmProvider().toAsnAlgorithm(pubkey.algorithm);
|
|
319
|
+
if (alg.algorithm != EC_PUBLIC_KEY) {
|
|
320
|
+
// not the expected algorithm, i.e., elliptic curve signing
|
|
321
|
+
throw new Error("Attestation contained unexpected signature algorithm");
|
|
322
|
+
}
|
|
323
|
+
const params = asn1_schema_1.AsnParser.parse(alg.parameters, asn1_ecc_1.ECParameters);
|
|
324
|
+
if (!params.namedCurve || params.namedCurve !== NIST_P384) {
|
|
325
|
+
// not the expected params, i.e., NIST P384
|
|
326
|
+
throw new Error("Attestation contained unexpected signature algorithm");
|
|
327
|
+
}
|
|
328
|
+
// verify the cose signature with the key, which we verified against
|
|
329
|
+
// the AWS Nitro CA certificate above
|
|
330
|
+
await att.verify(await pubkey.export());
|
|
331
|
+
return attDoc.public_key;
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ltcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFRQSxnRUFBMkU7QUFDM0UscUNBQXFGO0FBQ3JGLGlEQUFrRDtBQUNsRCx1REFBa0Q7QUFDbEQseUNBSXdCO0FBR3hCLHlDQUFtRDtBQUNuRCxpQ0FBbUU7QUFFbkUseUVBQXlFO0FBQ3pFLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsa0NBQWtDLENBQUMsQ0FBQztBQUU1RixtQ0FBbUM7QUFDbkMsTUFBTSwyQkFBMkIsR0FBRyxHQUFHLENBQUM7QUFDeEMsTUFBTSw4QkFBOEIsR0FBRyxFQUFFLENBQUM7QUFDMUMsTUFBTSx3QkFBd0IsR0FBRyxNQUFPLENBQUM7QUFFekMscUNBQXFDO0FBQ3JDLE1BQU0sYUFBYSxHQUFHLG1CQUFtQixDQUFDO0FBQzFDLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQztBQUVqQyx3REFBd0Q7QUFDeEQsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUM7QUFFckMseUNBQXlDO0FBQ3pDLHlFQUF5RTtBQUN6RSxFQUFFO0FBQ0YsK0RBQStEO0FBQy9ELG9FQUFvRTtBQUNwRSxNQUFNLFdBQVcsR0FDZiwwc0JBQTBzQixDQUFDO0FBRTdzQjs7R0FFRztBQUNILE1BQU0sZ0JBQWdCO0lBZ0JwQjs7OztPQUlHO0lBQ0gsWUFBb0IsSUFBZ0M7O1FBUjNDLHVEQUFnQztRQUNoQyxxREFBOEI7UUFRckMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBRUQscUJBQXFCO1FBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElB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TSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7SUFFOUIscURBQXFEO0lBQ3JELE1BQU0sR0FBRyxHQUFHLElBQUksd0JBQWlCLEVBQUUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3JFLElBQUksR0FBRyxDQUFDLFNBQVMsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNuQywyREFBMkQ7UUFDM0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyx1QkFBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVyxFQUFFLHVCQUFZLENBQUMsQ0FBQztJQUM5RCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFELDJDQUEyQztRQUMzQyxNQUFNLElBQUksS0FBSyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVELG9FQUFvRTtJQUNwRSxxQ0FBcUM7SUFDckMsTUFBTSxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFFeEMsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDO0FBQzNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7XG4gIENyZWF0ZUtleUltcG9ydEtleVJlc3BvbnNlLFxuICBJbXBvcnRLZXlSZXF1ZXN0LFxuICBJbXBvcnRLZXlSZXF1ZXN0TWF0ZXJpYWwsXG4gIEtleSxcbiAgS2V5VHlwZSxcbiAgT3JnLFxufSBmcm9tIFwiQGN1YmlzdC1sYWJzL2N1YmVzaWduZXItc2RrXCI7XG5pbXBvcnQgeyBsb2FkQ3J5cHRvLCBsb2FkU3VidGxlQ3J5cHRvIH0gZnJvbSBcIkBjdWJpc3QtbGFicy9jdWJlc2lnbmVyLXNka1wiO1xuaW1wb3J0IHsgQ2lwaGVyU3VpdGUsIEFlczI1NkdjbSwgSGtkZlNoYTM4NCwgRGhrZW1QMzg0SGtkZlNoYTM4NCB9IGZyb20gXCJAaHBrZS9jb3JlXCI7XG5pbXBvcnQgeyBFQ1BhcmFtZXRlcnMgfSBmcm9tIFwiQHBlY3VsaWFyL2FzbjEtZWNjXCI7XG5pbXBvcnQgeyBBc25QYXJzZXIgfSBmcm9tIFwiQHBlY3VsaWFyL2FzbjEtc2NoZW1hXCI7XG5pbXBvcnQge1xuICBBbGdvcml0aG1Qcm92aWRlcixcbiAgWDUwOUNlcnRpZmljYXRlLFxuICBjcnlwdG9Qcm92aWRlciBhcyB4NTA5Q3J5cHRvUHJvdmlkZXIsXG59IGZyb20gXCJAcGVjdWxpYXIveDUwOVwiO1xuXG5pbXBvcnQgdHlwZSB7IE1uZW1vbmljVG9JbXBvcnQgfSBmcm9tIFwiLi9tbmVtb25pY1wiO1xuaW1wb3J0IHsgbmV3TW5lbW9uaWNLZXlQYWNrYWdlIH0gZnJvbSBcIi4vbW5lbW9uaWNcIjtcbmltcG9ydCB7IHRvQmlnRW5kaWFuLCBjb25jYXRBcnJheXMsIG5vd0Vwb2NoTWlsbGlzIH0gZnJvbSBcIi4vdXRpbFwiO1xuXG4vLyBkb21haW4tc2VwYXJhdGlvbiB0YWcgdXNlZCB3aGVuIGdlbmVyYXRpbmcgc2lnbmluZyBoYXNoIGZvciBpbXBvcnQga2V5XG5jb25zdCBJTVBPUlRfS0VZX1NJR05JTkdfRFNUID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKFwiQ1VCRVNJR05FUl9FUEhFTUVSQUxfSU1QT1JUX1AzODRcIik7XG5cbi8vIGF0dGVzdGF0aW9uIGRvY3VtZW50IHNsYWNrIHRpbWVzXG5jb25zdCBNQVhfQVRURVNUQVRJT05fQUdFX01JTlVURVMgPSAxNW47XG5jb25zdCBNQVhfQVRURVNUQVRJT05fRlVUVVJFX01JTlVURVMgPSA1bjtcbmNvbnN0IFdJS19SRUZSRVNIX0VBUkxZX01JTExJUyA9IDYwXzAwMG47XG5cbi8vIE9JRHMgZm9yIGVsbGlwdGljIGN1cnZlIFg1MDkgY2VydHNcbmNvbnN0IEVDX1BVQkxJQ19LRVkgPSBcIjEuMi44NDAuMTAwNDUuMi4xXCI7XG5jb25zdCBOSVNUX1AzODQgPSBcIjEuMy4xMzIuMC4zNFwiO1xuXG4vLyBNYXhpbXVtIG51bWJlciBvZiBrZXlzIHRvIGltcG9ydCBpbiBhIHNpbmdsZSBBUEkgY2FsbFxuY29uc3QgTUFYX0lNUE9SVFNfUEVSX0FQSV9DQUxMID0gMzJuO1xuXG4vLyBBV1MgTml0cm8gRW5jbGF2ZXMgcm9vdCBDQSBjZXJ0aWZpY2F0ZVxuLy8gaHR0cHM6Ly9hd3Mtbml0cm8tZW5jbGF2ZXMuYW1hem9uYXdzLmNvbS9BV1NfTml0cm9FbmNsYXZlc19Sb290LUcxLnppcFxuLy9cbi8vIFNlZSB0aGUgZG9jdW1lbnRhdGlvbiBhYm91dCBBV1MgTml0cm8gRW5jbGF2ZXMgdmVyaWZpY2F0aW9uOlxuLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VuY2xhdmVzL2xhdGVzdC91c2VyL3ZlcmlmeS1yb290Lmh0bWxcbmNvbnN0IEFXU19DQV9DRVJUID1cbiAgXCJNSUlDRVRDQ0FaYWdBd0lCQWdJUkFQa3hkV2dia0svaEhVYk10T1RuK0ZZd0NnWUlLb1pJemowRUF3TXdTVEVMTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFvTUJrRnRZWHB2YmpFTU1Bb0dBMVVFQ3d3RFFWZFRNUnN3R1FZRFZRUUREQkpoZDNNdWJtbDBjbTh0Wlc1amJHRjJaWE13SGhjTk1Ua3hNREk0TVRNeU9EQTFXaGNOTkRreE1ESTRNVFF5T0RBMVdqQkpNUXN3Q1FZRFZRUUdFd0pWVXpFUE1BMEdBMVVFQ2d3R1FXMWhlbTl1TVF3d0NnWURWUVFMREFOQlYxTXhHekFaQmdOVkJBTU1FbUYzY3k1dWFYUnlieTFsYm1Oc1lYWmxjekIyTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQTJJQUJQd0NWT3VtQ01IemFIRGltdHFRdmtZNE1wSnpib2xMLy9aeTJZbEVTMUJSNVRTa3NmYmI0OEM4V0JveXQ3RjJCdzdlRXRhYVArb2hHMmJuVXM5OTBkMEpYMjhUY1BRWENFUFozQkFCSWVUUFl3RW9DV1pFaDhsNVlvUXdUY1UvOUtOQ01FQXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVrQ1cxRGRrRlIrZVd3NWI2Y3AzUG1hbmZTNVl3RGdZRFZSMFBBUUgvQkFRREFnR0dNQW9HQ0NxR1NNNDlCQU1EQTJrQU1HWUNNUUNqZnkrUm9jbTlYdWU0WW53V21OSlZBNDRmQTBQNVcyT3BZb3c5T1lDVlJhRWV2TDh1TzFYWXJ1NXh0TVBXcmZNQ01RQ2k4NXNXQmJKd0tLWGRTNkJwdFFGdVpiVDczby9nQmgxcVV4bC9uTnIxMlVPOFlmd3I2d1BMYis2Tkl3THozL1k9XCI7XG5cbi8qKlxuICogVGhlIHJlc3VsdCBvZiBkZXNlcmlhbGl6aW5nIGEgQ3JlYXRlS2V5SW1wb3J0S2V5UmVzcG9uc2VcbiAqL1xuY2xhc3MgV3JhcHBlZEltcG9ydEtleSB7XG4gIHJlYWRvbmx5IHZlcmlmaWVkSGFzaDogVWludDhBcnJheTtcblxuICByZWFkb25seSBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gIHJlYWRvbmx5IHB1YmxpY0tleUJhc2U2NDogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IHNrRW5jOiBVaW50OEFycmF5O1xuICByZWFkb25seSBza0VuY0Jhc2U2NDogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IGRrRW5jOiBVaW50OEFycmF5O1xuICByZWFkb25seSBka0VuY0Jhc2U2NDogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IGV4cEVwb2NoU2Vjb25kczogYmlnaW50O1xuICByZWFkb25seSAjZW5jbGF2ZUF0dGVzdGF0aW9uOiBVaW50OEFycmF5O1xuICByZWFkb25seSAjZW5jbGF2ZVNpZ25hdHVyZTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogQ29uc3RydWN0b3IuIFRoaXMgaXMgb25seSBjYWxsZWQgZnJvbSBgV3JhcHBlZEltcG9ydEtleS5jcmVhdGVBbmRWZXJpZnkoKWAuXG4gICAqXG4gICAqIEBwYXJhbSB7IENyZWF0ZUtleUltcG9ydEtleVJlc3BvbnNlIH0gcmVzcCBUaGUgcmVzcG9uc2UgZnJvbSBDdWJlU2lnbmVyXG4gICAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHJlc3A6IENyZWF0ZUtleUltcG9ydEtleVJlc3BvbnNlKSB7XG4gICAgaWYgKCFyZXNwLmVuY2xhdmVfYXR0ZXN0YXRpb24gfHwgIXJlc3AuZW5jbGF2ZV9zaWduYXR1cmUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGF0dGVzdGF0aW9uIGZvdW5kIGluIENyZWF0ZUtleUltcG9ydEtleVJlc3BvbnNlXCIpO1xuICAgIH1cblxuICAgIC8vIHBhcnNlIHRoZSByZXNwb25zZVxuICAgIHRoaXMucHVibGljS2V5ID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20ocmVzcC5wdWJsaWNfa2V5LCBcImJhc2U2NFwiKSk7XG4gICAgdGhpcy5wdWJsaWNLZXlCYXNlNjQgPSByZXNwLnB1YmxpY19rZXk7XG5cbiAgICB0aGlzLnNrRW5jID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20ocmVzcC5za19lbmMsIFwiYmFzZTY0XCIpKTtcbiAgICB0aGlzLnNrRW5jQmFzZTY0ID0gcmVzcC5za19lbmM7XG5cbiAgICB0aGlzLmRrRW5jID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20ocmVzcC5ka19lbmMsIFwiYmFzZTY0XCIpKTtcbiAgICB0aGlzLmRrRW5jQmFzZTY0ID0gcmVzcC5ka19lbmM7XG5cbiAgICB0aGlzLiNlbmNsYXZlQXR0ZXN0YXRpb24gPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShyZXNwLmVuY2xhdmVfYXR0ZXN0YXRpb24sIFwiYmFzZTY0XCIpKTtcbiAgICB0aGlzLiNlbmNsYXZlU2lnbmF0dXJlID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20ocmVzcC5lbmNsYXZlX3NpZ25hdHVyZSwgXCJiYXNlNjRcIikpO1xuICAgIHRoaXMuZXhwRXBvY2hTZWNvbmRzID0gQmlnSW50KHJlc3AuZXhwaXJlcyk7XG5cbiAgICAvLyB0aGlzIGFycmF5IGlzIHVwZGF0ZWQgaW4gY3JlYXRlQW5kVmVyaWZ5IG9uY2UgdmVyaWZpY2F0aW9uIHN1Y2NlZWRzXG4gICAgdGhpcy52ZXJpZmllZEhhc2ggPSBuZXcgVWludDhBcnJheSgzMik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuZCB2ZXJpZnkgYW4gaW5zdGFuY2Ugb2YgdGhpcyB0eXBlXG4gICAqXG4gICAqIEBwYXJhbSB7IENyZWF0ZUtleUltcG9ydEtleVJlc3BvbnNlIH0gcmVzcCBUaGUgcmVzcG9uc2UgZnJvbSBDdWJlU2lnbmVyXG4gICAqIEBwYXJhbSB7IFN1YnRsZUNyeXB0byB9IHN1YnRsZSBBbiBpbnN0YW5jZSBvZiBTdWJ0bGVDcnlwdG8gdXNlZCBmb3IgdmVyaWZpY2F0aW9uXG4gICAqIEByZXR1cm4geyBQcm9taXNlPFdyYXBwZWRJbXBvcnRLZXk+IH0gQSBuZXdseSBjb25zdHJ1Y3RlZCBpbnN0YW5jZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVhdGVBbmRWZXJpZnkoXG4gICAgcmVzcDogQ3JlYXRlS2V5SW1wb3J0S2V5UmVzcG9uc2UsXG4gICAgc3VidGxlOiBTdWJ0bGVDcnlwdG8sXG4gICk6IFByb21pc2U8V3JhcHBlZEltcG9ydEtleT4ge1xuICAgIGNvbnN0IHJldCA9IG5ldyBXcmFwcGVkSW1wb3J0S2V5KHJlc3ApO1xuICAgIGNvbnN0IGhhc2ggPSBhd2FpdCByZXQuI3ZlcmlmeUltcG9ydEtleShzdWJ0bGUpO1xuICAgIHJldC52ZXJpZmllZEhhc2guc2V0KGhhc2gpO1xuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHRoaXMgd3JhcHBlZCBpbXBvcnQga2V5LlxuICAgKlxuICAgKiBAcGFyYW0geyBTdWJ0bGVDcnlwdG8gfSBzdWJ0bGUgQW4gaW5zdGFuY2Ugb2YgU3VidGxlQ3J5cHRvIHVzZWQgZm9yIHZlcmlmaWNhdGlvblxuICAgKiBAcmV0dXJuIHsgUHJvbWlzZTxVaW50OEFycmF5PiB9IFRoZSBoYXNoIG9mIHRoZSBzdWNjZXNzZnVsbHkgdmVyaWZpZWQgd3JhcHBlZCBpbXBvcnQga2V5XG4gICAqL1xuICBhc3luYyAjdmVyaWZ5SW1wb3J0S2V5KHN1YnRsZTogU3VidGxlQ3J5cHRvKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gICAgLy8gY2hlY2sgZXhwaXJhdGlvbiBkYXRlXG4gICAgaWYgKG5vd0Vwb2NoTWlsbGlzKCkgPiB0aGlzLmV4cEVwb2NoU2Vjb25kcyAqIDEwMDBuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbXBvcnQga2V5IGlzIGV4cGlyZWRcIik7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlcmUgaXMgYW4gYXR0ZXN0YXRpb25cbiAgICBpZiAoIXRoaXMuI2VuY2xhdmVTaWduYXR1cmUgfHwgIXRoaXMuI2VuY2xhdmVBdHRlc3RhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gYXR0ZXN0YXRpb24gZm91bmRcIik7XG4gICAgfVxuICAgIGNvbnN0IHNpZ25pbmdfa2V5ID0gYXdhaXQgdmVyaWZ5QXR0ZXN0YXRpb25LZXkodGhpcy4jZW5jbGF2ZUF0dGVzdGF0aW9uKTtcblxuICAgIC8vIHdlIHVzZSBzdWJ0bGVjcnlwdG8ncyBpbXBsIG9mIFJTQS1QU1MgdmVyaWZpY2F0aW9uXG4gICAgY29uc3QgcnNhUHNzS2V5UGFyYW1zID0ge1xuICAgICAgbmFtZTogXCJSU0EtUFNTXCIsXG4gICAgICBoYXNoOiBcIlNIQS0yNTZcIixcbiAgICB9O1xuICAgIGNvbnN0IHB1YmtleSA9IGF3YWl0IHN1YnRsZS5pbXBvcnRLZXkoXCJzcGtpXCIsIHNpZ25pbmdfa2V5LCByc2FQc3NLZXlQYXJhbXMsIHRydWUsIFtcInZlcmlmeVwiXSk7XG4gICAgY29uc3QgcHVia2V5QWxnID0gcHVia2V5LmFsZ29yaXRobSBhcyB1bmtub3duIGFzIHsgbW9kdWx1c0xlbmd0aDogbnVtYmVyIH07XG5cbiAgICAvLyBjb21wdXRlIHRoZSBzaWduaW5nIGhhc2ggYW5kIHZlcmlmeSB0aGUgc2lnbmF0dXJlXG4gICAgY29uc3QgbWVzc2FnZSA9IHRoaXMuI3NpZ25lZERhdGEoKTtcbiAgICBjb25zdCBtbGVuID0gTnVtYmVyKEJpZ0ludChwdWJrZXlBbGcubW9kdWx1c0xlbmd0aCkgLyA4bik7XG4gICAgY29uc3QgcnNhUHNzUGFyYW1zID0ge1xuICAgICAgbmFtZTogXCJSU0EtUFNTXCIsXG4gICAgICBzYWx0TGVuZ3RoOiBtbGVuIC0gMiAtIDMyLFxuICAgIH07XG5cbiAgICBpZiAoYXdhaXQgc3VidGxlLnZlcmlmeShyc2FQc3NQYXJhbXMsIHB1YmtleSwgdGhpcy4jZW5jbGF2ZVNpZ25hdHVyZSwgbWVzc2FnZSkpIHtcbiAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCBzdWJ0bGUuZGlnZXN0KFwiU0hBLTI1NlwiLCBtZXNzYWdlKSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcIkltcG9ydCBrZXkgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBmYWlsZWRcIik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhpcyBXcmFwcGVkSW1wb3J0S2V5IG5lZWRzIHRvIGJlIHJlZnJlc2hlZC5cbiAgICpcbiAgICogQHJldHVybiB7IGJvb2xlYW4gfSBUcnVlIGp1c3QgaWYgdGhpcyBrZXkgbmVlZHMgdG8gYmUgcmVmcmVzaGVkLlxuICAgKi9cbiAgcHVibGljIG5lZWRzUmVmcmVzaCgpOiBib29sZWFuIHtcbiAgICAvLyBmb3JjZSByZWZyZXNoIGlmIHdlJ3JlIHdpdGhpbiBXSUtfUkVGUkVTSF9FQVJMWV9NSUxMSVMgb2YgdGhlIGV4cGlyYXRpb25cbiAgICByZXR1cm4gbm93RXBvY2hNaWxsaXMoKSArIFdJS19SRUZSRVNIX0VBUkxZX01JTExJUyA+IHRoaXMuZXhwRXBvY2hTZWNvbmRzICogMTAwMG47XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgdGhlIHNpZ25pbmcgaGFzaCBmb3IgYSB3cmFwcGVkIGltcG9ydCBrZXlcbiAgICpcbiAgICogQHJldHVybiB7IFVpbnQ4QXJyYXkgfSBUaGUgc2lnbmluZyBoYXNoXG4gICAqL1xuICAjc2lnbmVkRGF0YSgpOiBVaW50OEFycmF5IHtcbiAgICBjb25zdCBwYXJ0czogVWludDhBcnJheVtdID0gW1xuICAgICAgLy8gZG9tYWluIHNlcGFyYXRpb24gdGFnXG4gICAgICB0b0JpZ0VuZGlhbihCaWdJbnQoSU1QT1JUX0tFWV9TSUdOSU5HX0RTVC5sZW5ndGgpLCAyKSxcbiAgICAgIElNUE9SVF9LRVlfU0lHTklOR19EU1QsXG5cbiAgICAgIC8vIHB1YmxpYyBrZXlcbiAgICAgIHRvQmlnRW5kaWFuKEJpZ0ludCh0aGlzLnB1YmxpY0tleS5sZW5ndGgpLCAyKSxcbiAgICAgIHRoaXMucHVibGljS2V5LFxuXG4gICAgICAvLyBza19lbmNcbiAgICAgIHRvQmlnRW5kaWFuKEJpZ0ludCh0aGlzLnNrRW5jLmxlbmd0aCksIDIpLFxuICAgICAgdGhpcy5za0VuYyxcblxuICAgICAgLy8gZGtfZW5jXG4gICAgICB0b0JpZ0VuZGlhbihCaWdJbnQodGhpcy5ka0VuYy5sZW5ndGgpLCAyKSxcbiAgICAgIHRoaXMuZGtFbmMsXG5cbiAgICAgIC8vIDgtYnl0ZSBiaWctZW5kaWFuIGV4cGlyYXRpb24gdGltZSBpbiBzZWNvbmRzIHNpbmNlIFVOSVggZXBvY2hcbiAgICAgIHRvQmlnRW5kaWFuKHRoaXMuZXhwRXBvY2hTZWNvbmRzLCA4KSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIGNvbmNhdEFycmF5cyhwYXJ0cyk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgcmV0dXJuIHZhbHVlIGZyb20gS2V5SW1wb3J0ZXIuI2dldFdyYXBwZWRJbXBvcnRBbmRQdWJLZXkoKVxuICovXG50eXBlIFdyYXBwZWRJbXBvcnRBbmRQdWJLZXkgPSB7XG4gIHdpazogV3JhcHBlZEltcG9ydEtleTtcbiAgaXBrOiBDcnlwdG9LZXk7XG59O1xuXG4vKipcbiAqIEFuIGltcG9ydCBlbmNyeXB0aW9uIGtleSBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgYXR0ZXN0YXRpb24gZG9jdW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEtleUltcG9ydGVyIHtcbiAgI3dyYXBwZWRJbXBvcnRLZXk6IG51bGwgfCBXcmFwcGVkSW1wb3J0S2V5ID0gbnVsbDtcbiAgI3N1YnRsZUNyeXB0bzogbnVsbCB8IFN1YnRsZUNyeXB0byA9IG51bGw7XG4gICNwdWJsaWNLZXlIYW5kbGU6IG51bGwgfCBDcnlwdG9LZXkgPSBudWxsO1xuICByZWFkb25seSAjaHBrZVN1aXRlOiBDaXBoZXJTdWl0ZTtcbiAgcmVhZG9ubHkgI2NzOiBPcmc7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBmcm9tIGEgQ3ViZVNpZ25lciBgT3JnYCBpbnN0YW5jZVxuICAgKlxuICAgKiBAcGFyYW0geyBPcmcgfSBjcyBBIEN1YmVTaWduZXIgYE9yZ2AgaW5zdGFuY2VcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNzOiBPcmcpIHtcbiAgICB0aGlzLiNjcyA9IGNzO1xuICAgIHRoaXMuI2hwa2VTdWl0ZSA9IG5ldyBDaXBoZXJTdWl0ZSh7XG4gICAgICBrZW06IG5ldyBEaGtlbVAzODRIa2RmU2hhMzg0KCksXG4gICAgICBrZGY6IG5ldyBIa2RmU2hhMzg0KCksXG4gICAgICBhZWFkOiBuZXcgQWVzMjU2R2NtKCksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhhdCB0aGUgd3JhcHBlZCBpbXBvcnQga2V5IGlzIHVuZXhwaXJlZCBhbmQgdmVyaWZpZWQuIE90aGVyd2lzZSxcbiAgICogcmVxdWVzdCBhIG5ldyBvbmUsIHZlcmlmeSBpdCwgYW5kIHVwZGF0ZSB0aGUgdmVyaWZpZWQgc2lnbmluZyBoYXNoLlxuICAgKlxuICAgKiBAcmV0dXJuIHsgUHJvbWlzZTxbV3JhcHBlZEltcG9ydEtleSwgQ3J5cHRvS2V5XT4gfSBUaGUgdmVyaWZpZWQgc2lnbmluZyBoYXNoLlxuICAgKi9cbiAgYXN5bmMgI2dldFdyYXBwZWRJbXBvcnRBbmRQdWJLZXkoKTogUHJvbWlzZTxXcmFwcGVkSW1wb3J0QW5kUHViS2V5PiB7XG4gICAgaWYgKCF0aGlzLiN3cmFwcGVkSW1wb3J0S2V5KSB7XG4gICAgICAvLyBmaXJzdCB0aW1lIHdlIGxvYWQgYSBXcmFwcGVkSW1wb3J0S2V5LCBtYWtlIHN1cmUgdGhlIHg1MDkgY3J5cHRvXG4gICAgICAvLyBwcm92aWRlciBpcyBzZXQgY29ycmVjdGx5LlxuICAgICAgeDUwOUNyeXB0b1Byb3ZpZGVyLnNldChhd2FpdCBsb2FkQ3J5cHRvKCkpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuI3dyYXBwZWRJbXBvcnRLZXkgfHwgdGhpcy4jd3JhcHBlZEltcG9ydEtleS5uZWVkc1JlZnJlc2goKSkge1xuICAgICAgY29uc3Qga2lrUmVzcCA9IGF3YWl0IHRoaXMuI2NzLmNyZWF0ZUtleUltcG9ydEtleSgpO1xuICAgICAgY29uc3Qgc3VidGxlID0gYXdhaXQgdGhpcy4jZ2V0U3VidGxlQ3J5cHRvKCk7XG4gICAgICBjb25zdCB3aWsgPSBhd2FpdCBXcmFwcGVkSW1wb3J0S2V5LmNyZWF0ZUFuZFZlcmlmeShraWtSZXNwLCBzdWJ0bGUpO1xuXG4gICAgICAvLyBpbXBvcnQgdGhlIHB1YmxpYyBrZXkgZnJvbSB0aGUgV3JhcHBlZEltcG9ydEtleVxuICAgICAgY29uc3QgcDM4NFBhcmFtcyA9IHtcbiAgICAgICAgbmFtZTogXCJFQ0RIXCIsXG4gICAgICAgIG5hbWVkQ3VydmU6IFwiUC0zODRcIixcbiAgICAgIH07XG4gICAgICB0aGlzLiNwdWJsaWNLZXlIYW5kbGUgPSBhd2FpdCBzdWJ0bGUuaW1wb3J0S2V5KFwicmF3XCIsIHdpay5wdWJsaWNLZXksIHAzODRQYXJhbXMsIHRydWUsIFtdKTtcbiAgICAgIHRoaXMuI3dyYXBwZWRJbXBvcnRLZXkgPSB3aWs7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB3aWs6IHRoaXMuI3dyYXBwZWRJbXBvcnRLZXksXG4gICAgICBpcGs6IHRoaXMuI3B1YmxpY0tleUhhbmRsZSEsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgb3IgY3JlYXRlIGFuIGluc3RhbmNlIG9mIFN1YnRsZUNyeXB0by5cbiAgICpcbiAgICogQHJldHVybiB7IFN1YnRsZUNyeXB0byB9IFRoZSBpbnN0YW5jZSBvZiBTdWJ0bGVDcnlwdG8uXG4gICAqL1xuICBhc3luYyAjZ2V0U3VidGxlQ3J5cHRvKCk6IFByb21pc2U8U3VidGxlQ3J5cHRvPiB7XG4gICAgaWYgKCF0aGlzLiNzdWJ0bGVDcnlwdG8pIHtcbiAgICAgIHRoaXMuI3N1YnRsZUNyeXB0byA9IGF3YWl0IGxvYWRTdWJ0bGVDcnlwdG8oKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuI3N1YnRsZUNyeXB0bztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0cyBhIHNldCBvZiBtbmVtb25pY3MgYW5kIGltcG9ydHMgdGhlbS5cbiAgICpcbiAgICogQHBhcmFtIHsgS2V5VHlwZSB9IGtleVR5cGUgVGhlIHR5cGUgb2Yga2V5IHRvIGltcG9ydFxuICAgKiBAcGFyYW0geyBNbmVtb25pY1RvSW1wb3J0W10gfSBtbmVzIFRoZSBtbmVtb25pY3MgdG8gaW1wb3J0LCB3aXRoIG9wdGlvbmFsIGRlcml2YXRpb24gcGF0aHMgYW5kIHBhc3N3b3Jkc1xuICAgKiBAcmV0dXJuIHsgUHJvbWlzZTxLZXlbXT4gfSBgS2V5YCBvYmplY3RzIGZvciBlYWNoIGltcG9ydGVkIGtleS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbXBvcnRNbmVtb25pY3Moa2V5VHlwZTogS2V5VHlwZSwgbW5lczogTW5lbW9uaWNUb0ltcG9ydFtdKTogUHJvbWlzZTxLZXlbXT4ge1xuICAgIGNvbnN0IG5DaHVua3MgPSBOdW1iZXIoXG4gICAgICAoQmlnSW50KG1uZXMubGVuZ3RoKSArIE1BWF9JTVBPUlRTX1BFUl9BUElfQ0FMTCAtIDFuKSAvIE1BWF9JTVBPUlRTX1BFUl9BUElfQ0FMTCxcbiAgICApO1xuICAgIGNvbnN0IGtleXMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbkNodW5rczsgKytpKSB7XG4gICAgICAvLyBmaXJzdCwgbWFrZSBzdXJlIHRoYXQgdGhlIHdyYXBwZWQgaW1wb3J0IGtleSBpcyB2YWxpZCwgaS5lLiwgdGhhdFxuICAgICAgLy8gd2UgaGF2ZSByZXRyaWV2ZWQgaXQgYW5kIHRoYXQgaXQgaGFzbid0IGV4cGlyZWQuIFdlIGRvIHRoaXMgaGVyZVxuICAgICAgLy8gZm9yIGEgY291cGxlIHJlYXNvbnM6XG4gICAgICAvL1xuICAgICAgLy8gLSBhbGwgZW5jcnlwdGlvbnMgaW4gYSBnaXZlIHJlcXVlc3QgbXVzdCB1c2UgdGhlIHNhbWUgaW1wb3J0IGtleSwgYW5kXG4gICAgICAvL1xuICAgICAgLy8gLSB3aGVuIGltcG9ydGluZyBhIGh1Z2UgbnVtYmVyIG9mIGtleXMgdGhlIGltcG9ydCBwdWJrZXkgbWlnaHQgZXhwaXJlXG4gICAgICAvLyAgIGR1cmluZyB0aGUgaW1wb3J0LCBzbyB3ZSBjaGVjayBmb3IgZXhwaXJhdGlvbiBiZWZvcmUgZWFjaCByZXF1ZXN0XG4gICAgICBjb25zdCB7IHdpaywgaXBrIH0gPSBhd2FpdCB0aGlzLiNnZXRXcmFwcGVkSW1wb3J0QW5kUHViS2V5KCk7XG5cbiAgICAgIC8vIG5leHQsIGVuY3J5cHQgdGhpcyBjaHVuayBvZiBtbmVtb25pY3NcbiAgICAgIGNvbnN0IHN0YXJ0ID0gTnVtYmVyKE1BWF9JTVBPUlRTX1BFUl9BUElfQ0FMTCkgKiBpO1xuICAgICAgY29uc3QgZW5kID0gTnVtYmVyKE1BWF9JTVBPUlRTX1BFUl9BUElfQ0FMTCkgKyBzdGFydDtcbiAgICAgIGNvbnN0IG1uZVNsaWNlID0gbW5lcy5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgIGNvbnN0IGtleV9tYXRlcmlhbCA9IFtdO1xuICAgICAgZm9yIChjb25zdCBtbmUgb2YgbW5lU2xpY2UpIHtcbiAgICAgICAgY29uc3Qga2V5UGtnID0gbmV3TW5lbW9uaWNLZXlQYWNrYWdlKG1uZSk7XG4gICAgICAgIGNvbnN0IG1hdGVyaWFsID0gYXdhaXQgdGhpcy4jZW5jcnlwdChrZXlQa2csIHdpay52ZXJpZmllZEhhc2gsIGlwayk7XG4gICAgICAgIGtleV9tYXRlcmlhbC5wdXNoKG1hdGVyaWFsKTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uc3RydWN0IHRoZSByZXF1ZXN0XG4gICAgICBjb25zdCByZXE6IEltcG9ydEtleVJlcXVlc3QgPSB7XG4gICAgICAgIHB1YmxpY19rZXk6IHdpay5wdWJsaWNLZXlCYXNlNjQsXG4gICAgICAgIHNrX2VuYzogd2lrLnNrRW5jQmFzZTY0LFxuICAgICAgICBka19lbmM6IHdpay5ka0VuY0Jhc2U2NCxcbiAgICAgICAgZXhwaXJlczogTnVtYmVyKHdpay5leHBFcG9jaFNlY29uZHMpLFxuICAgICAgICBrZXlfdHlwZToga2V5VHlwZSxcbiAgICAgICAga2V5X21hdGVyaWFsLFxuICAgICAgfTtcblxuICAgICAgLy8gc2VuZCBpdCBhbmQgYXBwZW5kIHRoZSByZXN1bHQgdG8gdGhlIHJldHVybiB2YWx1ZVxuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHRoaXMuI2NzLmltcG9ydEtleXMocmVxKTtcbiAgICAgIGtleXMucHVzaCguLi5yZXNwKTtcbiAgICB9XG5cbiAgICByZXR1cm4ga2V5cztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNyeXB0IHRvIHRoaXMgd3JhcHBlZCBpbXBvcnQga2V5LiBTdG9yZXMgdGhlIHJlc3VsdCBpbiBgdGhpcy5lbmNyeXB0ZWRfa2V5c2BcbiAgICpcbiAgICogQHBhcmFtIHsgVWludDhBcnJheSB9IGRhdGEgVGhlIGRhdGEgdG8gZW5jcnlwdFxuICAgKiBAcGFyYW0geyBVaW50OEFycmF5IH0gdmVyaWZpZWRIYXNoIFRoZSB2ZXJpZmllZCBzaWduaW5nIGhhc2ggb2YgdGhlIHdyYXBwZWQgaW1wb3J0IGtleSB0byB3aGljaCB0byBlbmNyeXB0XG4gICAqIEBwYXJhbSB7IENyeXB0b0tleSB9IHB1YmtleSBUaGUgcHVibGljIGtleSB0byBlbmNyeXB0IHRvXG4gICAqIEByZXR1cm4geyBQcm9taXNlPEltcG9ydEtleVJlcXVlc3RNYXRlcmlhbD4gfSBUaGUgZW5jcnlwdGVkIGtleSBtYXRlcmlhbFxuICAgKi9cbiAgYXN5bmMgI2VuY3J5cHQoXG4gICAgZGF0YTogVWludDhBcnJheSxcbiAgICB2ZXJpZmllZEhhc2g6IFVpbnQ4QXJyYXksXG4gICAgcHVia2V5OiBDcnlwdG9LZXksXG4gICk6IFByb21pc2U8SW1wb3J0S2V5UmVxdWVzdE1hdGVyaWFsPiB7XG4gICAgLy8gc2V0IHVwIHRoZSBIUEtFIHNlbmRlclxuICAgIGNvbnN0IHNlbmRlciA9IGF3YWl0IHRoaXMuI2hwa2VTdWl0ZS5jcmVhdGVTZW5kZXJDb250ZXh0KHtcbiAgICAgIHJlY2lwaWVudFB1YmxpY0tleTogcHVia2V5LFxuICAgICAgaW5mbzogdmVyaWZpZWRIYXNoLFxuICAgIH0pO1xuXG4gICAgLy8gZW5jcnlwdCBhbmQgY29uc3RydWN0IHRoZSByZXR1cm4gdmFsdWVcbiAgICBjb25zdCBzZW5kZXJDdGV4dCA9IGF3YWl0IHNlbmRlci5zZWFsKGRhdGEpO1xuICAgIHJldHVybiB7XG4gICAgICBzYWx0OiBcIlwiLFxuICAgICAgY2xpZW50X3B1YmxpY19rZXk6IEJ1ZmZlci5mcm9tKHNlbmRlci5lbmMpLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgaWttX2VuYzogQnVmZmVyLmZyb20oc2VuZGVyQ3RleHQpLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgIH07XG4gIH1cbn1cblxuLypcbiAqIEFuIEFXUyBOaXRybyBhdHRlc3RhdGlvbiBkb2N1bWVudFxuICpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLW5pdHJvLWVuY2xhdmVzLW5zbS1hcGkvYmxvYi80Yjg1MWYzMDA2YzZmYTk4ZjIzZGNmZmIyY2JhMDNiMzlkZTliOGFmL3NyYy9hcGkvbW9kLnJzI0wyMDhcbiAqL1xudHlwZSBBdHRlc3RhdGlvbkRvYyA9IHtcbiAgbW9kdWxlX2lkOiBzdHJpbmc7XG4gIGRpZ2VzdDogXCJTSEEyNTZcIiB8IFwiU0hBMzg0XCIgfCBcIlNIQTUxMlwiO1xuICB0aW1lc3RhbXA6IGJpZ2ludDtcbiAgcGNyczogTWFwPG51bWJlciwgVWludDhBcnJheT47XG4gIGNlcnRpZmljYXRlOiBVaW50OEFycmF5O1xuICBjYWJ1bmRsZTogVWludDhBcnJheVtdO1xuICBwdWJsaWNfa2V5PzogVWludDhBcnJheTtcbiAgdXNlcl9kYXRhPzogVWludDhBcnJheTtcbiAgbm9uY2U/OiBVaW50OEFycmF5O1xufTtcblxuLyoqXG4gKiBWZXJpZmllcyB0aGUgYXR0ZXN0YXRpb24ga2V5IGFnYWluc3QgdGhlIEFXUyBOaXRybyBFbmNsYXZlcyBzaWduaW5nXG4gKiBrZXkgYW5kIHJldHVybnMgdGhlIGF0dGVzdGVkIHNpZ25pbmcga2V5LlxuICpcbiAqIEBwYXJhbSB7IFVpbnQ4QXJyYXkgfSBhdHRCeXRlcyBBbiBhdHRlc3RhdGlvbiBmcm9tIGFuIEFXUyBuaXRybyBlbmNsYXZlXG4gKiBAcmV0dXJuIHsgUHJvbWlzZTxVaW50OEFycmF5PiB9IFRoZSBzaWduaW5nIGtleSB0aGF0IHdhcyBhdHRlc3RlZCwgb3IgbnVsbCBpZiB2ZXJpZmljYXRpb24gZmFpbGVkXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHZlcmlmeUF0dGVzdGF0aW9uS2V5KGF0dEJ5dGVzOiBVaW50OEFycmF5KTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIC8vIGNib3IteCBpcyBiZWluZyBpbXBvcnRlZCBhcyBFU00sIHNvIHdlIG11c3QgYXN5bmNocm9ub3VzbHkgaW1wb3J0IGl0IGhlcmUuXG4gIC8vIEJlY2F1c2Ugd2Ugb25seSB1c2UgdGhhdCBhbmQgYXV0aDAvY29zZSBoZXJlLCB3ZSBpbXBvcnQgYm90aCB0aGlzIHdheS5cbiAgY29uc3QgeyBTaWduMSB9ID0gYXdhaXQgaW1wb3J0KFwiQGF1dGgwL2Nvc2VcIik7XG4gIGNvbnN0IHsgZGVjb2RlOiBjYm9yRGVjb2RlIH0gPSBhd2FpdCBpbXBvcnQoXCJjYm9yLXhcIik7XG5cbiAgY29uc3QgYXR0ID0gU2lnbjEuZGVjb2RlKGF0dEJ5dGVzKTtcbiAgY29uc3QgYXR0RG9jID0gY2JvckRlY29kZShhdHQucGF5bG9hZCkgYXMgQXR0ZXN0YXRpb25Eb2M7XG5cbiAgLy8gY2hlY2sgZXhwaXJhdGlvbiBkYXRlIG9mIGF0dGVzdGF0aW9uXG4gIGNvbnN0IGxhdGVzdCA9IG5vd0Vwb2NoTWlsbGlzKCkgKyBNQVhfQVRURVNUQVRJT05fRlVUVVJFX01JTlVURVMgKiA2MG4gKiAxMDAwbjtcbiAgY29uc3QgZWFybGllc3QgPVxuICAgIGxhdGVzdCAtIChNQVhfQVRURVNUQVRJT05fRlVUVVJFX01JTlVURVMgKyBNQVhfQVRURVNUQVRJT05fQUdFX01JTlVURVMpICogNjBuICogMTAwMG47XG4gIGlmIChhdHREb2MudGltZXN0YW1wIDwgZWFybGllc3QgfHwgYXR0RG9jLnRpbWVzdGFtcCA+IGxhdGVzdCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGVzdGF0aW9uIGlzIGV4cGlyZWRcIik7XG4gIH1cblxuICAvLyBpZiB0aGVyZSdzIG5vIHB1YmxpYyBrZXkgaW4gdGhpcyBhdHRlc3RhdGlvbiwgZ2l2ZSB1cFxuICBpZiAoIWF0dERvYy5wdWJsaWNfa2V5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXR0ZXN0YXRpb24gZGlkIG5vdCBpbmNsdWRlIGEgc2lnbmluZyBwdWJsaWMga2V5XCIpO1xuICB9XG5cbiAgLy8gVmVyaWZ5IGNlcnRpZmljYXRlIGNoYWluIHN0YXJ0aW5nIHdpdGggQVdTIE5pdHJvIENBIGNlcnRcbiAgbGV0IHBhcmVudCA9IG5ldyBYNTA5Q2VydGlmaWNhdGUoQVdTX0NBX0NFUlQpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dERvYy5jYWJ1bmRsZS5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IGNlcnQgPSBuZXcgWDUwOUNlcnRpZmljYXRlKGF0dERvYy5jYWJ1bmRsZVtpXSk7XG4gICAgaWYgKCEoYXdhaXQgY2VydC52ZXJpZnkocGFyZW50KSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQXR0ZXN0YXRpb24gY2VydGlmaWNhdGUgY2hhaW4gZmFpbGVkIGF0IGluZGV4ICR7aX1gKTtcbiAgICB9XG4gICAgcGFyZW50ID0gY2VydDtcbiAgfVxuICBjb25zdCBjZXJ0ID0gbmV3IFg1MDlDZXJ0aWZpY2F0ZShhdHREb2MuY2VydGlmaWNhdGUpO1xuICBpZiAoIShhd2FpdCBjZXJ0LnZlcmlmeShwYXJlbnQpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGVzdGF0aW9uIGNlcnRpZmljYXRlIGNoYWluIGZhaWxlZCBhdCBsZWFmXCIpO1xuICB9XG4gIGNvbnN0IHB1YmtleSA9IGNlcnQucHVibGljS2V5O1xuXG4gIC8vIG1ha2Ugc3VyZSB0aGF0IHdlIGdvdCB0aGUgZXhwZWN0ZWQgcHVibGljIGtleSB0eXBlXG4gIGNvbnN0IGFsZyA9IG5ldyBBbGdvcml0aG1Qcm92aWRlcigpLnRvQXNuQWxnb3JpdGhtKHB1YmtleS5hbGdvcml0aG0pO1xuICBpZiAoYWxnLmFsZ29yaXRobSAhPSBFQ19QVUJMSUNfS0VZKSB7XG4gICAgLy8gbm90IHRoZSBleHBlY3RlZCBhbGdvcml0aG0sIGkuZS4sIGVsbGlwdGljIGN1cnZlIHNpZ25pbmdcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJBdHRlc3RhdGlvbiBjb250YWluZWQgdW5leHBlY3RlZCBzaWduYXR1cmUgYWxnb3JpdGhtXCIpO1xuICB9XG4gIGNvbnN0IHBhcmFtcyA9IEFzblBhcnNlci5wYXJzZShhbGcucGFyYW1ldGVycyEsIEVDUGFyYW1ldGVycyk7XG4gIGlmICghcGFyYW1zLm5hbWVkQ3VydmUgfHwgcGFyYW1zLm5hbWVkQ3VydmUgIT09IE5JU1RfUDM4NCkge1xuICAgIC8vIG5vdCB0aGUgZXhwZWN0ZWQgcGFyYW1zLCBpLmUuLCBOSVNUIFAzODRcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJBdHRlc3RhdGlvbiBjb250YWluZWQgdW5leHBlY3RlZCBzaWduYXR1cmUgYWxnb3JpdGhtXCIpO1xuICB9XG5cbiAgLy8gdmVyaWZ5IHRoZSBjb3NlIHNpZ25hdHVyZSB3aXRoIHRoZSBrZXksIHdoaWNoIHdlIHZlcmlmaWVkIGFnYWluc3RcbiAgLy8gdGhlIEFXUyBOaXRybyBDQSBjZXJ0aWZpY2F0ZSBhYm92ZVxuICBhd2FpdCBhdHQudmVyaWZ5KGF3YWl0IHB1YmtleS5leHBvcnQoKSk7XG5cbiAgcmV0dXJuIGF0dERvYy5wdWJsaWNfa2V5O1xufVxuIl19
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeyImporter = void 0;
|
|
4
|
+
var import_1 = require("./import");
|
|
5
|
+
Object.defineProperty(exports, "KeyImporter", { enumerable: true, get: function () { return import_1.KeyImporter; } });
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXVDO0FBQTlCLHFHQUFBLFdBQVcsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IEtleUltcG9ydGVyIH0gZnJvbSBcIi4vaW1wb3J0XCI7XG5leHBvcnQgeyBNbmVtb25pY1RvSW1wb3J0IH0gZnJvbSBcIi4vbW5lbW9uaWNcIjtcbiJdfQ==
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type MnemonicKeyPackage = {
|
|
2
|
+
EnglishMnemonic: {
|
|
3
|
+
mnemonic: {
|
|
4
|
+
entropy: Uint8Array;
|
|
5
|
+
};
|
|
6
|
+
der_path: {
|
|
7
|
+
path: number[];
|
|
8
|
+
};
|
|
9
|
+
password: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A BIP39 mnemonic to be imported, plus optional BIP39 password
|
|
14
|
+
* and BIP32 derivation path.
|
|
15
|
+
*/
|
|
16
|
+
export type MnemonicToImport = {
|
|
17
|
+
mnemonic: string;
|
|
18
|
+
derivationPath?: string;
|
|
19
|
+
password?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Create a new MnemonicKeyPackage value
|
|
23
|
+
*
|
|
24
|
+
* @param { MnemonicToImport } mne A BIP39 mnemonic and optional BIP39 password and BIP32 derivation path
|
|
25
|
+
* @return { Uint8Array } A serialized key package for import to CubeSigner
|
|
26
|
+
*/
|
|
27
|
+
export declare function newMnemonicKeyPackage(mne: MnemonicToImport): Uint8Array;
|
|
28
|
+
/**
|
|
29
|
+
* Parse a derivation path into a sequence of 32-bit integers
|
|
30
|
+
*
|
|
31
|
+
* @param { string } derp The derivation path to parse; must start with 'm/'
|
|
32
|
+
* @return { number[] } The parsed path
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseDerivationPath(derp: string): number[];
|
|
35
|
+
//# sourceMappingURL=mnemonic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonic.d.ts","sourceRoot":"","sources":["../src/mnemonic.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE;QACf,QAAQ,EAAE;YACR,OAAO,EAAE,UAAU,CAAC;SACrB,CAAC;QACF,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,EAAE,CAAC;SAChB,CAAC;QACF,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,GAAG,UAAU,CAgBvE;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA6B1D"}
|