blockintel-gate-sdk 0.3.8 → 0.3.9
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 +2 -0
- package/dist/contracts-KKk945Ox.d.cts +380 -0
- package/dist/contracts-KKk945Ox.d.ts +380 -0
- package/dist/index.cjs +765 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +345 -341
- package/dist/index.d.ts +345 -341
- package/dist/index.js +762 -3
- package/dist/index.js.map +1 -1
- package/dist/pilot/index.cjs +2401 -0
- package/dist/pilot/index.cjs.map +1 -0
- package/dist/pilot/index.d.cts +38 -0
- package/dist/pilot/index.d.ts +38 -0
- package/dist/pilot/index.js +2397 -0
- package/dist/pilot/index.js.map +1 -0
- package/package.json +14 -1
package/dist/index.cjs
CHANGED
|
@@ -5,7 +5,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var crypto = require('crypto');
|
|
6
6
|
var uuid = require('uuid');
|
|
7
7
|
var clientKms = require('@aws-sdk/client-kms');
|
|
8
|
+
var module$1 = require('module');
|
|
8
9
|
|
|
10
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
9
11
|
var __defProp = Object.defineProperty;
|
|
10
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
13
|
var __esm = (fn, res) => function __init() {
|
|
@@ -918,6 +920,12 @@ var MetricsCollector = class {
|
|
|
918
920
|
this.circuitBreakerOpenTotal++;
|
|
919
921
|
this.emitMetrics();
|
|
920
922
|
}
|
|
923
|
+
/**
|
|
924
|
+
* Record soft-enforce override (app chose to sign despite BLOCK decision)
|
|
925
|
+
*/
|
|
926
|
+
recordSoftBlockOverride(decision) {
|
|
927
|
+
this.emitMetrics();
|
|
928
|
+
}
|
|
921
929
|
/**
|
|
922
930
|
* Get current metrics snapshot
|
|
923
931
|
*/
|
|
@@ -1778,6 +1786,7 @@ var GateClient = class {
|
|
|
1778
1786
|
const timestampMs = req.timestampMs ?? nowMs();
|
|
1779
1787
|
const startTime = Date.now();
|
|
1780
1788
|
const failSafeMode = this.config.failSafeMode ?? "ALLOW_ON_TIMEOUT";
|
|
1789
|
+
const evaluationMode = this.config.evaluationMode ?? "BLOCKING";
|
|
1781
1790
|
const requestMode = req.mode || this.mode;
|
|
1782
1791
|
const requireToken = this.getRequireDecisionToken();
|
|
1783
1792
|
const executeRequest = async () => {
|
|
@@ -2036,6 +2045,20 @@ var GateClient = class {
|
|
|
2036
2045
|
}
|
|
2037
2046
|
}
|
|
2038
2047
|
if (result.decision === "BLOCK") {
|
|
2048
|
+
if (requestMode === "SOFT_ENFORCE") {
|
|
2049
|
+
console.warn("[SOFT ENFORCE] Policy violation detected - app can override", {
|
|
2050
|
+
requestId,
|
|
2051
|
+
reasonCodes: result.reasonCodes
|
|
2052
|
+
});
|
|
2053
|
+
this.metrics.recordRequest("BLOCK", latencyMs);
|
|
2054
|
+
return {
|
|
2055
|
+
...result,
|
|
2056
|
+
decision: "BLOCK",
|
|
2057
|
+
enforced: false,
|
|
2058
|
+
mode: "SOFT_ENFORCE",
|
|
2059
|
+
warning: "Policy violation detected. Override at your own risk."
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2039
2062
|
if (requestMode === "SHADOW") {
|
|
2040
2063
|
console.warn("[GATE SHADOW MODE] Would have blocked transaction", {
|
|
2041
2064
|
requestId,
|
|
@@ -2074,6 +2097,26 @@ var GateClient = class {
|
|
|
2074
2097
|
this.metrics.recordRequest("ALLOW", latencyMs);
|
|
2075
2098
|
return result;
|
|
2076
2099
|
};
|
|
2100
|
+
if (evaluationMode === "FIRE_AND_FORGET") {
|
|
2101
|
+
executeRequest().then((res) => {
|
|
2102
|
+
if (res.decision === "BLOCK" || res.shadowWouldBlock) {
|
|
2103
|
+
console.warn("[FIRE-AND-FORGET] Would have blocked:", res.reasonCodes);
|
|
2104
|
+
}
|
|
2105
|
+
this.metrics.recordRequest(res.decision === "ALLOW" ? "ALLOW" : "WOULD_BLOCK", Date.now() - startTime);
|
|
2106
|
+
}).catch((err) => {
|
|
2107
|
+
console.error("[FIRE-AND-FORGET] Attestation failed:", err);
|
|
2108
|
+
this.metrics.recordError();
|
|
2109
|
+
});
|
|
2110
|
+
return {
|
|
2111
|
+
decision: "ALLOW",
|
|
2112
|
+
decisionId: requestId,
|
|
2113
|
+
correlationId: requestId,
|
|
2114
|
+
reasonCodes: [],
|
|
2115
|
+
enforced: false,
|
|
2116
|
+
mode: requestMode,
|
|
2117
|
+
fireAndForget: true
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2077
2120
|
try {
|
|
2078
2121
|
if (this.circuitBreaker) {
|
|
2079
2122
|
return await this.circuitBreaker.execute(executeRequest);
|
|
@@ -2214,6 +2257,102 @@ var GateClient = class {
|
|
|
2214
2257
|
intervalMs: args.intervalMs ?? this.config.stepUp?.pollingIntervalMs
|
|
2215
2258
|
});
|
|
2216
2259
|
}
|
|
2260
|
+
/**
|
|
2261
|
+
* Evaluate policy and sign in one call when decision is ALLOW.
|
|
2262
|
+
* Convenience for: evaluate → if ALLOW then sign → return { decision, signature }.
|
|
2263
|
+
*/
|
|
2264
|
+
async evaluateAndSign(params) {
|
|
2265
|
+
const decision = await this.evaluate({
|
|
2266
|
+
txIntent: params.txIntent,
|
|
2267
|
+
signingContext: params.signingContext
|
|
2268
|
+
});
|
|
2269
|
+
if (decision.decision === "ALLOW") {
|
|
2270
|
+
const signature = await params.signer.sign({
|
|
2271
|
+
keyId: params.keyId,
|
|
2272
|
+
message: params.message,
|
|
2273
|
+
algorithm: params.algorithm ?? "ECDSA_SHA_256"
|
|
2274
|
+
});
|
|
2275
|
+
return { decision, signature };
|
|
2276
|
+
}
|
|
2277
|
+
return { decision };
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* Attest a completed signature (post-sign). Use when you want zero latency impact on signing
|
|
2281
|
+
* but still want an audit trail. Policy is evaluated against txIntent; returns ALLOW or
|
|
2282
|
+
* POLICY_VIOLATION_DETECTED. Cannot be used for enforcement (signature already created).
|
|
2283
|
+
*/
|
|
2284
|
+
async attestCompleted(req) {
|
|
2285
|
+
const requestId = uuid.v4();
|
|
2286
|
+
const timestampMs = nowMs();
|
|
2287
|
+
const txIntent = { ...req.txIntent };
|
|
2288
|
+
if (txIntent.to && !txIntent.toAddress) {
|
|
2289
|
+
txIntent.toAddress = txIntent.to;
|
|
2290
|
+
delete txIntent.to;
|
|
2291
|
+
}
|
|
2292
|
+
if (!txIntent.networkFamily && txIntent.chainId) txIntent.networkFamily = "EVM";
|
|
2293
|
+
const signingContext = {
|
|
2294
|
+
...req.signingContext,
|
|
2295
|
+
signerId: req.signingContext?.signerId ?? req.signature.signerId
|
|
2296
|
+
};
|
|
2297
|
+
const body = {
|
|
2298
|
+
tenantId: this.config.tenantId,
|
|
2299
|
+
requestId,
|
|
2300
|
+
timestampMs,
|
|
2301
|
+
txIntent,
|
|
2302
|
+
signature: req.signature,
|
|
2303
|
+
signingContext
|
|
2304
|
+
};
|
|
2305
|
+
let headers = { "Content-Type": "application/json" };
|
|
2306
|
+
if (this.config.local) ; else if (this.hmacSigner) {
|
|
2307
|
+
const { canonicalizeJson: canonicalizeJson2 } = await Promise.resolve().then(() => (init_canonicalJson(), canonicalJson_exports));
|
|
2308
|
+
const canonicalBodyJson = canonicalizeJson2(body);
|
|
2309
|
+
const hmacHeaders = await this.hmacSigner.signRequest({
|
|
2310
|
+
method: "POST",
|
|
2311
|
+
path: "/defense/attest-completed",
|
|
2312
|
+
tenantId: this.config.tenantId,
|
|
2313
|
+
timestampMs,
|
|
2314
|
+
requestId,
|
|
2315
|
+
body
|
|
2316
|
+
});
|
|
2317
|
+
headers = { ...hmacHeaders };
|
|
2318
|
+
body.__canonicalJson = canonicalBodyJson;
|
|
2319
|
+
} else if (this.apiKeyAuth) {
|
|
2320
|
+
const apiKeyHeaders = this.apiKeyAuth.createHeaders({
|
|
2321
|
+
tenantId: this.config.tenantId,
|
|
2322
|
+
timestampMs,
|
|
2323
|
+
requestId
|
|
2324
|
+
});
|
|
2325
|
+
headers = { ...apiKeyHeaders };
|
|
2326
|
+
} else {
|
|
2327
|
+
throw new Error("No authentication configured");
|
|
2328
|
+
}
|
|
2329
|
+
const apiResponse = await this.httpClient.request({
|
|
2330
|
+
method: "POST",
|
|
2331
|
+
path: "/defense/attest-completed",
|
|
2332
|
+
headers,
|
|
2333
|
+
body,
|
|
2334
|
+
requestId
|
|
2335
|
+
});
|
|
2336
|
+
if (apiResponse.success === true && apiResponse.data) {
|
|
2337
|
+
const data = apiResponse.data;
|
|
2338
|
+
if (data.decision === "POLICY_VIOLATION_DETECTED") {
|
|
2339
|
+
console.warn("[POST-SIGN ATTESTATION] Policy violation detected after signing", {
|
|
2340
|
+
requestId,
|
|
2341
|
+
reasonCodes: data.reasonCodes
|
|
2342
|
+
});
|
|
2343
|
+
}
|
|
2344
|
+
return data;
|
|
2345
|
+
}
|
|
2346
|
+
if (apiResponse.error) {
|
|
2347
|
+
const err = apiResponse.error;
|
|
2348
|
+
throw new GateError(err.code || "SERVER_ERROR", err.message || "Request failed", {
|
|
2349
|
+
status: err.status,
|
|
2350
|
+
correlationId: err.correlationId,
|
|
2351
|
+
requestId
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
throw new GateError("INVALID_RESPONSE" /* INVALID_RESPONSE */, "Invalid response from attest-completed", { requestId });
|
|
2355
|
+
}
|
|
2217
2356
|
/**
|
|
2218
2357
|
* Wrap AWS SDK v3 KMS client to intercept SignCommand calls
|
|
2219
2358
|
*
|
|
@@ -2246,6 +2385,39 @@ var Gate = class {
|
|
|
2246
2385
|
constructor(opts) {
|
|
2247
2386
|
this.apiKey = opts?.apiKey ?? process.env.BLOCKINTEL_API_KEY;
|
|
2248
2387
|
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Create a GateClient from environment variables (5-line integration).
|
|
2390
|
+
*
|
|
2391
|
+
* Reads: GATE_BASE_URL, GATE_TENANT_ID, GATE_API_KEY (or GATE_KEY_ID + GATE_HMAC_SECRET), GATE_MODE.
|
|
2392
|
+
*/
|
|
2393
|
+
static fromEnv(overrides) {
|
|
2394
|
+
const baseUrl = process.env.GATE_BASE_URL;
|
|
2395
|
+
const tenantId = process.env.GATE_TENANT_ID;
|
|
2396
|
+
const apiKey = process.env.GATE_API_KEY;
|
|
2397
|
+
const keyId = process.env.GATE_KEY_ID;
|
|
2398
|
+
const hmacSecret = process.env.GATE_HMAC_SECRET;
|
|
2399
|
+
const mode = process.env.GATE_MODE ?? "SHADOW";
|
|
2400
|
+
if (!baseUrl || !tenantId) {
|
|
2401
|
+
throw new Error("GATE_BASE_URL and GATE_TENANT_ID environment variables are required");
|
|
2402
|
+
}
|
|
2403
|
+
let auth;
|
|
2404
|
+
if (apiKey) {
|
|
2405
|
+
auth = { mode: "apiKey", apiKey };
|
|
2406
|
+
} else if (keyId && hmacSecret) {
|
|
2407
|
+
auth = { mode: "hmac", keyId, secret: hmacSecret };
|
|
2408
|
+
} else {
|
|
2409
|
+
throw new Error(
|
|
2410
|
+
"Either GATE_API_KEY or (GATE_KEY_ID and GATE_HMAC_SECRET) environment variables are required"
|
|
2411
|
+
);
|
|
2412
|
+
}
|
|
2413
|
+
return new GateClient({
|
|
2414
|
+
baseUrl,
|
|
2415
|
+
tenantId,
|
|
2416
|
+
auth,
|
|
2417
|
+
mode,
|
|
2418
|
+
...overrides
|
|
2419
|
+
});
|
|
2420
|
+
}
|
|
2249
2421
|
/**
|
|
2250
2422
|
* Guard a signing operation. In passthrough mode, executes the callback.
|
|
2251
2423
|
* For full Gate integration, use GateClient with evaluate() before sending.
|
|
@@ -2254,18 +2426,611 @@ var Gate = class {
|
|
|
2254
2426
|
return cb();
|
|
2255
2427
|
}
|
|
2256
2428
|
};
|
|
2429
|
+
var AwsKmsSigner = class {
|
|
2430
|
+
config;
|
|
2431
|
+
constructor(config) {
|
|
2432
|
+
this.config = config;
|
|
2433
|
+
}
|
|
2434
|
+
getName() {
|
|
2435
|
+
return "AWS KMS";
|
|
2436
|
+
}
|
|
2437
|
+
isAvailable() {
|
|
2438
|
+
return !!this.config.kmsClient;
|
|
2439
|
+
}
|
|
2440
|
+
async sign(request) {
|
|
2441
|
+
if (!this.isAvailable()) {
|
|
2442
|
+
throw new Error("AWS KMS client not configured");
|
|
2443
|
+
}
|
|
2444
|
+
const algorithm = this.mapAlgorithm(request.algorithm || this.config.defaultAlgorithm || "ECDSA_SHA_256");
|
|
2445
|
+
const signInput = {
|
|
2446
|
+
KeyId: request.keyId,
|
|
2447
|
+
Message: Buffer.from(request.message),
|
|
2448
|
+
MessageType: request.messageType || this.config.defaultMessageType || "RAW",
|
|
2449
|
+
SigningAlgorithm: algorithm
|
|
2450
|
+
};
|
|
2451
|
+
const command = new clientKms.SignCommand(signInput);
|
|
2452
|
+
const response = await this.config.kmsClient.send(command);
|
|
2453
|
+
if (!response.Signature) {
|
|
2454
|
+
throw new Error("AWS KMS sign response missing signature");
|
|
2455
|
+
}
|
|
2456
|
+
return {
|
|
2457
|
+
signature: Buffer.from(response.Signature),
|
|
2458
|
+
keyId: response.KeyId || request.keyId,
|
|
2459
|
+
algorithm: response.SigningAlgorithm || algorithm,
|
|
2460
|
+
metadata: {
|
|
2461
|
+
keyId: response.KeyId,
|
|
2462
|
+
signingAlgorithm: response.SigningAlgorithm
|
|
2463
|
+
}
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
/**
|
|
2467
|
+
* Map algorithm string to AWS KMS SigningAlgorithmSpec
|
|
2468
|
+
*/
|
|
2469
|
+
mapAlgorithm(algorithm) {
|
|
2470
|
+
if (Object.values(clientKms.SigningAlgorithmSpec).includes(algorithm)) {
|
|
2471
|
+
return algorithm;
|
|
2472
|
+
}
|
|
2473
|
+
const algorithmMap = {
|
|
2474
|
+
"ECDSA_SHA_256": clientKms.SigningAlgorithmSpec.ECDSA_SHA_256,
|
|
2475
|
+
"ECDSA_SHA_384": clientKms.SigningAlgorithmSpec.ECDSA_SHA_384,
|
|
2476
|
+
"ECDSA_SHA_512": clientKms.SigningAlgorithmSpec.ECDSA_SHA_512,
|
|
2477
|
+
"RSASSA_PSS_SHA_256": clientKms.SigningAlgorithmSpec.RSASSA_PSS_SHA_256,
|
|
2478
|
+
"RSASSA_PSS_SHA_384": clientKms.SigningAlgorithmSpec.RSASSA_PSS_SHA_384,
|
|
2479
|
+
"RSASSA_PSS_SHA_512": clientKms.SigningAlgorithmSpec.RSASSA_PSS_SHA_512,
|
|
2480
|
+
"RSASSA_PKCS1_V1_5_SHA_256": clientKms.SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256,
|
|
2481
|
+
"RSASSA_PKCS1_V1_5_SHA_384": clientKms.SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_384,
|
|
2482
|
+
"RSASSA_PKCS1_V1_5_SHA_512": clientKms.SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_512
|
|
2483
|
+
};
|
|
2484
|
+
return algorithmMap[algorithm.toUpperCase()] || clientKms.SigningAlgorithmSpec.ECDSA_SHA_256;
|
|
2485
|
+
}
|
|
2486
|
+
};
|
|
2487
|
+
|
|
2488
|
+
// src/signer/VaultSigner.ts
|
|
2489
|
+
var VaultSigner = class {
|
|
2490
|
+
config;
|
|
2491
|
+
authToken = null;
|
|
2492
|
+
constructor(config) {
|
|
2493
|
+
this.config = {
|
|
2494
|
+
mountPath: "transit",
|
|
2495
|
+
...config
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
getName() {
|
|
2499
|
+
return "HashiCorp Vault";
|
|
2500
|
+
}
|
|
2501
|
+
isAvailable() {
|
|
2502
|
+
return !!this.config.vaultUrl && (!!this.config.token || !!this.config.appRole);
|
|
2503
|
+
}
|
|
2504
|
+
async sign(request) {
|
|
2505
|
+
if (!this.isAvailable()) {
|
|
2506
|
+
throw new Error("Vault signer not configured");
|
|
2507
|
+
}
|
|
2508
|
+
if (!this.authToken && this.config.appRole) {
|
|
2509
|
+
await this.authenticateAppRole();
|
|
2510
|
+
}
|
|
2511
|
+
const token = this.config.token || this.authToken;
|
|
2512
|
+
if (!token) {
|
|
2513
|
+
throw new Error("Vault authentication token not available");
|
|
2514
|
+
}
|
|
2515
|
+
const algorithm = this.mapAlgorithm(request.algorithm || this.config.defaultAlgorithm || "ecdsa-sha2-256");
|
|
2516
|
+
const url = `${this.config.vaultUrl}/v1/${this.config.mountPath}/sign/${request.keyId}`;
|
|
2517
|
+
const messageBase64 = Buffer.from(request.message).toString("base64");
|
|
2518
|
+
const requestBody = {
|
|
2519
|
+
input: messageBase64,
|
|
2520
|
+
...algorithm && { algorithm },
|
|
2521
|
+
...request.options || {}
|
|
2522
|
+
};
|
|
2523
|
+
const timeout = this.config.httpOptions?.timeout || 5e3;
|
|
2524
|
+
const controller = new AbortController();
|
|
2525
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
2526
|
+
try {
|
|
2527
|
+
const response = await fetch(url, {
|
|
2528
|
+
method: "POST",
|
|
2529
|
+
headers: {
|
|
2530
|
+
"Content-Type": "application/json",
|
|
2531
|
+
"X-Vault-Token": token
|
|
2532
|
+
},
|
|
2533
|
+
body: JSON.stringify(requestBody),
|
|
2534
|
+
signal: controller.signal
|
|
2535
|
+
});
|
|
2536
|
+
clearTimeout(timeoutId);
|
|
2537
|
+
if (!response.ok) {
|
|
2538
|
+
const errorText = await response.text();
|
|
2539
|
+
throw new Error(`Vault sign failed: ${response.status} ${errorText}`);
|
|
2540
|
+
}
|
|
2541
|
+
const data = await response.json();
|
|
2542
|
+
if (!data.data || !data.data.signature) {
|
|
2543
|
+
throw new Error("Vault sign response missing signature");
|
|
2544
|
+
}
|
|
2545
|
+
const signatureParts = data.data.signature.split(":");
|
|
2546
|
+
const signatureBase64 = signatureParts[signatureParts.length - 1];
|
|
2547
|
+
const signature = Buffer.from(signatureBase64, "base64");
|
|
2548
|
+
return {
|
|
2549
|
+
signature,
|
|
2550
|
+
keyId: request.keyId,
|
|
2551
|
+
algorithm,
|
|
2552
|
+
metadata: {
|
|
2553
|
+
vaultSignature: data.data.signature,
|
|
2554
|
+
keyVersion: data.data.key_version
|
|
2555
|
+
}
|
|
2556
|
+
};
|
|
2557
|
+
} catch (error) {
|
|
2558
|
+
clearTimeout(timeoutId);
|
|
2559
|
+
if (error.name === "AbortError") {
|
|
2560
|
+
throw new Error("Vault sign request timeout");
|
|
2561
|
+
}
|
|
2562
|
+
throw error;
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
/**
|
|
2566
|
+
* Authenticate using AppRole
|
|
2567
|
+
*/
|
|
2568
|
+
async authenticateAppRole() {
|
|
2569
|
+
if (!this.config.appRole) {
|
|
2570
|
+
throw new Error("AppRole not configured");
|
|
2571
|
+
}
|
|
2572
|
+
const url = `${this.config.vaultUrl}/v1/auth/approle/login`;
|
|
2573
|
+
const response = await fetch(url, {
|
|
2574
|
+
method: "POST",
|
|
2575
|
+
headers: {
|
|
2576
|
+
"Content-Type": "application/json"
|
|
2577
|
+
},
|
|
2578
|
+
body: JSON.stringify({
|
|
2579
|
+
role_id: this.config.appRole.roleId,
|
|
2580
|
+
secret_id: this.config.appRole.secretId
|
|
2581
|
+
})
|
|
2582
|
+
});
|
|
2583
|
+
if (!response.ok) {
|
|
2584
|
+
const errorText = await response.text();
|
|
2585
|
+
throw new Error(`Vault AppRole authentication failed: ${response.status} ${errorText}`);
|
|
2586
|
+
}
|
|
2587
|
+
const data = await response.json();
|
|
2588
|
+
if (!data.auth || !data.auth.client_token) {
|
|
2589
|
+
throw new Error("Vault AppRole authentication response missing token");
|
|
2590
|
+
}
|
|
2591
|
+
this.authToken = data.auth.client_token;
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Map algorithm string to Vault format
|
|
2595
|
+
*/
|
|
2596
|
+
mapAlgorithm(algorithm) {
|
|
2597
|
+
const algorithmMap = {
|
|
2598
|
+
"ECDSA_SHA_256": "ecdsa-sha2-256",
|
|
2599
|
+
"ECDSA_SHA_384": "ecdsa-sha2-384",
|
|
2600
|
+
"ECDSA_SHA_512": "ecdsa-sha2-512",
|
|
2601
|
+
"RSASSA_PSS_SHA_256": "rsa-sha2-256",
|
|
2602
|
+
"RSASSA_PSS_SHA_384": "rsa-sha2-384",
|
|
2603
|
+
"RSASSA_PSS_SHA_512": "rsa-sha2-512"
|
|
2604
|
+
};
|
|
2605
|
+
if (algorithm.startsWith("ecdsa-") || algorithm.startsWith("rsa-")) {
|
|
2606
|
+
return algorithm;
|
|
2607
|
+
}
|
|
2608
|
+
return algorithmMap[algorithm.toUpperCase()] || "ecdsa-sha2-256";
|
|
2609
|
+
}
|
|
2610
|
+
};
|
|
2611
|
+
|
|
2612
|
+
// src/signer/GcpKmsSigner.ts
|
|
2613
|
+
var GcpKmsSigner = class {
|
|
2614
|
+
config;
|
|
2615
|
+
accessToken = null;
|
|
2616
|
+
tokenExpiry = 0;
|
|
2617
|
+
constructor(config) {
|
|
2618
|
+
this.config = {
|
|
2619
|
+
useWorkloadIdentity: false,
|
|
2620
|
+
...config
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
getName() {
|
|
2624
|
+
return "Google Cloud KMS";
|
|
2625
|
+
}
|
|
2626
|
+
isAvailable() {
|
|
2627
|
+
if (this.config.useWorkloadIdentity) {
|
|
2628
|
+
return true;
|
|
2629
|
+
}
|
|
2630
|
+
return !!this.config.credentials && !!this.config.projectId;
|
|
2631
|
+
}
|
|
2632
|
+
async sign(request) {
|
|
2633
|
+
if (!this.isAvailable()) {
|
|
2634
|
+
throw new Error("GCP KMS signer not configured");
|
|
2635
|
+
}
|
|
2636
|
+
const accessToken = await this.getAccessToken();
|
|
2637
|
+
const algorithm = this.mapAlgorithm(request.algorithm || this.config.defaultAlgorithm || "EC_SIGN_P256_SHA256");
|
|
2638
|
+
const keyName = request.keyId.includes("/") ? request.keyId : `projects/${this.config.projectId}/locations/${this.config.location}/keyRings/${this.config.keyRing}/cryptoKeys/${request.keyId}`;
|
|
2639
|
+
const url = `https://cloudkms.googleapis.com/v1/${keyName}:asymmetricSign`;
|
|
2640
|
+
const messageBase64 = Buffer.from(request.message).toString("base64");
|
|
2641
|
+
const requestBody = {
|
|
2642
|
+
digest: {
|
|
2643
|
+
sha256: messageBase64
|
|
2644
|
+
// GCP expects digest, not raw message
|
|
2645
|
+
}
|
|
2646
|
+
};
|
|
2647
|
+
const timeout = this.config.httpOptions?.timeout || 5e3;
|
|
2648
|
+
const controller = new AbortController();
|
|
2649
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
2650
|
+
try {
|
|
2651
|
+
const response = await fetch(url, {
|
|
2652
|
+
method: "POST",
|
|
2653
|
+
headers: {
|
|
2654
|
+
"Content-Type": "application/json",
|
|
2655
|
+
"Authorization": `Bearer ${accessToken}`
|
|
2656
|
+
},
|
|
2657
|
+
body: JSON.stringify(requestBody),
|
|
2658
|
+
signal: controller.signal
|
|
2659
|
+
});
|
|
2660
|
+
clearTimeout(timeoutId);
|
|
2661
|
+
if (!response.ok) {
|
|
2662
|
+
const errorText = await response.text();
|
|
2663
|
+
throw new Error(`GCP KMS sign failed: ${response.status} ${errorText}`);
|
|
2664
|
+
}
|
|
2665
|
+
const data = await response.json();
|
|
2666
|
+
if (!data.signature) {
|
|
2667
|
+
throw new Error("GCP KMS sign response missing signature");
|
|
2668
|
+
}
|
|
2669
|
+
const signature = Buffer.from(data.signature, "base64");
|
|
2670
|
+
return {
|
|
2671
|
+
signature,
|
|
2672
|
+
keyId: request.keyId,
|
|
2673
|
+
algorithm,
|
|
2674
|
+
metadata: {
|
|
2675
|
+
name: data.name,
|
|
2676
|
+
verifiedDigestCrc32c: data.verifiedDigestCrc32c
|
|
2677
|
+
}
|
|
2678
|
+
};
|
|
2679
|
+
} catch (error) {
|
|
2680
|
+
clearTimeout(timeoutId);
|
|
2681
|
+
if (error.name === "AbortError") {
|
|
2682
|
+
throw new Error("GCP KMS sign request timeout");
|
|
2683
|
+
}
|
|
2684
|
+
throw error;
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
/**
|
|
2688
|
+
* Get GCP access token
|
|
2689
|
+
*/
|
|
2690
|
+
async getAccessToken() {
|
|
2691
|
+
if (this.accessToken && Date.now() < this.tokenExpiry - 5 * 60 * 1e3) {
|
|
2692
|
+
return this.accessToken;
|
|
2693
|
+
}
|
|
2694
|
+
if (this.config.useWorkloadIdentity) {
|
|
2695
|
+
const metadataUrl = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token";
|
|
2696
|
+
const response = await fetch(metadataUrl, {
|
|
2697
|
+
method: "GET",
|
|
2698
|
+
headers: {
|
|
2699
|
+
"Metadata-Flavor": "Google"
|
|
2700
|
+
}
|
|
2701
|
+
});
|
|
2702
|
+
if (!response.ok) {
|
|
2703
|
+
throw new Error(`GCP metadata service authentication failed: ${response.status}`);
|
|
2704
|
+
}
|
|
2705
|
+
const data = await response.json();
|
|
2706
|
+
this.accessToken = data.access_token;
|
|
2707
|
+
this.tokenExpiry = Date.now() + data.expires_in * 1e3;
|
|
2708
|
+
return data.access_token;
|
|
2709
|
+
} else {
|
|
2710
|
+
if (!this.config.credentials) {
|
|
2711
|
+
throw new Error("GCP credentials not configured");
|
|
2712
|
+
}
|
|
2713
|
+
throw new Error("Service account authentication requires @google-cloud/kms SDK. Install it with: npm install @google-cloud/kms. Alternatively, use workload identity (recommended for GCP environments).");
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
/**
|
|
2717
|
+
* Map algorithm string to GCP format
|
|
2718
|
+
*/
|
|
2719
|
+
mapAlgorithm(algorithm) {
|
|
2720
|
+
const algorithmMap = {
|
|
2721
|
+
"ECDSA_SHA_256": "EC_SIGN_P256_SHA256",
|
|
2722
|
+
"ECDSA_SHA_384": "EC_SIGN_P384_SHA384",
|
|
2723
|
+
"ECDSA_SHA_512": "EC_SIGN_P512_SHA512",
|
|
2724
|
+
"RSASSA_PSS_SHA_256": "RSA_SIGN_PSS_2048_SHA256",
|
|
2725
|
+
"RSASSA_PSS_SHA_384": "RSA_SIGN_PSS_3072_SHA256",
|
|
2726
|
+
"RSASSA_PSS_SHA_512": "RSA_SIGN_PSS_4096_SHA256",
|
|
2727
|
+
"RSASSA_PKCS1_V1_5_SHA_256": "RSA_SIGN_PKCS1_2048_SHA256",
|
|
2728
|
+
"RSASSA_PKCS1_V1_5_SHA_384": "RSA_SIGN_PKCS1_3072_SHA256",
|
|
2729
|
+
"RSASSA_PKCS1_V1_5_SHA_512": "RSA_SIGN_PKCS1_4096_SHA256"
|
|
2730
|
+
};
|
|
2731
|
+
if (algorithm.startsWith("EC_SIGN_") || algorithm.startsWith("RSA_SIGN_")) {
|
|
2732
|
+
return algorithm;
|
|
2733
|
+
}
|
|
2734
|
+
return algorithmMap[algorithm.toUpperCase()] || "EC_SIGN_P256_SHA256";
|
|
2735
|
+
}
|
|
2736
|
+
};
|
|
2737
|
+
var FireblocksSigner = class {
|
|
2738
|
+
config;
|
|
2739
|
+
apiBaseUrl;
|
|
2740
|
+
constructor(config) {
|
|
2741
|
+
this.config = config;
|
|
2742
|
+
this.apiBaseUrl = config.apiBaseUrl ?? "https://api.fireblocks.io";
|
|
2743
|
+
}
|
|
2744
|
+
getName() {
|
|
2745
|
+
return "Fireblocks";
|
|
2746
|
+
}
|
|
2747
|
+
isAvailable() {
|
|
2748
|
+
return !!this.config.apiKey && !!this.config.apiSecret;
|
|
2749
|
+
}
|
|
2750
|
+
async sign(request) {
|
|
2751
|
+
if (!this.isAvailable()) {
|
|
2752
|
+
throw new Error("Fireblocks API key and secret required");
|
|
2753
|
+
}
|
|
2754
|
+
const keyIdMatch = request.keyId.match(/^fireblocks:\/\/([^/]+)\/(.+)$/);
|
|
2755
|
+
if (!keyIdMatch) {
|
|
2756
|
+
throw new Error(
|
|
2757
|
+
"Invalid Fireblocks keyId format. Expected: fireblocks://vaultAccountId/assetId"
|
|
2758
|
+
);
|
|
2759
|
+
}
|
|
2760
|
+
const [, vaultAccountId, assetId] = keyIdMatch;
|
|
2761
|
+
const messageHex = request.message instanceof Buffer ? request.message.toString("hex") : Buffer.from(request.message).toString("hex");
|
|
2762
|
+
const requestId = request.options?.requestId || request.requestId;
|
|
2763
|
+
const txRequest = {
|
|
2764
|
+
operation: "RAW",
|
|
2765
|
+
source: { type: "VAULT_ACCOUNT", id: vaultAccountId },
|
|
2766
|
+
assetId,
|
|
2767
|
+
note: `Gate signing request: ${requestId ?? "unknown"}`,
|
|
2768
|
+
extraParameters: {
|
|
2769
|
+
rawMessageData: {
|
|
2770
|
+
messages: [{ content: messageHex }]
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
};
|
|
2774
|
+
const token = this.createAuthToken("/v1/transactions", JSON.stringify(txRequest));
|
|
2775
|
+
const response = await fetch(`${this.apiBaseUrl}/v1/transactions`, {
|
|
2776
|
+
method: "POST",
|
|
2777
|
+
headers: {
|
|
2778
|
+
"Content-Type": "application/json",
|
|
2779
|
+
"X-API-Key": this.config.apiKey,
|
|
2780
|
+
Authorization: `Bearer ${token}`
|
|
2781
|
+
},
|
|
2782
|
+
body: JSON.stringify(txRequest)
|
|
2783
|
+
});
|
|
2784
|
+
if (!response.ok) {
|
|
2785
|
+
const error = await response.text();
|
|
2786
|
+
throw new Error(`Fireblocks API error: ${response.status} ${error}`);
|
|
2787
|
+
}
|
|
2788
|
+
const result = await response.json();
|
|
2789
|
+
const txId = result.id;
|
|
2790
|
+
if (!txId) {
|
|
2791
|
+
throw new Error("Fireblocks API did not return transaction id");
|
|
2792
|
+
}
|
|
2793
|
+
const signed = await this.pollTransaction(txId);
|
|
2794
|
+
const sigHex = signed?.signature ?? signed?.signedMessages?.[0]?.signature;
|
|
2795
|
+
if (!sigHex) {
|
|
2796
|
+
throw new Error(`Fireblocks transaction ${txId} did not return signature`);
|
|
2797
|
+
}
|
|
2798
|
+
return {
|
|
2799
|
+
signature: Buffer.from(sigHex, "hex"),
|
|
2800
|
+
keyId: request.keyId,
|
|
2801
|
+
algorithm: request.algorithm ?? "ECDSA_SHA_256"
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
/**
|
|
2805
|
+
* Create JWT for Fireblocks API (RS256, uri + bodyHash in payload).
|
|
2806
|
+
*/
|
|
2807
|
+
createAuthToken(uri, bodyJson) {
|
|
2808
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
2809
|
+
const nonce = crypto.randomBytes(16).toString("hex");
|
|
2810
|
+
const bodyHash = bodyJson ? crypto.createHash("sha256").update(bodyJson, "utf8").digest("hex") : "";
|
|
2811
|
+
const payload = {
|
|
2812
|
+
uri,
|
|
2813
|
+
nonce,
|
|
2814
|
+
iat: now,
|
|
2815
|
+
exp: now + 30,
|
|
2816
|
+
sub: this.config.apiKey,
|
|
2817
|
+
bodyHash
|
|
2818
|
+
};
|
|
2819
|
+
const header = { alg: "RS256", typ: "JWT" };
|
|
2820
|
+
const encodedHeader = base64UrlEncode(JSON.stringify(header));
|
|
2821
|
+
const encodedPayload = base64UrlEncode(JSON.stringify(payload));
|
|
2822
|
+
const signingInput = `${encodedHeader}.${encodedPayload}`;
|
|
2823
|
+
const sign = crypto.createSign("RSA-SHA256");
|
|
2824
|
+
sign.update(signingInput);
|
|
2825
|
+
const signature = sign.sign(this.config.apiSecret);
|
|
2826
|
+
const encodedSig = base64UrlEncode(signature);
|
|
2827
|
+
return `${signingInput}.${encodedSig}`;
|
|
2828
|
+
}
|
|
2829
|
+
async pollTransaction(txId, maxAttempts = 30) {
|
|
2830
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
2831
|
+
const token = this.createAuthToken(`/v1/transactions/${txId}`);
|
|
2832
|
+
const response = await fetch(`${this.apiBaseUrl}/v1/transactions/${txId}`, {
|
|
2833
|
+
headers: {
|
|
2834
|
+
"X-API-Key": this.config.apiKey,
|
|
2835
|
+
Authorization: `Bearer ${token}`
|
|
2836
|
+
}
|
|
2837
|
+
});
|
|
2838
|
+
if (!response.ok) {
|
|
2839
|
+
throw new Error(`Failed to fetch transaction status: ${await response.text()}`);
|
|
2840
|
+
}
|
|
2841
|
+
const tx = await response.json();
|
|
2842
|
+
if (tx.status === "COMPLETED") {
|
|
2843
|
+
return tx.signedMessages?.[0] ? { signature: tx.signedMessages[0].signature } : tx;
|
|
2844
|
+
}
|
|
2845
|
+
if (tx.status === "FAILED" || tx.status === "REJECTED") {
|
|
2846
|
+
throw new Error(`Fireblocks transaction ${txId} failed: ${tx.status}`);
|
|
2847
|
+
}
|
|
2848
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
2849
|
+
}
|
|
2850
|
+
throw new Error(
|
|
2851
|
+
`Fireblocks transaction ${txId} did not complete within ${maxAttempts} seconds`
|
|
2852
|
+
);
|
|
2853
|
+
}
|
|
2854
|
+
};
|
|
2855
|
+
function base64UrlEncode(input) {
|
|
2856
|
+
const raw = typeof input === "string" ? Buffer.from(input, "utf8").toString("base64") : input.toString("base64");
|
|
2857
|
+
return raw.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
2858
|
+
}
|
|
2859
|
+
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
2860
|
+
var NOT_LINKED = "PKCS#11 runtime not linked. Install pkcs11js (npm install pkcs11js) and ensure the HSM library path is correct, or provide a custom pkcs11Session to GenericHsmSigner.";
|
|
2861
|
+
function mechanismToPkcs11(mechanism) {
|
|
2862
|
+
switch (mechanism) {
|
|
2863
|
+
case "CKM_ECDSA_SHA256":
|
|
2864
|
+
return getPkcs11().CKM_ECDSA_SHA256;
|
|
2865
|
+
case "CKM_RSA_PKCS":
|
|
2866
|
+
return getPkcs11().CKM_SHA256_RSA_PKCS;
|
|
2867
|
+
default:
|
|
2868
|
+
throw new Error(`Unsupported PKCS#11 mechanism: ${mechanism}`);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
var pkcs11Module = void 0;
|
|
2872
|
+
function getPkcs11() {
|
|
2873
|
+
if (pkcs11Module !== void 0) {
|
|
2874
|
+
if (pkcs11Module === null) throw new Error(NOT_LINKED);
|
|
2875
|
+
return pkcs11Module;
|
|
2876
|
+
}
|
|
2877
|
+
try {
|
|
2878
|
+
pkcs11Module = require2("pkcs11js");
|
|
2879
|
+
return pkcs11Module;
|
|
2880
|
+
} catch {
|
|
2881
|
+
pkcs11Module = null;
|
|
2882
|
+
throw new Error(NOT_LINKED);
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
var Pkcs11SessionImpl = class {
|
|
2886
|
+
libPath = "";
|
|
2887
|
+
pin = "";
|
|
2888
|
+
pkcs11 = null;
|
|
2889
|
+
session = null;
|
|
2890
|
+
initialized = false;
|
|
2891
|
+
async initialize(libraryPath, pin, options) {
|
|
2892
|
+
const p = getPkcs11();
|
|
2893
|
+
this.libPath = libraryPath;
|
|
2894
|
+
this.pin = pin;
|
|
2895
|
+
this.pkcs11 = new p.PKCS11();
|
|
2896
|
+
this.pkcs11.load(libraryPath);
|
|
2897
|
+
this.pkcs11.C_Initialize();
|
|
2898
|
+
this.initialized = true;
|
|
2899
|
+
const slots = this.pkcs11.C_GetSlotList(true);
|
|
2900
|
+
if (!slots || slots.length === 0) {
|
|
2901
|
+
await this.close();
|
|
2902
|
+
throw new Error("PKCS#11: no token present in any slot");
|
|
2903
|
+
}
|
|
2904
|
+
const slotIndex = options?.slotId ?? 0;
|
|
2905
|
+
if (slotIndex < 0 || slotIndex >= slots.length) {
|
|
2906
|
+
await this.close();
|
|
2907
|
+
throw new Error(`PKCS#11: slotId ${slotIndex} out of range (0..${slots.length - 1})`);
|
|
2908
|
+
}
|
|
2909
|
+
const slot = slots[slotIndex];
|
|
2910
|
+
const flags = p.CKF_SERIAL_SESSION | p.CKF_RW_SESSION;
|
|
2911
|
+
this.session = this.pkcs11.C_OpenSession(slot, flags);
|
|
2912
|
+
this.pkcs11.C_Login(this.session, p.CKU_USER, pin);
|
|
2913
|
+
}
|
|
2914
|
+
async sign(keyHandle, mechanism, data) {
|
|
2915
|
+
if (!this.pkcs11 || !this.session) {
|
|
2916
|
+
throw new Error("PKCS#11 session not initialized. Call initialize() first.");
|
|
2917
|
+
}
|
|
2918
|
+
getPkcs11();
|
|
2919
|
+
const mechCode = mechanismToPkcs11(mechanism);
|
|
2920
|
+
this.pkcs11.C_SignInit(this.session, { mechanism: mechCode }, keyHandle);
|
|
2921
|
+
const maxSigLen = 512;
|
|
2922
|
+
const outData = Buffer.alloc(maxSigLen);
|
|
2923
|
+
const signature = this.pkcs11.C_Sign(this.session, data, outData);
|
|
2924
|
+
return Buffer.from(signature);
|
|
2925
|
+
}
|
|
2926
|
+
async close() {
|
|
2927
|
+
if (!this.initialized) return;
|
|
2928
|
+
this.initialized = false;
|
|
2929
|
+
try {
|
|
2930
|
+
if (this.pkcs11 && this.session) {
|
|
2931
|
+
try {
|
|
2932
|
+
this.pkcs11.C_Logout(this.session);
|
|
2933
|
+
} catch {
|
|
2934
|
+
}
|
|
2935
|
+
try {
|
|
2936
|
+
this.pkcs11.C_CloseSession(this.session);
|
|
2937
|
+
} catch {
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
if (this.pkcs11) {
|
|
2941
|
+
try {
|
|
2942
|
+
this.pkcs11.C_Finalize();
|
|
2943
|
+
} catch {
|
|
2944
|
+
}
|
|
2945
|
+
try {
|
|
2946
|
+
this.pkcs11.close();
|
|
2947
|
+
} catch {
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
} finally {
|
|
2951
|
+
this.pkcs11 = null;
|
|
2952
|
+
this.session = null;
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
};
|
|
2956
|
+
|
|
2957
|
+
// src/signer/GenericHsmSigner.ts
|
|
2958
|
+
var GenericHsmSigner = class {
|
|
2959
|
+
config;
|
|
2960
|
+
session = null;
|
|
2961
|
+
constructor(config) {
|
|
2962
|
+
this.config = config;
|
|
2963
|
+
}
|
|
2964
|
+
getName() {
|
|
2965
|
+
return "Generic HSM (PKCS#11)";
|
|
2966
|
+
}
|
|
2967
|
+
isAvailable() {
|
|
2968
|
+
return !!this.config.pkcs11LibraryPath && !!this.config.pin;
|
|
2969
|
+
}
|
|
2970
|
+
async sign(request) {
|
|
2971
|
+
if (!this.session) {
|
|
2972
|
+
this.session = this.config.pkcs11Session ?? await this.initializePkcs11Session();
|
|
2973
|
+
}
|
|
2974
|
+
const keyIdMatch = request.keyId.match(/^hsm:\/\/(.+)$/);
|
|
2975
|
+
if (!keyIdMatch) {
|
|
2976
|
+
throw new Error(
|
|
2977
|
+
"Invalid HSM keyId format. Expected: hsm://keyHandle (hex-encoded) or hsm://keyLabel"
|
|
2978
|
+
);
|
|
2979
|
+
}
|
|
2980
|
+
const keyHandle = Buffer.from(keyIdMatch[1], "hex");
|
|
2981
|
+
const mechanism = this.mapAlgorithmToMechanism(
|
|
2982
|
+
request.algorithm ?? "ECDSA_SHA_256"
|
|
2983
|
+
);
|
|
2984
|
+
const message = request.message instanceof Buffer ? request.message : Buffer.from(request.message);
|
|
2985
|
+
const signature = await this.session.sign(keyHandle, mechanism, message);
|
|
2986
|
+
return {
|
|
2987
|
+
signature,
|
|
2988
|
+
keyId: request.keyId,
|
|
2989
|
+
algorithm: request.algorithm ?? "ECDSA_SHA_256"
|
|
2990
|
+
};
|
|
2991
|
+
}
|
|
2992
|
+
async initializePkcs11Session() {
|
|
2993
|
+
const session = new Pkcs11SessionImpl();
|
|
2994
|
+
await session.initialize(this.config.pkcs11LibraryPath, this.config.pin, {
|
|
2995
|
+
slotId: this.config.slotId
|
|
2996
|
+
});
|
|
2997
|
+
return session;
|
|
2998
|
+
}
|
|
2999
|
+
mapAlgorithmToMechanism(algorithm) {
|
|
3000
|
+
switch (algorithm) {
|
|
3001
|
+
case "ECDSA_SHA_256":
|
|
3002
|
+
return "CKM_ECDSA_SHA256";
|
|
3003
|
+
case "RSASSA_PKCS1_V1_5_SHA_256":
|
|
3004
|
+
return "CKM_RSA_PKCS";
|
|
3005
|
+
default:
|
|
3006
|
+
throw new Error(`Unsupported algorithm for HSM: ${algorithm}`);
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
/** Release the PKCS#11 session. Call when done to free resources. */
|
|
3010
|
+
async close() {
|
|
3011
|
+
if (this.session) {
|
|
3012
|
+
await this.session.close();
|
|
3013
|
+
this.session = null;
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
};
|
|
2257
3017
|
|
|
3018
|
+
exports.AwsKmsSigner = AwsKmsSigner;
|
|
2258
3019
|
exports.BlockIntelAuthError = BlockIntelAuthError;
|
|
2259
3020
|
exports.BlockIntelBlockedError = BlockIntelBlockedError;
|
|
2260
3021
|
exports.BlockIntelStepUpRequiredError = BlockIntelStepUpRequiredError;
|
|
2261
3022
|
exports.BlockIntelUnavailableError = BlockIntelUnavailableError;
|
|
3023
|
+
exports.FireblocksSigner = FireblocksSigner;
|
|
2262
3024
|
exports.Gate = Gate;
|
|
2263
3025
|
exports.GateClient = GateClient;
|
|
2264
3026
|
exports.GateError = GateError;
|
|
2265
3027
|
exports.GateErrorCode = GateErrorCode;
|
|
3028
|
+
exports.GcpKmsSigner = GcpKmsSigner;
|
|
3029
|
+
exports.GenericHsmSigner = GenericHsmSigner;
|
|
2266
3030
|
exports.HeartbeatManager = HeartbeatManager;
|
|
2267
3031
|
exports.ProvenanceProvider = ProvenanceProvider;
|
|
2268
3032
|
exports.StepUpNotConfiguredError = StepUpNotConfiguredError;
|
|
3033
|
+
exports.VaultSigner = VaultSigner;
|
|
2269
3034
|
exports.buildTxBindingObject = buildTxBindingObject;
|
|
2270
3035
|
exports.computeTxDigest = computeTxDigest;
|
|
2271
3036
|
exports.createGateClient = createGateClient;
|