@blamejs/blamejs-shop 0.5.12 → 0.5.13
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/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) blamejs contributors
|
|
3
|
+
"use strict";
|
|
4
|
+
/**
|
|
5
|
+
* b.crypto.spkiPin / b.crypto.spkiPinVerifier — RFC 7469 (HPKP §2.4)
|
|
6
|
+
* SubjectPublicKeyInfo pinning.
|
|
7
|
+
*
|
|
8
|
+
* The pin is base64(SHA-256(SPKI DER)) — the interop wire form browsers,
|
|
9
|
+
* curl `--pinnedpubkey`, and other pinning tooling render. Distinct from
|
|
10
|
+
* `b.crypto.hashCertFingerprint`, which is SHA3-512 over the WHOLE cert:
|
|
11
|
+
* an SPKI pin survives certificate reissue on the same key, a whole-cert
|
|
12
|
+
* fingerprint does not.
|
|
13
|
+
*
|
|
14
|
+
* Reuses the in-tree self-signed cert builder from crypto.test.js so the
|
|
15
|
+
* SPKI bytes come from a real X.509 cert rather than a synthetic fixture.
|
|
16
|
+
*
|
|
17
|
+
* Run standalone: `node test/layer-0-primitives/crypto-spki-pin.test.js`
|
|
18
|
+
* Or via smoke: `node test/smoke.js`
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var helpers = require("../helpers");
|
|
22
|
+
var b = helpers.b;
|
|
23
|
+
var check = helpers.check;
|
|
24
|
+
var nodeCrypto = require("node:crypto");
|
|
25
|
+
|
|
26
|
+
var _makeEcCert = require("./crypto.test.js")._makeEcCert;
|
|
27
|
+
|
|
28
|
+
// Peer-cert object in the shape Node hands `checkServerIdentity`: the
|
|
29
|
+
// detailed cert carries `.subject`, `.subjectaltname`, and `.raw` (DER).
|
|
30
|
+
function _peerCertObject(fixture, cn, san) {
|
|
31
|
+
return {
|
|
32
|
+
subject: { CN: cn },
|
|
33
|
+
subjectaltname: san,
|
|
34
|
+
raw: fixture.certDer,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function testSpkiPinShape() {
|
|
39
|
+
var fixture = _makeEcCert("pin-shape.example", "P-256");
|
|
40
|
+
var pin = b.crypto.spkiPin(fixture.certDer);
|
|
41
|
+
check("spkiPin returns { sha256, b64, hex }",
|
|
42
|
+
pin && typeof pin.sha256 === "string" &&
|
|
43
|
+
typeof pin.b64 === "string" && typeof pin.hex === "string");
|
|
44
|
+
// SHA-256 = 32 bytes → 44 base64 chars (43 data + 1 '=' pad).
|
|
45
|
+
check("spkiPin.sha256 is 'sha256/<44-char base64>'",
|
|
46
|
+
/^sha256\/[A-Za-z0-9+/]{43}=$/.test(pin.sha256));
|
|
47
|
+
check("spkiPin.b64 is the 44-char base64 body",
|
|
48
|
+
pin.b64.length === 44 && pin.sha256 === "sha256/" + pin.b64);
|
|
49
|
+
// SHA-256 = 32 bytes → 64 lowercase-hex chars.
|
|
50
|
+
check("spkiPin.hex is 64 lowercase-hex chars",
|
|
51
|
+
/^[0-9a-f]{64}$/.test(pin.hex));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function testSpkiPinKnownAnswer() {
|
|
55
|
+
var fixture = _makeEcCert("pin-kat.example", "P-384");
|
|
56
|
+
// Independently derive the pin: extract SPKI DER, SHA-256, base64.
|
|
57
|
+
var spkiDer = new nodeCrypto.X509Certificate(fixture.certDer)
|
|
58
|
+
.publicKey.export({ type: "spki", format: "der" });
|
|
59
|
+
var expB64 = nodeCrypto.createHash("sha256").update(spkiDer).digest("base64");
|
|
60
|
+
var expHex = nodeCrypto.createHash("sha256").update(spkiDer).digest("hex");
|
|
61
|
+
var pin = b.crypto.spkiPin(fixture.certDer);
|
|
62
|
+
check("spkiPin.b64 matches independent SHA-256(SPKI) KAT", pin.b64 === expB64);
|
|
63
|
+
check("spkiPin.sha256 matches 'sha256/' + KAT", pin.sha256 === "sha256/" + expB64);
|
|
64
|
+
check("spkiPin.hex matches independent hex KAT", pin.hex === expHex);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function testSpkiPinPemDerAgreement() {
|
|
68
|
+
var fixture = _makeEcCert("pin-pemder.example", "P-256");
|
|
69
|
+
var fromDer = b.crypto.spkiPin(fixture.certDer);
|
|
70
|
+
var fromPem = b.crypto.spkiPin(fixture.pem);
|
|
71
|
+
check("spkiPin(DER) === spkiPin(PEM)", fromDer.sha256 === fromPem.sha256);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function testSpkiPinBadInput() {
|
|
75
|
+
var threw = null;
|
|
76
|
+
try { b.crypto.spkiPin(42); } catch (e) { threw = e; }
|
|
77
|
+
check("spkiPin rejects non-Buffer/non-string input", threw instanceof TypeError);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function testVerifierMatchingCert() {
|
|
81
|
+
var fixture = _makeEcCert("verify-ok.example", "P-256");
|
|
82
|
+
var correctPin = b.crypto.spkiPin(fixture.certDer).sha256;
|
|
83
|
+
// RFC 7469 requires a backup pin — supply a second, non-matching one.
|
|
84
|
+
var backupPin = b.crypto.spkiPin(_makeEcCert("backup.example", "P-256").certDer).sha256;
|
|
85
|
+
var verify = b.crypto.spkiPinVerifier({ pins: [correctPin, backupPin] });
|
|
86
|
+
var certObj = _peerCertObject(fixture, "verify-ok.example", "DNS:verify-ok.example");
|
|
87
|
+
check("verifier: undefined for matching pin + matching hostname",
|
|
88
|
+
verify("verify-ok.example", certObj) === undefined);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function testVerifierNonMatchingPin() {
|
|
92
|
+
var fixture = _makeEcCert("verify-badpin.example", "P-256");
|
|
93
|
+
// Two pins, neither derived from this cert.
|
|
94
|
+
var wrong1 = b.crypto.spkiPin(_makeEcCert("other-1.example", "P-256").certDer).sha256;
|
|
95
|
+
var wrong2 = b.crypto.spkiPin(_makeEcCert("other-2.example", "P-256").certDer).sha256;
|
|
96
|
+
var verify = b.crypto.spkiPinVerifier({ pins: [wrong1, wrong2] });
|
|
97
|
+
var certObj = _peerCertObject(fixture, "verify-badpin.example", "DNS:verify-badpin.example");
|
|
98
|
+
var res = verify("verify-badpin.example", certObj);
|
|
99
|
+
check("verifier: Error when peer pin matches no configured pin",
|
|
100
|
+
res instanceof Error && res.code === "crypto/spki-pin-mismatch");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function testVerifierHostnameMismatchWinsOverPin() {
|
|
104
|
+
var fixture = _makeEcCert("verify-host.example", "P-256");
|
|
105
|
+
var correctPin = b.crypto.spkiPin(fixture.certDer).sha256;
|
|
106
|
+
var backupPin = b.crypto.spkiPin(_makeEcCert("backup2.example", "P-256").certDer).sha256;
|
|
107
|
+
var verify = b.crypto.spkiPinVerifier({ pins: [correctPin, backupPin] });
|
|
108
|
+
// Cert SAN is for verify-host.example, but we ask the verifier about a
|
|
109
|
+
// different host — the identity (hostname/SAN) check must refuse FIRST,
|
|
110
|
+
// even though the SPKI pin itself would match.
|
|
111
|
+
var certObj = _peerCertObject(fixture, "verify-host.example", "DNS:verify-host.example");
|
|
112
|
+
var res = verify("wrong-host.example", certObj);
|
|
113
|
+
check("verifier: hostname/SAN error precedes the pin match",
|
|
114
|
+
res instanceof Error &&
|
|
115
|
+
typeof res.code === "string" && res.code.indexOf("tls/pkix") === 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function testVerifierHostnameOptOverride() {
|
|
119
|
+
var fixture = _makeEcCert("verify-opt.example", "P-256");
|
|
120
|
+
var correctPin = b.crypto.spkiPin(fixture.certDer).sha256;
|
|
121
|
+
var backupPin = b.crypto.spkiPin(_makeEcCert("backup3.example", "P-256").certDer).sha256;
|
|
122
|
+
// opts.hostname pins the expected name; the host argument Node supplies
|
|
123
|
+
// is ignored in favour of it.
|
|
124
|
+
var verify = b.crypto.spkiPinVerifier({
|
|
125
|
+
pins: [correctPin, backupPin],
|
|
126
|
+
hostname: "verify-opt.example",
|
|
127
|
+
});
|
|
128
|
+
var certObj = _peerCertObject(fixture, "verify-opt.example", "DNS:verify-opt.example");
|
|
129
|
+
check("verifier: opts.hostname override accepts a matching cert",
|
|
130
|
+
verify("ignored-by-override.example", certObj) === undefined);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function testVerifierBadOpts() {
|
|
134
|
+
var t1 = null;
|
|
135
|
+
try { b.crypto.spkiPinVerifier(); } catch (e) { t1 = e; }
|
|
136
|
+
check("spkiPinVerifier: requires opts", t1 instanceof TypeError);
|
|
137
|
+
|
|
138
|
+
var t2 = null;
|
|
139
|
+
try { b.crypto.spkiPinVerifier({ pins: "sha256/x" }); } catch (e) { t2 = e; }
|
|
140
|
+
check("spkiPinVerifier: pins must be an array", t2 instanceof TypeError);
|
|
141
|
+
|
|
142
|
+
var t3 = null;
|
|
143
|
+
try { b.crypto.spkiPinVerifier({ pins: ["sha256/" + "A".repeat(43) + "="] }); }
|
|
144
|
+
catch (e) { t3 = e; }
|
|
145
|
+
check("spkiPinVerifier: refuses a single pin (RFC 7469 backup pin required)",
|
|
146
|
+
t3 instanceof TypeError);
|
|
147
|
+
|
|
148
|
+
// Two IDENTICAL pins are not a backup — the same key repeated passes a
|
|
149
|
+
// length-only check but leaves the endpoint with no rotation key.
|
|
150
|
+
var t3dup = null;
|
|
151
|
+
try {
|
|
152
|
+
var samePin = "sha256/" + "A".repeat(43) + "=";
|
|
153
|
+
b.crypto.spkiPinVerifier({ pins: [samePin, samePin] });
|
|
154
|
+
} catch (e) { t3dup = e; }
|
|
155
|
+
check("spkiPinVerifier: refuses two duplicate pins (no distinct backup key)",
|
|
156
|
+
t3dup instanceof TypeError);
|
|
157
|
+
|
|
158
|
+
var t4 = null;
|
|
159
|
+
try {
|
|
160
|
+
b.crypto.spkiPinVerifier({ pins: ["not-a-pin", "sha256/" + "A".repeat(43) + "="] });
|
|
161
|
+
} catch (e) { t4 = e; }
|
|
162
|
+
check("spkiPinVerifier: refuses a pin missing the 'sha256/' prefix",
|
|
163
|
+
t4 instanceof TypeError);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function run() {
|
|
167
|
+
testSpkiPinShape();
|
|
168
|
+
testSpkiPinKnownAnswer();
|
|
169
|
+
testSpkiPinPemDerAgreement();
|
|
170
|
+
testSpkiPinBadInput();
|
|
171
|
+
testVerifierMatchingCert();
|
|
172
|
+
testVerifierNonMatchingPin();
|
|
173
|
+
testVerifierHostnameMismatchWinsOverPin();
|
|
174
|
+
testVerifierHostnameOptOverride();
|
|
175
|
+
testVerifierBadOpts();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = { run: run };
|
|
179
|
+
|
|
180
|
+
if (require.main === module) {
|
|
181
|
+
try { run(); console.log("[crypto-spki-pin] OK"); }
|
|
182
|
+
catch (e) { console.error(e); process.exit(1); }
|
|
183
|
+
}
|
|
@@ -21,6 +21,13 @@ function code(fn) { try { fn(); return "NO-THROW"; } catch (e) { return e.code;
|
|
|
21
21
|
|
|
22
22
|
var x = b.crypto.xwing;
|
|
23
23
|
|
|
24
|
+
// Wire widths (bytes) fixed by draft-connolly-cfrg-xwing-kem, mirrored here so
|
|
25
|
+
// the low-order-point test can index the X25519 ephemeral inside the ciphertext.
|
|
26
|
+
var ML_KEM_PK = 1184;
|
|
27
|
+
var ML_KEM_CT = 1088;
|
|
28
|
+
var X25519_LEN = 32;
|
|
29
|
+
var SS_LEN = 32;
|
|
30
|
+
|
|
24
31
|
function testSurface() {
|
|
25
32
|
check("xwing.keygen is fn", typeof x.keygen === "function");
|
|
26
33
|
check("xwing.encapsulate is fn", typeof x.encapsulate === "function");
|
|
@@ -109,6 +116,46 @@ function testErrors() {
|
|
|
109
116
|
check("decapsulate rejects a short ct", code(function () { x.decapsulate(kp.secretKey, Buffer.alloc(100)); }) === "xwing/bad-ciphertext");
|
|
110
117
|
}
|
|
111
118
|
|
|
119
|
+
// draft-connolly-cfrg-xwing-kem section 5.1 uses X25519 as specified in RFC
|
|
120
|
+
// 7748 WITHOUT the RFC 7748 section 6.1 all-zero-output abort: decapsulation is
|
|
121
|
+
// uniform implicit-rejection and never signals ciphertext validity by throwing.
|
|
122
|
+
// A low-order X25519 ephemeral in ctX (all-zero, 1, or a small-subgroup point)
|
|
123
|
+
// yields an all-zero X25519 shared secret that flows through the combiner, and
|
|
124
|
+
// the ML-KEM-768 leg still protects the result. The framework's X25519 runs
|
|
125
|
+
// through OpenSSL, which aborts on the all-zero derivation, so a hostile ctX
|
|
126
|
+
// must NOT surface that raw error out of decapsulate/encapsulate.
|
|
127
|
+
function testLowOrderX25519NoThrow() {
|
|
128
|
+
var kp = x.keygen();
|
|
129
|
+
var enc = x.encapsulate(kp.publicKey);
|
|
130
|
+
// A few X25519 points that drive the Montgomery ladder to the all-zero
|
|
131
|
+
// shared secret (the identity + order-8 small-subgroup points, RFC 7748).
|
|
132
|
+
var lowOrder = [
|
|
133
|
+
Buffer.alloc(X25519_LEN, 0x00),
|
|
134
|
+
Buffer.from("0100000000000000000000000000000000000000000000000000000000000000", "hex"),
|
|
135
|
+
Buffer.from("e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800", "hex"),
|
|
136
|
+
Buffer.from("5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157", "hex"),
|
|
137
|
+
];
|
|
138
|
+
lowOrder.forEach(function (lp, i) {
|
|
139
|
+
var bad = Buffer.from(enc.ciphertext);
|
|
140
|
+
lp.copy(bad, ML_KEM_CT); // overwrite the trailing 32-byte X25519 ephemeral
|
|
141
|
+
var ss;
|
|
142
|
+
var threw = code(function () { ss = x.decapsulate(kp.secretKey, bad); });
|
|
143
|
+
check("decapsulate does not throw on a low-order X25519 ephemeral #" + i, threw === "NO-THROW");
|
|
144
|
+
check("decapsulate still yields a 32-byte secret #" + i, Buffer.isBuffer(ss) && ss.length === SS_LEN);
|
|
145
|
+
check("low-order ctX yields an implicit-rejection secret (differs from good) #" + i, !ss.equals(enc.sharedSecret));
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Encapsulate to a public key whose X25519 half is a low-order point must
|
|
149
|
+
// not surface the raw OpenSSL derivation error either (same X25519 seam).
|
|
150
|
+
var badPk = Buffer.from(kp.publicKey);
|
|
151
|
+
Buffer.alloc(X25519_LEN, 0x00).copy(badPk, ML_KEM_PK);
|
|
152
|
+
var out;
|
|
153
|
+
var encThrew = code(function () { out = x.encapsulate(badPk); });
|
|
154
|
+
check("encapsulate does not throw on a low-order X25519 recipient key", encThrew === "NO-THROW");
|
|
155
|
+
check("encapsulate to low-order key still returns the wire shape",
|
|
156
|
+
out && out.ciphertext.length === 1120 && out.sharedSecret.length === SS_LEN);
|
|
157
|
+
}
|
|
158
|
+
|
|
112
159
|
async function run() {
|
|
113
160
|
testSurface();
|
|
114
161
|
testCombinerKAT();
|
|
@@ -117,6 +164,7 @@ async function run() {
|
|
|
117
164
|
testDeterminism();
|
|
118
165
|
testImplicitRejection();
|
|
119
166
|
testErrors();
|
|
167
|
+
testLowOrderX25519NoThrow();
|
|
120
168
|
}
|
|
121
169
|
module.exports = { run: run };
|
|
122
170
|
if (require.main === module) { run().then(function () { console.log("[crypto-xwing] OK — " + helpers.getChecks() + " checks passed"); }, function (e) { console.error("FAIL:", e && e.stack || e); process.exit(1); }); }
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) blamejs contributors
|
|
3
|
+
"use strict";
|
|
4
|
+
/**
|
|
5
|
+
* Core b.crypto surface without a dedicated sub-domain file:
|
|
6
|
+
* - hmacSha3 / kdf / sri — keyed integrity, SHAKE256 derivation, W3C SRI.
|
|
7
|
+
* - hashCertFingerprint / isCertRevoked — peer-cert pinning + deny lists.
|
|
8
|
+
* - encryptEnvelopeAsCertPeer / decryptEnvelopeAsCertPeer — cert-bound
|
|
9
|
+
* envelope round trip against real P-384 cert + ML-KEM-1024 material.
|
|
10
|
+
*
|
|
11
|
+
* The cert-peer + fingerprint + revocation cases share one in-tree ASN.1
|
|
12
|
+
* DER self-signed cert whose SubjectPublicKeyInfo carries a P-384 ECDH
|
|
13
|
+
* public key — the exact shape `encryptEnvelopeAsCertPeer` extracts.
|
|
14
|
+
*
|
|
15
|
+
* Run standalone: `node test/layer-0-primitives/crypto.test.js`
|
|
16
|
+
* Or via smoke: `node test/smoke.js`
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
var helpers = require("../helpers");
|
|
20
|
+
var b = helpers.b;
|
|
21
|
+
var check = helpers.check;
|
|
22
|
+
var asn1 = require("../../lib/asn1-der");
|
|
23
|
+
var nodeCrypto = require("node:crypto");
|
|
24
|
+
|
|
25
|
+
// ---- In-tree self-signed cert builder (mirrors content-credentials.test.js
|
|
26
|
+
// but keyed on an EC curve so the SPKI carries an ECDH public key). Node's
|
|
27
|
+
// X509Certificate only parses — it never verifies the signature — so an
|
|
28
|
+
// ECDSA self-signature over the TBS is enough for `.publicKey` extraction.
|
|
29
|
+
function _utcTime(d) {
|
|
30
|
+
var s = d.toISOString().replace(/[-:T]/g, "").slice(2, 14) + "Z";
|
|
31
|
+
return asn1.writeNode(0x17, Buffer.from(s, "ascii"));
|
|
32
|
+
}
|
|
33
|
+
function _certName(cn) {
|
|
34
|
+
return asn1.writeSequence([
|
|
35
|
+
asn1.writeSet([
|
|
36
|
+
asn1.writeSequence([asn1.writeOid("2.5.4.3"), asn1.writeUtf8String(cn)]),
|
|
37
|
+
]),
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
// Build a self-signed X.509 cert for `cn` over `namedCurve`. Returns the
|
|
41
|
+
// DER bytes, the matching EC private key (KeyObject), and the parsed PEM.
|
|
42
|
+
function _makeEcCert(cn, namedCurve) {
|
|
43
|
+
var kp = nodeCrypto.generateKeyPairSync("ec", { namedCurve: namedCurve });
|
|
44
|
+
var spki = kp.publicKey.export({ type: "spki", format: "der" });
|
|
45
|
+
var name = _certName(cn);
|
|
46
|
+
var version = asn1.writeContextExplicit(0, asn1.writeInteger(Buffer.from([2])));
|
|
47
|
+
var serial = asn1.writeInteger(Buffer.from([0x2c]));
|
|
48
|
+
// ecdsa-with-SHA384 (1.2.840.10045.4.3.3) — ECDSA AlgorithmIdentifiers
|
|
49
|
+
// carry no parameters (not even NULL).
|
|
50
|
+
var sigAlgId = asn1.writeSequence([asn1.writeOid("1.2.840.10045.4.3.3")]);
|
|
51
|
+
var now = Date.now();
|
|
52
|
+
var validity = asn1.writeSequence([
|
|
53
|
+
_utcTime(new Date(now - 86400000)),
|
|
54
|
+
_utcTime(new Date(now + 86400000 * 3650)),
|
|
55
|
+
]);
|
|
56
|
+
var tbs = asn1.writeSequence([version, serial, sigAlgId, name, validity, name, spki]);
|
|
57
|
+
var sig = nodeCrypto.sign("sha384", tbs, kp.privateKey);
|
|
58
|
+
var certDer = asn1.writeSequence([tbs, sigAlgId, asn1.writeBitString(sig, 0)]);
|
|
59
|
+
return {
|
|
60
|
+
certDer: certDer,
|
|
61
|
+
ecPrivateKey: kp.privateKey,
|
|
62
|
+
ecPrivatePem: kp.privateKey.export({ type: "pkcs8", format: "pem" }),
|
|
63
|
+
pem: new nodeCrypto.X509Certificate(certDer).toString(),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function testHmacSha3() {
|
|
68
|
+
// HMAC-SHA3-512 = 64 bytes = 128 lowercase-hex chars.
|
|
69
|
+
var tag = b.crypto.hmacSha3("shared-secret", "POST /webhook|123");
|
|
70
|
+
check("hmacSha3 returns 128 hex chars", tag.length === 128 && /^[0-9a-f]+$/.test(tag));
|
|
71
|
+
|
|
72
|
+
// Known answer against an independent HMAC-SHA3-512 computation.
|
|
73
|
+
var expected = nodeCrypto.createHmac("sha3-512", "shared-secret")
|
|
74
|
+
.update("POST /webhook|123").digest("hex");
|
|
75
|
+
check("hmacSha3 matches HMAC-SHA3-512 KAT", tag === expected);
|
|
76
|
+
|
|
77
|
+
// Deterministic — same (key, data) → same tag.
|
|
78
|
+
var det1 = b.crypto.hmacSha3("k", "d");
|
|
79
|
+
var det2 = b.crypto.hmacSha3("k", "d");
|
|
80
|
+
check("hmacSha3 is deterministic", det1 === det2);
|
|
81
|
+
|
|
82
|
+
// Keyed difference — a different key over identical data diverges.
|
|
83
|
+
check("hmacSha3 diverges on key change",
|
|
84
|
+
b.crypto.hmacSha3("key-a", "d") !== b.crypto.hmacSha3("key-b", "d"));
|
|
85
|
+
|
|
86
|
+
// Data difference — same key over different data diverges.
|
|
87
|
+
check("hmacSha3 diverges on data change",
|
|
88
|
+
b.crypto.hmacSha3("k", "data-a") !== b.crypto.hmacSha3("k", "data-b"));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function testKdf() {
|
|
92
|
+
var seed = Buffer.from("master-secret|session-42", "utf8");
|
|
93
|
+
|
|
94
|
+
// Exact requested output length (SHAKE256 XOF — arbitrary length).
|
|
95
|
+
var k32 = b.crypto.kdf(seed, 32);
|
|
96
|
+
var k64 = b.crypto.kdf(seed, 64);
|
|
97
|
+
check("kdf honours outputLength 32", Buffer.isBuffer(k32) && k32.length === 32);
|
|
98
|
+
check("kdf honours outputLength 64", Buffer.isBuffer(k64) && k64.length === 64);
|
|
99
|
+
|
|
100
|
+
// Known answer against an independent SHAKE256 computation.
|
|
101
|
+
var expected = nodeCrypto.createHash("shake256", { outputLength: 32 })
|
|
102
|
+
.update(seed).digest();
|
|
103
|
+
check("kdf matches SHAKE256 KAT", Buffer.compare(k32, expected) === 0);
|
|
104
|
+
|
|
105
|
+
// Determinism — same (input, length) → identical key.
|
|
106
|
+
var kdet1 = b.crypto.kdf(seed, 32);
|
|
107
|
+
var kdet2 = b.crypto.kdf(seed, 32);
|
|
108
|
+
check("kdf is deterministic", Buffer.compare(kdet1, kdet2) === 0);
|
|
109
|
+
|
|
110
|
+
// Different input → different key (the "different salt" case: kdf's only
|
|
111
|
+
// domain-separation lever is the input, since it takes no explicit salt).
|
|
112
|
+
var other = b.crypto.kdf(Buffer.from("master-secret|session-99", "utf8"), 32);
|
|
113
|
+
check("kdf diverges on input change", Buffer.compare(k32, other) !== 0);
|
|
114
|
+
|
|
115
|
+
// XOF prefix property — the 32-byte output is the prefix of the 64-byte
|
|
116
|
+
// output for the same input (SHAKE256 is a stream, not a fresh hash).
|
|
117
|
+
check("kdf shorter output prefixes the longer", Buffer.compare(k32, k64.subarray(0, 32)) === 0);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function testSri() {
|
|
121
|
+
// W3C SRI 1.0 attribute string: "<alg>-<base64>". Known answer against an
|
|
122
|
+
// independent SHA-384 base64 computation.
|
|
123
|
+
var payload = Buffer.from("alert(1);", "utf8");
|
|
124
|
+
var attr = b.crypto.sri(payload, { algorithm: "sha384" });
|
|
125
|
+
var expB64 = nodeCrypto.createHash("sha384").update(payload).digest("base64");
|
|
126
|
+
check("sri sha384 matches known answer", attr === "sha384-" + expB64);
|
|
127
|
+
|
|
128
|
+
// RFC/W3C integrity format: alg token + base64 body (with optional padding).
|
|
129
|
+
check("sri emits W3C integrity format", /^sha(256|384|512)-[A-Za-z0-9+/]+={0,2}$/.test(attr));
|
|
130
|
+
check("sri base64 body decodes to 48 bytes (sha384)",
|
|
131
|
+
Buffer.from(attr.slice("sha384-".length), "base64").length === 48);
|
|
132
|
+
|
|
133
|
+
// Default algorithm is sha384.
|
|
134
|
+
check("sri default algorithm is sha384", b.crypto.sri("x").indexOf("sha384-") === 0);
|
|
135
|
+
|
|
136
|
+
// string and Buffer inputs agree; Uint8Array accepted.
|
|
137
|
+
check("sri string and Buffer agree",
|
|
138
|
+
b.crypto.sri("alert(1);", { algorithm: "sha384" }) === attr);
|
|
139
|
+
check("sri accepts Uint8Array",
|
|
140
|
+
b.crypto.sri(new Uint8Array(payload), { algorithm: "sha384" }) === attr);
|
|
141
|
+
|
|
142
|
+
// sha256 / sha512 emit the correct token + digest length.
|
|
143
|
+
var s256 = b.crypto.sri(payload, { algorithm: "sha256" });
|
|
144
|
+
var s512 = b.crypto.sri(payload, { algorithm: "sha512" });
|
|
145
|
+
check("sri sha256 token + 32-byte digest",
|
|
146
|
+
s256.indexOf("sha256-") === 0 && Buffer.from(s256.slice(7), "base64").length === 32);
|
|
147
|
+
check("sri sha512 token + 64-byte digest",
|
|
148
|
+
s512.indexOf("sha512-") === 0 && Buffer.from(s512.slice(7), "base64").length === 64);
|
|
149
|
+
|
|
150
|
+
// Array input → space-separated multi-integrity per W3C §3.3.
|
|
151
|
+
var multi = b.crypto.sri(["payload-a", "payload-b"], { algorithm: "sha512" });
|
|
152
|
+
var tokens = multi.split(" ");
|
|
153
|
+
check("sri array emits one token per element", tokens.length === 2);
|
|
154
|
+
check("sri array tokens are each valid integrity strings",
|
|
155
|
+
tokens[0] === b.crypto.sri("payload-a", { algorithm: "sha512" }) &&
|
|
156
|
+
tokens[1] === b.crypto.sri("payload-b", { algorithm: "sha512" }));
|
|
157
|
+
|
|
158
|
+
// Unsupported algorithm throws (config-time entry-tier).
|
|
159
|
+
var threwAlg = false;
|
|
160
|
+
try { b.crypto.sri(payload, { algorithm: "sha1" }); }
|
|
161
|
+
catch (e) { threwAlg = /unsupported algorithm/.test(e.message); }
|
|
162
|
+
check("sri refuses unsupported algorithm", threwAlg);
|
|
163
|
+
|
|
164
|
+
// Non-Buffer/string/Uint8Array content throws.
|
|
165
|
+
var threwType = false;
|
|
166
|
+
try { b.crypto.sri(42, { algorithm: "sha384" }); }
|
|
167
|
+
catch (e) { threwType = /content must be/.test(e.message); }
|
|
168
|
+
check("sri refuses non-byte content", threwType);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function testCertFingerprint() {
|
|
172
|
+
var cert = _makeEcCert("fp.example", "P-384");
|
|
173
|
+
|
|
174
|
+
// Accepts a PEM string (the shape the @example documents) — this path was
|
|
175
|
+
// silently broken before the safeBuffer()-call fix and threw a TypeError.
|
|
176
|
+
var fp = b.crypto.hashCertFingerprint(cert.pem);
|
|
177
|
+
check("hashCertFingerprint hex is 128 chars (SHA3-512)",
|
|
178
|
+
typeof fp.hex === "string" && fp.hex.length === 128 && /^[0-9a-f]+$/.test(fp.hex));
|
|
179
|
+
check("hashCertFingerprint colon form has 64 groups",
|
|
180
|
+
fp.colon.split(":").length === 64);
|
|
181
|
+
check("hashCertFingerprint colon form is uppercase hex pairs",
|
|
182
|
+
/^[0-9A-F]{2}(:[0-9A-F]{2}){63}$/.test(fp.colon));
|
|
183
|
+
|
|
184
|
+
// DER (Buffer) and PEM of the same cert produce identical fingerprints.
|
|
185
|
+
var fpDer = b.crypto.hashCertFingerprint(cert.certDer);
|
|
186
|
+
check("hashCertFingerprint PEM and DER agree", fpDer.hex === fp.hex);
|
|
187
|
+
|
|
188
|
+
// Known answer against an independent SHA3-512 over the DER bytes.
|
|
189
|
+
var direct = nodeCrypto.createHash("sha3-512").update(cert.certDer).digest("hex");
|
|
190
|
+
check("hashCertFingerprint matches SHA3-512(DER) KAT", fp.hex === direct);
|
|
191
|
+
|
|
192
|
+
// Non-Buffer / non-string input throws.
|
|
193
|
+
var threwType = false;
|
|
194
|
+
try { b.crypto.hashCertFingerprint(42); }
|
|
195
|
+
catch (e) { threwType = e instanceof TypeError; }
|
|
196
|
+
check("hashCertFingerprint refuses non-Buffer/non-string", threwType);
|
|
197
|
+
|
|
198
|
+
// PEM without BEGIN/END markers throws.
|
|
199
|
+
var threwMarker = false;
|
|
200
|
+
try { b.crypto.hashCertFingerprint("not a pem at all"); }
|
|
201
|
+
catch (e) { threwMarker = e instanceof TypeError && /BEGIN\/END/.test(e.message); }
|
|
202
|
+
check("hashCertFingerprint refuses markerless PEM", threwMarker);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function testCertRevoked() {
|
|
206
|
+
var cert = _makeEcCert("revoked.example", "P-384");
|
|
207
|
+
var other = _makeEcCert("other.example", "P-384");
|
|
208
|
+
var fp = b.crypto.hashCertFingerprint(cert.pem);
|
|
209
|
+
|
|
210
|
+
// A cert whose fingerprint (colon form) is on the deny list → revoked.
|
|
211
|
+
check("isCertRevoked true when colon fingerprint on deny list",
|
|
212
|
+
b.crypto.isCertRevoked(cert.pem, [fp.colon]) === true);
|
|
213
|
+
|
|
214
|
+
// Lowercase-hex deny entry also matches.
|
|
215
|
+
check("isCertRevoked true when hex fingerprint on deny list",
|
|
216
|
+
b.crypto.isCertRevoked(cert.pem, [fp.hex]) === true);
|
|
217
|
+
|
|
218
|
+
// A deny list carrying only an unrelated cert's fingerprint → not revoked.
|
|
219
|
+
var otherFp = b.crypto.hashCertFingerprint(other.pem);
|
|
220
|
+
check("isCertRevoked false when only another cert is denied",
|
|
221
|
+
b.crypto.isCertRevoked(cert.pem, [otherFp.colon, otherFp.hex]) === false);
|
|
222
|
+
|
|
223
|
+
// Empty deny list → not revoked.
|
|
224
|
+
check("isCertRevoked false on empty deny list",
|
|
225
|
+
b.crypto.isCertRevoked(cert.pem, []) === false);
|
|
226
|
+
|
|
227
|
+
// Match survives a deny list where the hit is not the first entry.
|
|
228
|
+
check("isCertRevoked scans the whole deny list",
|
|
229
|
+
b.crypto.isCertRevoked(cert.pem, ["DEADBEEF", "", fp.hex]) === true);
|
|
230
|
+
|
|
231
|
+
// Non-array deny list throws (entry-tier).
|
|
232
|
+
var threw = false;
|
|
233
|
+
try { b.crypto.isCertRevoked(cert.pem, "not-an-array"); }
|
|
234
|
+
catch (e) { threw = e instanceof TypeError; }
|
|
235
|
+
check("isCertRevoked refuses non-array deny list", threw);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function testCertPeerEnvelopeRoundTrip() {
|
|
239
|
+
// The recipient peer owns: a TLS cert carrying its P-384 ECDH pubkey, and
|
|
240
|
+
// an ML-KEM-1024 keypair (publishes the pubkey, keeps the secret).
|
|
241
|
+
var kem = b.crypto.generateEncryptionKeyPair(); // ML-KEM-1024 + P-384 bundle; use the KEM half
|
|
242
|
+
var cert = _makeEcCert("peer.example", "P-384");
|
|
243
|
+
|
|
244
|
+
var sealed = b.crypto.encryptEnvelopeAsCertPeer("cross-peer payload", {
|
|
245
|
+
peerCertDer: cert.certDer,
|
|
246
|
+
peerKemPubkey: kem.publicKey,
|
|
247
|
+
});
|
|
248
|
+
check("encryptEnvelopeAsCertPeer returns a base64 envelope string",
|
|
249
|
+
typeof sealed === "string" && sealed.length > 0);
|
|
250
|
+
|
|
251
|
+
// Receive side with the EC private key as a KeyObject.
|
|
252
|
+
var openedKo = b.crypto.decryptEnvelopeAsCertPeer(sealed, {
|
|
253
|
+
certPrivateKey: cert.ecPrivateKey,
|
|
254
|
+
kemSecret: kem.privateKey,
|
|
255
|
+
});
|
|
256
|
+
check("decryptEnvelopeAsCertPeer round-trips with KeyObject cert key",
|
|
257
|
+
openedKo === "cross-peer payload");
|
|
258
|
+
|
|
259
|
+
// Receive side with the EC private key as a PEM string.
|
|
260
|
+
var openedPem = b.crypto.decryptEnvelopeAsCertPeer(sealed, {
|
|
261
|
+
certPrivateKey: cert.ecPrivatePem,
|
|
262
|
+
kemSecret: kem.privateKey,
|
|
263
|
+
});
|
|
264
|
+
check("decryptEnvelopeAsCertPeer round-trips with PEM cert key",
|
|
265
|
+
openedPem === "cross-peer payload");
|
|
266
|
+
|
|
267
|
+
// Wrong recipient (fresh unrelated ML-KEM secret) cannot open it.
|
|
268
|
+
var wrongKem = b.crypto.generateEncryptionKeyPair();
|
|
269
|
+
var threwWrong = false;
|
|
270
|
+
try {
|
|
271
|
+
b.crypto.decryptEnvelopeAsCertPeer(sealed, {
|
|
272
|
+
certPrivateKey: cert.ecPrivateKey,
|
|
273
|
+
kemSecret: wrongKem.privateKey,
|
|
274
|
+
});
|
|
275
|
+
} catch (_e) { threwWrong = true; }
|
|
276
|
+
check("decryptEnvelopeAsCertPeer refuses a mismatched KEM secret", threwWrong);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function testCertPeerEnvelopeValidation() {
|
|
280
|
+
var kem = b.crypto.generateEncryptionKeyPair();
|
|
281
|
+
var cert = _makeEcCert("peer.example", "P-384");
|
|
282
|
+
|
|
283
|
+
// A cert whose key is not ECDH P-384 is refused with a specific code.
|
|
284
|
+
var p256 = _makeEcCert("p256.example", "P-256");
|
|
285
|
+
var threwCurve;
|
|
286
|
+
try {
|
|
287
|
+
b.crypto.encryptEnvelopeAsCertPeer("x", { peerCertDer: p256.certDer, peerKemPubkey: kem.publicKey });
|
|
288
|
+
} catch (e) { threwCurve = e; }
|
|
289
|
+
check("encryptEnvelopeAsCertPeer rejects non-P-384 cert key",
|
|
290
|
+
threwCurve && threwCurve.code === "crypto/cert-key-not-ecdh-p384");
|
|
291
|
+
|
|
292
|
+
// Missing peerCertDer / peerKemPubkey carry their documented codes.
|
|
293
|
+
var missCert;
|
|
294
|
+
try { b.crypto.encryptEnvelopeAsCertPeer("x", { peerKemPubkey: kem.publicKey }); }
|
|
295
|
+
catch (e) { missCert = e; }
|
|
296
|
+
check("encryptEnvelopeAsCertPeer flags missing peerCertDer",
|
|
297
|
+
missCert && missCert.code === "crypto/peer-cert-missing");
|
|
298
|
+
|
|
299
|
+
var missKem;
|
|
300
|
+
try { b.crypto.encryptEnvelopeAsCertPeer("x", { peerCertDer: cert.certDer, peerKemPubkey: "" }); }
|
|
301
|
+
catch (e) { missKem = e; }
|
|
302
|
+
check("encryptEnvelopeAsCertPeer flags empty peerKemPubkey",
|
|
303
|
+
missKem && missKem.code === "crypto/peer-kem-pubkey-missing");
|
|
304
|
+
|
|
305
|
+
// Decrypt side: missing keys + wrong-shape / wrong-curve cert private key.
|
|
306
|
+
var missCertPriv;
|
|
307
|
+
try { b.crypto.decryptEnvelopeAsCertPeer("AAAA", { kemSecret: kem.privateKey }); }
|
|
308
|
+
catch (e) { missCertPriv = e; }
|
|
309
|
+
check("decryptEnvelopeAsCertPeer flags missing certPrivateKey",
|
|
310
|
+
missCertPriv && missCertPriv.code === "crypto/cert-private-key-missing");
|
|
311
|
+
|
|
312
|
+
var badShape;
|
|
313
|
+
try { b.crypto.decryptEnvelopeAsCertPeer("AAAA", { certPrivateKey: 42, kemSecret: kem.privateKey }); }
|
|
314
|
+
catch (e) { badShape = e; }
|
|
315
|
+
check("decryptEnvelopeAsCertPeer flags bad-shape certPrivateKey",
|
|
316
|
+
badShape && badShape.code === "crypto/cert-private-key-bad-shape");
|
|
317
|
+
|
|
318
|
+
// A P-256 KeyObject as certPrivateKey is refused (wrong curve).
|
|
319
|
+
var p256Key = nodeCrypto.generateKeyPairSync("ec", { namedCurve: "P-256" }).privateKey;
|
|
320
|
+
var wrongCurveKey;
|
|
321
|
+
try { b.crypto.decryptEnvelopeAsCertPeer("AAAA", { certPrivateKey: p256Key, kemSecret: kem.privateKey }); }
|
|
322
|
+
catch (e) { wrongCurveKey = e; }
|
|
323
|
+
check("decryptEnvelopeAsCertPeer rejects non-P-384 KeyObject cert key",
|
|
324
|
+
wrongCurveKey && wrongCurveKey.code === "crypto/cert-key-not-ecdh-p384");
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function run() {
|
|
328
|
+
testHmacSha3();
|
|
329
|
+
testKdf();
|
|
330
|
+
testSri();
|
|
331
|
+
testCertFingerprint();
|
|
332
|
+
testCertRevoked();
|
|
333
|
+
testCertPeerEnvelopeRoundTrip();
|
|
334
|
+
testCertPeerEnvelopeValidation();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// _makeEcCert is shared with crypto-spki-pin.test.js so the SPKI-pin
|
|
338
|
+
// suite reuses the same in-tree self-signed cert builder rather than
|
|
339
|
+
// rolling its own ASN.1 fixture.
|
|
340
|
+
module.exports = { run: run, _makeEcCert: _makeEcCert };
|
|
341
|
+
|
|
342
|
+
if (require.main === module) {
|
|
343
|
+
try { run(); console.log("[crypto] OK"); }
|
|
344
|
+
catch (e) { console.error(e); process.exit(1); }
|
|
345
|
+
}
|
|
@@ -40,6 +40,7 @@ async function run() {
|
|
|
40
40
|
testOnRejectRejectsNonFunction();
|
|
41
41
|
await testValidPostReachesOnReport();
|
|
42
42
|
await testOversizedPostRefused();
|
|
43
|
+
await testReportCountCapped();
|
|
43
44
|
await testAuditDefaultEmitsViolationRow();
|
|
44
45
|
await testAuditFalseSuppressesViolationRow();
|
|
45
46
|
testMaxBytesGarbageThrowsAtCreate();
|
|
@@ -164,6 +165,63 @@ async function testOversizedPostRefused() {
|
|
|
164
165
|
rejected !== null && rejected.reason === "payload-too-large");
|
|
165
166
|
}
|
|
166
167
|
|
|
168
|
+
// A single POST batches multiple reports. The byte cap bounds the body,
|
|
169
|
+
// not the count — a 64 KiB body of tiny report objects is ~1600 reports,
|
|
170
|
+
// and the endpoint drove one audit-chain append + one onReport hook per
|
|
171
|
+
// entry, so an unauthenticated caller could force ~1600x work per request.
|
|
172
|
+
// The batch length is now capped independently: an over-cap batch is
|
|
173
|
+
// refused whole (413 + onReject "too-many-reports") with ZERO reports
|
|
174
|
+
// processed; a batch at the cap still processes end-to-end.
|
|
175
|
+
async function testReportCountCapped() {
|
|
176
|
+
// Over the default cap (100): refused whole, nothing processed.
|
|
177
|
+
var processedOver = 0, rejectedOver = null;
|
|
178
|
+
var resOver = _capRes();
|
|
179
|
+
var mwOver = b.middleware.cspReport({
|
|
180
|
+
audit: false,
|
|
181
|
+
onReport: function () { processedOver += 1; },
|
|
182
|
+
onReject: function (req, res, info) { rejectedOver = info; },
|
|
183
|
+
});
|
|
184
|
+
var over = [];
|
|
185
|
+
for (var i = 0; i < 150; i += 1) {
|
|
186
|
+
over.push({ type: "csp-violation", body: { effectiveDirective: "script-src" } });
|
|
187
|
+
}
|
|
188
|
+
await mwOver(_bodyReq("POST", { "content-type": "application/reports+json" }, JSON.stringify(over)),
|
|
189
|
+
resOver, function () {});
|
|
190
|
+
check("cspReport: over-cap batch refused with 413",
|
|
191
|
+
resOver._sent.status === 413 && resOver._sent.ended === true);
|
|
192
|
+
check("cspReport: over-cap batch processes zero reports (no per-entry audit/hook amplification)",
|
|
193
|
+
processedOver === 0);
|
|
194
|
+
check("cspReport: over-cap batch fires onReject too-many-reports",
|
|
195
|
+
rejectedOver !== null && rejectedOver.status === 413 && rejectedOver.reason === "too-many-reports");
|
|
196
|
+
|
|
197
|
+
// A custom lower cap is honored, and a batch at exactly the cap still
|
|
198
|
+
// processes every report (the cap is inclusive).
|
|
199
|
+
var processedAt = 0;
|
|
200
|
+
var resAt = _capRes();
|
|
201
|
+
var mwAt = b.middleware.cspReport({
|
|
202
|
+
audit: false,
|
|
203
|
+
maxReports: 5,
|
|
204
|
+
onReport: function () { processedAt += 1; },
|
|
205
|
+
});
|
|
206
|
+
var atCap = [];
|
|
207
|
+
for (var j = 0; j < 5; j += 1) {
|
|
208
|
+
atCap.push({ type: "csp-violation", body: { effectiveDirective: "img-src" } });
|
|
209
|
+
}
|
|
210
|
+
await mwAt(_bodyReq("POST", { "content-type": "application/reports+json" }, JSON.stringify(atCap)),
|
|
211
|
+
resAt, function () {});
|
|
212
|
+
check("cspReport: batch at the cap processes every report",
|
|
213
|
+
resAt._sent.status === 204 && processedAt === 5);
|
|
214
|
+
|
|
215
|
+
// maxReports garbage throws at create() (config-time entry-point tier),
|
|
216
|
+
// matching the sibling maxBytes contract.
|
|
217
|
+
var badThrew = false;
|
|
218
|
+
try { b.middleware.cspReport({ maxReports: 0 }); } catch (_e) { badThrew = true; }
|
|
219
|
+
check("cspReport: maxReports:0 throws at create", badThrew);
|
|
220
|
+
var negThrew = false;
|
|
221
|
+
try { b.middleware.cspReport({ maxReports: -3 }); } catch (_e) { negThrew = true; }
|
|
222
|
+
check("cspReport: maxReports:-3 throws at create", negThrew);
|
|
223
|
+
}
|
|
224
|
+
|
|
167
225
|
// onReject surfaces the otherwise-empty-bodied 405 / 413 / 400 refusals
|
|
168
226
|
// to the operator (W3C Reporting API §3.1 — the browser ignores the
|
|
169
227
|
// rejection body, so onReject is the only signal a metrics sink gets).
|