@blamejs/core 0.14.0 → 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 +4 -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 +45 -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/jar.js +11 -0
- package/lib/auth/jwt-external.js +5 -5
- package/lib/auth/oauth.js +7 -9
- package/lib/auth/oid4vci.js +10 -10
- 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 +29 -25
- 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 +53 -45
- 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 +99 -94
- 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 +9 -1
- package/lib/queue.js +4 -2
- 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
package/lib/network-dns.js
CHANGED
|
@@ -83,7 +83,7 @@ function _ensureSecureDefault() {
|
|
|
83
83
|
if (override === "system") { STATE.systemResolver = true; return; }
|
|
84
84
|
if (override === "dot") {
|
|
85
85
|
// Cloudflare 1.1.1.1 over TLS, port 853.
|
|
86
|
-
STATE.dot = { host: "1.1.1.1", port: 853, servername: "1.1.1.1", ca: null }; //
|
|
86
|
+
STATE.dot = { host: "1.1.1.1", port: 853, servername: "1.1.1.1", ca: null }; // IANA-assigned DoT port
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
// Default: DoH via Cloudflare.
|
|
@@ -320,7 +320,7 @@ function _encodeDnsQuery(host, qtype) {
|
|
|
320
320
|
function _skipDnsName(buf, state) {
|
|
321
321
|
var endedViaPointer = false;
|
|
322
322
|
while (state.off < buf.length && buf[state.off] !== 0) {
|
|
323
|
-
if ((buf[state.off] & 0xc0) === 0xc0) { //
|
|
323
|
+
if ((buf[state.off] & 0xc0) === 0xc0) { // RFC 1035 name-compression pointer mask
|
|
324
324
|
state.off += 2;
|
|
325
325
|
endedViaPointer = true;
|
|
326
326
|
break;
|
|
@@ -372,7 +372,7 @@ function _decodeDnsAnswer(buf, qtype) {
|
|
|
372
372
|
// the chain.
|
|
373
373
|
function _readAdBit(buf) {
|
|
374
374
|
if (!Buffer.isBuffer(buf) || buf.length < 12) return false;
|
|
375
|
-
return (buf.readUInt8(3) & 0x20) !== 0; //
|
|
375
|
+
return (buf.readUInt8(3) & 0x20) !== 0; // RFC 4035 AD-bit mask
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
// DoH GET URL length cap. RFC 8484 §4.1 says clients MAY use POST when
|
|
@@ -453,7 +453,7 @@ async function _dohLookup(host, family) {
|
|
|
453
453
|
// after chain validation. Internal — operators reach for
|
|
454
454
|
// `resolveSecure` instead.
|
|
455
455
|
async function _dohLookupSecure(host, family) {
|
|
456
|
-
var qtype = family === 6 ? 28 : 1; //
|
|
456
|
+
var qtype = family === 6 ? 28 : 1; // DNS QTYPE values for A / AAAA
|
|
457
457
|
var enc = _encodeDnsQuery(host, qtype);
|
|
458
458
|
var b64 = bCrypto.toBase64Url(enc.buf);
|
|
459
459
|
var getUrl = STATE.doh.url + (STATE.doh.url.indexOf("?") === -1 ? "?" : "&") + "dns=" + b64;
|
|
@@ -463,7 +463,7 @@ async function _dohLookupSecure(host, family) {
|
|
|
463
463
|
return new Promise(function (resolve, reject) {
|
|
464
464
|
var reqOpts = {
|
|
465
465
|
hostname: u.hostname,
|
|
466
|
-
port: u.port || 443, //
|
|
466
|
+
port: u.port || 443, // HTTPS default port
|
|
467
467
|
path: u.pathname + u.search,
|
|
468
468
|
method: usePost ? "POST" : "GET",
|
|
469
469
|
headers: { "accept": "application/dns-message" },
|
|
@@ -495,7 +495,7 @@ async function _dohLookupSecure(host, family) {
|
|
|
495
495
|
try {
|
|
496
496
|
if (pushFailed) { reject(pushFailed); return; }
|
|
497
497
|
var body = collector.result();
|
|
498
|
-
if (res.statusCode !== 200) { //
|
|
498
|
+
if (res.statusCode !== 200) { // HTTP 200 OK
|
|
499
499
|
reject(new DnsError("dns/doh-http", "DoH HTTP " + res.statusCode + " for " + host));
|
|
500
500
|
return;
|
|
501
501
|
}
|
|
@@ -528,7 +528,7 @@ async function resolveSecure(host, type) {
|
|
|
528
528
|
"resolveSecure requires DoH transport (call useDnsOverHttps " +
|
|
529
529
|
"or rely on the default-on DoH posture)");
|
|
530
530
|
}
|
|
531
|
-
if (typeof host !== "string" || host.length === 0 || host.length > 253) { //
|
|
531
|
+
if (typeof host !== "string" || host.length === 0 || host.length > 253) { // RFC 1035 hostname octet ceiling
|
|
532
532
|
throw new DnsError("dns/bad-host",
|
|
533
533
|
"resolveSecure host is malformed");
|
|
534
534
|
}
|
|
@@ -541,7 +541,7 @@ async function resolveSecure(host, type) {
|
|
|
541
541
|
var labels = host.split(".");
|
|
542
542
|
for (var li = 0; li < labels.length; li += 1) {
|
|
543
543
|
var label = labels[li];
|
|
544
|
-
if (label.length === 0 || label.length > 63) { //
|
|
544
|
+
if (label.length === 0 || label.length > 63) { // RFC 1035 max label length
|
|
545
545
|
throw new DnsError("dns/bad-host",
|
|
546
546
|
"resolveSecure host has invalid label (length 1..63 required, got " + label.length + ")");
|
|
547
547
|
}
|
|
@@ -720,7 +720,7 @@ function _readDnsName(buf, start) {
|
|
|
720
720
|
var off = start;
|
|
721
721
|
var nextOff = -1;
|
|
722
722
|
var iterations = 0;
|
|
723
|
-
var ITER_CAP = 256; //
|
|
723
|
+
var ITER_CAP = 256; // DNS name pointer-loop safeguard
|
|
724
724
|
while (off < buf.length && iterations < ITER_CAP) {
|
|
725
725
|
iterations += 1;
|
|
726
726
|
var len = buf[off];
|
|
@@ -728,13 +728,13 @@ function _readDnsName(buf, start) {
|
|
|
728
728
|
if (nextOff === -1) nextOff = off + 1;
|
|
729
729
|
break;
|
|
730
730
|
}
|
|
731
|
-
if ((len & 0xc0) === 0xc0) { //
|
|
731
|
+
if ((len & 0xc0) === 0xc0) { // RFC 1035 name-compression pointer mask
|
|
732
732
|
if (off + 1 >= buf.length) {
|
|
733
733
|
throw new DnsError("dns/svcb-malformed",
|
|
734
734
|
"DNS name truncated at compression pointer");
|
|
735
735
|
}
|
|
736
736
|
if (nextOff === -1) nextOff = off + 2;
|
|
737
|
-
var ptr = ((len & 0x3f) << 8) | buf[off + 1]; //
|
|
737
|
+
var ptr = ((len & 0x3f) << 8) | buf[off + 1]; // RFC 1035 pointer offset mask
|
|
738
738
|
if (ptr >= buf.length || ptr === off) {
|
|
739
739
|
throw new DnsError("dns/svcb-malformed",
|
|
740
740
|
"DNS name pointer out of bounds or self-referential");
|
|
@@ -742,7 +742,7 @@ function _readDnsName(buf, start) {
|
|
|
742
742
|
off = ptr;
|
|
743
743
|
continue;
|
|
744
744
|
}
|
|
745
|
-
if ((len & 0xc0) !== 0) { //
|
|
745
|
+
if ((len & 0xc0) !== 0) { // RFC 1035 reserved label-type bits
|
|
746
746
|
throw new DnsError("dns/svcb-malformed",
|
|
747
747
|
"DNS name has reserved label type 0x" + len.toString(HEX_RADIX));
|
|
748
748
|
}
|
|
@@ -770,7 +770,7 @@ function _decodeDnsAnswerRaw(buf) {
|
|
|
770
770
|
if (!Buffer.isBuffer(buf) || buf.length < 12) {
|
|
771
771
|
throw new DnsError("dns/bad-reply", "dns reply truncated");
|
|
772
772
|
}
|
|
773
|
-
var rcode = buf.readUInt8(3) & 0x0f; //
|
|
773
|
+
var rcode = buf.readUInt8(3) & 0x0f; // RFC 1035 RCODE nibble mask
|
|
774
774
|
if (rcode !== 0) {
|
|
775
775
|
throw new DnsError("dns/no-result", "dns reply rcode " + rcode);
|
|
776
776
|
}
|
|
@@ -818,7 +818,7 @@ async function _dohRawQuery(host, qtype) {
|
|
|
818
818
|
return new Promise(function (resolve, reject) {
|
|
819
819
|
var reqOpts = {
|
|
820
820
|
hostname: u.hostname,
|
|
821
|
-
port: u.port || 443, //
|
|
821
|
+
port: u.port || 443, // HTTPS default port
|
|
822
822
|
path: u.pathname + u.search,
|
|
823
823
|
method: usePost ? "POST" : "GET",
|
|
824
824
|
headers: { "accept": "application/dns-message" },
|
|
@@ -849,7 +849,7 @@ async function _dohRawQuery(host, qtype) {
|
|
|
849
849
|
res.on("end", function () {
|
|
850
850
|
try {
|
|
851
851
|
if (pushFailed) { reject(pushFailed); return; }
|
|
852
|
-
if (res.statusCode !== 200) { //
|
|
852
|
+
if (res.statusCode !== 200) { // HTTP 200 OK
|
|
853
853
|
reject(new DnsError("dns/doh-http", "DoH HTTP " + res.statusCode + " for " + host));
|
|
854
854
|
return;
|
|
855
855
|
}
|
|
@@ -950,15 +950,15 @@ async function _systemRawQuery(host, qtype) {
|
|
|
950
950
|
}
|
|
951
951
|
var serverEntry = servers[0];
|
|
952
952
|
var serverHost = serverEntry;
|
|
953
|
-
var serverPort = 53; //
|
|
953
|
+
var serverPort = 53; // IANA-assigned DNS port
|
|
954
954
|
var bracketEnd = serverEntry.lastIndexOf("]:");
|
|
955
955
|
if (bracketEnd !== -1) {
|
|
956
956
|
serverHost = serverEntry.slice(1, bracketEnd);
|
|
957
|
-
serverPort = parseInt(serverEntry.slice(bracketEnd + 2), 10) || 53; //
|
|
957
|
+
serverPort = parseInt(serverEntry.slice(bracketEnd + 2), 10) || 53; // IANA-assigned DNS port
|
|
958
958
|
} else if (serverEntry.indexOf(":") !== -1 && net.isIP(serverEntry) === 0) {
|
|
959
959
|
var colonIdx = serverEntry.lastIndexOf(":");
|
|
960
960
|
serverHost = serverEntry.slice(0, colonIdx);
|
|
961
|
-
serverPort = parseInt(serverEntry.slice(colonIdx + 1), 10) || 53; //
|
|
961
|
+
serverPort = parseInt(serverEntry.slice(colonIdx + 1), 10) || 53; // IANA-assigned DNS port
|
|
962
962
|
}
|
|
963
963
|
var enc = _encodeDnsQuery(host, qtype);
|
|
964
964
|
return new Promise(function (resolve, reject) {
|
|
@@ -1029,8 +1029,8 @@ async function _rawQuery(host, qtype, forceTransport) {
|
|
|
1029
1029
|
|
|
1030
1030
|
// ---- SVCB / HTTPS RR (RFC 9460) --------------------------------------
|
|
1031
1031
|
|
|
1032
|
-
var DNS_QTYPE_SVCB = 64; //
|
|
1033
|
-
var DNS_QTYPE_HTTPS = 65; //
|
|
1032
|
+
var DNS_QTYPE_SVCB = 64; // RFC 9460 §14.1 SVCB record type code
|
|
1033
|
+
var DNS_QTYPE_HTTPS = 65; // RFC 9460 §14.1 HTTPS record type code
|
|
1034
1034
|
|
|
1035
1035
|
// SvcParamKey assignments (RFC 9460 §14.3.2 + IANA registry). Keys
|
|
1036
1036
|
// past 7 are operator-extensible; we recognize the IETF-blessed set
|
|
@@ -1042,7 +1042,7 @@ var SVCB_KEY_PORT = 3;
|
|
|
1042
1042
|
var SVCB_KEY_IPV4HINT = 4;
|
|
1043
1043
|
var SVCB_KEY_ECH = 5;
|
|
1044
1044
|
var SVCB_KEY_IPV6HINT = 6;
|
|
1045
|
-
var SVCB_KEY_DOHPATH = 7; //
|
|
1045
|
+
var SVCB_KEY_DOHPATH = 7; // RFC 9461 SvcParamKey
|
|
1046
1046
|
|
|
1047
1047
|
function _readCharString(buf, off, end) {
|
|
1048
1048
|
if (off >= end) {
|
|
@@ -1149,7 +1149,7 @@ function _parseSvcbRdata(msg, rdataOff, rdlen) {
|
|
|
1149
1149
|
}
|
|
1150
1150
|
|
|
1151
1151
|
function _validateLdh(host, primitive) {
|
|
1152
|
-
if (typeof host !== "string" || host.length === 0 || host.length > 253) { //
|
|
1152
|
+
if (typeof host !== "string" || host.length === 0 || host.length > 253) { // RFC 1035 hostname octet ceiling
|
|
1153
1153
|
throw new DnsError("dns/bad-host",
|
|
1154
1154
|
primitive + ": host must be a non-empty RFC 1035 LDH name (length 1..253)");
|
|
1155
1155
|
}
|
|
@@ -1158,7 +1158,7 @@ function _validateLdh(host, primitive) {
|
|
|
1158
1158
|
var labels = host.split(".");
|
|
1159
1159
|
for (var li = 0; li < labels.length; li += 1) {
|
|
1160
1160
|
var label = labels[li];
|
|
1161
|
-
if (label.length === 0 || label.length > 63) { //
|
|
1161
|
+
if (label.length === 0 || label.length > 63) { // RFC 1035 max label length
|
|
1162
1162
|
throw new DnsError("dns/bad-host",
|
|
1163
1163
|
primitive + ": host label length must be 1..63");
|
|
1164
1164
|
}
|
|
@@ -1352,7 +1352,7 @@ async function discoverEncrypted(opts) {
|
|
|
1352
1352
|
alpn: alpn,
|
|
1353
1353
|
target: rec.target,
|
|
1354
1354
|
port: (rec.params && rec.params.port) ||
|
|
1355
|
-
(transportKind === "dot" ? 853 : 443), //
|
|
1355
|
+
(transportKind === "dot" ? 853 : 443), // IANA-assigned DoT/HTTPS ports
|
|
1356
1356
|
dohpath: (rec.params && rec.params.dohpath) || null,
|
|
1357
1357
|
ipv4hint: (rec.params && rec.params.ipv4hint) || [],
|
|
1358
1358
|
ipv6hint: (rec.params && rec.params.ipv6hint) || [],
|
|
@@ -1448,7 +1448,7 @@ function useDesignatedResolvers(list) {
|
|
|
1448
1448
|
} else {
|
|
1449
1449
|
useDnsOverTls({
|
|
1450
1450
|
host: v.host,
|
|
1451
|
-
port: v.port || 853, //
|
|
1451
|
+
port: v.port || 853, // IANA-assigned DoT port
|
|
1452
1452
|
servername: v.servername || v.host,
|
|
1453
1453
|
ca: v.ca || null,
|
|
1454
1454
|
});
|
|
@@ -1533,7 +1533,7 @@ async function lookup(host, opts) {
|
|
|
1533
1533
|
} else {
|
|
1534
1534
|
// System resolver (operator explicit opt-out via useSystemResolver).
|
|
1535
1535
|
var nodeOpts = { all: true };
|
|
1536
|
-
if (family === 4 || family === 6) nodeOpts.family = family; //
|
|
1536
|
+
if (family === 4 || family === 6) nodeOpts.family = family; // IPv4/IPv6 family literals
|
|
1537
1537
|
addrs = await _withTimeout(dnsPromises.lookup(host, nodeOpts), STATE.lookupTimeoutMs, host);
|
|
1538
1538
|
if (!Array.isArray(addrs)) addrs = [addrs];
|
|
1539
1539
|
}
|
|
@@ -1797,7 +1797,7 @@ var DNSKEY_ALGORITHMS = Object.freeze({
|
|
|
1797
1797
|
5: { name: "RSASHA1", deprecated: true, reason: "SHA-1 deprecated (RFC 9905 §3)" },
|
|
1798
1798
|
6: { name: "DSA-NSEC3-SHA1", deprecated: true, reason: "SHA-1 deprecated (RFC 9905 §3); DSA deprecated (RFC 8624 §3.1)" },
|
|
1799
1799
|
7: { name: "RSASHA1-NSEC3-SHA1", deprecated: true, reason: "SHA-1 deprecated (RFC 9905 §3)" },
|
|
1800
|
-
8: { name: "RSASHA256", deprecated: false, reason: "current — RFC 5702" }, //
|
|
1800
|
+
8: { name: "RSASHA256", deprecated: false, reason: "current — RFC 5702" }, // IANA DNSKEY algorithm number
|
|
1801
1801
|
9: { name: "Reserved", deprecated: true, reason: "Reserved (RFC 5155) — not for production use" },
|
|
1802
1802
|
10: { name: "RSASHA512", deprecated: false, reason: "current — RFC 5702" },
|
|
1803
1803
|
11: { name: "Reserved", deprecated: true, reason: "Reserved (RFC 5155) — not for production use" },
|
|
@@ -1805,13 +1805,13 @@ var DNSKEY_ALGORITHMS = Object.freeze({
|
|
|
1805
1805
|
13: { name: "ECDSAP256SHA256", deprecated: false, reason: "current — RFC 6605" },
|
|
1806
1806
|
14: { name: "ECDSAP384SHA384", deprecated: false, reason: "current — RFC 6605" },
|
|
1807
1807
|
15: { name: "ED25519", deprecated: false, reason: "current — RFC 8080" },
|
|
1808
|
-
16: { name: "ED448", deprecated: false, reason: "current — RFC 8080" }, //
|
|
1808
|
+
16: { name: "ED448", deprecated: false, reason: "current — RFC 8080" }, // IANA DNSKEY algorithm number
|
|
1809
1809
|
// 17-122: Unassigned per IANA. Operators that see one of these
|
|
1810
1810
|
// get known: false from classifyDnskeyAlgorithm() — the entry
|
|
1811
1811
|
// is not a typo against the framework table, it's a value the
|
|
1812
1812
|
// registry hasn't allocated yet.
|
|
1813
1813
|
// 123-251: Reserved per IANA.
|
|
1814
|
-
252: { name: "INDIRECT", deprecated: true, reason: "Reserved indirect-keys placeholder (RFC 4034 §A.1) — not usable for signing/verification" }, //
|
|
1814
|
+
252: { name: "INDIRECT", deprecated: true, reason: "Reserved indirect-keys placeholder (RFC 4034 §A.1) — not usable for signing/verification" }, // IANA DNSKEY algorithm number
|
|
1815
1815
|
253: { name: "PRIVATEDNS", deprecated: false, reason: "Private algorithm identified by domain name (RFC 4034 §A.1.1) — operators using this assume the private algorithm itself is acceptable" },
|
|
1816
1816
|
254: { name: "PRIVATEOID", deprecated: false, reason: "Private algorithm identified by OID (RFC 4034 §A.1.2) — operators using this assume the private algorithm itself is acceptable" },
|
|
1817
1817
|
255: { name: "Reserved", deprecated: true, reason: "Reserved (RFC 4034 §A.1) — not for production use" },
|
package/lib/network-dnssec.js
CHANGED
|
@@ -53,9 +53,9 @@ var DnssecError = defineClass("DnssecError", { alwaysPermanent: true });
|
|
|
53
53
|
|
|
54
54
|
// DNSSEC algorithm numbers (IANA DNSSEC Algorithm Numbers) → verify params.
|
|
55
55
|
var ALGS = {
|
|
56
|
-
8: { name: "RSASHA256", kind: "rsa", hash: "sha256" }, //
|
|
57
|
-
13: { name: "ECDSAP256SHA256", kind: "ec", hash: "sha256", crv: "P-256", coord: 32 }, //
|
|
58
|
-
14: { name: "ECDSAP384SHA384", kind: "ec", hash: "sha384", crv: "P-384", coord: 48 }, //
|
|
56
|
+
8: { name: "RSASHA256", kind: "rsa", hash: "sha256" }, // IANA DNSSEC algorithm number
|
|
57
|
+
13: { name: "ECDSAP256SHA256", kind: "ec", hash: "sha256", crv: "P-256", coord: 32 }, // P-256 coordinate size
|
|
58
|
+
14: { name: "ECDSAP384SHA384", kind: "ec", hash: "sha384", crv: "P-384", coord: 48 }, // P-384 coordinate size
|
|
59
59
|
15: { name: "ED25519", kind: "okp", hash: null, crv: "Ed25519" },
|
|
60
60
|
};
|
|
61
61
|
|
|
@@ -72,10 +72,10 @@ var DS_DIGESTS = { 2: "sha256", 4: "sha384" };
|
|
|
72
72
|
// (type numbers IANA): A 1, AAAA 28, TXT 16, DNSKEY 48, DS 43, CAA 257,
|
|
73
73
|
// TLSA 52, SSHFP 44, HINFO 13, CDS 59, CDNSKEY 60, OPENPGPKEY 61, SMIMEA
|
|
74
74
|
// 53, NSEC 47, NSEC3 50.
|
|
75
|
-
var NAME_FREE_TYPE_NUMS = [1, 28, 16, 48, 43, 257, 52, 44, 13, 59, 60, 61, 53, 47, 50]; // allow:raw-
|
|
75
|
+
var NAME_FREE_TYPE_NUMS = [1, 28, 16, 48, 43, 257, 52, 44, 13, 59, 60, 61, 53, 47, 50]; // allow:raw-time-literal — IANA DNS type numbers (no downcased embedded names)
|
|
76
76
|
var TYPE_NUM = {
|
|
77
77
|
A: 1, NS: 2, CNAME: 5, SOA: 6, PTR: 12, MX: 15, TXT: 16, AAAA: 28, SRV: 33,
|
|
78
|
-
DS: 43, SSHFP: 44, RRSIG: 46, NSEC: 47, DNSKEY: 48, NSEC3: 50, TLSA: 52, // allow:raw-
|
|
78
|
+
DS: 43, SSHFP: 44, RRSIG: 46, NSEC: 47, DNSKEY: 48, NSEC3: 50, TLSA: 52, // allow:raw-time-literal — IANA DNS type numbers
|
|
79
79
|
SMIMEA: 53, CDS: 59, CDNSKEY: 60, OPENPGPKEY: 61, CAA: 257, HINFO: 13,
|
|
80
80
|
};
|
|
81
81
|
|
|
@@ -95,7 +95,7 @@ function _canonicalName(name) {
|
|
|
95
95
|
var parts = [];
|
|
96
96
|
for (var i = 0; i < labels.length; i++) {
|
|
97
97
|
var lab = Buffer.from(labels[i].toLowerCase(), "ascii");
|
|
98
|
-
if (lab.length === 0 || lab.length > 63) { //
|
|
98
|
+
if (lab.length === 0 || lab.length > 63) { // DNS label length cap (RFC 1035)
|
|
99
99
|
throw new DnssecError("dnssec/bad-name", "dnssec: invalid label in '" + name + "'");
|
|
100
100
|
}
|
|
101
101
|
parts.push(Buffer.from([lab.length]), lab);
|
|
@@ -106,14 +106,14 @@ function _canonicalName(name) {
|
|
|
106
106
|
// Enforcing it here also bounds the per-label count (and thus the NSEC3
|
|
107
107
|
// closest-encloser candidate enumeration, CVE-2023-50868 class), since
|
|
108
108
|
// each label costs at least 2 octets.
|
|
109
|
-
if (wire.length > 255) { //
|
|
109
|
+
if (wire.length > 255) { // RFC 1035 total-name octet cap
|
|
110
110
|
throw new DnssecError("dnssec/bad-name",
|
|
111
111
|
"dnssec: name '" + name + "' encodes to " + wire.length + " octets, exceeds RFC 1035 cap of 255");
|
|
112
112
|
}
|
|
113
113
|
return wire;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
function _u16(n) { return Buffer.from([(n >> 8) & 0xff, n & 0xff]); } //
|
|
116
|
+
function _u16(n) { return Buffer.from([(n >> 8) & 0xff, n & 0xff]); } // 16-bit big-endian split
|
|
117
117
|
function _u32(n) {
|
|
118
118
|
var b = Buffer.alloc(4);
|
|
119
119
|
b.writeUInt32BE(n >>> 0, 0);
|
|
@@ -138,7 +138,7 @@ function _dnskeyToKey(algId, publicKey) {
|
|
|
138
138
|
// next 2 bytes; then exponent, then modulus.
|
|
139
139
|
var off = 0, explen = pk[0];
|
|
140
140
|
off = 1;
|
|
141
|
-
if (explen === 0) { explen = (pk[1] << 8) | pk[2]; off = 3; } //
|
|
141
|
+
if (explen === 0) { explen = (pk[1] << 8) | pk[2]; off = 3; } // RFC 3110 3-byte exponent length
|
|
142
142
|
if (explen === 0 || off + explen >= pk.length) {
|
|
143
143
|
throw new DnssecError("dnssec/bad-key", "dnssec: malformed RSA DNSKEY public key");
|
|
144
144
|
}
|
|
@@ -153,7 +153,7 @@ function _dnskeyToKey(algId, publicKey) {
|
|
|
153
153
|
return _jwkKey({ kty: "EC", crv: alg.crv, x: pk.slice(0, alg.coord).toString("base64url"), y: pk.slice(alg.coord).toString("base64url") });
|
|
154
154
|
}
|
|
155
155
|
// Ed25519
|
|
156
|
-
if (pk.length !== 32) throw new DnssecError("dnssec/bad-key", "dnssec: Ed25519 key must be 32 bytes"); //
|
|
156
|
+
if (pk.length !== 32) throw new DnssecError("dnssec/bad-key", "dnssec: Ed25519 key must be 32 bytes"); // Ed25519 key size
|
|
157
157
|
return _jwkKey({ kty: "OKP", crv: "Ed25519", x: pk.toString("base64url") });
|
|
158
158
|
}
|
|
159
159
|
function _jwkKey(jwk) {
|
|
@@ -179,10 +179,10 @@ function keyTag(dnskeyRdata) {
|
|
|
179
179
|
var rd = _bytes(dnskeyRdata, "dnskeyRdata");
|
|
180
180
|
var acc = 0;
|
|
181
181
|
for (var i = 0; i < rd.length; i++) {
|
|
182
|
-
acc += (i & 1) ? rd[i] : (rd[i] << 8); //
|
|
182
|
+
acc += (i & 1) ? rd[i] : (rd[i] << 8); // RFC 4034 App B key-tag accumulation
|
|
183
183
|
}
|
|
184
|
-
acc += (acc >> 16) & 0xffff; //
|
|
185
|
-
return acc & 0xffff; //
|
|
184
|
+
acc += (acc >> 16) & 0xffff; // App B fold
|
|
185
|
+
return acc & 0xffff; // App B 16-bit tag
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
/**
|
|
@@ -311,7 +311,7 @@ function verifyRrset(opts) {
|
|
|
311
311
|
|
|
312
312
|
// RRSIG RDATA without the signature (RFC 4034 §3.1.8.1).
|
|
313
313
|
var rrsigPrefix = Buffer.concat([
|
|
314
|
-
_u16(typeNum), Buffer.from([rrsig.algorithm & 0xff, rrsig.labels & 0xff]), //
|
|
314
|
+
_u16(typeNum), Buffer.from([rrsig.algorithm & 0xff, rrsig.labels & 0xff]), // single-octet alg + labels fields
|
|
315
315
|
_u32(rrsig.originalTtl), _u32(rrsig.expiration), _u32(rrsig.inception),
|
|
316
316
|
_u16(rrsig.keyTag), _canonicalName(rrsig.signerName),
|
|
317
317
|
]);
|
|
@@ -345,8 +345,8 @@ function verifyRrset(opts) {
|
|
|
345
345
|
// signature check. Passing unverified records proves nothing.
|
|
346
346
|
// ---------------------------------------------------------------------------
|
|
347
347
|
|
|
348
|
-
var BASE32HEX = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; //
|
|
349
|
-
var TYPE_DS = 43; //
|
|
348
|
+
var BASE32HEX = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; // RFC 4648 §7 extended-hex alphabet (RFC number in comment)
|
|
349
|
+
var TYPE_DS = 43; // IANA RR type DS
|
|
350
350
|
var TYPE_CNAME = 5;
|
|
351
351
|
var NSEC3_HASH_SHA1 = 1; // RFC 5155 §5 — the only registered NSEC3 hash
|
|
352
352
|
var DEFAULT_MAX_NSEC3_ITERATIONS = 150; // allow:raw-time-literal — DoS ceiling on iterated SHA-1; matches BIND 9.16.33+/Unbound 1.17.1 post-CVE-2023-50868 (RFC 9276 wants 0; deployed zones still use >0)
|
|
@@ -366,11 +366,11 @@ var DEFAULT_MAX_NSEC3_ITERATIONS = 150; // allow:raw-time-l
|
|
|
366
366
|
// while still bounding the bounded-collision amplification. Chain length
|
|
367
367
|
// itself is capped (a delegation can't be deeper than a DNS name's label
|
|
368
368
|
// count, RFC 1035), so the scaled budget can't be inflated arbitrarily.
|
|
369
|
-
var MAX_COLLIDING_KEYS = 4; //
|
|
370
|
-
var MAX_VALIDATIONS_PER_LINK = 8; //
|
|
371
|
-
var MAX_CHAIN_LINKS = 128; //
|
|
372
|
-
var MAX_DNSKEYS_PER_ZONE = 64; //
|
|
373
|
-
var MAX_DS_RECORDS = 16; //
|
|
369
|
+
var MAX_COLLIDING_KEYS = 4; // same-tag DNSKEY candidates tried per RRSIG
|
|
370
|
+
var MAX_VALIDATIONS_PER_LINK = 8; // 2 RRSIGs/link x MAX_COLLIDING_KEYS; budget = links.length x this
|
|
371
|
+
var MAX_CHAIN_LINKS = 128; // max delegation depth (>= RFC 1035 max label count)
|
|
372
|
+
var MAX_DNSKEYS_PER_ZONE = 64; // DNSKEY RRset size cap per zone link
|
|
373
|
+
var MAX_DS_RECORDS = 16; // DS RRset size cap (parent-supplied)
|
|
374
374
|
|
|
375
375
|
// RFC 4648 §7 base32hex decode (no padding, case-insensitive) — the
|
|
376
376
|
// label encoding of an NSEC3 owner-name hash.
|
|
@@ -380,9 +380,9 @@ function _base32hexDecode(s, label) {
|
|
|
380
380
|
for (var i = 0; i < up.length; i++) {
|
|
381
381
|
var idx = BASE32HEX.indexOf(up[i]);
|
|
382
382
|
if (idx === -1) throw new DnssecError("dnssec/bad-nsec3", "dnssec: " + label + " is not valid base32hex");
|
|
383
|
-
value = (value << 5) | idx; //
|
|
384
|
-
bits += 5; //
|
|
385
|
-
if (bits >= 8) { bits -= 8; out.push((value >> bits) & 0xff); } //
|
|
383
|
+
value = (value << 5) | idx; // base32 5-bit group
|
|
384
|
+
bits += 5; // base32 5-bit group
|
|
385
|
+
if (bits >= 8) { bits -= 8; out.push((value >> bits) & 0xff); } // emit a full octet
|
|
386
386
|
}
|
|
387
387
|
return Buffer.from(out);
|
|
388
388
|
}
|
|
@@ -394,13 +394,13 @@ function _parseTypeBitmaps(buf, off, end) {
|
|
|
394
394
|
while (i + 2 <= end) {
|
|
395
395
|
var win = buf[i], len = buf[i + 1];
|
|
396
396
|
i += 2;
|
|
397
|
-
if (len < 1 || len > 32 || i + len > end) { //
|
|
397
|
+
if (len < 1 || len > 32 || i + len > end) { // bitmap window ≤ 256 bits = 32 octets (RFC 4034 §4.1.2)
|
|
398
398
|
throw new DnssecError("dnssec/bad-bitmap", "dnssec: malformed NSEC type bitmap");
|
|
399
399
|
}
|
|
400
400
|
for (var j = 0; j < len; j++) {
|
|
401
401
|
var octet = buf[i + j];
|
|
402
|
-
for (var bit = 0; bit < 8; bit++) { //
|
|
403
|
-
if (octet & (0x80 >> bit)) types.add(win * 256 + j * 8 + bit); //
|
|
402
|
+
for (var bit = 0; bit < 8; bit++) { // 8 bits per octet
|
|
403
|
+
if (octet & (0x80 >> bit)) types.add(win * 256 + j * 8 + bit); // bit→type-number (window*256 + octet*8 + bit)
|
|
404
404
|
}
|
|
405
405
|
}
|
|
406
406
|
i += len;
|
|
@@ -417,7 +417,7 @@ function _readWireName(buf, off) {
|
|
|
417
417
|
if (i >= buf.length) throw new DnssecError("dnssec/bad-name", "dnssec: truncated name in RDATA");
|
|
418
418
|
var len = buf[i];
|
|
419
419
|
if (len === 0) { i++; break; }
|
|
420
|
-
if ((len & 0xc0) !== 0) throw new DnssecError("dnssec/bad-name", "dnssec: compression pointer in signed RDATA"); //
|
|
420
|
+
if ((len & 0xc0) !== 0) throw new DnssecError("dnssec/bad-name", "dnssec: compression pointer in signed RDATA"); // RFC 1035 label-length top-two-bits flag
|
|
421
421
|
i++;
|
|
422
422
|
labels.push(buf.slice(i, i + len).toString("ascii"));
|
|
423
423
|
i += len;
|
|
@@ -426,7 +426,7 @@ function _readWireName(buf, off) {
|
|
|
426
426
|
}
|
|
427
427
|
|
|
428
428
|
function _parseNsec3Rdata(rd) {
|
|
429
|
-
if (rd.length < 6) throw new DnssecError("dnssec/bad-nsec3", "dnssec: NSEC3 RDATA too short"); //
|
|
429
|
+
if (rd.length < 6) throw new DnssecError("dnssec/bad-nsec3", "dnssec: NSEC3 RDATA too short"); // fixed NSEC3 header octets
|
|
430
430
|
var hashAlg = rd[0], flags = rd[1], iterations = rd.readUInt16BE(2), saltLen = rd[4];
|
|
431
431
|
var off = 5 + saltLen;
|
|
432
432
|
if (off + 1 > rd.length) throw new DnssecError("dnssec/bad-nsec3", "dnssec: NSEC3 salt overruns RDATA");
|
|
@@ -762,17 +762,17 @@ function _commonSuffixLen(a, b) {
|
|
|
762
762
|
// KSK-2024 (tag 38696), published at data.iana.org/root-anchors. An
|
|
763
763
|
// operator pins their own via opts.trustAnchors.
|
|
764
764
|
var DEFAULT_ROOT_ANCHORS = [
|
|
765
|
-
{ keyTag: 20326, algorithm: 8, digestType: 2, digest: Buffer.from("E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D", "hex") }, //
|
|
766
|
-
{ keyTag: 38696, algorithm: 8, digestType: 2, digest: Buffer.from("683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16", "hex") }, //
|
|
765
|
+
{ keyTag: 20326, algorithm: 8, digestType: 2, digest: Buffer.from("E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D", "hex") }, // IANA root KSK-2017 DS
|
|
766
|
+
{ keyTag: 38696, algorithm: 8, digestType: 2, digest: Buffer.from("683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16", "hex") }, // IANA root KSK-2024 DS
|
|
767
767
|
];
|
|
768
768
|
|
|
769
769
|
function _dnskeyParts(rdata, what) {
|
|
770
770
|
var rd = _bytes(rdata, what || "dnskey rdata");
|
|
771
|
-
if (rd.length < 4) throw new DnssecError("dnssec/bad-key", "dnssec: DNSKEY RDATA too short"); //
|
|
771
|
+
if (rd.length < 4) throw new DnssecError("dnssec/bad-key", "dnssec: DNSKEY RDATA too short"); // DNSKEY fixed header octets
|
|
772
772
|
return { flags: rd.readUInt16BE(0), algorithm: rd[3], publicKey: rd.slice(4) };
|
|
773
773
|
}
|
|
774
774
|
function _parseDsRdata(rd) {
|
|
775
|
-
if (rd.length < 5) throw new DnssecError("dnssec/bad-ds", "dnssec: DS RDATA too short"); //
|
|
775
|
+
if (rd.length < 5) throw new DnssecError("dnssec/bad-ds", "dnssec: DS RDATA too short"); // DS fixed header octets
|
|
776
776
|
return { keyTag: rd.readUInt16BE(0), algorithm: rd[2], digestType: rd[3], digest: rd.slice(4) };
|
|
777
777
|
}
|
|
778
778
|
// ALL DNSKEYs whose key tag matches — 16-bit key tags collide (RFC 4034
|
|
@@ -182,8 +182,8 @@ async function mtaStsFetch(domain, opts) {
|
|
|
182
182
|
} catch (_e) {
|
|
183
183
|
return null;
|
|
184
184
|
}
|
|
185
|
-
if (res.statusCode === 404) return null; //
|
|
186
|
-
if (res.statusCode < 200 || res.statusCode >= 300) { //
|
|
185
|
+
if (res.statusCode === 404) return null; // HTTP 404
|
|
186
|
+
if (res.statusCode < 200 || res.statusCode >= 300) { // HTTP 2xx range
|
|
187
187
|
throw new SmtpPolicyError("smtp/mta-sts-fetch-failed",
|
|
188
188
|
"MTA-STS fetch returned " + res.statusCode + " for " + url);
|
|
189
189
|
}
|
|
@@ -234,7 +234,7 @@ async function daneTlsa(domain, port, opts) {
|
|
|
234
234
|
"dane.tlsa: domain must be a non-empty string");
|
|
235
235
|
}
|
|
236
236
|
opts = opts || {};
|
|
237
|
-
var p = typeof port === "number" ? port : 25; //
|
|
237
|
+
var p = typeof port === "number" ? port : 25; // IANA SMTP port
|
|
238
238
|
var qname = "_" + p + "._tcp." + domain.toLowerCase();
|
|
239
239
|
// node:dns has resolveTlsa() since Node 18.16.0.
|
|
240
240
|
if (typeof dnsPromises.resolveTlsa !== "function") {
|
|
@@ -326,7 +326,7 @@ function _extractIssuerDer(certDer) {
|
|
|
326
326
|
var idx = 0;
|
|
327
327
|
if (tbsKids.length > 0 &&
|
|
328
328
|
tbsKids[0].tagClass === asn1.TAG_CLASS.CONTEXT_SPECIFIC &&
|
|
329
|
-
tbsKids[0].tag === 0) { //
|
|
329
|
+
tbsKids[0].tag === 0) { // X.509 [0] EXPLICIT version tag
|
|
330
330
|
idx = 1;
|
|
331
331
|
}
|
|
332
332
|
// TBSCertificate fields: serial, signature, issuer, validity, subject, ...
|
|
@@ -352,7 +352,7 @@ function _extractSubjectDer(certDer) {
|
|
|
352
352
|
var idx = 0;
|
|
353
353
|
if (tbsKids.length > 0 &&
|
|
354
354
|
tbsKids[0].tagClass === asn1.TAG_CLASS.CONTEXT_SPECIFIC &&
|
|
355
|
-
tbsKids[0].tag === 0) { //
|
|
355
|
+
tbsKids[0].tag === 0) { // X.509 [0] EXPLICIT version tag
|
|
356
356
|
idx = 1;
|
|
357
357
|
}
|
|
358
358
|
// Subject = idx + 4 (after serial / signature / issuer / validity).
|
|
@@ -386,11 +386,11 @@ function _extractSubjectPublicKeyInfo(certDer) {
|
|
|
386
386
|
var idx = 0;
|
|
387
387
|
if (tbsKids.length > 0 &&
|
|
388
388
|
tbsKids[0].tagClass === asn1.TAG_CLASS.CONTEXT_SPECIFIC &&
|
|
389
|
-
tbsKids[0].tag === 0) { //
|
|
389
|
+
tbsKids[0].tag === 0) { // X.509 [0] EXPLICIT version tag
|
|
390
390
|
idx = 1;
|
|
391
391
|
}
|
|
392
392
|
// Skip serialNumber / signature / issuer / validity / subject — five fields.
|
|
393
|
-
var spkiIdx = idx + 5; //
|
|
393
|
+
var spkiIdx = idx + 5; // X.509 TBSCertificate field count
|
|
394
394
|
if (spkiIdx >= tbsKids.length) return null;
|
|
395
395
|
var spki = tbsKids[spkiIdx];
|
|
396
396
|
if (spki.tag !== asn1.TAG.SEQUENCE) return null;
|
|
@@ -452,7 +452,7 @@ function daneVerifyChain(certChain, tlsaRecords, opts) {
|
|
|
452
452
|
for (var t = 0; t < tlsaRecords.length; t += 1) {
|
|
453
453
|
var rec = tlsaRecords[t];
|
|
454
454
|
var usage = rec.usage;
|
|
455
|
-
if (usage === 2) { //
|
|
455
|
+
if (usage === 2) { // TLSA cert-usage code (RFC 6698 §2.1.1) — DANE-TA: match against trust anchor IN the chain (RFC 7672 §3.1.1).
|
|
456
456
|
// The framework now enforces chain order: the matched DANE-TA
|
|
457
457
|
// cert at position i must have its Subject equal to the Issuer
|
|
458
458
|
// of cert at position i-1 (i.e. it must actually be the parent
|
|
@@ -668,7 +668,7 @@ async function tlsRptSubmit(report, opts) {
|
|
|
668
668
|
timeoutMs: timeoutMs,
|
|
669
669
|
});
|
|
670
670
|
entry.status = rv && rv.status;
|
|
671
|
-
entry.ok = entry.status >= 200 && entry.status < 300; //
|
|
671
|
+
entry.ok = entry.status >= 200 && entry.status < 300; // HTTP 2xx range
|
|
672
672
|
if (!entry.ok) entry.error = "HTTP " + entry.status;
|
|
673
673
|
} else if (/^mailto:/i.test(uri)) {
|
|
674
674
|
// Operator-side transport. Surface the prepared body so the
|
|
@@ -716,7 +716,7 @@ async function tlsRptSubmit(report, opts) {
|
|
|
716
716
|
// tlsRpt.recordShape / tlsRpt.submit on the send side.
|
|
717
717
|
|
|
718
718
|
var TLS_RPT_MAX_REPORT_BYTES = C.BYTES.mib(8);
|
|
719
|
-
var TLS_RPT_MAX_POLICIES_PER_REPORT = 1024; // allow:raw-
|
|
719
|
+
var TLS_RPT_MAX_POLICIES_PER_REPORT = 1024; // allow:raw-time-literal — count cap, not seconds
|
|
720
720
|
|
|
721
721
|
function tlsRptParseReport(body, opts) {
|
|
722
722
|
opts = opts || {};
|