@fedify/fedify 2.1.0-dev.503 → 2.1.0-dev.523
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/dist/{builder-BHUnSQtB.js → builder-CJkMYxxc.js} +9 -3
- package/dist/compat/mod.d.cts +3 -3
- package/dist/compat/mod.d.ts +3 -3
- package/dist/compat/transformers.test.js +12 -12
- package/dist/{context-DZJhUmzF.d.ts → context--RwChtri.d.ts} +54 -2
- package/dist/{context-D3QkEtZd.d.cts → context-DL0cPpPV.d.cts} +54 -2
- package/dist/{deno-BYerLnry.js → deno-CQdJQjC5.js} +1 -1
- package/dist/{docloader-MSkogD2T.js → docloader-Cyl0-S8m.js} +2 -2
- package/dist/federation/builder.test.js +14 -3
- package/dist/federation/handler.test.js +97 -13
- package/dist/federation/idempotency.test.js +12 -12
- package/dist/federation/inbox.test.js +2 -2
- package/dist/federation/keycache.test.js +46 -2
- package/dist/federation/middleware.test.js +206 -12
- package/dist/federation/mod.cjs +4 -4
- package/dist/federation/mod.d.cts +4 -4
- package/dist/federation/mod.d.ts +4 -4
- package/dist/federation/mod.js +4 -4
- package/dist/federation/send.test.js +5 -5
- package/dist/federation/webfinger.test.js +12 -12
- package/dist/{http-DkHdFfrc.d.ts → http-BbfOqHGG.d.ts} +80 -8
- package/dist/{http-DJT6NciB.cjs → http-D6a6mMc0.cjs} +305 -99
- package/dist/{http-CSX1-Mgi.js → http-DJmytoC2.js} +295 -101
- package/dist/{http-S2U3qDwN.js → http-DK0CTomU.js} +153 -57
- package/dist/{http-Cz3MlXAZ.d.cts → http-DsqqmkXi.d.cts} +80 -8
- package/dist/{inbox-BaA0g5I_.js → inbox-CWa6sqsk.js} +1 -1
- package/dist/{key-DCdTVZiK.js → key-DRgvVevp.js} +145 -47
- package/dist/keycache-C7k8s1Bk.js +102 -0
- package/dist/{kv-cache-Vtxhbo1W.cjs → kv-cache-DPtsJ1sL.cjs} +1 -1
- package/dist/{kv-cache-CQPL_aGY.js → kv-cache-MPcS_mGG.js} +1 -1
- package/dist/{ld-CrX7pQda.js → ld-s9_8WfBc.js} +2 -2
- package/dist/{middleware-CfI9C9Xy.js → middleware-2XtoTBq0.js} +12 -12
- package/dist/{middleware-MlO5iUeZ.js → middleware-Ajnk9qHB.js} +158 -22
- package/dist/middleware-BgCIhb_C.cjs +12 -0
- package/dist/{middleware-D4S6i4A_.cjs → middleware-BoCzk7-G.cjs} +158 -22
- package/dist/{middleware-C8PKuPrm.js → middleware-DGUNDGCl.js} +4 -4
- package/dist/{middleware-BelSJK7m.js → middleware-Dn9UDJZP.js} +100 -24
- package/dist/{mod-CwZXZJ9d.d.ts → mod-BugwI0JN.d.ts} +1 -1
- package/dist/{mod-DPkRU3EK.d.cts → mod-CFBU2OT3.d.cts} +1 -1
- package/dist/{mod-DUWcVv49.d.ts → mod-CvxylbuV.d.ts} +1 -1
- package/dist/{mod-DVwHUI_x.d.cts → mod-DE8MYisy.d.cts} +1 -1
- package/dist/{mod-DXsQakeS.d.cts → mod-DKG0ovjR.d.cts} +1 -1
- package/dist/{mod-DnSsduJF.d.ts → mod-DcfFNgYf.d.ts} +1 -1
- package/dist/{mod-Di3W5OdP.d.cts → mod-Dp0kK0hO.d.cts} +1 -1
- package/dist/{mod-DosD6NsG.d.ts → mod-Z7lIaCfo.d.ts} +1 -1
- package/dist/mod.cjs +8 -4
- package/dist/mod.d.cts +8 -8
- package/dist/mod.d.ts +8 -8
- package/dist/mod.js +7 -5
- package/dist/nodeinfo/handler.test.js +12 -12
- package/dist/otel/exporter.test.js +43 -2
- package/dist/otel/mod.cjs +7 -1
- package/dist/otel/mod.d.cts +12 -0
- package/dist/otel/mod.d.ts +12 -0
- package/dist/otel/mod.js +7 -1
- package/dist/{owner-BAlnLKMO.js → owner-Cx8gV-j4.js} +1 -1
- package/dist/{proof-DMgHaXNJ.js → proof-CDr3NP3R.js} +2 -2
- package/dist/{proof-BgUVmaJz.js → proof-Le4DAkqb.js} +1 -1
- package/dist/{proof-CR5RUAmy.cjs → proof-qHcNgE5i.cjs} +1 -1
- package/dist/{send-B2aZYf9A.js → send-DreBSY1U.js} +2 -2
- package/dist/sig/http.test.js +85 -5
- package/dist/sig/key.test.js +70 -3
- package/dist/sig/ld.test.js +3 -3
- package/dist/sig/mod.cjs +4 -2
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.js +3 -3
- package/dist/sig/proof.test.js +3 -3
- package/dist/testing/mod.d.ts +92 -0
- package/dist/utils/docloader.test.js +4 -4
- package/dist/utils/mod.cjs +2 -2
- package/dist/utils/mod.d.cts +2 -2
- package/dist/utils/mod.d.ts +2 -2
- package/dist/utils/mod.js +2 -2
- package/package.json +5 -5
- package/dist/keycache-DRxpZ5r9.js +0 -48
- package/dist/middleware-D4XcpSBG.cjs +0 -12
|
@@ -14,7 +14,7 @@ const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runt
|
|
|
14
14
|
|
|
15
15
|
//#region deno.json
|
|
16
16
|
var name = "@fedify/fedify";
|
|
17
|
-
var version = "2.1.0-dev.
|
|
17
|
+
var version = "2.1.0-dev.523+150998a5";
|
|
18
18
|
var license = "MIT";
|
|
19
19
|
var exports$1 = {
|
|
20
20
|
".": "./src/mod.ts",
|
|
@@ -208,24 +208,10 @@ async function importJwk(jwk, type) {
|
|
|
208
208
|
validateCryptoKey(key, type);
|
|
209
209
|
return key;
|
|
210
210
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
* If the given URL contains an {@link Actor} object, it tries to find
|
|
214
|
-
* the corresponding key in the `publicKey` or `assertionMethod` property.
|
|
215
|
-
* @template T The type of the key to fetch. Either {@link CryptographicKey}
|
|
216
|
-
* or {@link Multikey}.
|
|
217
|
-
* @param keyId The URL of the key.
|
|
218
|
-
* @param cls The class of the key to fetch. Either {@link CryptographicKey}
|
|
219
|
-
* or {@link Multikey}.
|
|
220
|
-
* @param options Options for fetching the key. See {@link FetchKeyOptions}.
|
|
221
|
-
* @returns The fetched key or `null` if the key is not found.
|
|
222
|
-
* @since 1.3.0
|
|
223
|
-
*/
|
|
224
|
-
function fetchKey(keyId, cls, options = {}) {
|
|
225
|
-
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
211
|
+
async function withFetchKeySpan(keyId, tracerProvider, fetcher) {
|
|
212
|
+
tracerProvider ??= __opentelemetry_api.trace.getTracerProvider();
|
|
226
213
|
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
227
|
-
|
|
228
|
-
return tracer.startActiveSpan("activitypub.fetch_key", {
|
|
214
|
+
return await tracer.startActiveSpan("activitypub.fetch_key", {
|
|
229
215
|
kind: __opentelemetry_api.SpanKind.CLIENT,
|
|
230
216
|
attributes: {
|
|
231
217
|
"http.method": "GET",
|
|
@@ -238,7 +224,7 @@ function fetchKey(keyId, cls, options = {}) {
|
|
|
238
224
|
}
|
|
239
225
|
}, async (span) => {
|
|
240
226
|
try {
|
|
241
|
-
const result = await
|
|
227
|
+
const result = await fetcher();
|
|
242
228
|
span.setAttribute("activitypub.actor.key.cached", result.cached);
|
|
243
229
|
return result;
|
|
244
230
|
} catch (e) {
|
|
@@ -252,43 +238,105 @@ function fetchKey(keyId, cls, options = {}) {
|
|
|
252
238
|
}
|
|
253
239
|
});
|
|
254
240
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
241
|
+
/**
|
|
242
|
+
* Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL.
|
|
243
|
+
* If the given URL contains an {@link Actor} object, it tries to find
|
|
244
|
+
* the corresponding key in the `publicKey` or `assertionMethod` property.
|
|
245
|
+
* @template T The type of the key to fetch. Either {@link CryptographicKey}
|
|
246
|
+
* or {@link Multikey}.
|
|
247
|
+
* @param keyId The URL of the key.
|
|
248
|
+
* @param cls The class of the key to fetch. Either {@link CryptographicKey}
|
|
249
|
+
* or {@link Multikey}.
|
|
250
|
+
* @param options Options for fetching the key. See {@link FetchKeyOptions}.
|
|
251
|
+
* @returns The fetched key or `null` if the key is not found.
|
|
252
|
+
* @since 1.3.0
|
|
253
|
+
*/
|
|
254
|
+
function fetchKey(keyId, cls, options = {}) {
|
|
255
|
+
keyId = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
256
|
+
return withFetchKeySpan(keyId, options.tracerProvider, () => fetchKeyInternal(keyId, cls, options));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL,
|
|
260
|
+
* preserving transport-level fetch failures for callers that need to inspect
|
|
261
|
+
* why the key could not be loaded.
|
|
262
|
+
*
|
|
263
|
+
* @template T The type of the key to fetch. Either {@link CryptographicKey}
|
|
264
|
+
* or {@link Multikey}.
|
|
265
|
+
* @param keyId The URL of the key.
|
|
266
|
+
* @param cls The class of the key to fetch. Either {@link CryptographicKey}
|
|
267
|
+
* or {@link Multikey}.
|
|
268
|
+
* @param options Options for fetching the key.
|
|
269
|
+
* @returns The fetched key, or detailed fetch failure information.
|
|
270
|
+
* @since 2.1.0
|
|
271
|
+
*/
|
|
272
|
+
async function fetchKeyDetailed(keyId, cls, options = {}) {
|
|
261
273
|
const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
274
|
+
return await withFetchKeySpan(cacheKey, options.tracerProvider, async () => {
|
|
275
|
+
return await fetchKeyWithResult(cacheKey, cls, options, async (cacheKey$1, keyId$1, keyCache, logger) => {
|
|
276
|
+
const fetchError = await keyCache?.getFetchError?.(cacheKey$1);
|
|
277
|
+
if (fetchError != null) {
|
|
278
|
+
logger.debug("Entry {keyId} found in cache with preserved fetch failure details.", { keyId: keyId$1 });
|
|
279
|
+
return {
|
|
280
|
+
key: null,
|
|
281
|
+
cached: true,
|
|
282
|
+
fetchError
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
logger.debug("Entry {keyId} found in cache, but no fetch failure details are available.", { keyId: keyId$1 });
|
|
267
286
|
return {
|
|
268
|
-
key:
|
|
287
|
+
key: null,
|
|
269
288
|
cached: true
|
|
270
289
|
};
|
|
271
|
-
}
|
|
272
|
-
logger.debug("
|
|
290
|
+
}, async (error, cacheKey$1, keyId$1, keyCache, logger) => {
|
|
291
|
+
logger.debug("Failed to fetch key {keyId}.", {
|
|
292
|
+
keyId: keyId$1,
|
|
293
|
+
error
|
|
294
|
+
});
|
|
295
|
+
await keyCache?.set(cacheKey$1, null);
|
|
296
|
+
if (error instanceof __fedify_vocab_runtime.FetchError && error.response != null) {
|
|
297
|
+
const fetchError$1 = {
|
|
298
|
+
status: error.response.status,
|
|
299
|
+
response: error.response.clone()
|
|
300
|
+
};
|
|
301
|
+
await keyCache?.setFetchError?.(cacheKey$1, fetchError$1);
|
|
302
|
+
return {
|
|
303
|
+
key: null,
|
|
304
|
+
cached: false,
|
|
305
|
+
fetchError: fetchError$1
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
const fetchError = { error: error instanceof Error ? error : new Error(String(error)) };
|
|
309
|
+
await keyCache?.setFetchError?.(cacheKey$1, fetchError);
|
|
273
310
|
return {
|
|
274
311
|
key: null,
|
|
275
|
-
cached:
|
|
312
|
+
cached: false,
|
|
313
|
+
fetchError
|
|
276
314
|
};
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
|
|
319
|
+
if (keyCache == null) return null;
|
|
320
|
+
const cachedKey = await keyCache.get(cacheKey);
|
|
321
|
+
if (cachedKey instanceof cls && cachedKey.publicKey != null) {
|
|
322
|
+
logger.debug("Key {keyId} found in cache.", { keyId });
|
|
323
|
+
return {
|
|
324
|
+
key: cachedKey,
|
|
325
|
+
cached: true
|
|
326
|
+
};
|
|
327
|
+
} else if (cachedKey === null) {
|
|
328
|
+
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
287
329
|
return {
|
|
288
330
|
key: null,
|
|
289
|
-
cached:
|
|
331
|
+
cached: true
|
|
290
332
|
};
|
|
291
333
|
}
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
async function clearFetchErrorMetadata(keyId, keyCache) {
|
|
337
|
+
await keyCache?.setFetchError?.(keyId, null);
|
|
338
|
+
}
|
|
339
|
+
async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
|
|
292
340
|
let object;
|
|
293
341
|
try {
|
|
294
342
|
object = await __fedify_vocab.Object.fromJsonLd(document, {
|
|
@@ -308,6 +356,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
308
356
|
if (e$1 instanceof TypeError) {
|
|
309
357
|
logger.debug("Failed to verify; key {keyId} returned an invalid object.", { keyId });
|
|
310
358
|
await keyCache?.set(cacheKey, null);
|
|
359
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
311
360
|
return {
|
|
312
361
|
key: null,
|
|
313
362
|
cached: false
|
|
@@ -346,6 +395,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
346
395
|
actorType: object.constructor.name
|
|
347
396
|
});
|
|
348
397
|
await keyCache?.set(cacheKey, null);
|
|
398
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
349
399
|
return {
|
|
350
400
|
key: null,
|
|
351
401
|
cached: false
|
|
@@ -354,6 +404,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
354
404
|
} else {
|
|
355
405
|
logger.debug("Failed to verify; key {keyId} returned an invalid object.", { keyId });
|
|
356
406
|
await keyCache?.set(cacheKey, null);
|
|
407
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
357
408
|
return {
|
|
358
409
|
key: null,
|
|
359
410
|
cached: false
|
|
@@ -362,6 +413,7 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
362
413
|
if (key.publicKey == null) {
|
|
363
414
|
logger.debug("Failed to verify; key {keyId} has no publicKeyPem field.", { keyId });
|
|
364
415
|
await keyCache?.set(cacheKey, null);
|
|
416
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
365
417
|
return {
|
|
366
418
|
key: null,
|
|
367
419
|
cached: false
|
|
@@ -371,11 +423,57 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
371
423
|
await keyCache.set(cacheKey, key);
|
|
372
424
|
logger.debug("Key {keyId} cached.", { keyId });
|
|
373
425
|
}
|
|
426
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
374
427
|
return {
|
|
375
428
|
key,
|
|
376
429
|
cached: false
|
|
377
430
|
};
|
|
378
431
|
}
|
|
432
|
+
async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, onFetchError) {
|
|
433
|
+
const logger = (0, __logtape_logtape.getLogger)([
|
|
434
|
+
"fedify",
|
|
435
|
+
"sig",
|
|
436
|
+
"key"
|
|
437
|
+
]);
|
|
438
|
+
const keyId = cacheKey.href;
|
|
439
|
+
const keyCache = options.keyCache;
|
|
440
|
+
const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
|
|
441
|
+
if (cached?.key === null && cached.cached) return await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
|
|
442
|
+
if (cached != null) return cached;
|
|
443
|
+
logger.debug("Fetching key {keyId} to verify signature...", { keyId });
|
|
444
|
+
let document;
|
|
445
|
+
try {
|
|
446
|
+
const remoteDocument = await (options.documentLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)())(keyId);
|
|
447
|
+
document = remoteDocument.document;
|
|
448
|
+
} catch (error) {
|
|
449
|
+
return await onFetchError(error, cacheKey, keyId, keyCache, logger);
|
|
450
|
+
}
|
|
451
|
+
return await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
|
|
452
|
+
}
|
|
453
|
+
async function fetchKeyInternal(keyId, cls, options = {}) {
|
|
454
|
+
const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
455
|
+
return await fetchKeyWithResult(cacheKey, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
|
|
456
|
+
return {
|
|
457
|
+
key: null,
|
|
458
|
+
cached: true
|
|
459
|
+
};
|
|
460
|
+
}, async (error, cacheKey$1, keyId$1, keyCache, logger) => {
|
|
461
|
+
logger.debug("Failed to fetch key {keyId}.", {
|
|
462
|
+
keyId: keyId$1,
|
|
463
|
+
error
|
|
464
|
+
});
|
|
465
|
+
await keyCache?.set(cacheKey$1, null);
|
|
466
|
+
if (error instanceof __fedify_vocab_runtime.FetchError && error.response != null) await keyCache?.setFetchError?.(cacheKey$1, {
|
|
467
|
+
status: error.response.status,
|
|
468
|
+
response: error.response.clone()
|
|
469
|
+
});
|
|
470
|
+
else await keyCache?.setFetchError?.(cacheKey$1, { error: error instanceof Error ? error : new Error(String(error)) });
|
|
471
|
+
return {
|
|
472
|
+
key: null,
|
|
473
|
+
cached: false
|
|
474
|
+
};
|
|
475
|
+
});
|
|
476
|
+
}
|
|
379
477
|
|
|
380
478
|
//#endregion
|
|
381
479
|
//#region src/sig/http.ts
|
|
@@ -605,6 +703,55 @@ const supportedHashAlgorithms = {
|
|
|
605
703
|
"sha-256": "SHA-256",
|
|
606
704
|
"sha-512": "SHA-512"
|
|
607
705
|
};
|
|
706
|
+
function noSignatureResult() {
|
|
707
|
+
return {
|
|
708
|
+
verified: false,
|
|
709
|
+
reason: { type: "noSignature" }
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
function invalidSignatureResult(keyId) {
|
|
713
|
+
return keyId == null ? {
|
|
714
|
+
verified: false,
|
|
715
|
+
reason: { type: "invalidSignature" }
|
|
716
|
+
} : {
|
|
717
|
+
verified: false,
|
|
718
|
+
reason: {
|
|
719
|
+
type: "invalidSignature",
|
|
720
|
+
keyId
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
function keyFetchErrorResult(keyId, result) {
|
|
725
|
+
return {
|
|
726
|
+
verified: false,
|
|
727
|
+
reason: {
|
|
728
|
+
type: "keyFetchError",
|
|
729
|
+
keyId,
|
|
730
|
+
result
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function parseKeyId(value) {
|
|
735
|
+
if (value == null) return null;
|
|
736
|
+
try {
|
|
737
|
+
return new URL(value);
|
|
738
|
+
} catch {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
function getKeyFetchErrorName(error) {
|
|
743
|
+
return error.name || error.constructor.name || "Error";
|
|
744
|
+
}
|
|
745
|
+
function recordVerificationResult(span, result) {
|
|
746
|
+
span.setAttribute("http_signatures.verified", result.verified);
|
|
747
|
+
if (result.verified === true) return;
|
|
748
|
+
const reason = result.reason;
|
|
749
|
+
span.setAttribute("http_signatures.failure_reason", reason.type);
|
|
750
|
+
if ("keyId" in reason && reason.keyId != null) span.setAttribute("http_signatures.key_id", reason.keyId.href);
|
|
751
|
+
if (reason.type !== "keyFetchError") return;
|
|
752
|
+
if ("status" in reason.result) span.setAttribute("http_signatures.key_fetch_status", reason.result.status);
|
|
753
|
+
else span.setAttribute("http_signatures.key_fetch_error", getKeyFetchErrorName(reason.result.error));
|
|
754
|
+
}
|
|
608
755
|
/**
|
|
609
756
|
* Verifies the signature of a request.
|
|
610
757
|
*
|
|
@@ -619,6 +766,19 @@ const supportedHashAlgorithms = {
|
|
|
619
766
|
* could not be verified.
|
|
620
767
|
*/
|
|
621
768
|
async function verifyRequest(request, options = {}) {
|
|
769
|
+
const result = await verifyRequestDetailed(request, options);
|
|
770
|
+
return result.verified ? result.key : null;
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Verifies the signature of a request and returns a structured failure reason
|
|
774
|
+
* when verification does not succeed.
|
|
775
|
+
*
|
|
776
|
+
* @param request The request to verify.
|
|
777
|
+
* @param options Options for verifying the request.
|
|
778
|
+
* @returns The verified public key, or a structured verification failure.
|
|
779
|
+
* @since 2.1.0
|
|
780
|
+
*/
|
|
781
|
+
async function verifyRequestDetailed(request, options = {}) {
|
|
622
782
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
623
783
|
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
624
784
|
return await tracer.startActiveSpan("http_signatures.verify", async (span) => {
|
|
@@ -630,11 +790,12 @@ async function verifyRequest(request, options = {}) {
|
|
|
630
790
|
try {
|
|
631
791
|
let spec = options.spec;
|
|
632
792
|
if (spec == null) spec = request.headers.has("Signature-Input") ? "rfc9421" : "draft-cavage-http-signatures-12";
|
|
633
|
-
let
|
|
634
|
-
if (spec === "rfc9421")
|
|
635
|
-
else
|
|
636
|
-
|
|
637
|
-
|
|
793
|
+
let result;
|
|
794
|
+
if (spec === "rfc9421") result = await verifyRequestRfc9421(request, span, options);
|
|
795
|
+
else result = await verifyRequestDraft(request, span, options);
|
|
796
|
+
recordVerificationResult(span, result);
|
|
797
|
+
if (!result.verified) span.setStatus({ code: __opentelemetry_api.SpanStatusCode.ERROR });
|
|
798
|
+
return result;
|
|
638
799
|
} catch (error) {
|
|
639
800
|
span.setStatus({
|
|
640
801
|
code: __opentelemetry_api.SpanStatusCode.ERROR,
|
|
@@ -654,27 +815,29 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
654
815
|
]);
|
|
655
816
|
if (request.bodyUsed) {
|
|
656
817
|
logger.error("Failed to verify; the request body is already consumed.", { url: request.url });
|
|
657
|
-
return
|
|
818
|
+
return noSignatureResult();
|
|
658
819
|
} else if (request.body?.locked) {
|
|
659
820
|
logger.error("Failed to verify; the request body is locked.", { url: request.url });
|
|
660
|
-
return
|
|
821
|
+
return noSignatureResult();
|
|
661
822
|
}
|
|
662
823
|
const originalRequest = request;
|
|
663
824
|
request = request.clone();
|
|
664
|
-
const dateHeader = request.headers.get("Date");
|
|
665
|
-
if (dateHeader == null) {
|
|
666
|
-
logger.debug("Failed to verify; no Date header found.", { headers: Object.fromEntries(request.headers.entries()) });
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
825
|
const sigHeader = request.headers.get("Signature");
|
|
670
826
|
if (sigHeader == null) {
|
|
671
827
|
logger.debug("Failed to verify; no Signature header found.", { headers: Object.fromEntries(request.headers.entries()) });
|
|
672
|
-
return
|
|
828
|
+
return noSignatureResult();
|
|
829
|
+
}
|
|
830
|
+
const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
|
|
831
|
+
const parsedKeyId = parseKeyId(sigValues.keyId);
|
|
832
|
+
const dateHeader = request.headers.get("Date");
|
|
833
|
+
if (dateHeader == null) {
|
|
834
|
+
logger.debug("Failed to verify; no Date header found.", { headers: Object.fromEntries(request.headers.entries()) });
|
|
835
|
+
return invalidSignatureResult(parsedKeyId);
|
|
673
836
|
}
|
|
674
837
|
const digestHeader = request.headers.get("Digest");
|
|
675
838
|
if (request.method !== "GET" && request.method !== "HEAD" && digestHeader == null) {
|
|
676
839
|
logger.debug("Failed to verify; no Digest header found.", { headers: Object.fromEntries(request.headers.entries()) });
|
|
677
|
-
return
|
|
840
|
+
return invalidSignatureResult(parsedKeyId);
|
|
678
841
|
}
|
|
679
842
|
let body = null;
|
|
680
843
|
if (digestHeader != null) {
|
|
@@ -692,7 +855,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
692
855
|
digest: digestBase64,
|
|
693
856
|
error
|
|
694
857
|
});
|
|
695
|
-
return
|
|
858
|
+
return invalidSignatureResult(parsedKeyId);
|
|
696
859
|
}
|
|
697
860
|
if (span.isRecording()) span.setAttribute(`http_signatures.digest.${algo}`, (0, byte_encodings_hex.encodeHex)(digest));
|
|
698
861
|
const expectedDigest = await crypto.subtle.digest(supportedHashAlgorithms[algo], body);
|
|
@@ -702,7 +865,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
702
865
|
digest: digestBase64,
|
|
703
866
|
expectedDigest: (0, byte_encodings_base64.encodeBase64)(expectedDigest)
|
|
704
867
|
});
|
|
705
|
-
return
|
|
868
|
+
return invalidSignatureResult(parsedKeyId);
|
|
706
869
|
}
|
|
707
870
|
matched = true;
|
|
708
871
|
}
|
|
@@ -711,7 +874,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
711
874
|
supportedAlgorithms: Object.keys(supportedHashAlgorithms),
|
|
712
875
|
algorithms: digests.map(([algo]) => algo)
|
|
713
876
|
});
|
|
714
|
-
return
|
|
877
|
+
return invalidSignatureResult(parsedKeyId);
|
|
715
878
|
}
|
|
716
879
|
}
|
|
717
880
|
const date = Temporal.Instant.from(new Date(dateHeader).toISOString());
|
|
@@ -723,25 +886,24 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
723
886
|
date: date.toString(),
|
|
724
887
|
now: now.toString()
|
|
725
888
|
});
|
|
726
|
-
return
|
|
889
|
+
return invalidSignatureResult(parsedKeyId);
|
|
727
890
|
} else if (Temporal.Instant.compare(date, now.subtract(tw)) < 0) {
|
|
728
891
|
logger.debug("Failed to verify; Date is too far in the past.", {
|
|
729
892
|
date: date.toString(),
|
|
730
893
|
now: now.toString()
|
|
731
894
|
});
|
|
732
|
-
return
|
|
895
|
+
return invalidSignatureResult(parsedKeyId);
|
|
733
896
|
}
|
|
734
897
|
}
|
|
735
|
-
const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
|
|
736
898
|
if (!("keyId" in sigValues)) {
|
|
737
899
|
logger.debug("Failed to verify; no keyId field found in the Signature header.", { signature: sigHeader });
|
|
738
|
-
return null;
|
|
900
|
+
return invalidSignatureResult(null);
|
|
739
901
|
} else if (!("headers" in sigValues)) {
|
|
740
902
|
logger.debug("Failed to verify; no headers field found in the Signature header.", { signature: sigHeader });
|
|
741
|
-
return
|
|
903
|
+
return invalidSignatureResult(parsedKeyId);
|
|
742
904
|
} else if (!("signature" in sigValues)) {
|
|
743
905
|
logger.debug("Failed to verify; no signature field found in the Signature header.", { signature: sigHeader });
|
|
744
|
-
return
|
|
906
|
+
return invalidSignatureResult(parsedKeyId);
|
|
745
907
|
}
|
|
746
908
|
if ("expires" in sigValues) {
|
|
747
909
|
const expiresSeconds = parseInt(sigValues.expires);
|
|
@@ -750,7 +912,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
750
912
|
expires: sigValues.expires,
|
|
751
913
|
signature: sigHeader
|
|
752
914
|
});
|
|
753
|
-
return
|
|
915
|
+
return invalidSignatureResult(parsedKeyId);
|
|
754
916
|
}
|
|
755
917
|
const expires = Temporal.Instant.fromEpochMilliseconds(expiresSeconds * 1e3);
|
|
756
918
|
if (Temporal.Instant.compare(now, expires) > 0) {
|
|
@@ -759,7 +921,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
759
921
|
now: now.toString(),
|
|
760
922
|
signature: sigHeader
|
|
761
923
|
});
|
|
762
|
-
return
|
|
924
|
+
return invalidSignatureResult(parsedKeyId);
|
|
763
925
|
}
|
|
764
926
|
}
|
|
765
927
|
if ("created" in sigValues) {
|
|
@@ -769,7 +931,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
769
931
|
created: sigValues.created,
|
|
770
932
|
signature: sigHeader
|
|
771
933
|
});
|
|
772
|
-
return
|
|
934
|
+
return invalidSignatureResult(parsedKeyId);
|
|
773
935
|
}
|
|
774
936
|
if (timeWindow !== false) {
|
|
775
937
|
const created = Temporal.Instant.fromEpochMilliseconds(createdSeconds * 1e3);
|
|
@@ -779,34 +941,37 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
779
941
|
created: created.toString(),
|
|
780
942
|
now: now.toString()
|
|
781
943
|
});
|
|
782
|
-
return
|
|
944
|
+
return invalidSignatureResult(parsedKeyId);
|
|
783
945
|
} else if (Temporal.Instant.compare(created, now.subtract(tw)) < 0) {
|
|
784
946
|
logger.debug("Failed to verify; created is too far in the past.", {
|
|
785
947
|
created: created.toString(),
|
|
786
948
|
now: now.toString()
|
|
787
949
|
});
|
|
788
|
-
return
|
|
950
|
+
return invalidSignatureResult(parsedKeyId);
|
|
789
951
|
}
|
|
790
952
|
}
|
|
791
953
|
}
|
|
792
954
|
const { keyId, headers, signature } = sigValues;
|
|
955
|
+
const keyIdUrl = parseKeyId(keyId);
|
|
956
|
+
if (keyIdUrl == null) return invalidSignatureResult(null);
|
|
793
957
|
span?.setAttribute("http_signatures.key_id", keyId);
|
|
794
958
|
if ("algorithm" in sigValues) span?.setAttribute("http_signatures.algorithm", sigValues.algorithm);
|
|
795
|
-
const { key, cached } = await
|
|
959
|
+
const { key, cached, fetchError } = await fetchKeyDetailed(keyIdUrl, __fedify_vocab.CryptographicKey, {
|
|
796
960
|
documentLoader,
|
|
797
961
|
contextLoader,
|
|
798
962
|
keyCache,
|
|
799
963
|
tracerProvider
|
|
800
964
|
});
|
|
801
|
-
if (
|
|
965
|
+
if (fetchError != null) return keyFetchErrorResult(keyIdUrl, fetchError);
|
|
966
|
+
if (key == null) return invalidSignatureResult(keyIdUrl);
|
|
802
967
|
const headerNames = headers.split(/\s+/g);
|
|
803
968
|
if (!headerNames.includes("(request-target)") || !headerNames.includes("date")) {
|
|
804
969
|
logger.debug("Failed to verify; required headers missing in the Signature header: {headers}.", { headers });
|
|
805
|
-
return
|
|
970
|
+
return invalidSignatureResult(keyIdUrl);
|
|
806
971
|
}
|
|
807
972
|
if (body != null && !headerNames.includes("digest")) {
|
|
808
973
|
logger.debug("Failed to verify; required headers missing in the Signature header: {headers}.", { headers });
|
|
809
|
-
return
|
|
974
|
+
return invalidSignatureResult(keyIdUrl);
|
|
810
975
|
}
|
|
811
976
|
const message = headerNames.map((name$1) => `${name$1}: ` + (name$1 === "(request-target)" ? `${request.method.toLowerCase()} ${new URL(request.url).pathname}` : name$1 === "(created)" ? sigValues.created ?? "" : name$1 === "(expires)" ? sigValues.expires ?? "" : name$1 === "host" ? request.headers.get("host") ?? new URL(request.url).host : request.headers.get(name$1))).join("\n");
|
|
812
977
|
const sig = (0, byte_encodings_base64.decodeBase64)(signature);
|
|
@@ -819,7 +984,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
819
984
|
signature,
|
|
820
985
|
message
|
|
821
986
|
});
|
|
822
|
-
return await
|
|
987
|
+
return await verifyRequestDetailed(originalRequest, {
|
|
823
988
|
documentLoader,
|
|
824
989
|
contextLoader,
|
|
825
990
|
timeWindow,
|
|
@@ -835,9 +1000,12 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
835
1000
|
signature,
|
|
836
1001
|
message
|
|
837
1002
|
});
|
|
838
|
-
return
|
|
1003
|
+
return invalidSignatureResult(keyIdUrl);
|
|
839
1004
|
}
|
|
840
|
-
return
|
|
1005
|
+
return {
|
|
1006
|
+
verified: true,
|
|
1007
|
+
key
|
|
1008
|
+
};
|
|
841
1009
|
}
|
|
842
1010
|
/**
|
|
843
1011
|
* RFC 9421 map of algorithm identifiers to WebCrypto algorithms
|
|
@@ -908,22 +1076,22 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
908
1076
|
]);
|
|
909
1077
|
if (request.bodyUsed) {
|
|
910
1078
|
logger.error("Failed to verify; the request body is already consumed.", { url: request.url });
|
|
911
|
-
return
|
|
1079
|
+
return noSignatureResult();
|
|
912
1080
|
} else if (request.body?.locked) {
|
|
913
1081
|
logger.error("Failed to verify; the request body is locked.", { url: request.url });
|
|
914
|
-
return
|
|
1082
|
+
return noSignatureResult();
|
|
915
1083
|
}
|
|
916
1084
|
const originalRequest = request;
|
|
917
1085
|
request = request.clone();
|
|
918
1086
|
const signatureInputHeader = request.headers.get("Signature-Input");
|
|
919
1087
|
if (!signatureInputHeader) {
|
|
920
1088
|
logger.debug("Failed to verify; no Signature-Input header found.", { headers: Object.fromEntries(request.headers.entries()) });
|
|
921
|
-
return
|
|
1089
|
+
return noSignatureResult();
|
|
922
1090
|
}
|
|
923
1091
|
const signatureHeader = request.headers.get("Signature");
|
|
924
1092
|
if (!signatureHeader) {
|
|
925
1093
|
logger.debug("Failed to verify; no Signature header found.", { headers: Object.fromEntries(request.headers.entries()) });
|
|
926
|
-
return
|
|
1094
|
+
return noSignatureResult();
|
|
927
1095
|
}
|
|
928
1096
|
const signatureInputs = parseRfc9421SignatureInput(signatureInputHeader);
|
|
929
1097
|
logger.debug("Parsed Signature-Input header: {signatureInputs}", { signatureInputs });
|
|
@@ -931,18 +1099,23 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
931
1099
|
const signatureNames = Object.keys(signatureInputs);
|
|
932
1100
|
if (signatureNames.length === 0) {
|
|
933
1101
|
logger.debug("Failed to verify; no valid signatures found in Signature-Input header.", { header: signatureInputHeader });
|
|
934
|
-
return null;
|
|
1102
|
+
return invalidSignatureResult(null);
|
|
935
1103
|
}
|
|
936
|
-
let
|
|
1104
|
+
let failure = noSignatureResult();
|
|
937
1105
|
for (const sigName of signatureNames) {
|
|
938
|
-
if (!signatures[sigName])
|
|
1106
|
+
if (!signatures[sigName]) {
|
|
1107
|
+
failure = invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId));
|
|
1108
|
+
continue;
|
|
1109
|
+
}
|
|
939
1110
|
const sigInput = signatureInputs[sigName];
|
|
940
1111
|
const sigBytes = signatures[sigName];
|
|
1112
|
+
const keyId = parseKeyId(sigInput.keyId);
|
|
941
1113
|
if (!sigInput.keyId) {
|
|
942
1114
|
logger.debug("Failed to verify; missing keyId in signature {signatureName}.", {
|
|
943
1115
|
signatureName: sigName,
|
|
944
1116
|
signatureInput: signatureInputHeader
|
|
945
1117
|
});
|
|
1118
|
+
failure = invalidSignatureResult(null);
|
|
946
1119
|
continue;
|
|
947
1120
|
}
|
|
948
1121
|
if (!sigInput.created) {
|
|
@@ -950,6 +1123,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
950
1123
|
signatureName: sigName,
|
|
951
1124
|
signatureInput: signatureInputHeader
|
|
952
1125
|
});
|
|
1126
|
+
failure = invalidSignatureResult(keyId);
|
|
953
1127
|
continue;
|
|
954
1128
|
}
|
|
955
1129
|
const signatureCreated = Temporal.Instant.fromEpochMilliseconds(sigInput.created * 1e3);
|
|
@@ -961,12 +1135,14 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
961
1135
|
created: signatureCreated.toString(),
|
|
962
1136
|
now: now.toString()
|
|
963
1137
|
});
|
|
1138
|
+
failure = invalidSignatureResult(keyId);
|
|
964
1139
|
continue;
|
|
965
1140
|
} else if (Temporal.Instant.compare(signatureCreated, now.subtract(tw)) < 0) {
|
|
966
1141
|
logger.debug("Failed to verify; signature created time is too far in the past.", {
|
|
967
1142
|
created: signatureCreated.toString(),
|
|
968
1143
|
now: now.toString()
|
|
969
1144
|
});
|
|
1145
|
+
failure = invalidSignatureResult(keyId);
|
|
970
1146
|
continue;
|
|
971
1147
|
}
|
|
972
1148
|
}
|
|
@@ -974,25 +1150,36 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
974
1150
|
const contentDigestHeader = request.headers.get("Content-Digest");
|
|
975
1151
|
if (!contentDigestHeader) {
|
|
976
1152
|
logger.debug("Failed to verify; Content-Digest header required but not found.", { components: sigInput.components });
|
|
1153
|
+
failure = invalidSignatureResult(keyId);
|
|
977
1154
|
continue;
|
|
978
1155
|
}
|
|
979
1156
|
const body = await request.arrayBuffer();
|
|
980
1157
|
const digestValid = await verifyRfc9421ContentDigest(contentDigestHeader, body);
|
|
981
1158
|
if (!digestValid) {
|
|
982
1159
|
logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
|
|
1160
|
+
failure = invalidSignatureResult(keyId);
|
|
983
1161
|
continue;
|
|
984
1162
|
}
|
|
985
1163
|
}
|
|
986
1164
|
span?.setAttribute("http_signatures.key_id", sigInput.keyId);
|
|
987
1165
|
span?.setAttribute("http_signatures.created", sigInput.created.toString());
|
|
988
|
-
|
|
1166
|
+
if (keyId == null) {
|
|
1167
|
+
failure = invalidSignatureResult(null);
|
|
1168
|
+
continue;
|
|
1169
|
+
}
|
|
1170
|
+
const { key, cached, fetchError } = await fetchKeyDetailed(keyId, __fedify_vocab.CryptographicKey, {
|
|
989
1171
|
documentLoader,
|
|
990
1172
|
contextLoader,
|
|
991
1173
|
keyCache,
|
|
992
1174
|
tracerProvider
|
|
993
1175
|
});
|
|
1176
|
+
if (fetchError != null) {
|
|
1177
|
+
failure = keyFetchErrorResult(keyId, fetchError);
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
994
1180
|
if (!key) {
|
|
995
1181
|
logger.debug("Failed to fetch key: {keyId}", { keyId: sigInput.keyId });
|
|
1182
|
+
failure = invalidSignatureResult(keyId);
|
|
996
1183
|
continue;
|
|
997
1184
|
}
|
|
998
1185
|
let alg = sigInput.alg?.toLowerCase();
|
|
@@ -1009,6 +1196,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1009
1196
|
algorithm: sigInput.alg,
|
|
1010
1197
|
supported: Object.keys(rfc9421AlgorithmMap)
|
|
1011
1198
|
});
|
|
1199
|
+
failure = invalidSignatureResult(keyId);
|
|
1012
1200
|
continue;
|
|
1013
1201
|
}
|
|
1014
1202
|
let signatureBase;
|
|
@@ -1019,41 +1207,47 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1019
1207
|
error,
|
|
1020
1208
|
signatureInput: sigInput
|
|
1021
1209
|
});
|
|
1210
|
+
failure = invalidSignatureResult(keyId);
|
|
1022
1211
|
continue;
|
|
1023
1212
|
}
|
|
1024
1213
|
const signatureBaseBytes = new TextEncoder().encode(signatureBase);
|
|
1025
1214
|
span?.setAttribute("http_signatures.signature", (0, byte_encodings_hex.encodeHex)(sigBytes));
|
|
1026
1215
|
try {
|
|
1027
1216
|
const verified = await crypto.subtle.verify(algorithm, key.publicKey, sigBytes.slice(), signatureBaseBytes);
|
|
1028
|
-
if (verified) {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
}
|
|
1217
|
+
if (verified) return {
|
|
1218
|
+
verified: true,
|
|
1219
|
+
key
|
|
1220
|
+
};
|
|
1221
|
+
else if (cached) {
|
|
1032
1222
|
logger.debug("Failed to verify with cached key {keyId}; retrying with fresh key...", { keyId: sigInput.keyId });
|
|
1033
|
-
return await
|
|
1223
|
+
return await verifyRequestDetailed(originalRequest, {
|
|
1034
1224
|
documentLoader,
|
|
1035
1225
|
contextLoader,
|
|
1036
1226
|
timeWindow,
|
|
1037
1227
|
currentTime,
|
|
1038
1228
|
keyCache: {
|
|
1039
1229
|
get: () => Promise.resolve(void 0),
|
|
1040
|
-
set: async (keyId, key$1) => await keyCache?.set(keyId, key$1)
|
|
1230
|
+
set: async (keyId$1, key$1) => await keyCache?.set(keyId$1, key$1)
|
|
1041
1231
|
},
|
|
1042
1232
|
spec: "rfc9421"
|
|
1043
1233
|
});
|
|
1044
|
-
} else
|
|
1045
|
-
keyId
|
|
1046
|
-
|
|
1047
|
-
|
|
1234
|
+
} else {
|
|
1235
|
+
logger.debug("Failed to verify signature with fetched key {keyId}; signature invalid.", {
|
|
1236
|
+
keyId: sigInput.keyId,
|
|
1237
|
+
signatureBase
|
|
1238
|
+
});
|
|
1239
|
+
failure = invalidSignatureResult(keyId);
|
|
1240
|
+
}
|
|
1048
1241
|
} catch (error) {
|
|
1049
1242
|
logger.debug("Error during signature verification: {error}", {
|
|
1050
1243
|
error,
|
|
1051
1244
|
keyId: sigInput.keyId,
|
|
1052
1245
|
algorithm: sigInput.alg
|
|
1053
1246
|
});
|
|
1247
|
+
failure = invalidSignatureResult(keyId);
|
|
1054
1248
|
}
|
|
1055
1249
|
}
|
|
1056
|
-
return
|
|
1250
|
+
return failure;
|
|
1057
1251
|
}
|
|
1058
1252
|
/**
|
|
1059
1253
|
* Helper function to create a new Request for redirect handling.
|
|
@@ -1195,6 +1389,12 @@ Object.defineProperty(exports, 'fetchKey', {
|
|
|
1195
1389
|
return fetchKey;
|
|
1196
1390
|
}
|
|
1197
1391
|
});
|
|
1392
|
+
Object.defineProperty(exports, 'fetchKeyDetailed', {
|
|
1393
|
+
enumerable: true,
|
|
1394
|
+
get: function () {
|
|
1395
|
+
return fetchKeyDetailed;
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1198
1398
|
Object.defineProperty(exports, 'generateCryptoKeyPair', {
|
|
1199
1399
|
enumerable: true,
|
|
1200
1400
|
get: function () {
|
|
@@ -1224,4 +1424,10 @@ Object.defineProperty(exports, 'verifyRequest', {
|
|
|
1224
1424
|
get: function () {
|
|
1225
1425
|
return verifyRequest;
|
|
1226
1426
|
}
|
|
1427
|
+
});
|
|
1428
|
+
Object.defineProperty(exports, 'verifyRequestDetailed', {
|
|
1429
|
+
enumerable: true,
|
|
1430
|
+
get: function () {
|
|
1431
|
+
return verifyRequestDetailed;
|
|
1432
|
+
}
|
|
1227
1433
|
});
|