@ledgerhq/revault-sdk 0.27.15 → 0.28.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 +4 -7
- package/lib/bake.cjs +1 -1
- package/lib/bake.d.cts +1 -1
- package/lib/bake.d.ts +1 -1
- package/lib/bake.js +1 -1
- package/lib/{crypto-BxlPOWD9.cjs → crypto-B4xS0N1u.cjs} +2 -2
- package/lib/{crypto-BxlPOWD9.cjs.map → crypto-B4xS0N1u.cjs.map} +1 -1
- package/lib/{crypto-BHYSptBe.js → crypto-BZw0pZ1Z.js} +2 -2
- package/lib/{crypto-BHYSptBe.js.map → crypto-BZw0pZ1Z.js.map} +1 -1
- package/lib/crypto.cjs +1 -1
- package/lib/crypto.js +1 -1
- package/lib/{device-DBzLykrI.js → device-Bo6m3O1I.js} +51 -3
- package/lib/device-Bo6m3O1I.js.map +1 -0
- package/lib/{device-B6QZOEDT.cjs → device-dbZH_1Pt.cjs} +63 -2
- package/lib/device-dbZH_1Pt.cjs.map +1 -0
- package/lib/device.cjs +3 -1
- package/lib/device.d.cts +2 -2
- package/lib/device.d.ts +2 -2
- package/lib/device.js +2 -2
- package/lib/engine.cjs +195 -41
- package/lib/engine.cjs.map +1 -1
- package/lib/engine.d.cts +2 -2
- package/lib/engine.d.ts +2 -2
- package/lib/engine.js +195 -41
- package/lib/engine.js.map +1 -1
- package/lib/{index-sWTlrbOl.d.cts → index-C5AAKtIf.d.cts} +49 -4
- package/lib/{index-B7SUQ6NW.d.cts → index-D_EED8aS.d.cts} +1 -1
- package/lib/{index-CuWiM97X.d.ts → index-Ds_t9ilJ.d.ts} +49 -4
- package/lib/{index-DLUJ9Etg.d.ts → index-aYbRTZvr.d.ts} +1 -1
- package/lib/onboarding.cjs +1 -1
- package/lib/onboarding.d.cts +1 -1
- package/lib/onboarding.d.ts +1 -1
- package/lib/onboarding.js +1 -1
- package/lib/{types-BN2MzD_5.d.ts → types-ALsH_YtN.d.ts} +1 -1
- package/lib/{types-BXAwSr1F.d.cts → types-DP-rmxvy.d.cts} +1 -1
- package/package.json +2 -2
- package/lib/device-B6QZOEDT.cjs.map +0 -1
- package/lib/device-DBzLykrI.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
# revault-sdk
|
|
2
2
|
|
|
3
|
-
Node
|
|
3
|
+
Node.js and browser SDK for interacting with `revault-api`.
|
|
4
4
|
|
|
5
|
-
> 📖
|
|
6
|
-
> please check [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
5
|
+
> 📖 For internal developer instructions, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
7
6
|
|
|
8
7
|
## Installation
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
```
|
|
9
|
+
```bash
|
|
13
10
|
pnpm add @ledgerhq/revault-sdk
|
|
14
11
|
```
|
|
15
12
|
|
|
16
13
|
## Usage
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
See the [Documentation](https://ledgerhq.github.io/revault/) for the full API reference.
|
package/lib/bake.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
3
3
|
const require_utils = require("./utils-CavXJGCh.cjs");
|
|
4
|
-
const require_crypto = require("./crypto-
|
|
4
|
+
const require_crypto = require("./crypto-B4xS0N1u.cjs");
|
|
5
5
|
let invariant = require("invariant");
|
|
6
6
|
invariant = require_rolldown_runtime.__toESM(invariant, 1);
|
|
7
7
|
let ts_pattern = require("ts-pattern");
|
package/lib/bake.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Logger } from "./logger-DHtgWA66.cjs";
|
|
2
2
|
import { n as RouterInputs, t as RevaultApiTRPCClient } from "./trpc-DBU35NJq.cjs";
|
|
3
|
-
import { b as WithPsdAuth, d as Engine, v as WithDevice, x as WithWorkspace } from "./types-
|
|
3
|
+
import { b as WithPsdAuth, d as Engine, v as WithDevice, x as WithWorkspace } from "./types-DP-rmxvy.cjs";
|
|
4
4
|
import z from "zod";
|
|
5
5
|
import { VaultRequestResponse } from "@ledgerhq/revault-api";
|
|
6
6
|
|
package/lib/bake.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Logger } from "./logger-DHtgWA66.js";
|
|
2
2
|
import { n as RouterInputs, t as RevaultApiTRPCClient } from "./trpc-DBU35NJq.js";
|
|
3
|
-
import { b as WithPsdAuth, d as Engine, v as WithDevice, x as WithWorkspace } from "./types-
|
|
3
|
+
import { b as WithPsdAuth, d as Engine, v as WithDevice, x as WithWorkspace } from "./types-ALsH_YtN.js";
|
|
4
4
|
import z from "zod";
|
|
5
5
|
import { VaultRequestResponse } from "@ledgerhq/revault-api";
|
|
6
6
|
|
package/lib/bake.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as createDeviceIndexResolver, r as fetchAll } from "./utils-CW0gdJME.js";
|
|
2
|
-
import { t as genKeys } from "./crypto-
|
|
2
|
+
import { t as genKeys } from "./crypto-BZw0pZ1Z.js";
|
|
3
3
|
import invariant from "invariant";
|
|
4
4
|
import { match } from "ts-pattern";
|
|
5
5
|
import _ from "lodash";
|
|
@@ -262,7 +262,7 @@ function genKeys(entropy) {
|
|
|
262
262
|
const sign = async (privateKeyPem, base64Challenge) => {
|
|
263
263
|
const challengeDataBytes = jose.base64url.decode(base64Challenge);
|
|
264
264
|
const privateKey = node_crypto.default.createPrivateKey(privateKeyPem);
|
|
265
|
-
return
|
|
265
|
+
return new jose.CompactSign(challengeDataBytes).setProtectedHeader({
|
|
266
266
|
alg: "ES256",
|
|
267
267
|
typ: "JWT"
|
|
268
268
|
}).sign(privateKey);
|
|
@@ -293,4 +293,4 @@ Object.defineProperty(exports, "sign", {
|
|
|
293
293
|
}
|
|
294
294
|
});
|
|
295
295
|
|
|
296
|
-
//# sourceMappingURL=crypto-
|
|
296
|
+
//# sourceMappingURL=crypto-B4xS0N1u.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-BxlPOWD9.cjs","names":["wordlist","HDKey","asn1","BN","crypto"],"sources":["../src/crypto/gen-seed.ts","../src/crypto/key-encoder.ts","../src/crypto/utils.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { HDKey } from \"@scure/bip32\";\nimport { entropyToMnemonic, mnemonicToSeed } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\n/**\n * Generate a deterministic BIP39 mnemonic from a salt and device index.\n *\n * Produces `entropyToMnemonic(SHA256(salt + \"_\" + index))`, matching\n * the behavior of `@ledgerhq/vault-common`'s `genSeed`.\n *\n * @param salt The workspace salt\n * @param index The device index (1-based)\n * @returns A 24-word BIP39 mnemonic string\n */\nexport function genSeed(salt: string, index: number): string {\n const input = new TextEncoder().encode(`${salt}_${index}`);\n const entropy = sha256(input);\n return entropyToMnemonic(entropy, wordlist);\n}\n\nconst getSeedFragment = async (salt: string, index: number): Promise<Uint8Array> => {\n const seed = await mnemonicToSeed(genSeed(salt, index));\n const secpKey = HDKey.fromMasterSeed(seed);\n const fragment = secpKey.derive(\"m/5655636'/4932953'\");\n return Buffer.concat([fragment.privateKey!, fragment.chainCode!]);\n};\n\nexport const getMasterSeed = async (salt: string): Promise<Uint8Array> => {\n const fragments = await Promise.all([\n getSeedFragment(salt, 7),\n getSeedFragment(salt, 8),\n getSeedFragment(salt, 9),\n ]);\n\n const masterSeed = new Uint8Array(fragments[0].length);\n for (let i = 0; i < fragments[0].length; i++) {\n masterSeed[i] = fragments[0][i]! ^ fragments[1][i]! ^ fragments[2][i]!;\n }\n\n return masterSeed;\n};\n","// ========================================================================== //\n// //\n// DISCLAIMER //\n// //\n// This code has been blindly copy-pasted from: //\n// https://github.com/LedgerHQ/pkey-ts //\n// //\n// ========================================================================== //\n//\n// @ts-expect-error this library does not ship types\nimport asn1 from \"asn1.js\";\nimport BN from \"bn.js\";\nimport elliptic from \"elliptic\";\n\n/* cspell:disable */\nconst ECPrivateKeyASN = asn1.define(\"ECPrivateKey\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self.key(\"privateKey\").octstr(),\n self.key(\"parameters\").explicit(0).objid().optional(),\n self.key(\"publicKey\").explicit(1).bitstr().optional(),\n );\n});\n\nconst ECPrivateKey8ASN = asn1.define(\n \"ECPrivateKey\",\n /* v8 ignore next -- @preserve */\n function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self\n .key(\"privateKeyAlgorithm\")\n .seq()\n .obj(self.key(\"ecPublicKey\").objid(), self.key(\"curve\").objid()),\n self.key(\"privateKey\").octstr().contains(ECPrivateKeyASN),\n self.key(\"attributes\").explicit(0).bitstr().optional(),\n );\n },\n);\n\nconst SubjectPublicKeyInfoASN = asn1.define(\"SubjectPublicKeyInfo\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"algorithm\").seq().obj(self.key(\"id\").objid(), self.key(\"curve\").objid()),\n self.key(\"pub\").bitstr(),\n );\n});\n\ntype CurveOptions = {\n curveParameters: number[];\n privatePEMOptions: { label: string };\n publicPEMOptions: { label: string };\n curve: elliptic.ec;\n};\n\nconst curves: Record<string, CurveOptions> = {\n secp256k1: {\n curveParameters: [1, 3, 132, 0, 10],\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"secp256k1\"),\n },\n p256: {\n curveParameters: [1, 2, 840, 10045, 3, 1, 7], // OID for p256 curve\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"p256\"),\n },\n};\n\ntype PrivateKeyPKCS1 = {\n version: BN;\n privateKey: Buffer;\n parameters: number[];\n publicKey?: {\n unused: number;\n data: Buffer;\n };\n};\n\ntype PrivateKeyPKCS8 = {\n version: BN;\n privateKey: PrivateKeyPKCS1;\n privateKeyAlgorithm: { ecPublicKey: number[]; curve: number[] };\n};\n\nexport type KeyFormat = \"raw\" | \"pem\" | \"der\";\n\nexport class KeyEncoder {\n algorithmID: number[];\n options: CurveOptions;\n\n constructor(options: string | CurveOptions) {\n /* v8 ignore else -- @preserve */\n if (typeof options === \"string\") {\n /* v8 ignore if -- @preserve */\n if (options !== \"secp256k1\" && options !== \"p256\") {\n throw new Error(`Unknown curve ${options}`);\n }\n options = curves[options]!;\n }\n this.options = options;\n this.algorithmID = [1, 2, 840, 10045, 2, 1];\n }\n\n /* v8 ignore next -- @preserve */\n private PKCS1toPKCS8(privateKey: PrivateKeyPKCS1): PrivateKeyPKCS8 {\n return {\n version: new BN(0),\n privateKey,\n privateKeyAlgorithm: {\n ecPublicKey: this.algorithmID,\n curve: privateKey.parameters,\n },\n };\n }\n\n privateKeyObject(rawPrivateKey: string, rawPublicKey: string): PrivateKeyPKCS1 {\n const privateKeyObject: PrivateKeyPKCS1 = {\n version: new BN(1),\n privateKey: Buffer.from(rawPrivateKey, \"hex\"),\n parameters: this.options.curveParameters,\n };\n\n /* v8 ignore else -- @preserve */\n if (rawPublicKey) {\n privateKeyObject.publicKey = {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n };\n }\n\n return privateKeyObject;\n }\n\n publicKeyObject(rawPublicKey: string): {\n algorithm: { id: number[]; curve: number[] };\n pub: { unused: number; data: Buffer };\n } {\n return {\n algorithm: {\n id: this.algorithmID,\n curve: this.options.curveParameters,\n },\n pub: {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n },\n };\n }\n\n encodePrivate(\n privateKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n destinationFormatType: \"pkcs8\" | \"pkcs1\" = \"pkcs1\",\n ): string {\n let privateKeyObject: PrivateKeyPKCS1;\n\n /* Parse the incoming private key and convert it to a private key object */\n switch (originalFormat) {\n case \"raw\": {\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n const keyPair = this.options.curve.keyFromPrivate(privateKey, \"hex\");\n const rawPublicKey = keyPair.getPublic(\"hex\");\n privateKeyObject = this.privateKeyObject(privateKey, rawPublicKey);\n break;\n }\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof privateKey === \"string\") {\n privateKey = Buffer.from(privateKey, \"hex\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(privateKey, \"der\");\n break;\n case \"pem\":\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(\n privateKey,\n \"pem\",\n this.options.privatePEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid private key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n if (destinationFormatType === \"pkcs1\") {\n return privateKeyObject.privateKey.toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return this.PKCS1toPKCS8(privateKeyObject).privateKey.privateKey.toString(\"hex\");\n }\n break;\n case \"der\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"der\").toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"der\").toString(\n \"hex\",\n );\n }\n break;\n case \"pem\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"pem\", this.options.privatePEMOptions);\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"pem\", {\n ...this.options.privatePEMOptions,\n label: \"PRIVATE KEY\",\n });\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for private key\");\n }\n\n throw new Error(\"unsupported destination format or type\");\n }\n\n encodePublic(\n publicKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n ): string {\n // biome-ignore lint/suspicious/noImplicitAnyLet: melting pot object\n let publicKeyObject;\n\n switch (originalFormat) {\n case \"raw\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = this.publicKeyObject(publicKey);\n break;\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof publicKey === \"string\") {\n publicKey = Buffer.from(publicKey, \"hex\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(publicKey, \"der\");\n break;\n case \"pem\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(\n publicKey,\n \"pem\",\n this.options.publicPEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid public key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n return publicKeyObject.pub.data.toString(\"hex\");\n case \"der\":\n return SubjectPublicKeyInfoASN.encode(publicKeyObject, \"der\").toString(\"hex\");\n case \"pem\":\n return SubjectPublicKeyInfoASN.encode(\n publicKeyObject,\n \"pem\",\n this.options.publicPEMOptions,\n );\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for public key\");\n }\n }\n}\n/* cspell:enable */\n","import elliptic from \"elliptic\";\nimport * as jose from \"jose\";\n\nimport { KeyEncoder } from \"./key-encoder\";\nimport type { GeneratedKeys } from \"./types\";\nimport crypto from \"node:crypto\";\n\nfunction extractPublicKey(pemKey: string): string {\n // convert the PEM formatted public key to raw public key in X9.62 uncompressed format\n // this is an oversimplified method and may not work with different curves or PEM formats\n const pem = pemKey.split(\"\\n\");\n pem.shift(); // remove the first line (BEGIN PUBLIC KEY)\n pem.pop(); // remove the last line (END PUBLIC KEY)\n // convert base64 to buffer\n const keyBuffer = Buffer.from(pem.join(\"\"), \"base64\");\n // assuming the first 26 bytes are the header for the SPKI formatted key.\n // the actual key should begin after this header.\n const actualKeyBuffer = keyBuffer.slice(26);\n return actualKeyBuffer.toString(\"hex\").toUpperCase();\n}\n\nfunction hexToPem(hexString: string, { isPrivate = true } = {}): string {\n const keyEncoder = new KeyEncoder(\"p256\");\n if (isPrivate) {\n return keyEncoder.encodePrivate(hexString, \"raw\", \"pem\");\n }\n return keyEncoder.encodePublic(hexString, \"raw\", \"pem\");\n}\n\n/**\n * If `entropy` is passed, will generate keys pair deterministically\n * else, random keys pair generated\n */\nexport function genKeys(entropy?: string): GeneratedKeys {\n if (entropy) {\n const ec = new elliptic.ec(\"p256\");\n const hashedEntropy = crypto.createHash(\"sha256\").update(entropy).digest(\"hex\");\n const keyPair = ec.genKeyPair({\n entropy: Buffer.from(hashedEntropy, \"hex\"),\n });\n return {\n privateKey: String(hexToPem(keyPair.getPrivate(\"hex\"))),\n publicKey: String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false })),\n hexPubKey: extractPublicKey(String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false }))),\n };\n }\n const { publicKey, privateKey } = crypto.generateKeyPairSync(\"ec\", {\n namedCurve: \"P-256\",\n publicKeyEncoding: { type: \"spki\", format: \"pem\" },\n privateKeyEncoding: { type: \"sec1\", format: \"pem\" },\n });\n const hexPubKey = extractPublicKey(publicKey);\n return {\n privateKey,\n publicKey,\n hexPubKey,\n };\n}\n\nexport const sign = async (privateKeyPem: string, base64Challenge: string): Promise<string> => {\n // Decode base64url challenge to bytes\n const challengeDataBytes = jose.base64url.decode(base64Challenge);\n\n // For EC private key format, we need to use a different import method\n // Since jose doesn't support SEC1 format directly, let's use Node.js crypto\n // Create a KeyObject from the EC private key\n const privateKey = crypto.createPrivateKey(privateKeyPem);\n\n // Use jose with the KeyObject\n return await new jose.CompactSign(challengeDataBytes)\n .setProtectedHeader({ alg: \"ES256\", typ: \"JWT\" })\n .sign(privateKey);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,SAAgB,QAAQ,MAAc,OAAuB;CAG3D,QAAA,GAAA,aAAA,kBAAA,EAAA,GAAA,sBAAA,OAAA,CAFc,IAAI,YAAY,CAAC,CAAC,OAAO,GAAG,KAAK,GAAG,OACvB,CACI,GAAGA,kCAAAA,QAAQ;AAC5C;AAEA,MAAM,kBAAkB,OAAO,MAAc,UAAuC;CAClF,MAAM,OAAO,OAAA,GAAA,aAAA,eAAA,CAAqB,QAAQ,MAAM,KAAK,CAAC;CAEtD,MAAM,WADUC,aAAAA,MAAM,eAAe,IACd,CAAC,CAAC,OAAO,qBAAqB;CACrD,OAAO,OAAO,OAAO,CAAC,SAAS,YAAa,SAAS,SAAU,CAAC;AAClE;AAEA,MAAa,gBAAgB,OAAO,SAAsC;CACxE,MAAM,YAAY,MAAM,QAAQ,IAAI;EAClC,gBAAgB,MAAM,CAAC;EACvB,gBAAgB,MAAM,CAAC;EACvB,gBAAgB,MAAM,CAAC;CACzB,CAAC;CAED,MAAM,aAAa,IAAI,WAAW,UAAU,EAAE,CAAC,MAAM;CACrD,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC,QAAQ,KACvC,WAAW,KAAK,UAAU,EAAE,CAAC,KAAM,UAAU,EAAE,CAAC,KAAM,UAAU,EAAE,CAAC;CAGrE,OAAO;AACT;;;AC1BA,MAAM,kBAAkBC,QAAAA,QAAK,OAAO,gBAAgB,WAAY;CAG9D,MAAM,OAAO;CACb,KACG,IAAI,CAAC,CACL,IACC,KAAK,IAAI,SAAS,CAAC,CAAC,IAAI,GACxB,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,GAC9B,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,GACpD,KAAK,IAAI,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CACtD;AACJ,CAAC;AAED,MAAM,mBAAmBA,QAAAA,QAAK;CAC5B;;CAEA,WAAY;EAGV,MAAM,OAAO;EACb,KACG,IAAI,CAAC,CACL,IACC,KAAK,IAAI,SAAS,CAAC,CAAC,IAAI,GACxB,KACG,IAAI,qBAAqB,CAAC,CAC1B,IAAI,CAAC,CACL,IAAI,KAAK,IAAI,aAAa,CAAC,CAAC,MAAM,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,GACjE,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,eAAe,GACxD,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CACvD;CACJ;AACF;AAEA,MAAM,0BAA0BA,QAAAA,QAAK,OAAO,wBAAwB,WAAY;CAG9E,MAAM,OAAO;CACb,KACG,IAAI,CAAC,CACL,IACC,KAAK,IAAI,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,GACjF,KAAK,IAAI,KAAK,CAAC,CAAC,OAAO,CACzB;AACJ,CAAC;AASD,MAAM,SAAuC;CAC3C,WAAW;EACT,iBAAiB;GAAC;GAAG;GAAG;GAAK;GAAG;EAAE;EAClC,mBAAmB,EAAE,OAAO,iBAAiB;EAC7C,kBAAkB,EAAE,OAAO,aAAa;EACxC,OAAO,IAAI,SAAA,QAAS,GAAG,WAAW;CACpC;CACA,MAAM;EACJ,iBAAiB;GAAC;GAAG;GAAG;GAAK;GAAO;GAAG;GAAG;EAAC;EAC3C,mBAAmB,EAAE,OAAO,iBAAiB;EAC7C,kBAAkB,EAAE,OAAO,aAAa;EACxC,OAAO,IAAI,SAAA,QAAS,GAAG,MAAM;CAC/B;AACF;AAoBA,IAAa,aAAb,MAAwB;CACtB;CACA;CAEA,YAAY,SAAgC;;EAE1C,IAAI,OAAO,YAAY,UAAU;;GAE/B,IAAI,YAAY,eAAe,YAAY,QACzC,MAAM,IAAI,MAAM,iBAAiB,SAAS;GAE5C,UAAU,OAAO;EACnB;EACA,KAAK,UAAU;EACf,KAAK,cAAc;GAAC;GAAG;GAAG;GAAK;GAAO;GAAG;EAAC;CAC5C;;CAGA,aAAqB,YAA8C;EACjE,OAAO;GACL,SAAS,IAAIC,MAAAA,QAAG,CAAC;GACjB;GACA,qBAAqB;IACnB,aAAa,KAAK;IAClB,OAAO,WAAW;GACpB;EACF;CACF;CAEA,iBAAiB,eAAuB,cAAuC;EAC7E,MAAM,mBAAoC;GACxC,SAAS,IAAIA,MAAAA,QAAG,CAAC;GACjB,YAAY,OAAO,KAAK,eAAe,KAAK;GAC5C,YAAY,KAAK,QAAQ;EAC3B;;EAGA,IAAI,cACF,iBAAiB,YAAY;GAC3B,QAAQ;GACR,MAAM,OAAO,KAAK,cAAc,KAAK;EACvC;EAGF,OAAO;CACT;CAEA,gBAAgB,cAGd;EACA,OAAO;GACL,WAAW;IACT,IAAI,KAAK;IACT,OAAO,KAAK,QAAQ;GACtB;GACA,KAAK;IACH,QAAQ;IACR,MAAM,OAAO,KAAK,cAAc,KAAK;GACvC;EACF;CACF;CAEA,cACE,YACA,gBACA,mBACA,wBAA2C,SACnC;EACR,IAAI;EAGJ,QAAQ,gBAAR;GACE,KAAK,OAAO;IACV,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,MAAM,8BAA8B;IAGhD,MAAM,eADU,KAAK,QAAQ,MAAM,eAAe,YAAY,KACnC,CAAC,CAAC,UAAU,KAAK;IAC5C,mBAAmB,KAAK,iBAAiB,YAAY,YAAY;IACjE;GACF;;GAEA,KAAK;IACH,IAAI,OAAO,eAAe,UACxB,aAAa,OAAO,KAAK,YAAY,KAAK;IAE5C,mBAAmB,gBAAgB,OAAO,YAAY,KAAK;IAC3D;GACF,KAAK;IACH,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,MAAM,8BAA8B;IAEhD,mBAAmB,gBAAgB,OACjC,YACA,OACA,KAAK,QAAQ,iBACf;IACA;;GAEF,SACE,MAAM,IAAI,MAAM,4BAA4B;EAChD;EAGA,QAAQ,mBAAR;GACE,KAAK;IACH,IAAI,0BAA0B,SAC5B,OAAO,iBAAiB,WAAW,SAAS,KAAK;SAC5C,IAAI,0BAA0B,SACnC,OAAO,KAAK,aAAa,gBAAgB,CAAC,CAAC,WAAW,WAAW,SAAS,KAAK;IAEjF;GACF,KAAK;IACH,IAAI,0BAA0B,SAC5B,OAAO,gBAAgB,OAAO,kBAAkB,KAAK,CAAC,CAAC,SAAS,KAAK;SAChE,IAAI,0BAA0B,SACnC,OAAO,iBAAiB,OAAO,KAAK,aAAa,gBAAgB,GAAG,KAAK,CAAC,CAAC,SACzE,KACF;IAEF;GACF,KAAK;IACH,IAAI,0BAA0B,SAC5B,OAAO,gBAAgB,OAAO,kBAAkB,OAAO,KAAK,QAAQ,iBAAiB;SAChF,IAAI,0BAA0B,SACnC,OAAO,iBAAiB,OAAO,KAAK,aAAa,gBAAgB,GAAG,OAAO;KACzE,GAAG,KAAK,QAAQ;KAChB,OAAO;IACT,CAAC;IAEH;;GAEF,SACE,MAAM,IAAI,MAAM,4CAA4C;EAChE;EAEA,MAAM,IAAI,MAAM,wCAAwC;CAC1D;CAEA,aACE,WACA,gBACA,mBACQ;EAER,IAAI;EAEJ,QAAQ,gBAAR;GACE,KAAK;IACH,IAAI,OAAO,cAAc,UACvB,MAAM,IAAI,MAAM,6BAA6B;IAE/C,kBAAkB,KAAK,gBAAgB,SAAS;IAChD;;GAEF,KAAK;IACH,IAAI,OAAO,cAAc,UACvB,YAAY,OAAO,KAAK,WAAW,KAAK;IAE1C,kBAAkB,wBAAwB,OAAO,WAAW,KAAK;IACjE;GACF,KAAK;IACH,IAAI,OAAO,cAAc,UACvB,MAAM,IAAI,MAAM,6BAA6B;IAE/C,kBAAkB,wBAAwB,OACxC,WACA,OACA,KAAK,QAAQ,gBACf;IACA;;GAEF,SACE,MAAM,IAAI,MAAM,2BAA2B;EAC/C;EAGA,QAAQ,mBAAR;GACE,KAAK,OACH,OAAO,gBAAgB,IAAI,KAAK,SAAS,KAAK;GAChD,KAAK,OACH,OAAO,wBAAwB,OAAO,iBAAiB,KAAK,CAAC,CAAC,SAAS,KAAK;GAC9E,KAAK,OACH,OAAO,wBAAwB,OAC7B,iBACA,OACA,KAAK,QAAQ,gBACf;;GAEF,SACE,MAAM,IAAI,MAAM,2CAA2C;EAC/D;CACF;AACF;;;ACjSA,SAAS,iBAAiB,QAAwB;CAGhD,MAAM,MAAM,OAAO,MAAM,IAAI;CAC7B,IAAI,MAAM;CACV,IAAI,IAAI;CAMR,OAJkB,OAAO,KAAK,IAAI,KAAK,EAAE,GAAG,QAGZ,CAAC,CAAC,MAAM,EACnB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,YAAY;AACrD;AAEA,SAAS,SAAS,WAAmB,EAAE,YAAY,SAAS,CAAC,GAAW;CACtE,MAAM,aAAa,IAAI,WAAW,MAAM;CACxC,IAAI,WACF,OAAO,WAAW,cAAc,WAAW,OAAO,KAAK;CAEzD,OAAO,WAAW,aAAa,WAAW,OAAO,KAAK;AACxD;;;;;AAMA,SAAgB,QAAQ,SAAiC;CACvD,IAAI,SAAS;EACX,MAAM,KAAK,IAAI,SAAA,QAAS,GAAG,MAAM;EACjC,MAAM,gBAAgBC,YAAAA,QAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,OAAO,KAAK;EAC9E,MAAM,UAAU,GAAG,WAAW,EAC5B,SAAS,OAAO,KAAK,eAAe,KAAK,EAC3C,CAAC;EACD,OAAO;GACL,YAAY,OAAO,SAAS,QAAQ,WAAW,KAAK,CAAC,CAAC;GACtD,WAAW,OAAO,SAAS,QAAQ,UAAU,KAAK,GAAG,EAAE,WAAW,MAAM,CAAC,CAAC;GAC1E,WAAW,iBAAiB,OAAO,SAAS,QAAQ,UAAU,KAAK,GAAG,EAAE,WAAW,MAAM,CAAC,CAAC,CAAC;EAC9F;CACF;CACA,MAAM,EAAE,WAAW,eAAeA,YAAAA,QAAO,oBAAoB,MAAM;EACjE,YAAY;EACZ,mBAAmB;GAAE,MAAM;GAAQ,QAAQ;EAAM;EACjD,oBAAoB;GAAE,MAAM;GAAQ,QAAQ;EAAM;CACpD,CAAC;CAED,OAAO;EACL;EACA;EACA,WAJgB,iBAAiB,SAIzB;CACV;AACF;AAEA,MAAa,OAAO,OAAO,eAAuB,oBAA6C;CAE7F,MAAM,qBAAqB,KAAK,UAAU,OAAO,eAAe;CAKhE,MAAM,aAAaA,YAAAA,QAAO,iBAAiB,aAAa;CAGxD,OAAO,MAAM,IAAI,KAAK,YAAY,kBAAkB,CAAC,CAClD,mBAAmB;EAAE,KAAK;EAAS,KAAK;CAAM,CAAC,CAAC,CAChD,KAAK,UAAU;AACpB"}
|
|
1
|
+
{"version":3,"file":"crypto-B4xS0N1u.cjs","names":["wordlist","HDKey","asn1","BN","crypto"],"sources":["../src/crypto/gen-seed.ts","../src/crypto/key-encoder.ts","../src/crypto/utils.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { HDKey } from \"@scure/bip32\";\nimport { entropyToMnemonic, mnemonicToSeed } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\n/**\n * Generate a deterministic BIP39 mnemonic from a salt and device index.\n *\n * Produces `entropyToMnemonic(SHA256(salt + \"_\" + index))`, matching\n * the behavior of `@ledgerhq/vault-common`'s `genSeed`.\n *\n * @param salt The workspace salt\n * @param index The device index (1-based)\n * @returns A 24-word BIP39 mnemonic string\n */\nexport function genSeed(salt: string, index: number): string {\n const input = new TextEncoder().encode(`${salt}_${index}`);\n const entropy = sha256(input);\n return entropyToMnemonic(entropy, wordlist);\n}\n\nconst getSeedFragment = async (salt: string, index: number): Promise<Uint8Array> => {\n const seed = await mnemonicToSeed(genSeed(salt, index));\n const secpKey = HDKey.fromMasterSeed(seed);\n const fragment = secpKey.derive(\"m/5655636'/4932953'\");\n return Buffer.concat([fragment.privateKey!, fragment.chainCode!]);\n};\n\nexport const getMasterSeed = async (salt: string): Promise<Uint8Array> => {\n const fragments = await Promise.all([\n getSeedFragment(salt, 7),\n getSeedFragment(salt, 8),\n getSeedFragment(salt, 9),\n ]);\n\n const masterSeed = new Uint8Array(fragments[0].length);\n for (let i = 0; i < fragments[0].length; i++) {\n masterSeed[i] = fragments[0][i]! ^ fragments[1][i]! ^ fragments[2][i]!;\n }\n\n return masterSeed;\n};\n","// ========================================================================== //\n// //\n// DISCLAIMER //\n// //\n// This code has been blindly copy-pasted from: //\n// https://github.com/LedgerHQ/pkey-ts //\n// //\n// ========================================================================== //\n//\n// @ts-expect-error this library does not ship types\nimport asn1 from \"asn1.js\";\nimport BN from \"bn.js\";\nimport elliptic from \"elliptic\";\n\n/* cspell:disable */\nconst ECPrivateKeyASN = asn1.define(\"ECPrivateKey\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self.key(\"privateKey\").octstr(),\n self.key(\"parameters\").explicit(0).objid().optional(),\n self.key(\"publicKey\").explicit(1).bitstr().optional(),\n );\n});\n\nconst ECPrivateKey8ASN = asn1.define(\n \"ECPrivateKey\",\n /* v8 ignore next -- @preserve */\n function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self\n .key(\"privateKeyAlgorithm\")\n .seq()\n .obj(self.key(\"ecPublicKey\").objid(), self.key(\"curve\").objid()),\n self.key(\"privateKey\").octstr().contains(ECPrivateKeyASN),\n self.key(\"attributes\").explicit(0).bitstr().optional(),\n );\n },\n);\n\nconst SubjectPublicKeyInfoASN = asn1.define(\"SubjectPublicKeyInfo\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"algorithm\").seq().obj(self.key(\"id\").objid(), self.key(\"curve\").objid()),\n self.key(\"pub\").bitstr(),\n );\n});\n\ntype CurveOptions = {\n curveParameters: number[];\n privatePEMOptions: { label: string };\n publicPEMOptions: { label: string };\n curve: elliptic.ec;\n};\n\nconst curves: Record<string, CurveOptions> = {\n secp256k1: {\n curveParameters: [1, 3, 132, 0, 10],\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"secp256k1\"),\n },\n p256: {\n curveParameters: [1, 2, 840, 10045, 3, 1, 7], // OID for p256 curve\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"p256\"),\n },\n};\n\ntype PrivateKeyPKCS1 = {\n version: BN;\n privateKey: Buffer;\n parameters: number[];\n publicKey?: {\n unused: number;\n data: Buffer;\n };\n};\n\ntype PrivateKeyPKCS8 = {\n version: BN;\n privateKey: PrivateKeyPKCS1;\n privateKeyAlgorithm: { ecPublicKey: number[]; curve: number[] };\n};\n\nexport type KeyFormat = \"raw\" | \"pem\" | \"der\";\n\nexport class KeyEncoder {\n algorithmID: number[];\n options: CurveOptions;\n\n constructor(options: string | CurveOptions) {\n /* v8 ignore else -- @preserve */\n if (typeof options === \"string\") {\n /* v8 ignore if -- @preserve */\n if (options !== \"secp256k1\" && options !== \"p256\") {\n throw new Error(`Unknown curve ${options}`);\n }\n options = curves[options]!;\n }\n this.options = options;\n this.algorithmID = [1, 2, 840, 10045, 2, 1];\n }\n\n /* v8 ignore next -- @preserve */\n private PKCS1toPKCS8(privateKey: PrivateKeyPKCS1): PrivateKeyPKCS8 {\n return {\n version: new BN(0),\n privateKey,\n privateKeyAlgorithm: {\n ecPublicKey: this.algorithmID,\n curve: privateKey.parameters,\n },\n };\n }\n\n privateKeyObject(rawPrivateKey: string, rawPublicKey: string): PrivateKeyPKCS1 {\n const privateKeyObject: PrivateKeyPKCS1 = {\n version: new BN(1),\n privateKey: Buffer.from(rawPrivateKey, \"hex\"),\n parameters: this.options.curveParameters,\n };\n\n /* v8 ignore else -- @preserve */\n if (rawPublicKey) {\n privateKeyObject.publicKey = {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n };\n }\n\n return privateKeyObject;\n }\n\n publicKeyObject(rawPublicKey: string): {\n algorithm: { id: number[]; curve: number[] };\n pub: { unused: number; data: Buffer };\n } {\n return {\n algorithm: {\n id: this.algorithmID,\n curve: this.options.curveParameters,\n },\n pub: {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n },\n };\n }\n\n encodePrivate(\n privateKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n destinationFormatType: \"pkcs8\" | \"pkcs1\" = \"pkcs1\",\n ): string {\n let privateKeyObject: PrivateKeyPKCS1;\n\n /* Parse the incoming private key and convert it to a private key object */\n switch (originalFormat) {\n case \"raw\": {\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n const keyPair = this.options.curve.keyFromPrivate(privateKey, \"hex\");\n const rawPublicKey = keyPair.getPublic(\"hex\");\n privateKeyObject = this.privateKeyObject(privateKey, rawPublicKey);\n break;\n }\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof privateKey === \"string\") {\n privateKey = Buffer.from(privateKey, \"hex\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(privateKey, \"der\");\n break;\n case \"pem\":\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(\n privateKey,\n \"pem\",\n this.options.privatePEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid private key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n if (destinationFormatType === \"pkcs1\") {\n return privateKeyObject.privateKey.toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return this.PKCS1toPKCS8(privateKeyObject).privateKey.privateKey.toString(\"hex\");\n }\n break;\n case \"der\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"der\").toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"der\").toString(\n \"hex\",\n );\n }\n break;\n case \"pem\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"pem\", this.options.privatePEMOptions);\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"pem\", {\n ...this.options.privatePEMOptions,\n label: \"PRIVATE KEY\",\n });\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for private key\");\n }\n\n throw new Error(\"unsupported destination format or type\");\n }\n\n encodePublic(\n publicKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n ): string {\n // biome-ignore lint/suspicious/noImplicitAnyLet: melting pot object\n let publicKeyObject;\n\n switch (originalFormat) {\n case \"raw\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = this.publicKeyObject(publicKey);\n break;\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof publicKey === \"string\") {\n publicKey = Buffer.from(publicKey, \"hex\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(publicKey, \"der\");\n break;\n case \"pem\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(\n publicKey,\n \"pem\",\n this.options.publicPEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid public key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n return publicKeyObject.pub.data.toString(\"hex\");\n case \"der\":\n return SubjectPublicKeyInfoASN.encode(publicKeyObject, \"der\").toString(\"hex\");\n case \"pem\":\n return SubjectPublicKeyInfoASN.encode(\n publicKeyObject,\n \"pem\",\n this.options.publicPEMOptions,\n );\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for public key\");\n }\n }\n}\n/* cspell:enable */\n","import elliptic from \"elliptic\";\nimport * as jose from \"jose\";\n\nimport { KeyEncoder } from \"./key-encoder\";\nimport type { GeneratedKeys } from \"./types\";\nimport crypto from \"node:crypto\";\n\nfunction extractPublicKey(pemKey: string): string {\n // convert the PEM formatted public key to raw public key in X9.62 uncompressed format\n // this is an oversimplified method and may not work with different curves or PEM formats\n const pem = pemKey.split(\"\\n\");\n pem.shift(); // remove the first line (BEGIN PUBLIC KEY)\n pem.pop(); // remove the last line (END PUBLIC KEY)\n // convert base64 to buffer\n const keyBuffer = Buffer.from(pem.join(\"\"), \"base64\");\n // assuming the first 26 bytes are the header for the SPKI formatted key.\n // the actual key should begin after this header.\n const actualKeyBuffer = keyBuffer.slice(26);\n return actualKeyBuffer.toString(\"hex\").toUpperCase();\n}\n\nfunction hexToPem(hexString: string, { isPrivate = true } = {}): string {\n const keyEncoder = new KeyEncoder(\"p256\");\n if (isPrivate) {\n return keyEncoder.encodePrivate(hexString, \"raw\", \"pem\");\n }\n return keyEncoder.encodePublic(hexString, \"raw\", \"pem\");\n}\n\n/**\n * If `entropy` is passed, will generate keys pair deterministically\n * else, random keys pair generated\n */\nexport function genKeys(entropy?: string): GeneratedKeys {\n if (entropy) {\n const ec = new elliptic.ec(\"p256\");\n const hashedEntropy = crypto.createHash(\"sha256\").update(entropy).digest(\"hex\");\n const keyPair = ec.genKeyPair({\n entropy: Buffer.from(hashedEntropy, \"hex\"),\n });\n return {\n privateKey: String(hexToPem(keyPair.getPrivate(\"hex\"))),\n publicKey: String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false })),\n hexPubKey: extractPublicKey(String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false }))),\n };\n }\n const { publicKey, privateKey } = crypto.generateKeyPairSync(\"ec\", {\n namedCurve: \"P-256\",\n publicKeyEncoding: { type: \"spki\", format: \"pem\" },\n privateKeyEncoding: { type: \"sec1\", format: \"pem\" },\n });\n const hexPubKey = extractPublicKey(publicKey);\n return {\n privateKey,\n publicKey,\n hexPubKey,\n };\n}\n\nexport const sign = async (privateKeyPem: string, base64Challenge: string): Promise<string> => {\n // Decode base64url challenge to bytes\n const challengeDataBytes = jose.base64url.decode(base64Challenge);\n\n // For EC private key format, we need to use a different import method\n // Since jose doesn't support SEC1 format directly, let's use Node.js crypto\n // Create a KeyObject from the EC private key\n const privateKey = crypto.createPrivateKey(privateKeyPem);\n\n // Use jose with the KeyObject\n return new jose.CompactSign(challengeDataBytes)\n .setProtectedHeader({ alg: \"ES256\", typ: \"JWT\" })\n .sign(privateKey);\n};\n"],"mappings":"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"}
|
|
@@ -256,7 +256,7 @@ function genKeys(entropy) {
|
|
|
256
256
|
const sign = async (privateKeyPem, base64Challenge) => {
|
|
257
257
|
const challengeDataBytes = jose.base64url.decode(base64Challenge);
|
|
258
258
|
const privateKey = crypto.createPrivateKey(privateKeyPem);
|
|
259
|
-
return
|
|
259
|
+
return new jose.CompactSign(challengeDataBytes).setProtectedHeader({
|
|
260
260
|
alg: "ES256",
|
|
261
261
|
typ: "JWT"
|
|
262
262
|
}).sign(privateKey);
|
|
@@ -264,4 +264,4 @@ const sign = async (privateKeyPem, base64Challenge) => {
|
|
|
264
264
|
//#endregion
|
|
265
265
|
export { getMasterSeed as i, sign as n, genSeed as r, genKeys as t };
|
|
266
266
|
|
|
267
|
-
//# sourceMappingURL=crypto-
|
|
267
|
+
//# sourceMappingURL=crypto-BZw0pZ1Z.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-BHYSptBe.js","names":[],"sources":["../src/crypto/gen-seed.ts","../src/crypto/key-encoder.ts","../src/crypto/utils.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { HDKey } from \"@scure/bip32\";\nimport { entropyToMnemonic, mnemonicToSeed } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\n/**\n * Generate a deterministic BIP39 mnemonic from a salt and device index.\n *\n * Produces `entropyToMnemonic(SHA256(salt + \"_\" + index))`, matching\n * the behavior of `@ledgerhq/vault-common`'s `genSeed`.\n *\n * @param salt The workspace salt\n * @param index The device index (1-based)\n * @returns A 24-word BIP39 mnemonic string\n */\nexport function genSeed(salt: string, index: number): string {\n const input = new TextEncoder().encode(`${salt}_${index}`);\n const entropy = sha256(input);\n return entropyToMnemonic(entropy, wordlist);\n}\n\nconst getSeedFragment = async (salt: string, index: number): Promise<Uint8Array> => {\n const seed = await mnemonicToSeed(genSeed(salt, index));\n const secpKey = HDKey.fromMasterSeed(seed);\n const fragment = secpKey.derive(\"m/5655636'/4932953'\");\n return Buffer.concat([fragment.privateKey!, fragment.chainCode!]);\n};\n\nexport const getMasterSeed = async (salt: string): Promise<Uint8Array> => {\n const fragments = await Promise.all([\n getSeedFragment(salt, 7),\n getSeedFragment(salt, 8),\n getSeedFragment(salt, 9),\n ]);\n\n const masterSeed = new Uint8Array(fragments[0].length);\n for (let i = 0; i < fragments[0].length; i++) {\n masterSeed[i] = fragments[0][i]! ^ fragments[1][i]! ^ fragments[2][i]!;\n }\n\n return masterSeed;\n};\n","// ========================================================================== //\n// //\n// DISCLAIMER //\n// //\n// This code has been blindly copy-pasted from: //\n// https://github.com/LedgerHQ/pkey-ts //\n// //\n// ========================================================================== //\n//\n// @ts-expect-error this library does not ship types\nimport asn1 from \"asn1.js\";\nimport BN from \"bn.js\";\nimport elliptic from \"elliptic\";\n\n/* cspell:disable */\nconst ECPrivateKeyASN = asn1.define(\"ECPrivateKey\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self.key(\"privateKey\").octstr(),\n self.key(\"parameters\").explicit(0).objid().optional(),\n self.key(\"publicKey\").explicit(1).bitstr().optional(),\n );\n});\n\nconst ECPrivateKey8ASN = asn1.define(\n \"ECPrivateKey\",\n /* v8 ignore next -- @preserve */\n function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self\n .key(\"privateKeyAlgorithm\")\n .seq()\n .obj(self.key(\"ecPublicKey\").objid(), self.key(\"curve\").objid()),\n self.key(\"privateKey\").octstr().contains(ECPrivateKeyASN),\n self.key(\"attributes\").explicit(0).bitstr().optional(),\n );\n },\n);\n\nconst SubjectPublicKeyInfoASN = asn1.define(\"SubjectPublicKeyInfo\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"algorithm\").seq().obj(self.key(\"id\").objid(), self.key(\"curve\").objid()),\n self.key(\"pub\").bitstr(),\n );\n});\n\ntype CurveOptions = {\n curveParameters: number[];\n privatePEMOptions: { label: string };\n publicPEMOptions: { label: string };\n curve: elliptic.ec;\n};\n\nconst curves: Record<string, CurveOptions> = {\n secp256k1: {\n curveParameters: [1, 3, 132, 0, 10],\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"secp256k1\"),\n },\n p256: {\n curveParameters: [1, 2, 840, 10045, 3, 1, 7], // OID for p256 curve\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"p256\"),\n },\n};\n\ntype PrivateKeyPKCS1 = {\n version: BN;\n privateKey: Buffer;\n parameters: number[];\n publicKey?: {\n unused: number;\n data: Buffer;\n };\n};\n\ntype PrivateKeyPKCS8 = {\n version: BN;\n privateKey: PrivateKeyPKCS1;\n privateKeyAlgorithm: { ecPublicKey: number[]; curve: number[] };\n};\n\nexport type KeyFormat = \"raw\" | \"pem\" | \"der\";\n\nexport class KeyEncoder {\n algorithmID: number[];\n options: CurveOptions;\n\n constructor(options: string | CurveOptions) {\n /* v8 ignore else -- @preserve */\n if (typeof options === \"string\") {\n /* v8 ignore if -- @preserve */\n if (options !== \"secp256k1\" && options !== \"p256\") {\n throw new Error(`Unknown curve ${options}`);\n }\n options = curves[options]!;\n }\n this.options = options;\n this.algorithmID = [1, 2, 840, 10045, 2, 1];\n }\n\n /* v8 ignore next -- @preserve */\n private PKCS1toPKCS8(privateKey: PrivateKeyPKCS1): PrivateKeyPKCS8 {\n return {\n version: new BN(0),\n privateKey,\n privateKeyAlgorithm: {\n ecPublicKey: this.algorithmID,\n curve: privateKey.parameters,\n },\n };\n }\n\n privateKeyObject(rawPrivateKey: string, rawPublicKey: string): PrivateKeyPKCS1 {\n const privateKeyObject: PrivateKeyPKCS1 = {\n version: new BN(1),\n privateKey: Buffer.from(rawPrivateKey, \"hex\"),\n parameters: this.options.curveParameters,\n };\n\n /* v8 ignore else -- @preserve */\n if (rawPublicKey) {\n privateKeyObject.publicKey = {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n };\n }\n\n return privateKeyObject;\n }\n\n publicKeyObject(rawPublicKey: string): {\n algorithm: { id: number[]; curve: number[] };\n pub: { unused: number; data: Buffer };\n } {\n return {\n algorithm: {\n id: this.algorithmID,\n curve: this.options.curveParameters,\n },\n pub: {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n },\n };\n }\n\n encodePrivate(\n privateKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n destinationFormatType: \"pkcs8\" | \"pkcs1\" = \"pkcs1\",\n ): string {\n let privateKeyObject: PrivateKeyPKCS1;\n\n /* Parse the incoming private key and convert it to a private key object */\n switch (originalFormat) {\n case \"raw\": {\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n const keyPair = this.options.curve.keyFromPrivate(privateKey, \"hex\");\n const rawPublicKey = keyPair.getPublic(\"hex\");\n privateKeyObject = this.privateKeyObject(privateKey, rawPublicKey);\n break;\n }\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof privateKey === \"string\") {\n privateKey = Buffer.from(privateKey, \"hex\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(privateKey, \"der\");\n break;\n case \"pem\":\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(\n privateKey,\n \"pem\",\n this.options.privatePEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid private key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n if (destinationFormatType === \"pkcs1\") {\n return privateKeyObject.privateKey.toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return this.PKCS1toPKCS8(privateKeyObject).privateKey.privateKey.toString(\"hex\");\n }\n break;\n case \"der\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"der\").toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"der\").toString(\n \"hex\",\n );\n }\n break;\n case \"pem\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"pem\", this.options.privatePEMOptions);\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"pem\", {\n ...this.options.privatePEMOptions,\n label: \"PRIVATE KEY\",\n });\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for private key\");\n }\n\n throw new Error(\"unsupported destination format or type\");\n }\n\n encodePublic(\n publicKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n ): string {\n // biome-ignore lint/suspicious/noImplicitAnyLet: melting pot object\n let publicKeyObject;\n\n switch (originalFormat) {\n case \"raw\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = this.publicKeyObject(publicKey);\n break;\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof publicKey === \"string\") {\n publicKey = Buffer.from(publicKey, \"hex\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(publicKey, \"der\");\n break;\n case \"pem\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(\n publicKey,\n \"pem\",\n this.options.publicPEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid public key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n return publicKeyObject.pub.data.toString(\"hex\");\n case \"der\":\n return SubjectPublicKeyInfoASN.encode(publicKeyObject, \"der\").toString(\"hex\");\n case \"pem\":\n return SubjectPublicKeyInfoASN.encode(\n publicKeyObject,\n \"pem\",\n this.options.publicPEMOptions,\n );\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for public key\");\n }\n }\n}\n/* cspell:enable */\n","import elliptic from \"elliptic\";\nimport * as jose from \"jose\";\n\nimport { KeyEncoder } from \"./key-encoder\";\nimport type { GeneratedKeys } from \"./types\";\nimport crypto from \"node:crypto\";\n\nfunction extractPublicKey(pemKey: string): string {\n // convert the PEM formatted public key to raw public key in X9.62 uncompressed format\n // this is an oversimplified method and may not work with different curves or PEM formats\n const pem = pemKey.split(\"\\n\");\n pem.shift(); // remove the first line (BEGIN PUBLIC KEY)\n pem.pop(); // remove the last line (END PUBLIC KEY)\n // convert base64 to buffer\n const keyBuffer = Buffer.from(pem.join(\"\"), \"base64\");\n // assuming the first 26 bytes are the header for the SPKI formatted key.\n // the actual key should begin after this header.\n const actualKeyBuffer = keyBuffer.slice(26);\n return actualKeyBuffer.toString(\"hex\").toUpperCase();\n}\n\nfunction hexToPem(hexString: string, { isPrivate = true } = {}): string {\n const keyEncoder = new KeyEncoder(\"p256\");\n if (isPrivate) {\n return keyEncoder.encodePrivate(hexString, \"raw\", \"pem\");\n }\n return keyEncoder.encodePublic(hexString, \"raw\", \"pem\");\n}\n\n/**\n * If `entropy` is passed, will generate keys pair deterministically\n * else, random keys pair generated\n */\nexport function genKeys(entropy?: string): GeneratedKeys {\n if (entropy) {\n const ec = new elliptic.ec(\"p256\");\n const hashedEntropy = crypto.createHash(\"sha256\").update(entropy).digest(\"hex\");\n const keyPair = ec.genKeyPair({\n entropy: Buffer.from(hashedEntropy, \"hex\"),\n });\n return {\n privateKey: String(hexToPem(keyPair.getPrivate(\"hex\"))),\n publicKey: String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false })),\n hexPubKey: extractPublicKey(String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false }))),\n };\n }\n const { publicKey, privateKey } = crypto.generateKeyPairSync(\"ec\", {\n namedCurve: \"P-256\",\n publicKeyEncoding: { type: \"spki\", format: \"pem\" },\n privateKeyEncoding: { type: \"sec1\", format: \"pem\" },\n });\n const hexPubKey = extractPublicKey(publicKey);\n return {\n privateKey,\n publicKey,\n hexPubKey,\n };\n}\n\nexport const sign = async (privateKeyPem: string, base64Challenge: string): Promise<string> => {\n // Decode base64url challenge to bytes\n const challengeDataBytes = jose.base64url.decode(base64Challenge);\n\n // For EC private key format, we need to use a different import method\n // Since jose doesn't support SEC1 format directly, let's use Node.js crypto\n // Create a KeyObject from the EC private key\n const privateKey = crypto.createPrivateKey(privateKeyPem);\n\n // Use jose with the KeyObject\n return await new jose.CompactSign(challengeDataBytes)\n .setProtectedHeader({ alg: \"ES256\", typ: \"JWT\" })\n .sign(privateKey);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"crypto-BZw0pZ1Z.js","names":[],"sources":["../src/crypto/gen-seed.ts","../src/crypto/key-encoder.ts","../src/crypto/utils.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { HDKey } from \"@scure/bip32\";\nimport { entropyToMnemonic, mnemonicToSeed } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\n/**\n * Generate a deterministic BIP39 mnemonic from a salt and device index.\n *\n * Produces `entropyToMnemonic(SHA256(salt + \"_\" + index))`, matching\n * the behavior of `@ledgerhq/vault-common`'s `genSeed`.\n *\n * @param salt The workspace salt\n * @param index The device index (1-based)\n * @returns A 24-word BIP39 mnemonic string\n */\nexport function genSeed(salt: string, index: number): string {\n const input = new TextEncoder().encode(`${salt}_${index}`);\n const entropy = sha256(input);\n return entropyToMnemonic(entropy, wordlist);\n}\n\nconst getSeedFragment = async (salt: string, index: number): Promise<Uint8Array> => {\n const seed = await mnemonicToSeed(genSeed(salt, index));\n const secpKey = HDKey.fromMasterSeed(seed);\n const fragment = secpKey.derive(\"m/5655636'/4932953'\");\n return Buffer.concat([fragment.privateKey!, fragment.chainCode!]);\n};\n\nexport const getMasterSeed = async (salt: string): Promise<Uint8Array> => {\n const fragments = await Promise.all([\n getSeedFragment(salt, 7),\n getSeedFragment(salt, 8),\n getSeedFragment(salt, 9),\n ]);\n\n const masterSeed = new Uint8Array(fragments[0].length);\n for (let i = 0; i < fragments[0].length; i++) {\n masterSeed[i] = fragments[0][i]! ^ fragments[1][i]! ^ fragments[2][i]!;\n }\n\n return masterSeed;\n};\n","// ========================================================================== //\n// //\n// DISCLAIMER //\n// //\n// This code has been blindly copy-pasted from: //\n// https://github.com/LedgerHQ/pkey-ts //\n// //\n// ========================================================================== //\n//\n// @ts-expect-error this library does not ship types\nimport asn1 from \"asn1.js\";\nimport BN from \"bn.js\";\nimport elliptic from \"elliptic\";\n\n/* cspell:disable */\nconst ECPrivateKeyASN = asn1.define(\"ECPrivateKey\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self.key(\"privateKey\").octstr(),\n self.key(\"parameters\").explicit(0).objid().optional(),\n self.key(\"publicKey\").explicit(1).bitstr().optional(),\n );\n});\n\nconst ECPrivateKey8ASN = asn1.define(\n \"ECPrivateKey\",\n /* v8 ignore next -- @preserve */\n function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"version\").int(),\n self\n .key(\"privateKeyAlgorithm\")\n .seq()\n .obj(self.key(\"ecPublicKey\").objid(), self.key(\"curve\").objid()),\n self.key(\"privateKey\").octstr().contains(ECPrivateKeyASN),\n self.key(\"attributes\").explicit(0).bitstr().optional(),\n );\n },\n);\n\nconst SubjectPublicKeyInfoASN = asn1.define(\"SubjectPublicKeyInfo\", function () {\n // @ts-expect-error pure black box\n // biome-ignore lint/suspicious/noExplicitAny: black box\n const self = this as any;\n self\n .seq()\n .obj(\n self.key(\"algorithm\").seq().obj(self.key(\"id\").objid(), self.key(\"curve\").objid()),\n self.key(\"pub\").bitstr(),\n );\n});\n\ntype CurveOptions = {\n curveParameters: number[];\n privatePEMOptions: { label: string };\n publicPEMOptions: { label: string };\n curve: elliptic.ec;\n};\n\nconst curves: Record<string, CurveOptions> = {\n secp256k1: {\n curveParameters: [1, 3, 132, 0, 10],\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"secp256k1\"),\n },\n p256: {\n curveParameters: [1, 2, 840, 10045, 3, 1, 7], // OID for p256 curve\n privatePEMOptions: { label: \"EC PRIVATE KEY\" },\n publicPEMOptions: { label: \"PUBLIC KEY\" },\n curve: new elliptic.ec(\"p256\"),\n },\n};\n\ntype PrivateKeyPKCS1 = {\n version: BN;\n privateKey: Buffer;\n parameters: number[];\n publicKey?: {\n unused: number;\n data: Buffer;\n };\n};\n\ntype PrivateKeyPKCS8 = {\n version: BN;\n privateKey: PrivateKeyPKCS1;\n privateKeyAlgorithm: { ecPublicKey: number[]; curve: number[] };\n};\n\nexport type KeyFormat = \"raw\" | \"pem\" | \"der\";\n\nexport class KeyEncoder {\n algorithmID: number[];\n options: CurveOptions;\n\n constructor(options: string | CurveOptions) {\n /* v8 ignore else -- @preserve */\n if (typeof options === \"string\") {\n /* v8 ignore if -- @preserve */\n if (options !== \"secp256k1\" && options !== \"p256\") {\n throw new Error(`Unknown curve ${options}`);\n }\n options = curves[options]!;\n }\n this.options = options;\n this.algorithmID = [1, 2, 840, 10045, 2, 1];\n }\n\n /* v8 ignore next -- @preserve */\n private PKCS1toPKCS8(privateKey: PrivateKeyPKCS1): PrivateKeyPKCS8 {\n return {\n version: new BN(0),\n privateKey,\n privateKeyAlgorithm: {\n ecPublicKey: this.algorithmID,\n curve: privateKey.parameters,\n },\n };\n }\n\n privateKeyObject(rawPrivateKey: string, rawPublicKey: string): PrivateKeyPKCS1 {\n const privateKeyObject: PrivateKeyPKCS1 = {\n version: new BN(1),\n privateKey: Buffer.from(rawPrivateKey, \"hex\"),\n parameters: this.options.curveParameters,\n };\n\n /* v8 ignore else -- @preserve */\n if (rawPublicKey) {\n privateKeyObject.publicKey = {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n };\n }\n\n return privateKeyObject;\n }\n\n publicKeyObject(rawPublicKey: string): {\n algorithm: { id: number[]; curve: number[] };\n pub: { unused: number; data: Buffer };\n } {\n return {\n algorithm: {\n id: this.algorithmID,\n curve: this.options.curveParameters,\n },\n pub: {\n unused: 0,\n data: Buffer.from(rawPublicKey, \"hex\"),\n },\n };\n }\n\n encodePrivate(\n privateKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n destinationFormatType: \"pkcs8\" | \"pkcs1\" = \"pkcs1\",\n ): string {\n let privateKeyObject: PrivateKeyPKCS1;\n\n /* Parse the incoming private key and convert it to a private key object */\n switch (originalFormat) {\n case \"raw\": {\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n const keyPair = this.options.curve.keyFromPrivate(privateKey, \"hex\");\n const rawPublicKey = keyPair.getPublic(\"hex\");\n privateKeyObject = this.privateKeyObject(privateKey, rawPublicKey);\n break;\n }\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof privateKey === \"string\") {\n privateKey = Buffer.from(privateKey, \"hex\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(privateKey, \"der\");\n break;\n case \"pem\":\n if (typeof privateKey !== \"string\") {\n throw new Error(\"private key must be a string\");\n }\n privateKeyObject = ECPrivateKeyASN.decode(\n privateKey,\n \"pem\",\n this.options.privatePEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid private key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n if (destinationFormatType === \"pkcs1\") {\n return privateKeyObject.privateKey.toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return this.PKCS1toPKCS8(privateKeyObject).privateKey.privateKey.toString(\"hex\");\n }\n break;\n case \"der\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"der\").toString(\"hex\");\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"der\").toString(\n \"hex\",\n );\n }\n break;\n case \"pem\":\n if (destinationFormatType === \"pkcs1\") {\n return ECPrivateKeyASN.encode(privateKeyObject, \"pem\", this.options.privatePEMOptions);\n } else if (destinationFormatType === \"pkcs8\") {\n return ECPrivateKey8ASN.encode(this.PKCS1toPKCS8(privateKeyObject), \"pem\", {\n ...this.options.privatePEMOptions,\n label: \"PRIVATE KEY\",\n });\n }\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for private key\");\n }\n\n throw new Error(\"unsupported destination format or type\");\n }\n\n encodePublic(\n publicKey: string | Buffer,\n originalFormat: KeyFormat,\n destinationFormat: KeyFormat,\n ): string {\n // biome-ignore lint/suspicious/noImplicitAnyLet: melting pot object\n let publicKeyObject;\n\n switch (originalFormat) {\n case \"raw\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = this.publicKeyObject(publicKey);\n break;\n /* v8 ignore next -- @preserve */\n case \"der\":\n if (typeof publicKey === \"string\") {\n publicKey = Buffer.from(publicKey, \"hex\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(publicKey, \"der\");\n break;\n case \"pem\":\n if (typeof publicKey !== \"string\") {\n throw new Error(\"public key must be a string\");\n }\n publicKeyObject = SubjectPublicKeyInfoASN.decode(\n publicKey,\n \"pem\",\n this.options.publicPEMOptions,\n );\n break;\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid public key format\");\n }\n\n /* Export the private key object to the desired format */\n switch (destinationFormat) {\n case \"raw\":\n return publicKeyObject.pub.data.toString(\"hex\");\n case \"der\":\n return SubjectPublicKeyInfoASN.encode(publicKeyObject, \"der\").toString(\"hex\");\n case \"pem\":\n return SubjectPublicKeyInfoASN.encode(\n publicKeyObject,\n \"pem\",\n this.options.publicPEMOptions,\n );\n /* v8 ignore next -- @preserve */\n default:\n throw new Error(\"invalid destination format for public key\");\n }\n }\n}\n/* cspell:enable */\n","import elliptic from \"elliptic\";\nimport * as jose from \"jose\";\n\nimport { KeyEncoder } from \"./key-encoder\";\nimport type { GeneratedKeys } from \"./types\";\nimport crypto from \"node:crypto\";\n\nfunction extractPublicKey(pemKey: string): string {\n // convert the PEM formatted public key to raw public key in X9.62 uncompressed format\n // this is an oversimplified method and may not work with different curves or PEM formats\n const pem = pemKey.split(\"\\n\");\n pem.shift(); // remove the first line (BEGIN PUBLIC KEY)\n pem.pop(); // remove the last line (END PUBLIC KEY)\n // convert base64 to buffer\n const keyBuffer = Buffer.from(pem.join(\"\"), \"base64\");\n // assuming the first 26 bytes are the header for the SPKI formatted key.\n // the actual key should begin after this header.\n const actualKeyBuffer = keyBuffer.slice(26);\n return actualKeyBuffer.toString(\"hex\").toUpperCase();\n}\n\nfunction hexToPem(hexString: string, { isPrivate = true } = {}): string {\n const keyEncoder = new KeyEncoder(\"p256\");\n if (isPrivate) {\n return keyEncoder.encodePrivate(hexString, \"raw\", \"pem\");\n }\n return keyEncoder.encodePublic(hexString, \"raw\", \"pem\");\n}\n\n/**\n * If `entropy` is passed, will generate keys pair deterministically\n * else, random keys pair generated\n */\nexport function genKeys(entropy?: string): GeneratedKeys {\n if (entropy) {\n const ec = new elliptic.ec(\"p256\");\n const hashedEntropy = crypto.createHash(\"sha256\").update(entropy).digest(\"hex\");\n const keyPair = ec.genKeyPair({\n entropy: Buffer.from(hashedEntropy, \"hex\"),\n });\n return {\n privateKey: String(hexToPem(keyPair.getPrivate(\"hex\"))),\n publicKey: String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false })),\n hexPubKey: extractPublicKey(String(hexToPem(keyPair.getPublic(\"hex\"), { isPrivate: false }))),\n };\n }\n const { publicKey, privateKey } = crypto.generateKeyPairSync(\"ec\", {\n namedCurve: \"P-256\",\n publicKeyEncoding: { type: \"spki\", format: \"pem\" },\n privateKeyEncoding: { type: \"sec1\", format: \"pem\" },\n });\n const hexPubKey = extractPublicKey(publicKey);\n return {\n privateKey,\n publicKey,\n hexPubKey,\n };\n}\n\nexport const sign = async (privateKeyPem: string, base64Challenge: string): Promise<string> => {\n // Decode base64url challenge to bytes\n const challengeDataBytes = jose.base64url.decode(base64Challenge);\n\n // For EC private key format, we need to use a different import method\n // Since jose doesn't support SEC1 format directly, let's use Node.js crypto\n // Create a KeyObject from the EC private key\n const privateKey = crypto.createPrivateKey(privateKeyPem);\n\n // Use jose with the KeyObject\n return new jose.CompactSign(challengeDataBytes)\n .setProtectedHeader({ alg: \"ES256\", typ: \"JWT\" })\n .sign(privateKey);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAeA,SAAgB,QAAQ,MAAc,OAAuB;CAG3D,OAAO,kBADS,OADF,IAAI,YAAY,CAAC,CAAC,OAAO,GAAG,KAAK,GAAG,OACvB,CACI,GAAG,QAAQ;AAC5C;AAEA,MAAM,kBAAkB,OAAO,MAAc,UAAuC;CAClF,MAAM,OAAO,MAAM,eAAe,QAAQ,MAAM,KAAK,CAAC;CAEtD,MAAM,WADU,MAAM,eAAe,IACd,CAAC,CAAC,OAAO,qBAAqB;CACrD,OAAO,OAAO,OAAO,CAAC,SAAS,YAAa,SAAS,SAAU,CAAC;AAClE;AAEA,MAAa,gBAAgB,OAAO,SAAsC;CACxE,MAAM,YAAY,MAAM,QAAQ,IAAI;EAClC,gBAAgB,MAAM,CAAC;EACvB,gBAAgB,MAAM,CAAC;EACvB,gBAAgB,MAAM,CAAC;CACzB,CAAC;CAED,MAAM,aAAa,IAAI,WAAW,UAAU,EAAE,CAAC,MAAM;CACrD,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC,QAAQ,KACvC,WAAW,KAAK,UAAU,EAAE,CAAC,KAAM,UAAU,EAAE,CAAC,KAAM,UAAU,EAAE,CAAC;CAGrE,OAAO;AACT;;;AC1BA,MAAM,kBAAkB,KAAK,OAAO,gBAAgB,WAAY;CAG9D,MAAM,OAAO;CACb,KACG,IAAI,CAAC,CACL,IACC,KAAK,IAAI,SAAS,CAAC,CAAC,IAAI,GACxB,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,GAC9B,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,GACpD,KAAK,IAAI,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CACtD;AACJ,CAAC;AAED,MAAM,mBAAmB,KAAK;CAC5B;;CAEA,WAAY;EAGV,MAAM,OAAO;EACb,KACG,IAAI,CAAC,CACL,IACC,KAAK,IAAI,SAAS,CAAC,CAAC,IAAI,GACxB,KACG,IAAI,qBAAqB,CAAC,CAC1B,IAAI,CAAC,CACL,IAAI,KAAK,IAAI,aAAa,CAAC,CAAC,MAAM,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,GACjE,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,eAAe,GACxD,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CACvD;CACJ;AACF;AAEA,MAAM,0BAA0B,KAAK,OAAO,wBAAwB,WAAY;CAG9E,MAAM,OAAO;CACb,KACG,IAAI,CAAC,CACL,IACC,KAAK,IAAI,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,GACjF,KAAK,IAAI,KAAK,CAAC,CAAC,OAAO,CACzB;AACJ,CAAC;AASD,MAAM,SAAuC;CAC3C,WAAW;EACT,iBAAiB;GAAC;GAAG;GAAG;GAAK;GAAG;EAAE;EAClC,mBAAmB,EAAE,OAAO,iBAAiB;EAC7C,kBAAkB,EAAE,OAAO,aAAa;EACxC,OAAO,IAAI,SAAS,GAAG,WAAW;CACpC;CACA,MAAM;EACJ,iBAAiB;GAAC;GAAG;GAAG;GAAK;GAAO;GAAG;GAAG;EAAC;EAC3C,mBAAmB,EAAE,OAAO,iBAAiB;EAC7C,kBAAkB,EAAE,OAAO,aAAa;EACxC,OAAO,IAAI,SAAS,GAAG,MAAM;CAC/B;AACF;AAoBA,IAAa,aAAb,MAAwB;CACtB;CACA;CAEA,YAAY,SAAgC;;EAE1C,IAAI,OAAO,YAAY,UAAU;;GAE/B,IAAI,YAAY,eAAe,YAAY,QACzC,MAAM,IAAI,MAAM,iBAAiB,SAAS;GAE5C,UAAU,OAAO;EACnB;EACA,KAAK,UAAU;EACf,KAAK,cAAc;GAAC;GAAG;GAAG;GAAK;GAAO;GAAG;EAAC;CAC5C;;CAGA,aAAqB,YAA8C;EACjE,OAAO;GACL,SAAS,IAAI,GAAG,CAAC;GACjB;GACA,qBAAqB;IACnB,aAAa,KAAK;IAClB,OAAO,WAAW;GACpB;EACF;CACF;CAEA,iBAAiB,eAAuB,cAAuC;EAC7E,MAAM,mBAAoC;GACxC,SAAS,IAAI,GAAG,CAAC;GACjB,YAAY,OAAO,KAAK,eAAe,KAAK;GAC5C,YAAY,KAAK,QAAQ;EAC3B;;EAGA,IAAI,cACF,iBAAiB,YAAY;GAC3B,QAAQ;GACR,MAAM,OAAO,KAAK,cAAc,KAAK;EACvC;EAGF,OAAO;CACT;CAEA,gBAAgB,cAGd;EACA,OAAO;GACL,WAAW;IACT,IAAI,KAAK;IACT,OAAO,KAAK,QAAQ;GACtB;GACA,KAAK;IACH,QAAQ;IACR,MAAM,OAAO,KAAK,cAAc,KAAK;GACvC;EACF;CACF;CAEA,cACE,YACA,gBACA,mBACA,wBAA2C,SACnC;EACR,IAAI;EAGJ,QAAQ,gBAAR;GACE,KAAK,OAAO;IACV,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,MAAM,8BAA8B;IAGhD,MAAM,eADU,KAAK,QAAQ,MAAM,eAAe,YAAY,KACnC,CAAC,CAAC,UAAU,KAAK;IAC5C,mBAAmB,KAAK,iBAAiB,YAAY,YAAY;IACjE;GACF;;GAEA,KAAK;IACH,IAAI,OAAO,eAAe,UACxB,aAAa,OAAO,KAAK,YAAY,KAAK;IAE5C,mBAAmB,gBAAgB,OAAO,YAAY,KAAK;IAC3D;GACF,KAAK;IACH,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,MAAM,8BAA8B;IAEhD,mBAAmB,gBAAgB,OACjC,YACA,OACA,KAAK,QAAQ,iBACf;IACA;;GAEF,SACE,MAAM,IAAI,MAAM,4BAA4B;EAChD;EAGA,QAAQ,mBAAR;GACE,KAAK;IACH,IAAI,0BAA0B,SAC5B,OAAO,iBAAiB,WAAW,SAAS,KAAK;SAC5C,IAAI,0BAA0B,SACnC,OAAO,KAAK,aAAa,gBAAgB,CAAC,CAAC,WAAW,WAAW,SAAS,KAAK;IAEjF;GACF,KAAK;IACH,IAAI,0BAA0B,SAC5B,OAAO,gBAAgB,OAAO,kBAAkB,KAAK,CAAC,CAAC,SAAS,KAAK;SAChE,IAAI,0BAA0B,SACnC,OAAO,iBAAiB,OAAO,KAAK,aAAa,gBAAgB,GAAG,KAAK,CAAC,CAAC,SACzE,KACF;IAEF;GACF,KAAK;IACH,IAAI,0BAA0B,SAC5B,OAAO,gBAAgB,OAAO,kBAAkB,OAAO,KAAK,QAAQ,iBAAiB;SAChF,IAAI,0BAA0B,SACnC,OAAO,iBAAiB,OAAO,KAAK,aAAa,gBAAgB,GAAG,OAAO;KACzE,GAAG,KAAK,QAAQ;KAChB,OAAO;IACT,CAAC;IAEH;;GAEF,SACE,MAAM,IAAI,MAAM,4CAA4C;EAChE;EAEA,MAAM,IAAI,MAAM,wCAAwC;CAC1D;CAEA,aACE,WACA,gBACA,mBACQ;EAER,IAAI;EAEJ,QAAQ,gBAAR;GACE,KAAK;IACH,IAAI,OAAO,cAAc,UACvB,MAAM,IAAI,MAAM,6BAA6B;IAE/C,kBAAkB,KAAK,gBAAgB,SAAS;IAChD;;GAEF,KAAK;IACH,IAAI,OAAO,cAAc,UACvB,YAAY,OAAO,KAAK,WAAW,KAAK;IAE1C,kBAAkB,wBAAwB,OAAO,WAAW,KAAK;IACjE;GACF,KAAK;IACH,IAAI,OAAO,cAAc,UACvB,MAAM,IAAI,MAAM,6BAA6B;IAE/C,kBAAkB,wBAAwB,OACxC,WACA,OACA,KAAK,QAAQ,gBACf;IACA;;GAEF,SACE,MAAM,IAAI,MAAM,2BAA2B;EAC/C;EAGA,QAAQ,mBAAR;GACE,KAAK,OACH,OAAO,gBAAgB,IAAI,KAAK,SAAS,KAAK;GAChD,KAAK,OACH,OAAO,wBAAwB,OAAO,iBAAiB,KAAK,CAAC,CAAC,SAAS,KAAK;GAC9E,KAAK,OACH,OAAO,wBAAwB,OAC7B,iBACA,OACA,KAAK,QAAQ,gBACf;;GAEF,SACE,MAAM,IAAI,MAAM,2CAA2C;EAC/D;CACF;AACF;;;ACjSA,SAAS,iBAAiB,QAAwB;CAGhD,MAAM,MAAM,OAAO,MAAM,IAAI;CAC7B,IAAI,MAAM;CACV,IAAI,IAAI;CAMR,OAJkB,OAAO,KAAK,IAAI,KAAK,EAAE,GAAG,QAGZ,CAAC,CAAC,MAAM,EACnB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,YAAY;AACrD;AAEA,SAAS,SAAS,WAAmB,EAAE,YAAY,SAAS,CAAC,GAAW;CACtE,MAAM,aAAa,IAAI,WAAW,MAAM;CACxC,IAAI,WACF,OAAO,WAAW,cAAc,WAAW,OAAO,KAAK;CAEzD,OAAO,WAAW,aAAa,WAAW,OAAO,KAAK;AACxD;;;;;AAMA,SAAgB,QAAQ,SAAiC;CACvD,IAAI,SAAS;EACX,MAAM,KAAK,IAAI,SAAS,GAAG,MAAM;EACjC,MAAM,gBAAgB,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,OAAO,KAAK;EAC9E,MAAM,UAAU,GAAG,WAAW,EAC5B,SAAS,OAAO,KAAK,eAAe,KAAK,EAC3C,CAAC;EACD,OAAO;GACL,YAAY,OAAO,SAAS,QAAQ,WAAW,KAAK,CAAC,CAAC;GACtD,WAAW,OAAO,SAAS,QAAQ,UAAU,KAAK,GAAG,EAAE,WAAW,MAAM,CAAC,CAAC;GAC1E,WAAW,iBAAiB,OAAO,SAAS,QAAQ,UAAU,KAAK,GAAG,EAAE,WAAW,MAAM,CAAC,CAAC,CAAC;EAC9F;CACF;CACA,MAAM,EAAE,WAAW,eAAe,OAAO,oBAAoB,MAAM;EACjE,YAAY;EACZ,mBAAmB;GAAE,MAAM;GAAQ,QAAQ;EAAM;EACjD,oBAAoB;GAAE,MAAM;GAAQ,QAAQ;EAAM;CACpD,CAAC;CAED,OAAO;EACL;EACA;EACA,WAJgB,iBAAiB,SAIzB;CACV;AACF;AAEA,MAAa,OAAO,OAAO,eAAuB,oBAA6C;CAE7F,MAAM,qBAAqB,KAAK,UAAU,OAAO,eAAe;CAKhE,MAAM,aAAa,OAAO,iBAAiB,aAAa;CAGxD,OAAO,IAAI,KAAK,YAAY,kBAAkB,CAAC,CAC5C,mBAAmB;EAAE,KAAK;EAAS,KAAK;CAAM,CAAC,CAAC,CAChD,KAAK,UAAU;AACpB"}
|
package/lib/crypto.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_crypto = require("./crypto-
|
|
2
|
+
const require_crypto = require("./crypto-B4xS0N1u.cjs");
|
|
3
3
|
exports.genKeys = require_crypto.genKeys;
|
|
4
4
|
exports.genSeed = require_crypto.genSeed;
|
|
5
5
|
exports.getMasterSeed = require_crypto.getMasterSeed;
|
package/lib/crypto.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as getMasterSeed, n as sign, r as genSeed, t as genKeys } from "./crypto-
|
|
1
|
+
import { i as getMasterSeed, n as sign, r as genSeed, t as genKeys } from "./crypto-BZw0pZ1Z.js";
|
|
2
2
|
export { genKeys, genSeed, getMasterSeed, sign };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import invariant from "invariant";
|
|
1
2
|
import axios from "axios";
|
|
2
3
|
import { v4 } from "uuid";
|
|
3
4
|
import { Observable, throwError, timer } from "rxjs";
|
|
@@ -344,7 +345,9 @@ function createApiDevice(options, logger) {
|
|
|
344
345
|
return getPublicKey({ path: PATHS.VALIDATION });
|
|
345
346
|
};
|
|
346
347
|
const hasPairing = async () => {
|
|
347
|
-
|
|
348
|
+
const seed = await getSeed();
|
|
349
|
+
if ((await deviceApi.post("/get-partition-ids", { seed })).data.length === 0) return "NO_PAIRING";
|
|
350
|
+
return (await deviceApi.post("/partition-psk-status", { seed })).data.psk_missing ? "PSK_MISSING" : "OK";
|
|
348
351
|
};
|
|
349
352
|
const initPairingHandshake = async () => {
|
|
350
353
|
const { data } = await deviceApi.post("/initiate-pairing-handshake", { seed: await getSeed() });
|
|
@@ -430,6 +433,21 @@ function createApiDevice(options, logger) {
|
|
|
430
433
|
};
|
|
431
434
|
await deviceApi.post("/set-partition-key", payload);
|
|
432
435
|
};
|
|
436
|
+
const signRefreshPskAuth = async ({ ephemeralKey }) => {
|
|
437
|
+
const { data } = await deviceApi.post("/sign-refresh-psk-auth", {
|
|
438
|
+
seed: await getSeed(),
|
|
439
|
+
ephemeral_key: ephemeralKey
|
|
440
|
+
});
|
|
441
|
+
return Buffer.from(data, "hex").toString("base64");
|
|
442
|
+
};
|
|
443
|
+
const finalizePskRefresh = async (params) => {
|
|
444
|
+
const payload = {
|
|
445
|
+
seed: await getSeed(),
|
|
446
|
+
handshake: Buffer.from(params.handshake, "base64").toString("hex"),
|
|
447
|
+
ciphertext: Buffer.from(params.encryptedPairingPayload, "base64").toString("hex")
|
|
448
|
+
};
|
|
449
|
+
await deviceApi.post("/finalize-psk-refresh", payload);
|
|
450
|
+
};
|
|
433
451
|
const startKKPatternAsResponder = async (params) => {
|
|
434
452
|
const payload = {
|
|
435
453
|
seed: await getSeed(),
|
|
@@ -458,6 +476,18 @@ function createApiDevice(options, logger) {
|
|
|
458
476
|
const { data: deviceResponse } = await deviceApi.post("/start-k-pattern-as-responder", payload);
|
|
459
477
|
if (deviceResponse !== "9000") throw new Error(`device-api device failed with code: ${deviceResponse}`);
|
|
460
478
|
};
|
|
479
|
+
const startPskSession = async (params) => {
|
|
480
|
+
const { nonce, partitionId } = params;
|
|
481
|
+
invariant(nonce.length === 64, `PSK nonce must be 32 bytes (64 hex chars), got ${nonce.length} chars`);
|
|
482
|
+
invariant(partitionId.length === 32, `partitionId must be 16 bytes (32 hex chars), got ${partitionId.length} chars`);
|
|
483
|
+
const payload = {
|
|
484
|
+
seed: await getSeed(),
|
|
485
|
+
nonce: Buffer.from(nonce, "hex").toString("base64"),
|
|
486
|
+
partition_id: Buffer.from(partitionId, "hex").toString("base64")
|
|
487
|
+
};
|
|
488
|
+
const { data: deviceResponse } = await deviceApi.post("/start-psk-session", payload);
|
|
489
|
+
if (deviceResponse !== "9000") throw new Error(`device-api device failed with code: ${deviceResponse}`);
|
|
490
|
+
};
|
|
461
491
|
const getPublicKey = async (params) => {
|
|
462
492
|
const { path } = params;
|
|
463
493
|
const payload = {
|
|
@@ -513,8 +543,11 @@ function createApiDevice(options, logger) {
|
|
|
513
543
|
register,
|
|
514
544
|
registerData,
|
|
515
545
|
setPairing,
|
|
546
|
+
signRefreshPskAuth,
|
|
547
|
+
finalizePskRefresh,
|
|
516
548
|
startKKPatternAsResponder,
|
|
517
549
|
startKPatternAsResponder,
|
|
550
|
+
startPskSession,
|
|
518
551
|
validateVaultOperation,
|
|
519
552
|
getVersion,
|
|
520
553
|
sendAPDU,
|
|
@@ -926,7 +959,22 @@ const CANCEL_STATUS_CODES = [
|
|
|
926
959
|
const isDeviceCancelError = (error) => {
|
|
927
960
|
return isTransportStatusError(error) && CANCEL_STATUS_CODES.includes(error.statusCode);
|
|
928
961
|
};
|
|
962
|
+
const isDeviceApiSwError = (error, sw) => {
|
|
963
|
+
if (typeof error !== "object" || error === null || !("response" in error)) return false;
|
|
964
|
+
const { response } = error;
|
|
965
|
+
if (typeof response !== "object" || response === null || !("data" in response)) return false;
|
|
966
|
+
const { data } = response;
|
|
967
|
+
if (typeof data !== "object" || data === null) return false;
|
|
968
|
+
const hasSw = (obj) => typeof obj === "object" && obj !== null && "sw" in obj && obj.sw === sw;
|
|
969
|
+
return hasSw(data) || hasSw(data.data);
|
|
970
|
+
};
|
|
971
|
+
const isPskMissingError = (error) => {
|
|
972
|
+
return isTransportStatusError(error) && error.statusCode === 24677 || isDeviceApiSwError(error, "6065");
|
|
973
|
+
};
|
|
974
|
+
const isPskMismatchError = (error) => {
|
|
975
|
+
return isTransportStatusError(error) && error.statusCode === 24679 || isDeviceApiSwError(error, "6067");
|
|
976
|
+
};
|
|
929
977
|
//#endregion
|
|
930
|
-
export {
|
|
978
|
+
export { registerTransportModule as a, LockedDeviceError as c, PAGINATED_STATUS as d, PATHS as f, isTransportStatusError as i, createApiDevice as l, STR_ROLES as m, isPskMismatchError as n, withDevicePolling as o, SCRIPT_IDS as p, isPskMissingError as r, DisconnectedDevice as s, isDeviceCancelError as t, APPID_VAULT_ADMINISTRATOR as u };
|
|
931
979
|
|
|
932
|
-
//# sourceMappingURL=device-
|
|
980
|
+
//# sourceMappingURL=device-Bo6m3O1I.js.map
|