@peac/protocol 0.10.6 → 0.10.8

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.
@@ -0,0 +1,578 @@
1
+ "use strict";
2
+ /**
3
+ * PEAC Verifier Core
4
+ *
5
+ * Implements the verification flow per VERIFIER-SECURITY-MODEL.md with:
6
+ * - Ordered checks with short-circuit behavior
7
+ * - Trust pinning (issuer allowlist + RFC 7638 thumbprints)
8
+ * - SSRF-safe network fetches
9
+ * - Deterministic verification reports
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.verifyReceiptCore = verifyReceiptCore;
15
+ exports.clearJWKSCache = clearJWKSCache;
16
+ exports.getJWKSCacheSize = getJWKSCacheSize;
17
+ const crypto_1 = require("@peac/crypto");
18
+ const kernel_1 = require("@peac/kernel");
19
+ const schema_1 = require("@peac/schema");
20
+ const ssrf_safe_fetch_js_1 = require("./ssrf-safe-fetch.js");
21
+ const verification_report_js_1 = require("./verification-report.js");
22
+ const verifier_types_js_1 = require("./verifier-types.js");
23
+ /**
24
+ * In-memory JWKS cache (5 minute TTL)
25
+ */
26
+ const jwksCache = new Map();
27
+ const CACHE_TTL_MS = 5 * 60 * 1000;
28
+ // ---------------------------------------------------------------------------
29
+ // Helper Functions
30
+ // ---------------------------------------------------------------------------
31
+ /**
32
+ * Normalize issuer to origin format (https://host[:port])
33
+ */
34
+ function normalizeIssuer(issuer) {
35
+ try {
36
+ const url = new URL(issuer);
37
+ // Include port only if non-standard for HTTPS
38
+ if (url.port && url.port !== '443') {
39
+ return `${url.protocol}//${url.hostname}:${url.port}`;
40
+ }
41
+ return `${url.protocol}//${url.hostname}`;
42
+ }
43
+ catch {
44
+ return issuer;
45
+ }
46
+ }
47
+ /**
48
+ * Check if issuer is in the allowlist
49
+ */
50
+ function isIssuerAllowed(issuer, allowlist) {
51
+ if (!allowlist || allowlist.length === 0) {
52
+ // No allowlist means all issuers are allowed
53
+ return true;
54
+ }
55
+ const normalized = normalizeIssuer(issuer);
56
+ return allowlist.some((allowed) => normalizeIssuer(allowed) === normalized);
57
+ }
58
+ /**
59
+ * Find pinned key for issuer and kid
60
+ */
61
+ function findPinnedKey(issuer, kid, pinnedKeys) {
62
+ if (!pinnedKeys || pinnedKeys.length === 0) {
63
+ return undefined;
64
+ }
65
+ const normalizedIssuer = normalizeIssuer(issuer);
66
+ return pinnedKeys.find((pk) => normalizeIssuer(pk.issuer) === normalizedIssuer && pk.kid === kid);
67
+ }
68
+ /**
69
+ * Fetch issuer configuration
70
+ */
71
+ async function fetchIssuerConfig(issuerOrigin) {
72
+ const configUrl = `${issuerOrigin}/.well-known/peac-issuer.json`;
73
+ const result = await (0, ssrf_safe_fetch_js_1.ssrfSafeFetch)(configUrl, {
74
+ maxBytes: 65536, // 64 KB
75
+ headers: { Accept: 'application/json' },
76
+ });
77
+ if (!result.ok) {
78
+ return null;
79
+ }
80
+ try {
81
+ return JSON.parse(result.body);
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ /**
88
+ * Fetch JWKS from issuer
89
+ */
90
+ async function fetchIssuerJWKS(issuerOrigin) {
91
+ const now = Date.now();
92
+ // Check cache
93
+ const cached = jwksCache.get(issuerOrigin);
94
+ if (cached && cached.expiresAt > now) {
95
+ return { jwks: cached.jwks, fromCache: true };
96
+ }
97
+ // Fetch issuer config first
98
+ const config = await fetchIssuerConfig(issuerOrigin);
99
+ if (!config?.jwks_uri) {
100
+ // Fallback to well-known JWKS path
101
+ const fallbackUrl = `${issuerOrigin}/.well-known/jwks.json`;
102
+ const result = await (0, ssrf_safe_fetch_js_1.fetchJWKSSafe)(fallbackUrl);
103
+ if (!result.ok) {
104
+ return { error: result };
105
+ }
106
+ try {
107
+ const jwks = JSON.parse(result.body);
108
+ jwksCache.set(issuerOrigin, { jwks, expiresAt: now + CACHE_TTL_MS });
109
+ return { jwks, fromCache: false, rawBytes: result.rawBytes };
110
+ }
111
+ catch {
112
+ return {
113
+ error: {
114
+ ok: false,
115
+ reason: 'network_error',
116
+ message: 'Invalid JWKS JSON',
117
+ },
118
+ };
119
+ }
120
+ }
121
+ // Fetch JWKS from discovered URI
122
+ const result = await (0, ssrf_safe_fetch_js_1.fetchJWKSSafe)(config.jwks_uri);
123
+ if (!result.ok) {
124
+ return { error: result };
125
+ }
126
+ try {
127
+ const jwks = JSON.parse(result.body);
128
+ // Validate JWKS limits
129
+ if (jwks.keys.length > kernel_1.VERIFIER_LIMITS.maxJwksKeys) {
130
+ return {
131
+ error: {
132
+ ok: false,
133
+ reason: 'jwks_too_many_keys',
134
+ message: `JWKS has too many keys: ${jwks.keys.length} > ${kernel_1.VERIFIER_LIMITS.maxJwksKeys}`,
135
+ },
136
+ };
137
+ }
138
+ jwksCache.set(issuerOrigin, { jwks, expiresAt: now + CACHE_TTL_MS });
139
+ return { jwks, fromCache: false, rawBytes: result.rawBytes };
140
+ }
141
+ catch {
142
+ return {
143
+ error: {
144
+ ok: false,
145
+ reason: 'network_error',
146
+ message: 'Invalid JWKS JSON',
147
+ },
148
+ };
149
+ }
150
+ }
151
+ // ---------------------------------------------------------------------------
152
+ // Main Verification Function
153
+ // ---------------------------------------------------------------------------
154
+ /**
155
+ * Verify a PEAC receipt with full security checks and report emission
156
+ *
157
+ * Implements the verification flow per VERIFIER-SECURITY-MODEL.md:
158
+ * 1. jws.parse - Parse JWS structure
159
+ * 2. limits.receipt_bytes - Check receipt size
160
+ * 3. jws.protected_header - Validate protected header
161
+ * 4. claims.schema_unverified - Pre-signature schema check
162
+ * 5. issuer.trust_policy - Check issuer allowlist/pins
163
+ * 6. issuer.discovery - Fetch JWKS (if network mode)
164
+ * 7. key.resolve - Resolve signing key by kid
165
+ * 8. jws.signature - Verify signature
166
+ * 9. claims.time_window - Check iat/exp
167
+ * 10. extensions.limits - Check extension sizes
168
+ */
169
+ async function verifyReceiptCore(options) {
170
+ const { receipt, policy = (0, verifier_types_js_1.createDefaultPolicy)('offline_preferred'), referenceTime, includeMeta = false, } = options;
171
+ // Convert receipt to string if needed
172
+ const receiptJws = typeof receipt === 'string' ? receipt : new TextDecoder().decode(receipt);
173
+ const receiptBytes = typeof receipt === 'string' ? new TextEncoder().encode(receipt) : receipt;
174
+ // Compute receipt digest for report
175
+ const receiptDigestHex = await (0, crypto_1.sha256Hex)(receiptBytes);
176
+ // Start building report
177
+ const builder = (0, verification_report_js_1.createReportBuilder)(policy);
178
+ builder.setInputWithDigest(receiptDigestHex);
179
+ // Current time (or reference time for deterministic verification)
180
+ const nowSeconds = referenceTime ?? Math.floor(Date.now() / 1000);
181
+ // Track issuer and kid for result
182
+ let issuer;
183
+ let kid;
184
+ let parsedClaims;
185
+ // ---------------------------------------------------------------------------
186
+ // Check 1: jws.parse - Parse JWS structure
187
+ // ---------------------------------------------------------------------------
188
+ let header;
189
+ let payload;
190
+ try {
191
+ const decoded = (0, crypto_1.decode)(receiptJws);
192
+ header = decoded.header;
193
+ payload = decoded.payload;
194
+ builder.pass('jws.parse');
195
+ }
196
+ catch (err) {
197
+ builder.fail('jws.parse', 'E_VERIFY_MALFORMED_RECEIPT', {
198
+ error: err instanceof Error ? err.message : String(err),
199
+ });
200
+ builder.failure('malformed_receipt');
201
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
202
+ }
203
+ // ---------------------------------------------------------------------------
204
+ // Check 2: limits.receipt_bytes - Check receipt size
205
+ // ---------------------------------------------------------------------------
206
+ if (receiptBytes.length > policy.limits.max_receipt_bytes) {
207
+ builder.fail('limits.receipt_bytes', 'E_VERIFY_RECEIPT_TOO_LARGE', {
208
+ size: receiptBytes.length,
209
+ limit: policy.limits.max_receipt_bytes,
210
+ });
211
+ builder.failure('receipt_too_large');
212
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
213
+ }
214
+ builder.pass('limits.receipt_bytes', { size: receiptBytes.length });
215
+ // ---------------------------------------------------------------------------
216
+ // Check 3: jws.protected_header - Validate protected header
217
+ // ---------------------------------------------------------------------------
218
+ if (header.alg !== 'EdDSA') {
219
+ builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {
220
+ expected_alg: 'EdDSA',
221
+ actual_alg: header.alg,
222
+ });
223
+ builder.failure('malformed_receipt');
224
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
225
+ }
226
+ if (header.typ !== kernel_1.WIRE_TYPE) {
227
+ builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {
228
+ expected_typ: kernel_1.WIRE_TYPE,
229
+ actual_typ: header.typ,
230
+ });
231
+ builder.failure('malformed_receipt');
232
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
233
+ }
234
+ if (!header.kid) {
235
+ builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {
236
+ error: 'Missing kid in protected header',
237
+ });
238
+ builder.failure('malformed_receipt');
239
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
240
+ }
241
+ kid = header.kid;
242
+ builder.pass('jws.protected_header', { alg: header.alg, typ: header.typ, kid: header.kid });
243
+ // ---------------------------------------------------------------------------
244
+ // Check 4: claims.schema_unverified - Pre-signature schema check
245
+ // ---------------------------------------------------------------------------
246
+ try {
247
+ schema_1.ReceiptClaims.parse(payload);
248
+ issuer = payload.iss;
249
+ builder.pass('claims.schema_unverified');
250
+ }
251
+ catch (err) {
252
+ builder.fail('claims.schema_unverified', 'E_VERIFY_SCHEMA_INVALID', {
253
+ error: err instanceof Error ? err.message : String(err),
254
+ });
255
+ builder.failure('schema_invalid');
256
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
257
+ }
258
+ // ---------------------------------------------------------------------------
259
+ // Check 5: issuer.trust_policy - Check issuer allowlist/pins
260
+ // ---------------------------------------------------------------------------
261
+ const normalizedIssuer = normalizeIssuer(issuer);
262
+ if (!isIssuerAllowed(issuer, policy.issuer_allowlist)) {
263
+ builder.fail('issuer.trust_policy', 'E_VERIFY_ISSUER_NOT_ALLOWED', {
264
+ issuer: normalizedIssuer,
265
+ allowlist: policy.issuer_allowlist,
266
+ });
267
+ builder.failure('issuer_not_allowed', normalizedIssuer, kid);
268
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
269
+ }
270
+ builder.pass('issuer.trust_policy', { issuer: normalizedIssuer });
271
+ // ---------------------------------------------------------------------------
272
+ // Check 6: issuer.discovery - Fetch JWKS (if network mode)
273
+ // Check 7: key.resolve - Resolve signing key by kid
274
+ // ---------------------------------------------------------------------------
275
+ let publicKey;
276
+ let keySource;
277
+ let keyThumbprint;
278
+ let jwksRawBytes;
279
+ // Check for pinned key first
280
+ const pinnedKey = findPinnedKey(issuer, kid, policy.pinned_keys);
281
+ if (pinnedKey) {
282
+ // Use pinned key - skip discovery
283
+ builder.skip('issuer.discovery', { reason: 'pinned_key_available' });
284
+ // Check if pinned key has key material for offline verification
285
+ if (pinnedKey.jwk) {
286
+ // Full JWK provided - verify thumbprint and use directly
287
+ const actualThumbprint = await (0, crypto_1.computeJwkThumbprint)(pinnedKey.jwk);
288
+ if (actualThumbprint !== pinnedKey.jwk_thumbprint_sha256) {
289
+ builder.fail('key.resolve', 'E_VERIFY_POLICY_VIOLATION', {
290
+ error: 'Pinned JWK thumbprint does not match declared thumbprint',
291
+ expected: pinnedKey.jwk_thumbprint_sha256,
292
+ actual: actualThumbprint,
293
+ });
294
+ builder.failure('policy_violation', normalizedIssuer, kid);
295
+ return {
296
+ valid: false,
297
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
298
+ };
299
+ }
300
+ publicKey = (0, crypto_1.jwkToPublicKeyBytes)(pinnedKey.jwk);
301
+ keySource = 'pinned_keys';
302
+ keyThumbprint = actualThumbprint;
303
+ builder.pass('key.resolve', {
304
+ source: keySource,
305
+ kid,
306
+ thumbprint_verified: true,
307
+ offline: true,
308
+ });
309
+ }
310
+ else if (pinnedKey.public_key) {
311
+ // Raw public key bytes provided (base64url, 32 bytes for Ed25519)
312
+ try {
313
+ publicKey = (0, crypto_1.base64urlDecode)(pinnedKey.public_key);
314
+ if (publicKey.length !== 32) {
315
+ throw new Error(`Expected 32 bytes, got ${publicKey.length}`);
316
+ }
317
+ keySource = 'pinned_keys';
318
+ // Note: We can't compute thumbprint from raw key bytes alone
319
+ // The thumbprint is computed from canonical JWK JSON
320
+ // Use the declared thumbprint from the pinned key entry
321
+ keyThumbprint = pinnedKey.jwk_thumbprint_sha256;
322
+ builder.pass('key.resolve', {
323
+ source: keySource,
324
+ kid,
325
+ offline: true,
326
+ thumbprint_verified: false,
327
+ });
328
+ }
329
+ catch (err) {
330
+ builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {
331
+ error: `Invalid pinned public_key: ${err instanceof Error ? err.message : String(err)}`,
332
+ });
333
+ builder.failure('key_not_found', normalizedIssuer, kid);
334
+ return {
335
+ valid: false,
336
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
337
+ };
338
+ }
339
+ }
340
+ else if (policy.mode === 'offline_only') {
341
+ // Offline mode but pinned key has no key material - fail
342
+ builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {
343
+ error: 'Offline mode requires key material (jwk or public_key) in pinned_keys',
344
+ });
345
+ builder.failure('key_not_found', normalizedIssuer, kid);
346
+ return {
347
+ valid: false,
348
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
349
+ };
350
+ }
351
+ else {
352
+ // Network mode - fetch JWKS and verify thumbprint
353
+ const jwksResult = await fetchIssuerJWKS(normalizedIssuer);
354
+ if ('error' in jwksResult) {
355
+ const reason = (0, verifier_types_js_1.ssrfErrorToReasonCode)(jwksResult.error.reason, 'key');
356
+ builder.fail('issuer.discovery', (0, verifier_types_js_1.reasonCodeToErrorCode)(reason), {
357
+ error: jwksResult.error.message,
358
+ url: jwksResult.error.blockedUrl,
359
+ });
360
+ builder.failure(reason, normalizedIssuer, kid);
361
+ return {
362
+ valid: false,
363
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
364
+ };
365
+ }
366
+ // Store raw bytes for digest computation (only when not from cache)
367
+ if (jwksResult.rawBytes) {
368
+ jwksRawBytes = jwksResult.rawBytes;
369
+ }
370
+ builder.pass('issuer.discovery', {
371
+ from_cache: jwksResult.fromCache,
372
+ keys_count: jwksResult.jwks.keys.length,
373
+ });
374
+ // Find the key
375
+ const jwk = jwksResult.jwks.keys.find((k) => k.kid === kid);
376
+ if (!jwk) {
377
+ builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {
378
+ kid,
379
+ available_kids: jwksResult.jwks.keys.map((k) => k.kid),
380
+ });
381
+ builder.failure('key_not_found', normalizedIssuer, kid);
382
+ return {
383
+ valid: false,
384
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
385
+ };
386
+ }
387
+ // Verify thumbprint matches
388
+ const actualThumbprint = await (0, crypto_1.computeJwkThumbprint)(jwk);
389
+ if (actualThumbprint !== pinnedKey.jwk_thumbprint_sha256) {
390
+ builder.fail('key.resolve', 'E_VERIFY_POLICY_VIOLATION', {
391
+ error: 'JWK thumbprint does not match pinned key',
392
+ expected: pinnedKey.jwk_thumbprint_sha256,
393
+ actual: actualThumbprint,
394
+ });
395
+ builder.failure('policy_violation', normalizedIssuer, kid);
396
+ return {
397
+ valid: false,
398
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
399
+ };
400
+ }
401
+ publicKey = (0, crypto_1.jwkToPublicKeyBytes)(jwk);
402
+ keySource = 'pinned_keys';
403
+ keyThumbprint = actualThumbprint;
404
+ builder.pass('key.resolve', { source: keySource, kid, thumbprint_verified: true });
405
+ }
406
+ }
407
+ else {
408
+ // No pinned key - need to discover
409
+ if (policy.mode === 'offline_only') {
410
+ builder.fail('issuer.discovery', 'E_VERIFY_KEY_NOT_FOUND', {
411
+ error: 'Offline mode requires pinned keys',
412
+ });
413
+ builder.failure('key_not_found', normalizedIssuer, kid);
414
+ return {
415
+ valid: false,
416
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
417
+ };
418
+ }
419
+ const jwksResult = await fetchIssuerJWKS(normalizedIssuer);
420
+ if ('error' in jwksResult) {
421
+ const reason = (0, verifier_types_js_1.ssrfErrorToReasonCode)(jwksResult.error.reason, 'key');
422
+ builder.fail('issuer.discovery', (0, verifier_types_js_1.reasonCodeToErrorCode)(reason), {
423
+ error: jwksResult.error.message,
424
+ url: jwksResult.error.blockedUrl,
425
+ });
426
+ builder.failure(reason, normalizedIssuer, kid);
427
+ return {
428
+ valid: false,
429
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
430
+ };
431
+ }
432
+ // Store raw bytes for digest computation (only when not from cache)
433
+ if (jwksResult.rawBytes) {
434
+ jwksRawBytes = jwksResult.rawBytes;
435
+ }
436
+ builder.pass('issuer.discovery', {
437
+ from_cache: jwksResult.fromCache,
438
+ keys_count: jwksResult.jwks.keys.length,
439
+ });
440
+ // Find the key
441
+ const jwk = jwksResult.jwks.keys.find((k) => k.kid === kid);
442
+ if (!jwk) {
443
+ builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {
444
+ kid,
445
+ available_kids: jwksResult.jwks.keys.map((k) => k.kid),
446
+ });
447
+ builder.failure('key_not_found', normalizedIssuer, kid);
448
+ return {
449
+ valid: false,
450
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
451
+ };
452
+ }
453
+ publicKey = (0, crypto_1.jwkToPublicKeyBytes)(jwk);
454
+ keySource = 'jwks_discovery';
455
+ keyThumbprint = await (0, crypto_1.computeJwkThumbprint)(jwk);
456
+ builder.pass('key.resolve', { source: keySource, kid, thumbprint: keyThumbprint });
457
+ }
458
+ // ---------------------------------------------------------------------------
459
+ // Check 8: jws.signature - Verify signature
460
+ // ---------------------------------------------------------------------------
461
+ try {
462
+ const result = await (0, crypto_1.verify)(receiptJws, publicKey);
463
+ if (!result.valid) {
464
+ builder.fail('jws.signature', 'E_VERIFY_SIGNATURE_INVALID', {
465
+ error: 'Ed25519 signature verification failed',
466
+ });
467
+ builder.failure('signature_invalid', normalizedIssuer, kid);
468
+ return {
469
+ valid: false,
470
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
471
+ };
472
+ }
473
+ parsedClaims = result.payload;
474
+ builder.pass('jws.signature');
475
+ }
476
+ catch (err) {
477
+ builder.fail('jws.signature', 'E_VERIFY_SIGNATURE_INVALID', {
478
+ error: err instanceof Error ? err.message : String(err),
479
+ });
480
+ builder.failure('signature_invalid', normalizedIssuer, kid);
481
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
482
+ }
483
+ // ---------------------------------------------------------------------------
484
+ // Check 9: claims.time_window - Check iat/exp
485
+ // ---------------------------------------------------------------------------
486
+ const iatTolerance = 60; // 60 seconds tolerance for future iat
487
+ // Check iat (issued at) - required field per schema
488
+ if (parsedClaims.iat > nowSeconds + iatTolerance) {
489
+ builder.fail('claims.time_window', 'E_VERIFY_NOT_YET_VALID', {
490
+ error: 'Receipt issued in the future',
491
+ iat: parsedClaims.iat,
492
+ now: nowSeconds,
493
+ tolerance: iatTolerance,
494
+ });
495
+ builder.failure('not_yet_valid', normalizedIssuer, kid);
496
+ return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };
497
+ }
498
+ // Check exp (expiration) - no tolerance
499
+ if (parsedClaims.exp) {
500
+ if (parsedClaims.exp < nowSeconds) {
501
+ builder.fail('claims.time_window', 'E_VERIFY_EXPIRED', {
502
+ error: 'Receipt expired',
503
+ exp: parsedClaims.exp,
504
+ now: nowSeconds,
505
+ });
506
+ builder.failure('expired', normalizedIssuer, kid);
507
+ return {
508
+ valid: false,
509
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
510
+ };
511
+ }
512
+ }
513
+ builder.pass('claims.time_window', {
514
+ iat: parsedClaims.iat,
515
+ exp: parsedClaims.exp,
516
+ now: nowSeconds,
517
+ });
518
+ // ---------------------------------------------------------------------------
519
+ // Check 10: extensions.limits - Check extension sizes
520
+ // ---------------------------------------------------------------------------
521
+ // Check for oversized extensions in ext object
522
+ if (parsedClaims.ext) {
523
+ for (const [extKey, extValue] of Object.entries(parsedClaims.ext)) {
524
+ if (extValue !== undefined) {
525
+ const extJson = JSON.stringify(extValue);
526
+ if (extJson.length > policy.limits.max_extension_bytes) {
527
+ builder.fail('extensions.limits', 'E_VERIFY_EXTENSION_TOO_LARGE', {
528
+ extension: extKey,
529
+ size: extJson.length,
530
+ limit: policy.limits.max_extension_bytes,
531
+ });
532
+ builder.failure('extension_too_large', normalizedIssuer, kid);
533
+ return {
534
+ valid: false,
535
+ report: includeMeta ? builder.addTimestamp().build() : builder.build(),
536
+ };
537
+ }
538
+ }
539
+ }
540
+ }
541
+ builder.pass('extensions.limits');
542
+ // ---------------------------------------------------------------------------
543
+ // Success!
544
+ // ---------------------------------------------------------------------------
545
+ builder.success(normalizedIssuer, kid);
546
+ // Add JWKS artifacts for enterprise debuggability
547
+ // Map internal key source to artifact format
548
+ const artifactKeySource = keySource === 'pinned_keys' ? 'pinned' : 'jwks_fetch';
549
+ builder.addArtifact('issuer_key_source', artifactKeySource);
550
+ if (keyThumbprint) {
551
+ builder.addArtifact('issuer_key_thumbprint', keyThumbprint);
552
+ }
553
+ // Add JWKS digest when fetched (not from cache)
554
+ // Computed over raw bytes to avoid encoding round-trip issues
555
+ if (jwksRawBytes) {
556
+ const jwksDigestHex = await (0, crypto_1.sha256Hex)(jwksRawBytes);
557
+ builder.addArtifact('issuer_jwks_digest', (0, verifier_types_js_1.createDigest)(jwksDigestHex));
558
+ }
559
+ const report = includeMeta ? builder.addTimestamp().build() : builder.build();
560
+ return {
561
+ valid: true,
562
+ report,
563
+ claims: parsedClaims,
564
+ };
565
+ }
566
+ /**
567
+ * Clear the JWKS cache
568
+ */
569
+ function clearJWKSCache() {
570
+ jwksCache.clear();
571
+ }
572
+ /**
573
+ * Get JWKS cache size (for testing)
574
+ */
575
+ function getJWKSCacheSize() {
576
+ return jwksCache.size;
577
+ }
578
+ //# sourceMappingURL=verifier-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier-core.js","sourceRoot":"","sources":["../src/verifier-core.ts"],"names":[],"mappings":"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"}