@blamejs/core 0.14.1 → 0.14.2
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/CHANGELOG.md +2 -0
- package/lib/_test/crypto-fixtures.js +3 -3
- package/lib/a2a-tasks.js +18 -18
- package/lib/a2a.js +4 -4
- package/lib/acme.js +3 -3
- package/lib/agent-idempotency.js +1 -1
- package/lib/agent-orchestrator.js +8 -8
- package/lib/agent-posture-chain.js +2 -2
- package/lib/agent-saga.js +1 -1
- package/lib/agent-snapshot.js +1 -1
- package/lib/agent-stream.js +1 -1
- package/lib/agent-tenant.js +1 -1
- package/lib/agent-trace.js +3 -3
- package/lib/ai-capability.js +1 -1
- package/lib/ai-dp.js +4 -4
- package/lib/ai-input.js +3 -3
- package/lib/ai-model-manifest.js +7 -7
- package/lib/ai-pref.js +3 -3
- package/lib/archive-gz.js +2 -2
- package/lib/archive-read.js +25 -25
- package/lib/archive-tar-read.js +2 -2
- package/lib/archive-tar.js +20 -20
- package/lib/archive-wrap.js +10 -10
- package/lib/argon2-builtin.js +1 -1
- package/lib/asn1-der.js +34 -34
- package/lib/atomic-file.js +2 -2
- package/lib/audit-daily-review.js +3 -3
- package/lib/audit-sign.js +5 -5
- package/lib/audit-tools.js +1 -1
- package/lib/audit.js +2 -2
- package/lib/auth/acr-vocabulary.js +2 -2
- package/lib/auth/bot-challenge.js +3 -3
- package/lib/auth/ciba.js +7 -7
- package/lib/auth/dpop.js +3 -3
- package/lib/auth/fido-mds3.js +8 -8
- package/lib/auth/jwt-external.js +5 -5
- package/lib/auth/oauth.js +2 -2
- package/lib/auth/oid4vci.js +9 -9
- package/lib/auth/oid4vp.js +2 -2
- package/lib/auth/openid-federation.js +2 -2
- package/lib/auth/passkey.js +3 -3
- package/lib/auth/saml.js +23 -23
- package/lib/auth/sd-jwt-vc-disclosure.js +1 -1
- package/lib/auth/sd-jwt-vc.js +4 -4
- package/lib/auth/status-list.js +10 -10
- package/lib/auth/step-up.js +1 -1
- package/lib/auth-bot-challenge.js +1 -1
- package/lib/backup/index.js +7 -7
- package/lib/base32.js +8 -8
- package/lib/budr.js +2 -2
- package/lib/cache-status.js +2 -2
- package/lib/calendar.js +23 -23
- package/lib/cbor.js +12 -12
- package/lib/cdn-cache-control.js +1 -1
- package/lib/cert.js +5 -5
- package/lib/cloud-events.js +5 -5
- package/lib/cms-codec.js +21 -21
- package/lib/codepoint-class.js +12 -12
- package/lib/compliance-sanctions-fuzzy.js +4 -4
- package/lib/compliance-sanctions.js +4 -4
- package/lib/compliance.js +29 -29
- package/lib/content-credentials.js +36 -36
- package/lib/cookies.js +1 -1
- package/lib/cose.js +13 -13
- package/lib/cra-report.js +1 -1
- package/lib/crdt.js +1 -1
- package/lib/crypto-field.js +2 -2
- package/lib/crypto-xwing.js +7 -7
- package/lib/crypto.js +6 -6
- package/lib/csp.js +2 -2
- package/lib/cwt.js +4 -4
- package/lib/dark-patterns.js +2 -2
- package/lib/data-act.js +2 -2
- package/lib/db-file-lifecycle.js +4 -4
- package/lib/db-query.js +1 -1
- package/lib/db.js +6 -6
- package/lib/dbsc.js +13 -13
- package/lib/did.js +17 -17
- package/lib/dora.js +4 -4
- package/lib/dsr.js +1 -1
- package/lib/early-hints.js +2 -2
- package/lib/eat.js +4 -4
- package/lib/external-db-migrate.js +1 -1
- package/lib/external-db.js +1 -1
- package/lib/flag-cache.js +1 -1
- package/lib/flag-evaluation-context.js +2 -2
- package/lib/graphql-federation.js +4 -4
- package/lib/guard-agent-registry.js +5 -5
- package/lib/guard-archive.js +24 -24
- package/lib/guard-cidr.js +33 -33
- package/lib/guard-csv.js +1 -1
- package/lib/guard-domain.js +10 -10
- package/lib/guard-dsn.js +4 -4
- package/lib/guard-email.js +19 -19
- package/lib/guard-event-bus-payload.js +4 -4
- package/lib/guard-event-bus-topic.js +6 -6
- package/lib/guard-filename.js +7 -7
- package/lib/guard-graphql.js +9 -9
- package/lib/guard-html-wcag-tagwalk.js +1 -1
- package/lib/guard-html-wcag.js +4 -4
- package/lib/guard-html.js +7 -7
- package/lib/guard-idempotency-key.js +6 -6
- package/lib/guard-image.js +4 -4
- package/lib/guard-imap-command.js +17 -17
- package/lib/guard-jmap.js +20 -20
- package/lib/guard-json.js +12 -12
- package/lib/guard-jsonpath.js +3 -3
- package/lib/guard-jwt.js +4 -4
- package/lib/guard-list-id.js +7 -7
- package/lib/guard-list-unsubscribe.js +8 -8
- package/lib/guard-mail-compose.js +4 -4
- package/lib/guard-mail-move.js +5 -5
- package/lib/guard-mail-query.js +3 -3
- package/lib/guard-mail-reply.js +3 -3
- package/lib/guard-mail-sieve.js +6 -6
- package/lib/guard-managesieve-command.js +25 -25
- package/lib/guard-markdown.js +31 -31
- package/lib/guard-message-id.js +5 -5
- package/lib/guard-mime.js +1 -1
- package/lib/guard-oauth.js +3 -3
- package/lib/guard-pdf.js +6 -6
- package/lib/guard-pop3-command.js +11 -11
- package/lib/guard-posture-chain.js +5 -5
- package/lib/guard-regex.js +10 -10
- package/lib/guard-saga-config.js +5 -5
- package/lib/guard-smtp-command.js +6 -6
- package/lib/guard-snapshot-envelope.js +3 -3
- package/lib/guard-stream-args.js +4 -4
- package/lib/guard-svg.js +11 -11
- package/lib/guard-tenant-id.js +5 -5
- package/lib/guard-time.js +15 -15
- package/lib/guard-trace-context.js +4 -4
- package/lib/guard-uuid.js +11 -11
- package/lib/guard-xml.js +12 -12
- package/lib/guard-yaml.js +16 -16
- package/lib/honeytoken.js +5 -5
- package/lib/http-client.js +1 -1
- package/lib/http-message-signature.js +2 -2
- package/lib/iab-mspa.js +3 -3
- package/lib/iab-tcf.js +70 -70
- package/lib/inbox.js +4 -4
- package/lib/ip-utils.js +15 -15
- package/lib/jose-jwe-experimental.js +2 -2
- package/lib/json-path.js +3 -3
- package/lib/json-schema.js +1 -1
- package/lib/jsonapi.js +3 -3
- package/lib/jtd.js +2 -2
- package/lib/link-header.js +1 -1
- package/lib/local-db-thin.js +1 -1
- package/lib/log.js +1 -1
- package/lib/lro.js +4 -4
- package/lib/mail-agent.js +1 -1
- package/lib/mail-arc-sign.js +6 -6
- package/lib/mail-auth.js +43 -43
- package/lib/mail-bimi.js +3 -3
- package/lib/mail-crypto-pgp.js +31 -31
- package/lib/mail-crypto-smime.js +5 -5
- package/lib/mail-dav.js +1 -1
- package/lib/mail-deploy.js +39 -39
- package/lib/mail-dkim.js +11 -11
- package/lib/mail-greylist.js +12 -12
- package/lib/mail-helo.js +1 -1
- package/lib/mail-journal.js +8 -8
- package/lib/mail-rbl.js +7 -7
- package/lib/mail-scan.js +7 -7
- package/lib/mail-send-deliver.js +2 -2
- package/lib/mail-server-imap.js +12 -12
- package/lib/mail-server-jmap.js +16 -16
- package/lib/mail-server-managesieve.js +4 -4
- package/lib/mail-server-mx.js +17 -17
- package/lib/mail-server-pop3.js +4 -4
- package/lib/mail-server-rate-limit.js +2 -2
- package/lib/mail-server-submission.js +21 -21
- package/lib/mail-sieve.js +2 -2
- package/lib/mail-spam-score.js +5 -5
- package/lib/mail-srs.js +12 -12
- package/lib/mail-store-fts.js +2 -2
- package/lib/mail-store.js +8 -8
- package/lib/mail-unsubscribe.js +4 -4
- package/lib/mail.js +4 -4
- package/lib/mcp-tool-registry.js +4 -4
- package/lib/mcp.js +8 -8
- package/lib/mdoc.js +2 -2
- package/lib/metrics.js +8 -8
- package/lib/middleware/age-gate.js +1 -1
- package/lib/middleware/api-encrypt.js +7 -7
- package/lib/middleware/assetlinks.js +2 -2
- package/lib/middleware/asyncapi-serve.js +2 -2
- package/lib/middleware/bearer-auth.js +5 -5
- package/lib/middleware/body-parser.js +5 -5
- package/lib/middleware/compose-pipeline.js +15 -15
- package/lib/middleware/csp-report.js +4 -4
- package/lib/middleware/daily-byte-quota.js +1 -1
- package/lib/middleware/dpop.js +1 -1
- package/lib/middleware/headers.js +2 -2
- package/lib/middleware/host-allowlist.js +1 -1
- package/lib/middleware/idempotency-key.js +12 -12
- package/lib/middleware/nel.js +1 -1
- package/lib/middleware/openapi-serve.js +2 -2
- package/lib/middleware/protected-resource-metadata.js +2 -2
- package/lib/middleware/require-aal.js +1 -1
- package/lib/middleware/require-bound-key.js +2 -2
- package/lib/middleware/require-content-type.js +1 -1
- package/lib/middleware/require-methods.js +1 -1
- package/lib/middleware/require-step-up.js +2 -2
- package/lib/middleware/scim-server.js +1 -1
- package/lib/middleware/security-txt.js +3 -3
- package/lib/middleware/tus-upload.js +12 -12
- package/lib/middleware/web-app-manifest.js +2 -2
- package/lib/network-byte-quota.js +1 -1
- package/lib/network-dns-resolver.js +23 -23
- package/lib/network-dns.js +29 -29
- package/lib/network-dnssec.js +33 -33
- package/lib/network-smtp-policy.js +10 -10
- package/lib/network-tls.js +87 -87
- package/lib/network-tsig.js +33 -33
- package/lib/nis2-report.js +1 -1
- package/lib/ntp-check.js +3 -3
- package/lib/observability-otlp-exporter.js +17 -17
- package/lib/observability-tracer.js +6 -6
- package/lib/observability.js +8 -8
- package/lib/openapi-yaml.js +1 -1
- package/lib/openapi.js +1 -1
- package/lib/outbox.js +6 -6
- package/lib/pqc-agent.js +4 -4
- package/lib/pqc-software.js +1 -1
- package/lib/privacy-pass.js +5 -5
- package/lib/problem-details.js +5 -5
- package/lib/promise-pool.js +1 -1
- package/lib/protobuf-encoder.js +1 -1
- package/lib/redact.js +2 -2
- package/lib/request-helpers.js +1 -1
- package/lib/router.js +10 -10
- package/lib/safe-async.js +2 -2
- package/lib/safe-dns.js +71 -71
- package/lib/safe-ical.js +19 -19
- package/lib/safe-icap.js +24 -24
- package/lib/safe-jsonpath.js +2 -2
- package/lib/safe-mime.js +10 -10
- package/lib/safe-mount-info.js +3 -3
- package/lib/safe-redirect.js +1 -1
- package/lib/safe-sieve.js +23 -23
- package/lib/safe-smtp.js +1 -1
- package/lib/safe-vcard.js +14 -14
- package/lib/sandbox.js +5 -5
- package/lib/sec-cyber.js +1 -1
- package/lib/self-update-standalone-verifier.js +3 -3
- package/lib/self-update.js +3 -3
- package/lib/server-timing.js +3 -3
- package/lib/session-device-binding.js +7 -7
- package/lib/session.js +8 -8
- package/lib/standard-webhooks.js +4 -4
- package/lib/storage.js +2 -2
- package/lib/stream-throttle.js +1 -1
- package/lib/structured-fields.js +15 -15
- package/lib/subject.js +1 -1
- package/lib/tcpa-10dlc.js +1 -1
- package/lib/tenant-quota.js +3 -3
- package/lib/test-harness.js +1 -1
- package/lib/tracing.js +1 -1
- package/lib/tsa.js +5 -5
- package/lib/uri-template.js +5 -5
- package/lib/vault/index.js +2 -2
- package/lib/vault/seal-pem-file.js +4 -4
- package/lib/vc.js +2 -2
- package/lib/vendor-data.js +1 -1
- package/lib/watcher.js +4 -4
- package/lib/web-push-vapid.js +21 -21
- package/lib/webhook.js +2 -2
- package/lib/websocket.js +3 -3
- package/lib/worker-pool.js +3 -3
- package/lib/ws-client.js +24 -24
- package/lib/xml-c14n.js +2 -2
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -97,7 +97,7 @@ var MAX_TOKEN_BYTES = C.BYTES.kib(4);
|
|
|
97
97
|
// headroom; operators can override per-call but cannot drop below
|
|
98
98
|
// MIN_TIMEOUT_MS without the create() factory refusing the opts.
|
|
99
99
|
var DEFAULT_TIMEOUT_MS = C.TIME.seconds(5);
|
|
100
|
-
var MIN_TIMEOUT_MS = 500; // anti-misconfiguration floor //
|
|
100
|
+
var MIN_TIMEOUT_MS = 500; // anti-misconfiguration floor // 500ms wall-clock floor, not a byte literal
|
|
101
101
|
|
|
102
102
|
// Response-body cap. Provider siteverify responses are small JSON
|
|
103
103
|
// (well under 4 KiB); a multi-MiB response is either a redirect to
|
|
@@ -116,7 +116,7 @@ var EXPECTED_CONTENT_TYPE_PREFIX = "application/json";
|
|
|
116
116
|
// the surfaced bytes are not the secret token (≈ 48 bits visible vs.
|
|
117
117
|
// ~2 KiB total), but large enough to cluster verifications belonging
|
|
118
118
|
// to the same widget render in a debug session.
|
|
119
|
-
var TOKEN_PREFIX_AUDIT_CHARS = 8; //
|
|
119
|
+
var TOKEN_PREFIX_AUDIT_CHARS = 8; // debug-prefix length, not a byte literal
|
|
120
120
|
|
|
121
121
|
// ---- provider catalog ----
|
|
122
122
|
//
|
|
@@ -440,7 +440,7 @@ function create(opts) {
|
|
|
440
440
|
"siteverify transport failure: " + ((e && e.message) || String(e)));
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
-
if (res.statusCode < 200 || res.statusCode >= 300) { //
|
|
443
|
+
if (res.statusCode < 200 || res.statusCode >= 300) { // HTTP 2xx range bounds
|
|
444
444
|
_safeAudit(safeEmit, "auth.bot_challenge.verify", "failure", {
|
|
445
445
|
provider: providerKey, ok: false, reason: "non-2xx",
|
|
446
446
|
statusCode: res.statusCode, prefix: tokenPrefix,
|
package/lib/auth/ciba.js
CHANGED
|
@@ -174,7 +174,7 @@ function create(opts) {
|
|
|
174
174
|
// 2026-05-11). CIBA §7.1.2 requires the token be opaque + hard to
|
|
175
175
|
// guess; the framework's other token-shaped primitives enforce 32
|
|
176
176
|
// chars minimum. A 4-char token was previously accepted; refuse.
|
|
177
|
-
if (clientNotificationToken !== null && clientNotificationToken.length < 32) { //
|
|
177
|
+
if (clientNotificationToken !== null && clientNotificationToken.length < 32) { // RFC 9700 §7.1.2 token char-length minimum, not bytes
|
|
178
178
|
throw new AuthError("auth-ciba/notification-token-too-short",
|
|
179
179
|
"auth.ciba.client.create: clientNotificationToken must be >= 32 chars " +
|
|
180
180
|
"(generate via b.crypto.generateToken(32) or stronger; CIBA §7.1.2 " +
|
|
@@ -239,7 +239,7 @@ function create(opts) {
|
|
|
239
239
|
(cc >= 0x200b && cc <= 0x200f) ||
|
|
240
240
|
(cc >= 0x202a && cc <= 0x202e) ||
|
|
241
241
|
(cc >= 0x2066 && cc <= 0x2069) ||
|
|
242
|
-
cc === 0xfeff) { //
|
|
242
|
+
cc === 0xfeff) { // codepoint constants for control / bidi / zero-width / BOM
|
|
243
243
|
throw new AuthError("auth-ciba/binding-message-control-chars",
|
|
244
244
|
"ciba: bindingMessage contains control / bidi / zero-width characters");
|
|
245
245
|
}
|
|
@@ -278,7 +278,7 @@ function create(opts) {
|
|
|
278
278
|
var err;
|
|
279
279
|
try { err = safeJson.parse(bodyText, { maxBytes: MAX_RESPONSE_BYTES }); } catch (_e) { /* silent-catch: non-JSON IdP error body falls through to the bodyText snippet path below */ }
|
|
280
280
|
var code = (err && err.error) || ("http-" + res.statusCode);
|
|
281
|
-
var msg = (err && (err.error_description || err.error)) || bodyText.slice(0, 200); //
|
|
281
|
+
var msg = (err && (err.error_description || err.error)) || bodyText.slice(0, 200); // error-message snippet length
|
|
282
282
|
var aerr = new AuthError("auth-ciba/" + code, "ciba: " + msg);
|
|
283
283
|
aerr.cibaError = err || null;
|
|
284
284
|
aerr.statusCode = res.statusCode;
|
|
@@ -355,8 +355,8 @@ function create(opts) {
|
|
|
355
355
|
if (clientAuth === "jwt") {
|
|
356
356
|
var assertion = await opts.clientAssertionSigner({
|
|
357
357
|
iss: opts.clientId, sub: opts.clientId, aud: endpoint,
|
|
358
|
-
iat: Math.floor(Date.now() / 1000), //
|
|
359
|
-
exp: Math.floor(Date.now() / 1000) + 300, //
|
|
358
|
+
iat: Math.floor(Date.now() / 1000), // ms→s
|
|
359
|
+
exp: Math.floor(Date.now() / 1000) + 300, // assertion 5m TTL
|
|
360
360
|
jti: generateToken(16),
|
|
361
361
|
});
|
|
362
362
|
body.set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
|
|
@@ -465,8 +465,8 @@ function create(opts) {
|
|
|
465
465
|
if (clientAuth === "jwt") {
|
|
466
466
|
var assertion = await opts.clientAssertionSigner({
|
|
467
467
|
iss: opts.clientId, sub: opts.clientId, aud: endpoint,
|
|
468
|
-
iat: Math.floor(Date.now() / 1000), //
|
|
469
|
-
exp: Math.floor(Date.now() / 1000) + 300, //
|
|
468
|
+
iat: Math.floor(Date.now() / 1000), // ms→s
|
|
469
|
+
exp: Math.floor(Date.now() / 1000) + 300, // assertion 5m TTL
|
|
470
470
|
jti: generateToken(16),
|
|
471
471
|
});
|
|
472
472
|
body.set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
|
package/lib/auth/dpop.js
CHANGED
|
@@ -131,9 +131,9 @@ function _signParamsForAlg(alg) {
|
|
|
131
131
|
if (alg === "RS256") return { hash: "sha256", padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
|
132
132
|
if (alg === "RS384") return { hash: "sha384", padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
|
133
133
|
if (alg === "RS512") return { hash: "sha512", padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
|
134
|
-
if (alg === "PS256") return { hash: "sha256", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 32 }; //
|
|
135
|
-
if (alg === "PS384") return { hash: "sha384", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 48 }; //
|
|
136
|
-
if (alg === "PS512") return { hash: "sha512", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 64 }; //
|
|
134
|
+
if (alg === "PS256") return { hash: "sha256", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 32 }; // RFC 7518 PS256 salt length
|
|
135
|
+
if (alg === "PS384") return { hash: "sha384", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 48 }; // RFC 7518 PS384 salt length
|
|
136
|
+
if (alg === "PS512") return { hash: "sha512", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 64 }; // RFC 7518 PS512 salt length
|
|
137
137
|
if (alg === "ES256") return { hash: "sha256", dsaEncoding: "ieee-p1363" };
|
|
138
138
|
if (alg === "ES384") return { hash: "sha384", dsaEncoding: "ieee-p1363" };
|
|
139
139
|
if (alg === "ES512") return { hash: "sha512", dsaEncoding: "ieee-p1363" };
|
package/lib/auth/fido-mds3.js
CHANGED
|
@@ -97,7 +97,7 @@ function _b64urlDecode(s) {
|
|
|
97
97
|
// node:crypto.X509Certificate accepts it.
|
|
98
98
|
function _derToPem(b64) {
|
|
99
99
|
var lines = [];
|
|
100
|
-
for (var i = 0; i < b64.length; i += 64) lines.push(b64.slice(i, i + 64)); //
|
|
100
|
+
for (var i = 0; i < b64.length; i += 64) lines.push(b64.slice(i, i + 64)); // RFC 7468 PEM line width
|
|
101
101
|
return "-----BEGIN CERTIFICATE-----\n" + lines.join("\n") +
|
|
102
102
|
"\n-----END CERTIFICATE-----\n";
|
|
103
103
|
}
|
|
@@ -145,9 +145,9 @@ function _verifyParamsForAlg(alg) {
|
|
|
145
145
|
case "RS256": return { hash: "sha256", padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
|
146
146
|
case "RS384": return { hash: "sha384", padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
|
147
147
|
case "RS512": return { hash: "sha512", padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
|
148
|
-
case "PS256": return { hash: "sha256", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 32 }; //
|
|
149
|
-
case "PS384": return { hash: "sha384", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 48 }; //
|
|
150
|
-
case "PS512": return { hash: "sha512", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 64 }; //
|
|
148
|
+
case "PS256": return { hash: "sha256", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 32 }; // SHA-256 hash length
|
|
149
|
+
case "PS384": return { hash: "sha384", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 48 }; // SHA-384 hash length
|
|
150
|
+
case "PS512": return { hash: "sha512", padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 64 }; // SHA-512 hash length
|
|
151
151
|
case "ES256": return { hash: "sha256", dsaEncoding: "ieee-p1363" };
|
|
152
152
|
case "ES384": return { hash: "sha384", dsaEncoding: "ieee-p1363" };
|
|
153
153
|
case "ES512": return { hash: "sha512", dsaEncoding: "ieee-p1363" };
|
|
@@ -292,7 +292,7 @@ function _getCache() {
|
|
|
292
292
|
_sharedCache = cache().create({
|
|
293
293
|
namespace: "auth-fido-mds3.blob",
|
|
294
294
|
ttlMs: MAX_CACHE_TTL_MS,
|
|
295
|
-
maxEntries: 8, //
|
|
295
|
+
maxEntries: 8, // operator-pinned URL set
|
|
296
296
|
});
|
|
297
297
|
return _sharedCache;
|
|
298
298
|
}
|
|
@@ -315,7 +315,7 @@ function _ttlFromNextUpdate(nextUpdateDate) {
|
|
|
315
315
|
// valid future timestamp and influence the cache-TTL clamp downstream.
|
|
316
316
|
function _parseNextUpdate(s) {
|
|
317
317
|
if (typeof s !== "string") return null;
|
|
318
|
-
var m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/); //
|
|
318
|
+
var m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/); // ISO-8601 date components
|
|
319
319
|
if (!m) return null;
|
|
320
320
|
var year = parseInt(m[1], 10);
|
|
321
321
|
var month = parseInt(m[2], 10) - 1;
|
|
@@ -464,7 +464,7 @@ async function fetch(opts) { // allow:raw-outbound-http — function name is f
|
|
|
464
464
|
throw new FidoMds3Error("fido-mds3/network",
|
|
465
465
|
"BLOB GET " + url + " failed: " + ((e && e.message) || String(e)));
|
|
466
466
|
}
|
|
467
|
-
if (rsp.statusCode < 200 || rsp.statusCode >= 300) { //
|
|
467
|
+
if (rsp.statusCode < 200 || rsp.statusCode >= 300) { // HTTP 2xx range
|
|
468
468
|
throw new FidoMds3Error("fido-mds3/bad-status",
|
|
469
469
|
"BLOB GET " + url + " returned " + rsp.statusCode);
|
|
470
470
|
}
|
|
@@ -539,7 +539,7 @@ function lookupAaguid(blob, aaguid) {
|
|
|
539
539
|
throw new FidoMds3Error("fido-mds3/bad-aaguid", "aaguid must be a non-empty string");
|
|
540
540
|
}
|
|
541
541
|
var canon = aaguid.replace(/-/g, "").toLowerCase();
|
|
542
|
-
if (!safeBuffer.isHex(canon, 32)) { //
|
|
542
|
+
if (!safeBuffer.isHex(canon, 32)) { // 32 = AAGUID hex-char count, not bytes
|
|
543
543
|
throw new FidoMds3Error("fido-mds3/bad-aaguid",
|
|
544
544
|
"aaguid must be a UUID (with or without dashes)");
|
|
545
545
|
}
|
package/lib/auth/jwt-external.js
CHANGED
|
@@ -75,9 +75,9 @@ var MAX_TOKEN_BYTES = C.BYTES.kib(16);
|
|
|
75
75
|
var REFUSED_ALGS = ["HS256", "HS384", "HS512", "none"];
|
|
76
76
|
|
|
77
77
|
// PSS salt lengths per RFC 7518 §3.5.
|
|
78
|
-
var PSS_SALT_SHA256 = 32; //
|
|
79
|
-
var PSS_SALT_SHA384 = 48; //
|
|
80
|
-
var PSS_SALT_SHA512 = 64; //
|
|
78
|
+
var PSS_SALT_SHA256 = 32; // RFC 7518 SHA-256 salt length
|
|
79
|
+
var PSS_SALT_SHA384 = 48; // RFC 7518 SHA-384 salt length
|
|
80
|
+
var PSS_SALT_SHA512 = 64; // RFC 7518 SHA-512 salt length
|
|
81
81
|
|
|
82
82
|
var SUPPORTED_CLASSICAL_ALGS = [
|
|
83
83
|
"RS256", "RS384", "RS512",
|
|
@@ -105,7 +105,7 @@ function _b64urlDecode(s) {
|
|
|
105
105
|
throw new AuthError("auth-jwt-external/bad-base64", "expected base64url string");
|
|
106
106
|
}
|
|
107
107
|
var padded = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
108
|
-
while (padded.length % 4) padded += "="; //
|
|
108
|
+
while (padded.length % 4) padded += "="; // base64 quartet padding
|
|
109
109
|
return Buffer.from(padded, "base64");
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -241,7 +241,7 @@ async function _fetchJwks(uri, cacheMs) {
|
|
|
241
241
|
maxBytes: MAX_JWKS_BYTES,
|
|
242
242
|
timeoutMs: C.TIME.seconds(10),
|
|
243
243
|
});
|
|
244
|
-
if (res.statusCode < 200 || res.statusCode >= 300) { //
|
|
244
|
+
if (res.statusCode < 200 || res.statusCode >= 300) { // HTTP 2xx range
|
|
245
245
|
throw new AuthError("auth-jwt-external/jwks-fetch-failed",
|
|
246
246
|
"JWKS endpoint " + uri + " returned " + res.statusCode);
|
|
247
247
|
}
|
package/lib/auth/oauth.js
CHANGED
|
@@ -1297,7 +1297,7 @@ function create(opts) {
|
|
|
1297
1297
|
if (!rv || typeof rv.request_uri !== "string" || rv.request_uri.length === 0) {
|
|
1298
1298
|
throw new OAuthError("auth-oauth/par-bad-response",
|
|
1299
1299
|
"pushAuthorizationRequest: IdP did not return a request_uri (got " +
|
|
1300
|
-
JSON.stringify(rv).slice(0, 200) + ")"); //
|
|
1300
|
+
JSON.stringify(rv).slice(0, 200) + ")"); // error-message snippet length
|
|
1301
1301
|
}
|
|
1302
1302
|
// Build the browser-side redirect URL: /authorize?client_id=...&request_uri=...
|
|
1303
1303
|
var authzEndpoint = await _resolveEndpoint("authorizationEndpoint");
|
|
@@ -1951,7 +1951,7 @@ function create(opts) {
|
|
|
1951
1951
|
}
|
|
1952
1952
|
// Terminal errors.
|
|
1953
1953
|
throw new OAuthError("auth-oauth/device-" + (err || "unknown"),
|
|
1954
|
-
"pollDeviceCode: " + (parsed && parsed.error_description ? parsed.error_description : text.slice(0, 200))); //
|
|
1954
|
+
"pollDeviceCode: " + (parsed && parsed.error_description ? parsed.error_description : text.slice(0, 200))); // 200-char error-snippet cap, not bytes
|
|
1955
1955
|
}
|
|
1956
1956
|
throw new OAuthError("auth-oauth/device-poll-timeout",
|
|
1957
1957
|
"pollDeviceCode: exceeded maxWaitMs " + (popts.maxWaitMs || C.TIME.minutes(10)));
|
package/lib/auth/oid4vci.js
CHANGED
|
@@ -98,7 +98,7 @@ function _verifyProofJwt(proofJwt, expectedAud, expectedCNonce, expectedClientId
|
|
|
98
98
|
}
|
|
99
99
|
var header, payload;
|
|
100
100
|
try {
|
|
101
|
-
header = safeJson.parse(_b64uDecodeStr(parts[0]), { maxBytes: 4096 }); //
|
|
101
|
+
header = safeJson.parse(_b64uDecodeStr(parts[0]), { maxBytes: 4096 }); // proof header cap
|
|
102
102
|
payload = safeJson.parse(_b64uDecodeStr(parts[1]), { maxBytes: MAX_PROOF_BYTES });
|
|
103
103
|
} catch (e) {
|
|
104
104
|
throw new AuthError("auth-oid4vci/bad-proof-decode",
|
|
@@ -367,7 +367,7 @@ function create(opts) {
|
|
|
367
367
|
"createCredentialOffer: credentialId \"" + id + "\" not in supportedCredentials");
|
|
368
368
|
}
|
|
369
369
|
});
|
|
370
|
-
var preAuthCode = generateToken(32); //
|
|
370
|
+
var preAuthCode = generateToken(32); // 256-bit single-use pre-auth code
|
|
371
371
|
var txCode = coOpts.txCode || null;
|
|
372
372
|
if (txCode !== null) {
|
|
373
373
|
if (typeof txCode !== "object" || typeof txCode.value !== "string") {
|
|
@@ -388,7 +388,7 @@ function create(opts) {
|
|
|
388
388
|
"urn:ietf:params:oauth:grant-type:pre-authorized_code": {
|
|
389
389
|
"pre-authorized_code": preAuthCode,
|
|
390
390
|
tx_code: txCode ? {
|
|
391
|
-
length: typeof txCode.length === "number" ? txCode.length : 4, //
|
|
391
|
+
length: typeof txCode.length === "number" ? txCode.length : 4, // default tx-code 4 digits
|
|
392
392
|
input_mode: txCode.input_mode || "numeric",
|
|
393
393
|
description: txCode.description || undefined,
|
|
394
394
|
} : undefined,
|
|
@@ -467,8 +467,8 @@ function create(opts) {
|
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
await codeStore.delete(eopts.preAuthCode);
|
|
470
|
-
var accessToken = generateToken(32); //
|
|
471
|
-
var cNonce = generateToken(16); //
|
|
470
|
+
var accessToken = generateToken(32); // 256-bit access token
|
|
471
|
+
var cNonce = generateToken(16); // 128-bit c_nonce
|
|
472
472
|
var record = {
|
|
473
473
|
subject: entry.subject,
|
|
474
474
|
credentialIds: entry.credentialIds,
|
|
@@ -485,9 +485,9 @@ function create(opts) {
|
|
|
485
485
|
return {
|
|
486
486
|
access_token: accessToken,
|
|
487
487
|
token_type: "Bearer",
|
|
488
|
-
expires_in: Math.floor(accessTokenTtl / 1000), //
|
|
488
|
+
expires_in: Math.floor(accessTokenTtl / 1000), // ms→s
|
|
489
489
|
c_nonce: cNonce,
|
|
490
|
-
c_nonce_expires_in: Math.floor(cNonceTtl / 1000), //
|
|
490
|
+
c_nonce_expires_in: Math.floor(cNonceTtl / 1000), // ms→s
|
|
491
491
|
authorization_details: entry.credentialIds.map(function (id) {
|
|
492
492
|
return {
|
|
493
493
|
type: "openid_credential",
|
|
@@ -572,7 +572,7 @@ function create(opts) {
|
|
|
572
572
|
|
|
573
573
|
// Rotate c_nonce so a replayed proof-JWT for a follow-up
|
|
574
574
|
// batch_credential request is rejected.
|
|
575
|
-
var newCNonce = generateToken(16); //
|
|
575
|
+
var newCNonce = generateToken(16); // 128-bit c_nonce
|
|
576
576
|
await cNonceStore.set(iopts.accessToken, newCNonce);
|
|
577
577
|
|
|
578
578
|
// AUTH-6 — when single-use is on (default), DELETE the access token
|
|
@@ -600,7 +600,7 @@ function create(opts) {
|
|
|
600
600
|
format: spec.format,
|
|
601
601
|
credential: sdJwtToken.token,
|
|
602
602
|
c_nonce: newCNonce,
|
|
603
|
-
c_nonce_expires_in: Math.floor(cNonceTtl / 1000), //
|
|
603
|
+
c_nonce_expires_in: Math.floor(cNonceTtl / 1000), // ms→s
|
|
604
604
|
};
|
|
605
605
|
}
|
|
606
606
|
|
package/lib/auth/oid4vp.js
CHANGED
|
@@ -348,8 +348,8 @@ function create(opts) {
|
|
|
348
348
|
"createRequest: dcql is required");
|
|
349
349
|
}
|
|
350
350
|
_validateDcql(ropts.dcql);
|
|
351
|
-
var nonce = ropts.nonce || generateToken(16); //
|
|
352
|
-
var state = ropts.state || generateToken(16); //
|
|
351
|
+
var nonce = ropts.nonce || generateToken(16); // 128-bit nonce
|
|
352
|
+
var state = ropts.state || generateToken(16); // 128-bit state
|
|
353
353
|
var request = {
|
|
354
354
|
response_type: "vp_token",
|
|
355
355
|
response_mode: ropts.responseMode || "direct_post",
|
|
@@ -82,7 +82,7 @@ var _emitMetric = emit.metric;
|
|
|
82
82
|
|
|
83
83
|
var SUPPORTED_ALGS = ["ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "RS256", "EdDSA"];
|
|
84
84
|
var MAX_STATEMENT_BYTES = 64 * 1024; // allow:raw-byte-literal — entity-statement size cap
|
|
85
|
-
var MAX_CHAIN_DEPTH = 10; //
|
|
85
|
+
var MAX_CHAIN_DEPTH = 10; // federation chain depth ceiling
|
|
86
86
|
|
|
87
87
|
function _b64uDecodeStr(s) { return Buffer.from(s, "base64url").toString("utf8"); }
|
|
88
88
|
|
|
@@ -117,7 +117,7 @@ function parseEntityStatement(jwt) {
|
|
|
117
117
|
}
|
|
118
118
|
var header, payload;
|
|
119
119
|
try {
|
|
120
|
-
header = safeJson.parse(_b64uDecodeStr(parts[0]), { maxBytes: 4096 }); //
|
|
120
|
+
header = safeJson.parse(_b64uDecodeStr(parts[0]), { maxBytes: 4096 }); // header cap
|
|
121
121
|
payload = safeJson.parse(_b64uDecodeStr(parts[1]), { maxBytes: MAX_STATEMENT_BYTES });
|
|
122
122
|
} catch (e) {
|
|
123
123
|
throw new AuthError("auth-openid-federation/bad-decode",
|
package/lib/auth/passkey.js
CHANGED
|
@@ -64,7 +64,7 @@ var { AuthError } = require("../framework-error");
|
|
|
64
64
|
// W3C WebAuthn name field cap — same as the rpName/userName ceiling in
|
|
65
65
|
// the spec's CredentialUserEntity / PublicKeyCredentialEntity dictionaries
|
|
66
66
|
// (no normative limit but RPs broadly cap at 256 to defeat DOM cost).
|
|
67
|
-
var MAX_NAME_LEN = 256; //
|
|
67
|
+
var MAX_NAME_LEN = 256; // UTF-16 codepoint count, not bytes
|
|
68
68
|
|
|
69
69
|
function _vendor() {
|
|
70
70
|
return _wa;
|
|
@@ -306,7 +306,7 @@ async function conditionalAuthOptions(opts) {
|
|
|
306
306
|
|
|
307
307
|
// CTAP2.1 §6.5 — PRF eval inputs are 32-byte salts. Caps every
|
|
308
308
|
// extension input that ships through the binary normalizer.
|
|
309
|
-
var MAX_EXT_INPUT_BYTES = 32; //
|
|
309
|
+
var MAX_EXT_INPUT_BYTES = 32; // CTAP2.1 §6.5 PRF salt length
|
|
310
310
|
|
|
311
311
|
function _b64urlExtInput(value, name, maxBytes) {
|
|
312
312
|
// Accept a base64url string OR a Buffer / Uint8Array. Normalize the
|
|
@@ -436,7 +436,7 @@ function _credBlobExt(args) {
|
|
|
436
436
|
throw new AuthError("auth-passkey/bad-credblob",
|
|
437
437
|
"extensions.credBlob blob must be a Uint8Array / Buffer");
|
|
438
438
|
}
|
|
439
|
-
if (buf.length === 0 || buf.length > 32) { //
|
|
439
|
+
if (buf.length === 0 || buf.length > 32) { // CTAP2.1 §11.1 credBlob max
|
|
440
440
|
throw new AuthError("auth-passkey/credblob-bad-length",
|
|
441
441
|
"extensions.credBlob blob must be 1-32 bytes (CTAP2.1 §11.1)");
|
|
442
442
|
}
|
package/lib/auth/saml.js
CHANGED
|
@@ -592,7 +592,7 @@ function create(opts) {
|
|
|
592
592
|
var nameId = _textContent(nameIdEl);
|
|
593
593
|
var nameIdFormat = _attr(nameIdEl, "Format");
|
|
594
594
|
|
|
595
|
-
var nowSec = Math.floor((vopts.now || Date.now()) / 1000); //
|
|
595
|
+
var nowSec = Math.floor((vopts.now || Date.now()) / 1000); // ms→s
|
|
596
596
|
var confirmations = _findAllChildren(subject, "SubjectConfirmation", SAML_NS.assertion);
|
|
597
597
|
var bearerOk = false;
|
|
598
598
|
var hokOk = false;
|
|
@@ -684,10 +684,10 @@ function create(opts) {
|
|
|
684
684
|
// as Bearer (Profile §3.1 incorporates §3 by reference).
|
|
685
685
|
var nbHok = _attr(scdHok, "NotBefore");
|
|
686
686
|
var noaHok = _attr(scdHok, "NotOnOrAfter");
|
|
687
|
-
if (nbHok && isFinite(Date.parse(nbHok) / 1000) && //
|
|
688
|
-
Date.parse(nbHok) / 1000 > nowSec + clockSkewSec) continue; //
|
|
689
|
-
if (noaHok && isFinite(Date.parse(noaHok) / 1000) && //
|
|
690
|
-
Date.parse(noaHok) / 1000 < nowSec - clockSkewSec) continue; //
|
|
687
|
+
if (nbHok && isFinite(Date.parse(nbHok) / 1000) && // ms→s
|
|
688
|
+
Date.parse(nbHok) / 1000 > nowSec + clockSkewSec) continue; // ms→s
|
|
689
|
+
if (noaHok && isFinite(Date.parse(noaHok) / 1000) && // ms→s
|
|
690
|
+
Date.parse(noaHok) / 1000 < nowSec - clockSkewSec) continue; // ms→s
|
|
691
691
|
var recipHok = _attr(scdHok, "Recipient");
|
|
692
692
|
if (recipHok && recipHok !== opts.assertionConsumerServiceUrl) continue;
|
|
693
693
|
hokOk = true;
|
|
@@ -698,14 +698,14 @@ function create(opts) {
|
|
|
698
698
|
if (!scd) continue;
|
|
699
699
|
var notOnOrAfter = _attr(scd, "NotOnOrAfter");
|
|
700
700
|
if (notOnOrAfter) {
|
|
701
|
-
var t = Date.parse(notOnOrAfter) / 1000; //
|
|
701
|
+
var t = Date.parse(notOnOrAfter) / 1000; // ms→s
|
|
702
702
|
if (!isFinite(t) || t < nowSec - clockSkewSec) {
|
|
703
703
|
continue; // expired confirmation — try next
|
|
704
704
|
}
|
|
705
705
|
}
|
|
706
706
|
var notBefore = _attr(scd, "NotBefore");
|
|
707
707
|
if (notBefore) {
|
|
708
|
-
var nb = Date.parse(notBefore) / 1000; //
|
|
708
|
+
var nb = Date.parse(notBefore) / 1000; // ms→s
|
|
709
709
|
if (isFinite(nb) && nb > nowSec + clockSkewSec) continue;
|
|
710
710
|
}
|
|
711
711
|
var recipient = _attr(scd, "Recipient");
|
|
@@ -741,14 +741,14 @@ function create(opts) {
|
|
|
741
741
|
var cNotBefore = _attr(conditions, "NotBefore");
|
|
742
742
|
var cNotOnOrAfter = _attr(conditions, "NotOnOrAfter");
|
|
743
743
|
if (cNotBefore) {
|
|
744
|
-
var cnb = Date.parse(cNotBefore) / 1000; //
|
|
744
|
+
var cnb = Date.parse(cNotBefore) / 1000; // ms→s
|
|
745
745
|
if (isFinite(cnb) && cnb > nowSec + clockSkewSec) {
|
|
746
746
|
throw new AuthError("auth-saml/conditions-not-yet-valid",
|
|
747
747
|
"Conditions NotBefore is in the future");
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
750
|
if (cNotOnOrAfter) {
|
|
751
|
-
var cnoa = Date.parse(cNotOnOrAfter) / 1000; //
|
|
751
|
+
var cnoa = Date.parse(cNotOnOrAfter) / 1000; // ms→s
|
|
752
752
|
if (isFinite(cnoa) && cnoa < nowSec - clockSkewSec) {
|
|
753
753
|
throw new AuthError("auth-saml/conditions-expired",
|
|
754
754
|
"Conditions NotOnOrAfter has passed");
|
|
@@ -888,7 +888,7 @@ function create(opts) {
|
|
|
888
888
|
throw new AuthError("auth-saml/no-idp-slo",
|
|
889
889
|
"buildLogoutRequest: opts.idpSloUrl (or sp.create's opts.idpSloUrl) required");
|
|
890
890
|
}
|
|
891
|
-
var id = "_" + generateToken(20); //
|
|
891
|
+
var id = "_" + generateToken(20); // 20-byte SAML ID token
|
|
892
892
|
var issueInstant = new Date().toISOString();
|
|
893
893
|
var c14n = xmlC14n();
|
|
894
894
|
var nameIdFormatAttr = bopts.nameIdFormat
|
|
@@ -1089,7 +1089,7 @@ function create(opts) {
|
|
|
1089
1089
|
validateOpts.requireNonEmptyString(bopts.inResponseTo, "inResponseTo", AuthError, "auth-saml/no-in-response-to");
|
|
1090
1090
|
validateOpts.requireNonEmptyString(bopts.destination, "destination", AuthError, "auth-saml/no-destination");
|
|
1091
1091
|
var statusCode = bopts.statusCode || "urn:oasis:names:tc:SAML:2.0:status:Success";
|
|
1092
|
-
var id = "_" + generateToken(20); //
|
|
1092
|
+
var id = "_" + generateToken(20); // 20-byte SAML ID token
|
|
1093
1093
|
var issueInstant = new Date().toISOString();
|
|
1094
1094
|
var c14n = xmlC14n();
|
|
1095
1095
|
var xml =
|
|
@@ -1292,7 +1292,7 @@ function create(opts) {
|
|
|
1292
1292
|
throw new AuthError("auth-saml/no-idp-slo",
|
|
1293
1293
|
"buildLogoutRequestPost: opts.idpSloUrl required");
|
|
1294
1294
|
}
|
|
1295
|
-
var id = "_" + generateToken(20); //
|
|
1295
|
+
var id = "_" + generateToken(20); // 20-byte SAML ID token
|
|
1296
1296
|
var issueInstant = new Date().toISOString();
|
|
1297
1297
|
var c14n = xmlC14n();
|
|
1298
1298
|
var nameIdFormatAttr = bopts.nameIdFormat
|
|
@@ -1667,18 +1667,18 @@ function _decryptEncryptedAssertion(encAssertion, spPrivateKeyPem) {
|
|
|
1667
1667
|
var clearBytes;
|
|
1668
1668
|
if (contentAlg === "http://www.w3.org/2009/xmlenc11#aes128-gcm" ||
|
|
1669
1669
|
contentAlg === "http://www.w3.org/2009/xmlenc11#aes256-gcm") {
|
|
1670
|
-
var aesBits = contentAlg.indexOf("aes128") !== -1 ? 128 : 256; //
|
|
1671
|
-
var expectedKeyBytes = aesBits / 8; //
|
|
1670
|
+
var aesBits = contentAlg.indexOf("aes128") !== -1 ? 128 : 256; // AES key size
|
|
1671
|
+
var expectedKeyBytes = aesBits / 8; // bits→bytes
|
|
1672
1672
|
if (cek.length !== expectedKeyBytes) {
|
|
1673
1673
|
throw new AuthError("auth-saml/encrypted-wrong-cek-len",
|
|
1674
1674
|
"AES-" + aesBits + "-GCM CEK length is " + cek.length + ", expected " + expectedKeyBytes);
|
|
1675
1675
|
}
|
|
1676
|
-
if (contentBlob.length < 28) { //
|
|
1676
|
+
if (contentBlob.length < 28) { // 12 IV + 16 tag
|
|
1677
1677
|
throw new AuthError("auth-saml/encrypted-content-too-short",
|
|
1678
1678
|
"AES-GCM CipherValue too short to contain IV (12) + tag (16)");
|
|
1679
1679
|
}
|
|
1680
|
-
var iv = contentBlob.subarray(0, 12); //
|
|
1681
|
-
var tag = contentBlob.subarray(contentBlob.length - 16); //
|
|
1680
|
+
var iv = contentBlob.subarray(0, 12); // GCM IV size
|
|
1681
|
+
var tag = contentBlob.subarray(contentBlob.length - 16); // GCM tag size
|
|
1682
1682
|
var ct = contentBlob.subarray(12, contentBlob.length - 16);
|
|
1683
1683
|
var decipher = nodeCrypto.createDecipheriv("aes-" + aesBits + "-gcm", cek, iv);
|
|
1684
1684
|
decipher.setAuthTag(tag);
|
|
@@ -1688,16 +1688,16 @@ function _decryptEncryptedAssertion(encAssertion, spPrivateKeyPem) {
|
|
|
1688
1688
|
"AES-GCM authentication tag mismatch: " + ((eD && eD.message) || String(eD)));
|
|
1689
1689
|
}
|
|
1690
1690
|
} else if (contentAlg === "urn:blamejs:experimental:xmlenc:xchacha20-poly1305") {
|
|
1691
|
-
if (cek.length !== 32) { //
|
|
1691
|
+
if (cek.length !== 32) { // XChaCha20 key size
|
|
1692
1692
|
throw new AuthError("auth-saml/encrypted-wrong-cek-len",
|
|
1693
1693
|
"XChaCha20-Poly1305 CEK length is " + cek.length + ", expected 32");
|
|
1694
1694
|
}
|
|
1695
|
-
if (contentBlob.length < 40) { //
|
|
1695
|
+
if (contentBlob.length < 40) { // 24 nonce + 16 tag
|
|
1696
1696
|
throw new AuthError("auth-saml/encrypted-content-too-short",
|
|
1697
1697
|
"XChaCha20-Poly1305 CipherValue too short");
|
|
1698
1698
|
}
|
|
1699
|
-
var xnonce = contentBlob.subarray(0, 24); //
|
|
1700
|
-
var xtag = contentBlob.subarray(contentBlob.length - 16); //
|
|
1699
|
+
var xnonce = contentBlob.subarray(0, 24); // XChaCha20 nonce size
|
|
1700
|
+
var xtag = contentBlob.subarray(contentBlob.length - 16); // Poly1305 tag size
|
|
1701
1701
|
var xct = contentBlob.subarray(24, contentBlob.length - 16);
|
|
1702
1702
|
try {
|
|
1703
1703
|
clearBytes = bCrypto.aeadDecrypt({
|
|
@@ -1975,7 +1975,7 @@ function _sigAlgUrn(alg) {
|
|
|
1975
1975
|
var keyObj = (sk && typeof sk === "object" && sk.type === "private") ? sk
|
|
1976
1976
|
: (typeof sk === "string" || (sk && sk.kty)) ? nodeCrypto.createPrivateKey(sk)
|
|
1977
1977
|
: nodeCrypto.createPrivateKey({ key: Buffer.concat([
|
|
1978
|
-
Buffer.from("302e020100300506032b657004220420", "hex"), //
|
|
1978
|
+
Buffer.from("302e020100300506032b657004220420", "hex"), // Ed25519 PKCS#8 prefix
|
|
1979
1979
|
Buffer.from(sk),
|
|
1980
1980
|
]), format: "der", type: "pkcs8" });
|
|
1981
1981
|
return nodeCrypto.sign(null, Buffer.from(bytes), keyObj);
|
|
@@ -1984,7 +1984,7 @@ function _sigAlgUrn(alg) {
|
|
|
1984
1984
|
var keyObj = (pk && typeof pk === "object" && pk.type === "public") ? pk
|
|
1985
1985
|
: (typeof pk === "string" || (pk && pk.kty)) ? nodeCrypto.createPublicKey(pk)
|
|
1986
1986
|
: nodeCrypto.createPublicKey({ key: Buffer.concat([
|
|
1987
|
-
Buffer.from("302a300506032b6570032100", "hex"), //
|
|
1987
|
+
Buffer.from("302a300506032b6570032100", "hex"), // Ed25519 SPKI prefix
|
|
1988
1988
|
Buffer.from(pk),
|
|
1989
1989
|
]), format: "der", type: "spki" });
|
|
1990
1990
|
return nodeCrypto.verify(null, Buffer.from(msg), keyObj, Buffer.from(sig));
|
|
@@ -17,7 +17,7 @@ var nodeCrypto = require("node:crypto");
|
|
|
17
17
|
var safeJson = require("../safe-json");
|
|
18
18
|
var { AuthError } = require("../framework-error");
|
|
19
19
|
|
|
20
|
-
var DEFAULT_SALT_BYTES = 16; //
|
|
20
|
+
var DEFAULT_SALT_BYTES = 16; // 128-bit salt per spec recommendation
|
|
21
21
|
|
|
22
22
|
function _newSalt(opts) {
|
|
23
23
|
if (opts && opts.saltSource && typeof opts.saltSource === "function") {
|
package/lib/auth/sd-jwt-vc.js
CHANGED
|
@@ -239,8 +239,8 @@ function issue(opts) {
|
|
|
239
239
|
sdDigests.sort();
|
|
240
240
|
|
|
241
241
|
var now = (typeof opts.issuedAt === "number" && isFinite(opts.issuedAt))
|
|
242
|
-
? Math.floor(opts.issuedAt / 1000) : Math.floor(Date.now() / 1000); //
|
|
243
|
-
var ttlSec = opts.ttlMs ? Math.floor(opts.ttlMs / 1000) : 30 * 24 * 60 * 60; //
|
|
242
|
+
? Math.floor(opts.issuedAt / 1000) : Math.floor(Date.now() / 1000); // ms→s conversion factor
|
|
243
|
+
var ttlSec = opts.ttlMs ? Math.floor(opts.ttlMs / 1000) : 30 * 24 * 60 * 60; // ms→s conversion + 30-day default in seconds
|
|
244
244
|
|
|
245
245
|
var payload = Object.assign({}, plainClaims, {
|
|
246
246
|
iss: opts.issuer,
|
|
@@ -355,7 +355,7 @@ function present(opts) {
|
|
|
355
355
|
"present: algorithm must be one of " + SUPPORTED_ALGS.join(", "));
|
|
356
356
|
}
|
|
357
357
|
var now = (typeof opts.issuedAt === "number" && isFinite(opts.issuedAt))
|
|
358
|
-
? Math.floor(opts.issuedAt / 1000) : Math.floor(Date.now() / 1000); //
|
|
358
|
+
? Math.floor(opts.issuedAt / 1000) : Math.floor(Date.now() / 1000); // ms→s conversion factor
|
|
359
359
|
// The KB-JWT's hash binds it to the specific SD-JWT + presentation
|
|
360
360
|
var kbHashInput = presentation; // jwt~d1~d2~ (without KB)
|
|
361
361
|
// sd_hash uses the SAME hash algorithm the credential's _sd
|
|
@@ -505,7 +505,7 @@ async function verify(presentation, opts) {
|
|
|
505
505
|
|
|
506
506
|
// 2. Validate iss / iat / exp / vct
|
|
507
507
|
var nowSec = (typeof opts.now === "number" && isFinite(opts.now))
|
|
508
|
-
? Math.floor(opts.now / 1000) : Math.floor(Date.now() / 1000); //
|
|
508
|
+
? Math.floor(opts.now / 1000) : Math.floor(Date.now() / 1000); // ms→s conversion factor
|
|
509
509
|
var skew = (typeof opts.maxClockSkewSec === "number") ? opts.maxClockSkewSec : 60; // allow:raw-time-literal — default 60s clock-skew tolerance
|
|
510
510
|
if (typeof jwtParsed.payload.iat === "number" && jwtParsed.payload.iat > nowSec + skew) {
|
|
511
511
|
throw new AuthError("auth-sd-jwt-vc/iat-future",
|
package/lib/auth/status-list.js
CHANGED
|
@@ -55,7 +55,7 @@ var { defineClass } = require("../framework-error");
|
|
|
55
55
|
|
|
56
56
|
var StatusListError = defineClass("StatusListError", { alwaysPermanent: true });
|
|
57
57
|
|
|
58
|
-
var SUPPORTED_BIT_SIZES = { 1: 1, 2: 1, 4: 1, 8: 1 }; //
|
|
58
|
+
var SUPPORTED_BIT_SIZES = { 1: 1, 2: 1, 4: 1, 8: 1 }; // bit-size enum (1/2/4/8 bits per status), not bytes
|
|
59
59
|
var STATUS_VALID = 0;
|
|
60
60
|
var STATUS_INVALID = 1;
|
|
61
61
|
var STATUS_SUSPENDED = 2;
|
|
@@ -107,7 +107,7 @@ function create(opts) {
|
|
|
107
107
|
var bits = opts.bits === undefined ? 1 : opts.bits;
|
|
108
108
|
_validateBits(bits);
|
|
109
109
|
// Allocate the bit-packed buffer up front. byteCount = ceil(size*bits/8).
|
|
110
|
-
var bitBytes = Math.ceil((size * bits) / 8); //
|
|
110
|
+
var bitBytes = Math.ceil((size * bits) / 8); // bits-per-byte conversion
|
|
111
111
|
var bytes = Buffer.alloc(bitBytes);
|
|
112
112
|
if (opts.fill !== undefined && opts.fill !== 0) {
|
|
113
113
|
_validateStatus(opts.fill, bits);
|
|
@@ -184,19 +184,19 @@ function create(opts) {
|
|
|
184
184
|
// ---- bit-packed helpers ----
|
|
185
185
|
|
|
186
186
|
function _setAt(bytes, bits, idx, status) {
|
|
187
|
-
if (bits === 8) { bytes[idx] = status & 0xff; return; } //
|
|
187
|
+
if (bits === 8) { bytes[idx] = status & 0xff; return; } // byte mask
|
|
188
188
|
var bitOffset = idx * bits;
|
|
189
|
-
var byteIdx = Math.floor(bitOffset / 8); //
|
|
190
|
-
var bitInByte = bitOffset % 8; //
|
|
189
|
+
var byteIdx = Math.floor(bitOffset / 8); // bits-per-byte
|
|
190
|
+
var bitInByte = bitOffset % 8; // bits-per-byte
|
|
191
191
|
var mask = ((1 << bits) - 1) << bitInByte;
|
|
192
192
|
bytes[byteIdx] = (bytes[byteIdx] & ~mask) | ((status << bitInByte) & mask);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
function _getAt(bytes, bits, idx) {
|
|
196
|
-
if (bits === 8) return bytes[idx]; //
|
|
196
|
+
if (bits === 8) return bytes[idx]; // 8-bit fast path
|
|
197
197
|
var bitOffset = idx * bits;
|
|
198
|
-
var byteIdx = Math.floor(bitOffset / 8); //
|
|
199
|
-
var bitInByte = bitOffset % 8; //
|
|
198
|
+
var byteIdx = Math.floor(bitOffset / 8); // bits-per-byte
|
|
199
|
+
var bitInByte = bitOffset % 8; // bits-per-byte
|
|
200
200
|
var mask = (1 << bits) - 1;
|
|
201
201
|
return (bytes[byteIdx] >> bitInByte) & mask;
|
|
202
202
|
}
|
|
@@ -238,13 +238,13 @@ async function fromJwt(token, opts) {
|
|
|
238
238
|
"statusList.fromJwt: compressed list exceeds " + MAX_LIST_BYTES + " bytes");
|
|
239
239
|
}
|
|
240
240
|
var inflated;
|
|
241
|
-
try { inflated = zlib.inflateRawSync(deflated, { maxOutputLength: MAX_LIST_BYTES * 8 }); } //
|
|
241
|
+
try { inflated = zlib.inflateRawSync(deflated, { maxOutputLength: MAX_LIST_BYTES * 8 }); } // 8x compression-ratio cap
|
|
242
242
|
catch (e) {
|
|
243
243
|
throw new StatusListError("status-list/inflate-failed",
|
|
244
244
|
"statusList.fromJwt: zlib inflate failed: " + ((e && e.message) || String(e)));
|
|
245
245
|
}
|
|
246
246
|
// Reconstruct the list object pointing at the inflated bytes.
|
|
247
|
-
var size = (inflated.length * 8) / bits; //
|
|
247
|
+
var size = (inflated.length * 8) / bits; // bits-per-byte
|
|
248
248
|
return {
|
|
249
249
|
list: {
|
|
250
250
|
size: size,
|
package/lib/auth/step-up.js
CHANGED
|
@@ -86,7 +86,7 @@ function _quote(value) {
|
|
|
86
86
|
// Reject CTLs and quote-injecting characters.
|
|
87
87
|
for (var i = 0; i < value.length; i += 1) {
|
|
88
88
|
var code = value.charCodeAt(i);
|
|
89
|
-
if (code < 32 || code === 127) { //
|
|
89
|
+
if (code < 32 || code === 127) { // ASCII control codepoints
|
|
90
90
|
throw new AuthError("auth-step-up/bad-challenge",
|
|
91
91
|
"challenge value contains control character at index " + i);
|
|
92
92
|
}
|
|
@@ -270,7 +270,7 @@ function create(opts) {
|
|
|
270
270
|
function _runBotGuardCheck(req) {
|
|
271
271
|
return new Promise(function (resolve) {
|
|
272
272
|
var capturedRes = {
|
|
273
|
-
statusCode: 200, //
|
|
273
|
+
statusCode: 200, // HTTP 200 status code, not bytes
|
|
274
274
|
writableEnded: false,
|
|
275
275
|
writeHead: function (status) { capturedRes.statusCode = status; },
|
|
276
276
|
end: function () { capturedRes.writableEnded = true; },
|