@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
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
* (2) an OpenSSL `ts -reply` round-trip when openssl(1) is on PATH —
|
|
14
14
|
* an independent implementation, regression-guarding real-world
|
|
15
15
|
* interop (skipped gracefully where openssl is absent).
|
|
16
|
+
*
|
|
17
|
+
* The mock-TSA builders below take a wide option surface so the
|
|
18
|
+
* adversarial §2.4.2 / §2.3 verification branches (malformed / truncated
|
|
19
|
+
* responses, wrong PKIStatus, missing fields, imprint / digest / nonce /
|
|
20
|
+
* signature / EKU / chain mismatches) can be driven through the exported
|
|
21
|
+
* b.tsa.* consumer path without a live TSA.
|
|
16
22
|
*/
|
|
17
23
|
|
|
18
24
|
var b = require("../../index");
|
|
@@ -30,14 +36,18 @@ var OID_SIGNED_DATA = "1.2.840.113549.1.7.2";
|
|
|
30
36
|
var OID_SHA256 = "2.16.840.1.101.3.4.2.1";
|
|
31
37
|
var OID_SHA512 = "2.16.840.1.101.3.4.2.3";
|
|
32
38
|
var OID_RSA_ENCRYPTION = "1.2.840.113549.1.1.1";
|
|
39
|
+
var OID_RSA_PSS = "1.2.840.113549.1.1.10";
|
|
33
40
|
var OID_ECDSA_SHA256 = "1.2.840.10045.4.3.2";
|
|
41
|
+
var OID_BASIC_CONSTRAINTS = "2.5.29.19";
|
|
42
|
+
var OID_EKU_EXT = "2.5.29.37";
|
|
34
43
|
|
|
35
44
|
function _utcTime(date) {
|
|
36
45
|
var s = date.toISOString().replace(/[-:T]/g, "").slice(2, 14) + "Z"; // YYMMDDHHMMSSZ
|
|
37
46
|
return asn1.writeNode(0x17, Buffer.from(s, "ascii"));
|
|
38
47
|
}
|
|
39
|
-
function _genTime(date) {
|
|
40
|
-
var s = date.toISOString().replace(/[-:T]/g, "").slice(0, 14)
|
|
48
|
+
function _genTime(date, fractional) {
|
|
49
|
+
var s = date.toISOString().replace(/[-:T]/g, "").slice(0, 14); // YYYYMMDDHHMMSS
|
|
50
|
+
s += fractional ? ".500Z" : "Z";
|
|
41
51
|
return asn1.writeNode(0x18, Buffer.from(s, "ascii"));
|
|
42
52
|
}
|
|
43
53
|
function _algId(oid, withNull) {
|
|
@@ -50,66 +60,131 @@ function _name(cn) {
|
|
|
50
60
|
])]);
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
// Mint a minimal
|
|
63
|
+
// Mint a minimal X.509v3 cert. Self-signed unless opts.issuerName +
|
|
64
|
+
// opts.issuerKey supply an issuing certificate. Supports a chosen
|
|
65
|
+
// extendedKeyUsage, basicConstraints cA, a custom serial / validity
|
|
66
|
+
// window, and deliberately-malformed EKU shapes for the refusal paths.
|
|
54
67
|
function _makeCert(opts) {
|
|
55
68
|
opts = opts || {};
|
|
56
69
|
var keyType = opts.keyType || "rsa";
|
|
57
|
-
var kp
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
var kp;
|
|
71
|
+
if (keyType === "ec") kp = nodeCrypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
|
|
72
|
+
else if (keyType === "ed25519") kp = nodeCrypto.generateKeyPairSync("ed25519");
|
|
73
|
+
else kp = nodeCrypto.generateKeyPairSync("rsa", { modulusLength: 2048 });
|
|
60
74
|
var spki = kp.publicKey.export({ type: "spki", format: "der" });
|
|
61
75
|
|
|
62
76
|
var version = asn1.writeContextExplicit(0, asn1.writeInteger(Buffer.from([2]))); // v3
|
|
63
|
-
var
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
var
|
|
77
|
+
var serialBuf = opts.serial || Buffer.from([0x2a]);
|
|
78
|
+
var serial = asn1.writeInteger(serialBuf);
|
|
79
|
+
// Whatever key signs the tbs determines the cert's signatureAlgorithm.
|
|
80
|
+
var signingKey = opts.issuerKey || kp.privateKey;
|
|
81
|
+
var signingType = opts.issuerKey ? (opts.issuerKeyType || "rsa") : keyType;
|
|
82
|
+
var signingIsEc = signingType === "ec";
|
|
83
|
+
var signingIsEd = signingType === "ed25519";
|
|
84
|
+
var sigOid = signingIsEd ? "1.3.101.112" : (signingIsEc ? OID_ECDSA_SHA256 : "1.2.840.113549.1.1.11");
|
|
85
|
+
var sigAlgId = signingIsEd ? _algId(sigOid, false) : _algId(sigOid, !signingIsEc);
|
|
86
|
+
var subjectName = _name(opts.cn || "Test TSA");
|
|
87
|
+
var issuerName = opts.issuerName || subjectName;
|
|
67
88
|
var now = Date.now();
|
|
68
89
|
var validity = asn1.writeSequence([
|
|
69
|
-
_utcTime(new Date(now - 86400000)),
|
|
70
|
-
_utcTime(new Date(now + 86400000 * 3650)),
|
|
90
|
+
_utcTime(opts.notBefore || new Date(now - 86400000)),
|
|
91
|
+
_utcTime(opts.notAfter || new Date(now + 86400000 * 3650)),
|
|
71
92
|
]);
|
|
72
93
|
|
|
73
94
|
var extsList = [];
|
|
95
|
+
if (opts.ca) {
|
|
96
|
+
extsList.push(asn1.writeSequence([
|
|
97
|
+
asn1.writeOid(OID_BASIC_CONSTRAINTS), asn1.writeBoolean(true),
|
|
98
|
+
asn1.writeOctetString(asn1.writeSequence([asn1.writeBoolean(true)])), // cA TRUE
|
|
99
|
+
]));
|
|
100
|
+
} else if (opts.basicConstraintsFalse) {
|
|
101
|
+
extsList.push(asn1.writeSequence([
|
|
102
|
+
asn1.writeOid(OID_BASIC_CONSTRAINTS),
|
|
103
|
+
asn1.writeOctetString(asn1.writeSequence([])), // empty → cA defaults FALSE
|
|
104
|
+
]));
|
|
105
|
+
}
|
|
74
106
|
if (opts.ekuOids !== null) {
|
|
75
107
|
var ekuOids = opts.ekuOids || [ID_KP_TIMESTAMPING];
|
|
76
|
-
var ekuChildren = [asn1.writeOid(
|
|
108
|
+
var ekuChildren = [asn1.writeOid(OID_EKU_EXT)];
|
|
77
109
|
if (opts.ekuCritical !== false) ekuChildren.push(asn1.writeBoolean(true));
|
|
78
|
-
|
|
110
|
+
// ekuNoValue omits the extnValue OCTET STRING — a malformed extension
|
|
111
|
+
// whose value node the manual walker cannot find.
|
|
112
|
+
if (!opts.ekuNoValue) {
|
|
113
|
+
ekuChildren.push(asn1.writeOctetString(asn1.writeSequence(ekuOids.map(asn1.writeOid))));
|
|
114
|
+
}
|
|
79
115
|
extsList.push(asn1.writeSequence(ekuChildren));
|
|
80
116
|
}
|
|
81
|
-
var children = [version, serial, sigAlgId,
|
|
117
|
+
var children = [version, serial, sigAlgId, issuerName, validity, subjectName, spki];
|
|
82
118
|
if (extsList.length) children.push(asn1.writeContextExplicit(3, asn1.writeSequence(extsList)));
|
|
83
119
|
var tbs = asn1.writeSequence(children);
|
|
84
120
|
|
|
85
|
-
var tbsSig = nodeCrypto.sign("sha256", tbs,
|
|
121
|
+
var tbsSig = nodeCrypto.sign(signingIsEd ? null : "sha256", tbs, signingKey);
|
|
86
122
|
var certDer = asn1.writeSequence([tbs, sigAlgId, asn1.writeBitString(tbsSig, 0)]);
|
|
87
|
-
return {
|
|
123
|
+
return {
|
|
124
|
+
certDer: certDer, key: kp.privateKey, serial: serialBuf,
|
|
125
|
+
issuer: issuerName, subjectName: subjectName, publicKey: kp.publicKey,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Build a chain: self-signed Root CA → Intermediate CA → Leaf TSA. The
|
|
130
|
+
// leaf carries the timeStamping EKU (+ a benign basicConstraints:FALSE so
|
|
131
|
+
// the extension walker iterates past a non-matching extension); the CAs
|
|
132
|
+
// carry basicConstraints cA:TRUE and no EKU.
|
|
133
|
+
function _makeChain() {
|
|
134
|
+
var root = _makeCert({ cn: "Root CA", serial: Buffer.from([0x01]), ca: true, ekuOids: null });
|
|
135
|
+
var interm = _makeCert({
|
|
136
|
+
cn: "Intermediate CA", serial: Buffer.from([0x02]), ca: true, ekuOids: null,
|
|
137
|
+
issuerName: root.subjectName, issuerKey: root.key,
|
|
138
|
+
});
|
|
139
|
+
var leaf = _makeCert({
|
|
140
|
+
cn: "Leaf TSA", serial: Buffer.from([0x03]), basicConstraintsFalse: true,
|
|
141
|
+
issuerName: interm.subjectName, issuerKey: interm.key,
|
|
142
|
+
});
|
|
143
|
+
return { root: root, interm: interm, leaf: leaf,
|
|
144
|
+
tokenCerts: Buffer.concat([leaf.certDer, interm.certDer]) };
|
|
88
145
|
}
|
|
89
146
|
|
|
90
|
-
// Build an RFC 3161 TimeStampToken (CMS SignedData over a TSTInfo).
|
|
147
|
+
// Build an RFC 3161 TimeStampToken (CMS SignedData over a TSTInfo). The
|
|
148
|
+
// wide option surface drives the verifier's adversarial branches.
|
|
91
149
|
function _makeToken(opts) {
|
|
92
150
|
var imprintOid = opts.imprintHashOid || OID_SHA512;
|
|
93
|
-
var
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
151
|
+
var tstInfo;
|
|
152
|
+
if (opts.rawTstInfo) {
|
|
153
|
+
tstInfo = opts.rawTstInfo;
|
|
154
|
+
} else {
|
|
155
|
+
var genTimeNode = opts.rawGenTimeNode || _genTime(opts.genTime || new Date(), opts.genTimeFractional);
|
|
156
|
+
var tstChildren = [
|
|
157
|
+
asn1.writeInteger(Buffer.from([1])), // version
|
|
158
|
+
asn1.writeOid(opts.policy || "1.2.3.4.1"), // policy
|
|
159
|
+
asn1.writeSequence([_algId(imprintOid, true), asn1.writeOctetString(opts.imprintHash)]),
|
|
160
|
+
asn1.writeInteger(Buffer.from([0x05])), // serialNumber
|
|
161
|
+
genTimeNode,
|
|
162
|
+
];
|
|
163
|
+
if (opts.accuracy) tstChildren.push(opts.accuracy);
|
|
164
|
+
if (opts.nonce) tstChildren.push(asn1.writeInteger(opts.nonce));
|
|
165
|
+
tstInfo = asn1.writeSequence(tstChildren);
|
|
166
|
+
}
|
|
103
167
|
|
|
104
|
-
// signed attributes (contentType + messageDigest), signed as a SET.
|
|
105
168
|
var digestNode = opts.signerDigest || "sha512";
|
|
106
169
|
var digestOid = digestNode === "sha256" ? OID_SHA256 : OID_SHA512;
|
|
170
|
+
var siDigestOid = opts.signerDigestOidOverride || digestOid;
|
|
107
171
|
var msgDigest = nodeCrypto.createHash(digestNode).update(tstInfo).digest();
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
var
|
|
111
|
-
|
|
112
|
-
|
|
172
|
+
|
|
173
|
+
// signed attributes (contentType + messageDigest), signed as a SET.
|
|
174
|
+
var attrs = [];
|
|
175
|
+
if (!opts.omitContentTypeAttr) {
|
|
176
|
+
attrs.push(asn1.writeSequence([asn1.writeOid(OID_CONTENT_TYPE_ATTR),
|
|
177
|
+
asn1.writeSet([asn1.writeOid(opts.wrongContentTypeOid || ID_CT_TST_INFO)])]));
|
|
178
|
+
}
|
|
179
|
+
if (!opts.omitMessageDigestAttr) {
|
|
180
|
+
attrs.push(asn1.writeSequence([asn1.writeOid(OID_MESSAGE_DIGEST_ATTR),
|
|
181
|
+
asn1.writeSet([asn1.writeOctetString(opts.messageDigestOverride || msgDigest)])]));
|
|
182
|
+
}
|
|
183
|
+
if (opts.extraEmptyAttr) {
|
|
184
|
+
attrs.push(asn1.writeSequence([asn1.writeOid("1.2.3.4.99"), asn1.writeSet([])]));
|
|
185
|
+
}
|
|
186
|
+
var signedSet = asn1.writeSet(attrs); // 0x31… — the signed bytes
|
|
187
|
+
|
|
113
188
|
var sigAlgOid = opts.sigAlgOid || OID_RSA_ENCRYPTION;
|
|
114
189
|
// The signature hash is the one the signatureAlgorithm OID implies;
|
|
115
190
|
// hashless OIDs (rsaEncryption / id-ecPublicKey / PSS) take the
|
|
@@ -119,29 +194,47 @@ function _makeToken(opts) {
|
|
|
119
194
|
"1.2.840.113549.1.1.11": "sha256", "1.2.840.113549.1.1.12": "sha384", "1.2.840.113549.1.1.13": "sha512",
|
|
120
195
|
};
|
|
121
196
|
var signHash = SIGN_HASH[sigAlgOid] || digestNode;
|
|
122
|
-
var sig
|
|
197
|
+
var sig;
|
|
198
|
+
if (opts.corruptSignature) {
|
|
199
|
+
sig = Buffer.from([0xff]); // garbage — skip signing entirely
|
|
200
|
+
} else if (opts.pss) {
|
|
201
|
+
sig = nodeCrypto.sign(signHash, signedSet, {
|
|
202
|
+
key: opts.key, padding: nodeCrypto.constants.RSA_PKCS1_PSS_PADDING,
|
|
203
|
+
saltLength: nodeCrypto.constants.RSA_PSS_SALTLEN_DIGEST,
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
sig = nodeCrypto.sign(signHash, signedSet, opts.key);
|
|
207
|
+
}
|
|
123
208
|
var signedAttrsImplicit = Buffer.concat([Buffer.from([0xa0]), signedSet.slice(1)]); // [0] IMPLICIT
|
|
124
209
|
|
|
125
|
-
var sid = asn1.writeSequence([opts.issuer, asn1.writeInteger(opts.serial)]);
|
|
126
|
-
var
|
|
210
|
+
var sid = opts.rawSid || asn1.writeSequence([opts.issuer, asn1.writeInteger(opts.serial)]);
|
|
211
|
+
var siChildren = [
|
|
127
212
|
asn1.writeInteger(Buffer.from([1])), // version
|
|
128
213
|
sid,
|
|
129
|
-
_algId(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
var
|
|
138
|
-
|
|
214
|
+
_algId(siDigestOid, true),
|
|
215
|
+
];
|
|
216
|
+
if (!opts.omitSignedAttrs) siChildren.push(signedAttrsImplicit);
|
|
217
|
+
siChildren.push(_algId(sigAlgOid, sigAlgOid.indexOf("10045") === -1)); // RSA: AlgId+NULL; EC: no NULL
|
|
218
|
+
siChildren.push(asn1.writeOctetString(sig));
|
|
219
|
+
var signerInfo = asn1.writeSequence(siChildren);
|
|
220
|
+
|
|
221
|
+
var eContentTypeOid = opts.wrongEContentTypeOid || ID_CT_TST_INFO;
|
|
222
|
+
var encapChildren = [asn1.writeOid(eContentTypeOid)];
|
|
223
|
+
if (!opts.detached) encapChildren.push(asn1.writeContextExplicit(0, asn1.writeOctetString(tstInfo)));
|
|
224
|
+
var encap = asn1.writeSequence(encapChildren);
|
|
225
|
+
|
|
226
|
+
var signerInfosSet = opts.emptySignerInfos ? asn1.writeSet([]) : asn1.writeSet([signerInfo]);
|
|
227
|
+
var sdChildren = [
|
|
139
228
|
asn1.writeInteger(Buffer.from([3])), // version
|
|
140
229
|
asn1.writeSet([_algId(digestOid, true)]),
|
|
141
230
|
encap,
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
231
|
+
];
|
|
232
|
+
if (!opts.omitCerts) {
|
|
233
|
+
var certBytes = opts.extraCertDer ? Buffer.concat([opts.certDer, opts.extraCertDer]) : opts.certDer;
|
|
234
|
+
sdChildren.push(asn1.writeContextImplicit(0, certBytes, { constructed: true }));
|
|
235
|
+
}
|
|
236
|
+
sdChildren.push(signerInfosSet);
|
|
237
|
+
var signedData = asn1.writeSequence(sdChildren);
|
|
145
238
|
return asn1.writeSequence([asn1.writeOid(OID_SIGNED_DATA), asn1.writeContextExplicit(0, signedData)]);
|
|
146
239
|
}
|
|
147
240
|
|
|
@@ -150,6 +243,15 @@ function _imprintOf(data, hashAlg) {
|
|
|
150
243
|
return nodeCrypto.createHash(node).update(data).digest();
|
|
151
244
|
}
|
|
152
245
|
|
|
246
|
+
// A ready-to-verify token bound to `data` with a fresh timeStamping cert.
|
|
247
|
+
function _validTokenFor(data, tokenOpts) {
|
|
248
|
+
var cert = _makeCert({});
|
|
249
|
+
var o = { certDer: cert.certDer, key: cert.key, issuer: cert.issuer, serial: cert.serial,
|
|
250
|
+
imprintHash: _imprintOf(data, "SHA-512") };
|
|
251
|
+
Object.keys(tokenOpts || {}).forEach(function (k) { o[k] = tokenOpts[k]; });
|
|
252
|
+
return { token: _makeToken(o), cert: cert };
|
|
253
|
+
}
|
|
254
|
+
|
|
153
255
|
function testSurface() {
|
|
154
256
|
check("b.tsa.buildRequest is a function", typeof b.tsa.buildRequest === "function");
|
|
155
257
|
check("b.tsa.parseResponse is a function", typeof b.tsa.parseResponse === "function");
|
|
@@ -181,6 +283,38 @@ function testBuildRequest() {
|
|
|
181
283
|
var badAlg = null;
|
|
182
284
|
try { b.tsa.buildRequest(Buffer.from("z"), { hashAlg: "MD5" }); } catch (e) { badAlg = e; }
|
|
183
285
|
check("buildRequest rejects unknown hashAlg", badAlg && badAlg.code === "tsa/bad-hash-alg");
|
|
286
|
+
// An inherited Object.prototype member must get the typed refusal, not a
|
|
287
|
+
// raw createHash(undefined) ERR_INVALID_ARG_TYPE: the hashAlg indexes the
|
|
288
|
+
// IMPRINT_HASHES lookup, and every such member is a truthy prototype-chain
|
|
289
|
+
// hit that a `!IMPRINT_HASHES[hashAlg]` guard would let slip.
|
|
290
|
+
["constructor", "__proto__", "toString", "valueOf"].forEach(function (m) {
|
|
291
|
+
var inh = null;
|
|
292
|
+
try { b.tsa.buildRequest(Buffer.from("z"), { hashAlg: m }); } catch (e) { inh = e; }
|
|
293
|
+
check("buildRequest rejects inherited-member hashAlg '" + m + "' with typed error",
|
|
294
|
+
inh && inh.code === "tsa/bad-hash-alg");
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// buildRequest: opts omitted entirely, a requested policy OID, an
|
|
299
|
+
// explicit nonce Buffer, and certReq:false omitting the boolean.
|
|
300
|
+
function testBuildRequestExtras() {
|
|
301
|
+
var noOpts = b.tsa.buildRequest(Buffer.from("no-opts"));
|
|
302
|
+
check("buildRequest with no opts defaults to SHA-512 + random nonce",
|
|
303
|
+
noOpts.hashAlg === "SHA-512" && Buffer.isBuffer(noOpts.nonce) && noOpts.nonce.length === 8);
|
|
304
|
+
|
|
305
|
+
var withPolicy = b.tsa.buildRequest(Buffer.from("p"), { reqPolicy: "1.3.6.1.4.1.99.5", nonce: false, certReq: false });
|
|
306
|
+
var pc = asn1.readSequence(asn1.readNode(withPolicy.der, 0).value);
|
|
307
|
+
// children: version, messageImprint, reqPolicy(OID) — no nonce, no certReq boolean.
|
|
308
|
+
var hasPolicyOid = pc.some(function (n) {
|
|
309
|
+
return n.tag === asn1.TAG.OID && n.tagClass === asn1.TAG_CLASS.UNIVERSAL && asn1.readOid(n) === "1.3.6.1.4.1.99.5";
|
|
310
|
+
});
|
|
311
|
+
check("buildRequest reqPolicy encodes the policy OID", hasPolicyOid);
|
|
312
|
+
var hasBoolean = pc.some(function (n) { return n.tag === asn1.TAG.BOOLEAN; });
|
|
313
|
+
check("buildRequest certReq:false omits the certReq boolean", hasBoolean === false);
|
|
314
|
+
|
|
315
|
+
var myNonce = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
|
|
316
|
+
var withNonce = b.tsa.buildRequest(Buffer.from("n"), { nonce: myNonce });
|
|
317
|
+
check("buildRequest honours an explicit nonce Buffer", withNonce.nonce === myNonce);
|
|
184
318
|
}
|
|
185
319
|
|
|
186
320
|
function testVerifyHappyPath(keyType, sigAlgOid, label) {
|
|
@@ -196,33 +330,48 @@ function testVerifyHappyPath(keyType, sigAlgOid, label) {
|
|
|
196
330
|
imprintHash: _imprintOf(data, "SHA-512"), nonce: nonce,
|
|
197
331
|
sigAlgOid: sigAlgOid, signerDigest: "sha512",
|
|
198
332
|
});
|
|
199
|
-
var out = b.tsa.verifyToken(token, { data: data, hashAlg: "SHA-512", nonce: nonce });
|
|
333
|
+
var out = b.tsa.verifyToken(token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512", nonce: nonce });
|
|
200
334
|
check(label + ": verifyToken returns genTime Date", out.genTime instanceof Date);
|
|
201
335
|
check(label + ": verifyToken returns policy", out.policy === "1.2.3.4.1");
|
|
202
336
|
check(label + ": verifyToken reports hashAlg", out.hashAlg === "SHA-512");
|
|
203
337
|
|
|
204
338
|
// wrong data → imprint mismatch
|
|
205
339
|
var e1 = null;
|
|
206
|
-
try { b.tsa.verifyToken(token, { data: Buffer.from("other"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
340
|
+
try { b.tsa.verifyToken(token, { allowUntrustedIssuer: true, data: Buffer.from("other"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
207
341
|
check(label + ": wrong data refused (imprint-mismatch)", e1 && e1.code === "tsa/imprint-mismatch");
|
|
208
342
|
|
|
209
343
|
// wrong nonce → nonce mismatch
|
|
210
344
|
var e2 = null;
|
|
211
|
-
try { b.tsa.verifyToken(token, { data: data, hashAlg: "SHA-512", nonce: nodeCrypto.randomBytes(8) }); } catch (e) { e2 = e; }
|
|
345
|
+
try { b.tsa.verifyToken(token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512", nonce: nodeCrypto.randomBytes(8) }); } catch (e) { e2 = e; }
|
|
212
346
|
check(label + ": wrong nonce refused", e2 && e2.code === "tsa/nonce-mismatch");
|
|
213
347
|
|
|
214
348
|
// wrong hashAlg → imprint-alg mismatch
|
|
215
349
|
var e3 = null;
|
|
216
|
-
try { b.tsa.verifyToken(token, { data: data, hashAlg: "SHA-256" }); } catch (e) { e3 = e; }
|
|
350
|
+
try { b.tsa.verifyToken(token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-256" }); } catch (e) { e3 = e; }
|
|
217
351
|
check(label + ": wrong hashAlg refused (imprint-alg-mismatch)", e3 && e3.code === "tsa/imprint-alg-mismatch");
|
|
218
352
|
|
|
219
353
|
// tamper a byte in the token → signature fails
|
|
220
354
|
var bad = Buffer.from(token); bad[bad.length - 5] ^= 0xff;
|
|
221
355
|
var e4 = null;
|
|
222
|
-
try { b.tsa.verifyToken(bad, { data: data, hashAlg: "SHA-512" }); } catch (e) { e4 = e; }
|
|
356
|
+
try { b.tsa.verifyToken(bad, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e4 = e; }
|
|
223
357
|
check(label + ": tampered token refused", e4 && (e4.code === "tsa/bad-signature" || e4.code === "tsa/message-digest-mismatch" || e4.code === "tsa/not-cms"));
|
|
224
358
|
}
|
|
225
359
|
|
|
360
|
+
// verifyToken driven by a pre-computed digest (opts.hash) rather than raw
|
|
361
|
+
// data, plus a token whose imprint uses a pre-hashed input.
|
|
362
|
+
function testVerifyWithPrecomputedHash() {
|
|
363
|
+
var data = Buffer.from("prehash-bytes");
|
|
364
|
+
var digest = _imprintOf(data, "SHA-512");
|
|
365
|
+
var cert = _makeCert({});
|
|
366
|
+
var token = _makeToken({ certDer: cert.certDer, key: cert.key, issuer: cert.issuer, serial: cert.serial,
|
|
367
|
+
imprintHash: digest });
|
|
368
|
+
var out = b.tsa.verifyToken(token, { allowUntrustedIssuer: true, hash: digest, hashAlg: "SHA-512" });
|
|
369
|
+
check("verifyToken accepts a pre-computed hash via opts.hash", out.policy === "1.2.3.4.1");
|
|
370
|
+
var e1 = null;
|
|
371
|
+
try { b.tsa.verifyToken(token, { allowUntrustedIssuer: true, hash: _imprintOf(Buffer.from("other"), "SHA-512"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
372
|
+
check("verifyToken opts.hash mismatch refused", e1 && e1.code === "tsa/imprint-mismatch");
|
|
373
|
+
}
|
|
374
|
+
|
|
226
375
|
function testEkuRefusals() {
|
|
227
376
|
var data = Buffer.from("eku-test");
|
|
228
377
|
function tokenFor(certOpts) {
|
|
@@ -232,20 +381,197 @@ function testEkuRefusals() {
|
|
|
232
381
|
}
|
|
233
382
|
// non-critical EKU
|
|
234
383
|
var e1 = null;
|
|
235
|
-
try { b.tsa.verifyToken(tokenFor({ ekuCritical: false }), { data: data, hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
384
|
+
try { b.tsa.verifyToken(tokenFor({ ekuCritical: false }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
236
385
|
check("non-critical EKU refused", e1 && e1.code === "tsa/bad-eku");
|
|
237
386
|
// multi-purpose EKU (timeStamping + serverAuth) — not the sole purpose
|
|
238
387
|
var e2 = null;
|
|
239
|
-
try { b.tsa.verifyToken(tokenFor({ ekuOids: [ID_KP_TIMESTAMPING, ID_KP_SERVER_AUTH] }), { data: data, hashAlg: "SHA-512" }); } catch (e) { e2 = e; }
|
|
388
|
+
try { b.tsa.verifyToken(tokenFor({ ekuOids: [ID_KP_TIMESTAMPING, ID_KP_SERVER_AUTH] }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e2 = e; }
|
|
240
389
|
check("multi-purpose EKU refused (not sole)", e2 && e2.code === "tsa/bad-eku");
|
|
241
390
|
// wrong single purpose
|
|
242
391
|
var e3 = null;
|
|
243
|
-
try { b.tsa.verifyToken(tokenFor({ ekuOids: [ID_KP_SERVER_AUTH] }), { data: data, hashAlg: "SHA-512" }); } catch (e) { e3 = e; }
|
|
392
|
+
try { b.tsa.verifyToken(tokenFor({ ekuOids: [ID_KP_SERVER_AUTH] }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e3 = e; }
|
|
244
393
|
check("wrong EKU purpose refused", e3 && e3.code === "tsa/bad-eku");
|
|
245
|
-
// no EKU extension at all
|
|
394
|
+
// no EKU extension at all (no extensions wrapper at all)
|
|
246
395
|
var e4 = null;
|
|
247
|
-
try { b.tsa.verifyToken(tokenFor({ ekuOids: null }), { data: data, hashAlg: "SHA-512" }); } catch (e) { e4 = e; }
|
|
396
|
+
try { b.tsa.verifyToken(tokenFor({ ekuOids: null }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e4 = e; }
|
|
248
397
|
check("missing EKU refused", e4 && e4.code === "tsa/bad-eku");
|
|
398
|
+
// extensions present (basicConstraints) but NO EKU among them — the
|
|
399
|
+
// walker must iterate past the non-matching extension and still refuse.
|
|
400
|
+
var e5 = null;
|
|
401
|
+
try { b.tsa.verifyToken(tokenFor({ ekuOids: null, ca: true }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e5 = e; }
|
|
402
|
+
check("cert with other extensions but no EKU refused", e5 && e5.code === "tsa/bad-eku");
|
|
403
|
+
// EKU extension present but malformed (no extnValue OCTET STRING).
|
|
404
|
+
var e6 = null;
|
|
405
|
+
try { b.tsa.verifyToken(tokenFor({ ekuNoValue: true }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e6 = e; }
|
|
406
|
+
check("malformed EKU (no value) refused", e6 && e6.code === "tsa/bad-eku");
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Structural CMS refusals: wrong eContentType, detached content, no
|
|
410
|
+
// SignerInfo, no certificate, and SignerInfo with no signed attributes.
|
|
411
|
+
function testVerifyStructuralRefusals() {
|
|
412
|
+
var data = Buffer.from("structural-test");
|
|
413
|
+
var e1 = null;
|
|
414
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { wrongEContentTypeOid: "1.2.3.4.7" }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
415
|
+
check("wrong eContentType refused (not-tst)", e1 && e1.code === "tsa/not-tst");
|
|
416
|
+
|
|
417
|
+
var e2 = null;
|
|
418
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { detached: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e2 = e; }
|
|
419
|
+
check("detached token (no embedded TSTInfo) refused", e2 && e2.code === "tsa/detached");
|
|
420
|
+
|
|
421
|
+
var e3 = null;
|
|
422
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { emptySignerInfos: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e3 = e; }
|
|
423
|
+
check("token with no SignerInfo refused", e3 && e3.code === "tsa/no-signer");
|
|
424
|
+
|
|
425
|
+
var e4 = null;
|
|
426
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { omitCerts: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e4 = e; }
|
|
427
|
+
check("token carrying no certificate refused (no-cert)", e4 && e4.code === "tsa/no-cert");
|
|
428
|
+
|
|
429
|
+
var e5 = null;
|
|
430
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { omitSignedAttrs: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e5 = e; }
|
|
431
|
+
check("SignerInfo with no signed attributes refused", e5 && e5.code === "tsa/no-signed-attrs");
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Attribute + signature-algorithm refusals inside the CMS signature check,
|
|
435
|
+
// plus a token that verifies against a MISMATCHED messageDigest (a valid
|
|
436
|
+
// signature over the wrong content must not be accepted).
|
|
437
|
+
function testVerifyAttrAndSigRefusals() {
|
|
438
|
+
var data = Buffer.from("attr-sig-test");
|
|
439
|
+
|
|
440
|
+
var e1 = null;
|
|
441
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { sigAlgOid: "1.3.6.1.4.1.99.3.2" }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
442
|
+
check("unsupported signature algorithm refused (bad-sig-alg)", e1 && e1.code === "tsa/bad-sig-alg");
|
|
443
|
+
|
|
444
|
+
var e2 = null;
|
|
445
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { signerDigestOidOverride: "1.3.14.3.2.26" }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e2 = e; }
|
|
446
|
+
check("unsupported SignerInfo digest algorithm refused (bad-digest)", e2 && e2.code === "tsa/bad-digest");
|
|
447
|
+
|
|
448
|
+
var e3 = null;
|
|
449
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { omitMessageDigestAttr: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e3 = e; }
|
|
450
|
+
check("missing messageDigest attribute refused (no-message-digest)", e3 && e3.code === "tsa/no-message-digest");
|
|
451
|
+
|
|
452
|
+
var e4 = null;
|
|
453
|
+
try { b.tsa.verifyToken(_validTokenFor(data, { wrongContentTypeOid: "1.2.3.4.8" }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e4 = e; }
|
|
454
|
+
check("wrong signed contentType attribute refused (bad-content-type-attr)", e4 && e4.code === "tsa/bad-content-type-attr");
|
|
455
|
+
|
|
456
|
+
// A cryptographically-valid signature over a messageDigest attribute that
|
|
457
|
+
// does NOT equal the recomputed eContent digest must be refused — the
|
|
458
|
+
// signature must bind the exact TSTInfo bytes, never a substituted digest.
|
|
459
|
+
var e5 = null;
|
|
460
|
+
var mismatchDigest = nodeCrypto.createHash("sha512").update(Buffer.from("some other content")).digest();
|
|
461
|
+
try {
|
|
462
|
+
b.tsa.verifyToken(_validTokenFor(data, { messageDigestOverride: mismatchDigest }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
463
|
+
} catch (e) { e5 = e; }
|
|
464
|
+
check("valid signature over a mismatched messageDigest refused", e5 && e5.code === "tsa/message-digest-mismatch");
|
|
465
|
+
|
|
466
|
+
// A signed attrs SET carrying an extra attribute with an empty value SET
|
|
467
|
+
// is tolerated (skipped) — contentType + messageDigest still verify.
|
|
468
|
+
var okExtra = b.tsa.verifyToken(_validTokenFor(data, { extraEmptyAttr: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
469
|
+
check("extra empty-valued signed attribute skipped, token still verifies", okExtra.policy === "1.2.3.4.1");
|
|
470
|
+
|
|
471
|
+
// RSASSA-PSS signer (hash taken from the digestAlgorithm).
|
|
472
|
+
var okPss = b.tsa.verifyToken(_validTokenFor(data, { sigAlgOid: OID_RSA_PSS, pss: true }).token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
473
|
+
check("RSASSA-PSS signed token verifies", okPss.genTime instanceof Date);
|
|
474
|
+
|
|
475
|
+
// A garbage ECDSA signature (structurally broken) is refused, never
|
|
476
|
+
// silently accepted.
|
|
477
|
+
var e6 = null;
|
|
478
|
+
var ecCert = _makeCert({ keyType: "ec" });
|
|
479
|
+
var ecTok = _makeToken({ certDer: ecCert.certDer, key: ecCert.key, issuer: ecCert.issuer, serial: ecCert.serial,
|
|
480
|
+
imprintHash: _imprintOf(data, "SHA-512"), sigAlgOid: OID_ECDSA_SHA256, signerDigest: "sha512", corruptSignature: true });
|
|
481
|
+
try { b.tsa.verifyToken(ecTok, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e6 = e; }
|
|
482
|
+
check("garbage ECDSA signature refused (bad-signature / verify-threw)",
|
|
483
|
+
e6 && (e6.code === "tsa/verify-threw" || e6.code === "tsa/bad-signature"));
|
|
484
|
+
|
|
485
|
+
// A token declaring a supported RSA signatureAlgorithm whose certificate
|
|
486
|
+
// actually carries an Ed25519 key: node's hashed verify cannot run
|
|
487
|
+
// against an Ed25519 key and throws — the verifier must surface that as
|
|
488
|
+
// tsa/verify-threw, never treat the failure-to-verify as a pass.
|
|
489
|
+
var e7 = null;
|
|
490
|
+
var edCert = _makeCert({ keyType: "ed25519" });
|
|
491
|
+
var edTok = _makeToken({ certDer: edCert.certDer, key: edCert.key, issuer: edCert.issuer, serial: edCert.serial,
|
|
492
|
+
imprintHash: _imprintOf(data, "SHA-512"), sigAlgOid: OID_RSA_ENCRYPTION, corruptSignature: true });
|
|
493
|
+
try { b.tsa.verifyToken(edTok, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e7 = e; }
|
|
494
|
+
check("Ed25519-key cert under an RSA signature algorithm surfaces (verify-threw)", e7 && e7.code === "tsa/verify-threw");
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// TSTInfo-parsing branches: malformed / fractional GeneralizedTime,
|
|
498
|
+
// accuracy fields, too-short / non-SEQUENCE TSTInfo, and a token with no
|
|
499
|
+
// nonce compared against a request nonce.
|
|
500
|
+
function testTstInfoParsing() {
|
|
501
|
+
var data = Buffer.from("tstinfo-test");
|
|
502
|
+
var imp = _imprintOf(data, "SHA-512");
|
|
503
|
+
var cert = _makeCert({});
|
|
504
|
+
function tok(extra) {
|
|
505
|
+
var o = { certDer: cert.certDer, key: cert.key, issuer: cert.issuer, serial: cert.serial, imprintHash: imp };
|
|
506
|
+
Object.keys(extra || {}).forEach(function (k) { o[k] = extra[k]; });
|
|
507
|
+
return _makeToken(o);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// malformed GeneralizedTime → bad-gentime
|
|
511
|
+
var e1 = null;
|
|
512
|
+
try { b.tsa.verifyToken(tok({ rawGenTimeNode: asn1.writeNode(0x18, Buffer.from("not-a-time", "ascii")) }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
513
|
+
check("malformed GeneralizedTime refused (bad-gentime)", e1 && e1.code === "tsa/bad-gentime");
|
|
514
|
+
|
|
515
|
+
// fractional-second GeneralizedTime → parsed to milliseconds
|
|
516
|
+
var frac = b.tsa.verifyToken(tok({ genTimeFractional: true }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
517
|
+
check("fractional-second genTime parses to ms", frac.genTime instanceof Date && frac.genTime.getUTCMilliseconds() === 500);
|
|
518
|
+
|
|
519
|
+
// accuracy { seconds, [0] millis, [1] micros } surfaces on the result
|
|
520
|
+
var accuracy = asn1.writeSequence([
|
|
521
|
+
asn1.writeInteger(Buffer.from([0x01])), // seconds = 1
|
|
522
|
+
asn1.writeContextImplicit(0, Buffer.from([0x64])), // millis = 100 [0] IMPLICIT
|
|
523
|
+
asn1.writeContextImplicit(1, Buffer.from([0x0a])), // micros = 10 [1] IMPLICIT
|
|
524
|
+
]);
|
|
525
|
+
var acc = b.tsa.verifyToken(tok({ accuracy: accuracy }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
526
|
+
check("accuracy seconds/millis/micros decoded",
|
|
527
|
+
acc.accuracy && acc.accuracy.seconds === 1 && acc.accuracy.millis === 100 && acc.accuracy.micros === 10);
|
|
528
|
+
|
|
529
|
+
// too-short TSTInfo (fewer than 5 fields) → malformed
|
|
530
|
+
var e2 = null;
|
|
531
|
+
var shortTst = asn1.writeSequence([asn1.writeInteger(Buffer.from([1])), asn1.writeOid("1.2.3"), asn1.writeOctetString(Buffer.alloc(0))]);
|
|
532
|
+
try { b.tsa.verifyToken(tok({ rawTstInfo: shortTst }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e2 = e; }
|
|
533
|
+
check("too-short TSTInfo refused (malformed)", e2 && e2.code === "tsa/malformed");
|
|
534
|
+
|
|
535
|
+
// TSTInfo that is not a SEQUENCE → malformed
|
|
536
|
+
var e3 = null;
|
|
537
|
+
try { b.tsa.verifyToken(tok({ rawTstInfo: asn1.writeInteger(Buffer.from([1])) }), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" }); } catch (e) { e3 = e; }
|
|
538
|
+
check("non-SEQUENCE TSTInfo refused (malformed)", e3 && e3.code === "tsa/malformed");
|
|
539
|
+
|
|
540
|
+
// token has no nonce but a request nonce is supplied → nonce-mismatch
|
|
541
|
+
// (the absent-nonce comparison branch).
|
|
542
|
+
var e4 = null;
|
|
543
|
+
try { b.tsa.verifyToken(tok({}), { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512", nonce: nodeCrypto.randomBytes(8) }); } catch (e) { e4 = e; }
|
|
544
|
+
check("nonce required but token has none refused", e4 && e4.code === "tsa/nonce-mismatch");
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// SignerInfo-selection (_candidateSigners) branches: a SID that is not an
|
|
548
|
+
// IssuerAndSerialNumber, an IssuerAndSerial whose serial matches no cert,
|
|
549
|
+
// and a bogus (unparseable) cert in the pool alongside the real signer.
|
|
550
|
+
function testCandidateSigners() {
|
|
551
|
+
var data = Buffer.from("candidate-signers");
|
|
552
|
+
var cert = _makeCert({});
|
|
553
|
+
var imp = _imprintOf(data, "SHA-512");
|
|
554
|
+
|
|
555
|
+
// (a) SID is a [0] SubjectKeyIdentifier (no serial) → fall back to all certs.
|
|
556
|
+
var skiSid = asn1.writeContextImplicit(0, Buffer.from([0xab, 0xcd, 0xef]));
|
|
557
|
+
var outA = b.tsa.verifyToken(
|
|
558
|
+
_makeToken({ certDer: cert.certDer, key: cert.key, rawSid: skiSid, serial: cert.serial, issuer: cert.issuer, imprintHash: imp }),
|
|
559
|
+
{ allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
560
|
+
check("SKI-style SID (no serial) falls back to all certs", outA.policy === "1.2.3.4.1");
|
|
561
|
+
|
|
562
|
+
// (b) IssuerAndSerial SID whose serial matches no cert → fall back to all certs.
|
|
563
|
+
var outB = b.tsa.verifyToken(
|
|
564
|
+
_makeToken({ certDer: cert.certDer, key: cert.key, serial: Buffer.from([0x77]), issuer: cert.issuer, imprintHash: imp }),
|
|
565
|
+
{ allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
566
|
+
check("SID serial matching no cert falls back to all certs", outB.policy === "1.2.3.4.1");
|
|
567
|
+
|
|
568
|
+
// (c) a bogus, unparseable cert in the pool is skipped; the real signer
|
|
569
|
+
// is still selected by serial.
|
|
570
|
+
var bogus = asn1.writeSequence([asn1.writeInteger(Buffer.from([0x01]))]);
|
|
571
|
+
var outC = b.tsa.verifyToken(
|
|
572
|
+
_makeToken({ certDer: cert.certDer, extraCertDer: bogus, key: cert.key, serial: cert.serial, issuer: cert.issuer, imprintHash: imp }),
|
|
573
|
+
{ allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
574
|
+
check("bogus cert in the pool skipped; real signer selected", outC.policy === "1.2.3.4.1");
|
|
249
575
|
}
|
|
250
576
|
|
|
251
577
|
function testChainVerify() {
|
|
@@ -284,10 +610,112 @@ function testChainVerify() {
|
|
|
284
610
|
check("invalid opts.at Date refused", e4 && e4.code === "tsa/bad-at");
|
|
285
611
|
}
|
|
286
612
|
|
|
613
|
+
// Multi-cert chain: signer → intermediate CA → root anchor. Exercises the
|
|
614
|
+
// walk-up through the token's intermediates and the cA-enforced anchor
|
|
615
|
+
// termination, plus the validity-window check driven by opts.at.
|
|
616
|
+
function testChainWalkAndValidity() {
|
|
617
|
+
var data = Buffer.from("chain-walk-test");
|
|
618
|
+
var chain = _makeChain();
|
|
619
|
+
var token = _makeToken({ certDer: chain.tokenCerts, key: chain.leaf.key, issuer: chain.leaf.issuer,
|
|
620
|
+
serial: chain.leaf.serial, imprintHash: _imprintOf(data, "SHA-512") });
|
|
621
|
+
var rootPem = new nodeCrypto.X509Certificate(chain.root.certDer).toString();
|
|
622
|
+
var out = b.tsa.verifyToken(token, { data: data, hashAlg: "SHA-512", trustAnchorsPem: [rootPem] });
|
|
623
|
+
check("chain walks signer → intermediate → root anchor", out.policy === "1.2.3.4.1");
|
|
624
|
+
|
|
625
|
+
// The intermediate is NOT a trust anchor on its own — only the root is.
|
|
626
|
+
// Supplying only the intermediate fails to terminate at an anchor.
|
|
627
|
+
var intermPem = new nodeCrypto.X509Certificate(chain.interm.certDer).toString();
|
|
628
|
+
var eNoRoot = null;
|
|
629
|
+
try { b.tsa.verifyToken(token, { data: data, hashAlg: "SHA-512", trustAnchorsPem: [intermPem] }); } catch (e) { eNoRoot = e; }
|
|
630
|
+
// The intermediate DID issue the signer, so it terminates as a
|
|
631
|
+
// fingerprint/issuer anchor — this asserts it verifies (intermediate is a
|
|
632
|
+
// valid anchor for the signer directly).
|
|
633
|
+
check("intermediate as sole anchor still terminates (it issued the signer)", eNoRoot === null);
|
|
634
|
+
|
|
635
|
+
// Validity window: a self-anchored cert with opts.at far past the cert's
|
|
636
|
+
// notAfter must be refused (cert-expired), and a valid opts.at accepted.
|
|
637
|
+
var soloData = Buffer.from("validity-window");
|
|
638
|
+
var solo = _makeCert({});
|
|
639
|
+
var soloTok = _makeToken({ certDer: solo.certDer, key: solo.key, issuer: solo.issuer, serial: solo.serial,
|
|
640
|
+
imprintHash: _imprintOf(soloData, "SHA-512") });
|
|
641
|
+
var soloPem = new nodeCrypto.X509Certificate(solo.certDer).toString();
|
|
642
|
+
var eExpired = null;
|
|
643
|
+
try {
|
|
644
|
+
b.tsa.verifyToken(soloTok, { data: soloData, hashAlg: "SHA-512", trustAnchorsPem: [soloPem],
|
|
645
|
+
at: new Date(Date.now() + 86400000 * 100000) });
|
|
646
|
+
} catch (e) { eExpired = e; }
|
|
647
|
+
check("cert not valid at opts.at refused (cert-expired)", eExpired && eExpired.code === "tsa/cert-expired");
|
|
648
|
+
|
|
649
|
+
var okAt = b.tsa.verifyToken(soloTok, { data: soloData, hashAlg: "SHA-512", trustAnchorsPem: [soloPem], at: new Date() });
|
|
650
|
+
check("valid opts.at within the window accepted", okAt.policy === "1.2.3.4.1");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// parseResponse malformed / non-granted / granted-with-token branches.
|
|
654
|
+
function testParseResponseBranches() {
|
|
655
|
+
// Well-formed non-SEQUENCE root (an INTEGER) → malformed.
|
|
656
|
+
var e1 = null;
|
|
657
|
+
try { b.tsa.parseResponse(asn1.writeInteger(Buffer.from([1]))); } catch (e) { e1 = e; }
|
|
658
|
+
check("parseResponse refuses a non-SEQUENCE root", e1 && e1.code === "tsa/malformed");
|
|
659
|
+
|
|
660
|
+
// First child is not the PKIStatusInfo SEQUENCE.
|
|
661
|
+
var e2 = null;
|
|
662
|
+
try { b.tsa.parseResponse(asn1.writeSequence([asn1.writeInteger(Buffer.from([1]))])); } catch (e) { e2 = e; }
|
|
663
|
+
check("parseResponse refuses a missing PKIStatusInfo SEQUENCE", e2 && e2.code === "tsa/malformed");
|
|
664
|
+
|
|
665
|
+
// PKIStatusInfo present but first element is not an INTEGER.
|
|
666
|
+
var e3 = null;
|
|
667
|
+
try { b.tsa.parseResponse(asn1.writeSequence([asn1.writeSequence([asn1.writeNull()])])); } catch (e) { e3 = e; }
|
|
668
|
+
check("parseResponse refuses a PKIStatusInfo without a status INTEGER", e3 && e3.code === "tsa/malformed");
|
|
669
|
+
|
|
670
|
+
// Status INTEGER too large to be a small unsigned status → out of range.
|
|
671
|
+
var e4 = null;
|
|
672
|
+
var bigStatus = asn1.writeNode(0x02, Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8])); // 9-byte INTEGER
|
|
673
|
+
try { b.tsa.parseResponse(asn1.writeSequence([asn1.writeSequence([bigStatus])])); } catch (e) { e4 = e; }
|
|
674
|
+
check("parseResponse refuses an out-of-range status integer", e4 && e4.code === "tsa/malformed");
|
|
675
|
+
|
|
676
|
+
// Rejection with a PKIFreeText statusString.
|
|
677
|
+
var withText = asn1.writeSequence([asn1.writeSequence([
|
|
678
|
+
asn1.writeInteger(Buffer.from([0x02])), // rejection
|
|
679
|
+
asn1.writeSequence([asn1.writeUtf8String("policy not accepted")]), // PKIFreeText
|
|
680
|
+
])]);
|
|
681
|
+
var pText = b.tsa.parseResponse(withText);
|
|
682
|
+
check("parseResponse decodes a statusString", pText.granted === false && pText.statusString === "policy not accepted");
|
|
683
|
+
|
|
684
|
+
// failInfo BIT STRING with only the unused-bits byte → empty flags.
|
|
685
|
+
var emptyFail = asn1.writeSequence([asn1.writeSequence([
|
|
686
|
+
asn1.writeInteger(Buffer.from([0x02])),
|
|
687
|
+
asn1.writeNode(0x03, Buffer.from([0x00])), // empty BIT STRING
|
|
688
|
+
])]);
|
|
689
|
+
var pEmpty = b.tsa.parseResponse(emptyFail);
|
|
690
|
+
check("parseResponse handles an empty failInfo BIT STRING", pEmpty.failInfo.length === 0);
|
|
691
|
+
|
|
692
|
+
// failInfo bit at a position with no named flag → "bitN".
|
|
693
|
+
var unknownBit = asn1.writeSequence([asn1.writeSequence([
|
|
694
|
+
asn1.writeInteger(Buffer.from([0x02])),
|
|
695
|
+
asn1.writeNode(0x03, Buffer.from([0x06, 0x40])), // bit position 1 set (unnamed)
|
|
696
|
+
])]);
|
|
697
|
+
var pUnknown = b.tsa.parseResponse(unknownBit);
|
|
698
|
+
check("parseResponse names an unmapped failInfo bit", pUnknown.failInfo.indexOf("bit1") !== -1);
|
|
699
|
+
|
|
700
|
+
// granted status but no timeStampToken present → no-token.
|
|
701
|
+
var e5 = null;
|
|
702
|
+
try { b.tsa.parseResponse(asn1.writeSequence([asn1.writeSequence([asn1.writeInteger(Buffer.from([0x01]))])])); } catch (e) { e5 = e; }
|
|
703
|
+
check("parseResponse refuses granted-without-token", e5 && e5.code === "tsa/no-token");
|
|
704
|
+
|
|
705
|
+
// granted status WITH a token → surfaces the token and verifies end-to-end.
|
|
706
|
+
var data = Buffer.from("granted-with-token");
|
|
707
|
+
var vt = _validTokenFor(data, {});
|
|
708
|
+
var grantedResp = asn1.writeSequence([asn1.writeSequence([asn1.writeInteger(Buffer.from([0x00]))]), vt.token]);
|
|
709
|
+
var pGranted = b.tsa.parseResponse(grantedResp);
|
|
710
|
+
check("parseResponse surfaces a granted token", pGranted.granted === true && pGranted.status === 0 && Buffer.isBuffer(pGranted.token));
|
|
711
|
+
var out = b.tsa.verifyToken(pGranted.token, { allowUntrustedIssuer: true, data: data, hashAlg: "SHA-512" });
|
|
712
|
+
check("token surfaced by parseResponse verifies", out.policy === "1.2.3.4.1");
|
|
713
|
+
}
|
|
714
|
+
|
|
287
715
|
function testParseResponseAndInputGuards() {
|
|
288
716
|
// garbage token → not CMS
|
|
289
717
|
var e1 = null;
|
|
290
|
-
try { b.tsa.verifyToken(Buffer.from([0x30, 0x01, 0x00]), { data: Buffer.from("x"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
718
|
+
try { b.tsa.verifyToken(Buffer.from([0x30, 0x01, 0x00]), { allowUntrustedIssuer: true, data: Buffer.from("x"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
291
719
|
check("verifyToken refuses non-CMS bytes", e1 && (e1.code === "tsa/not-cms" || e1.code === "tsa/malformed"));
|
|
292
720
|
// no data
|
|
293
721
|
var e2 = null;
|
|
@@ -344,23 +772,56 @@ function testOpensslInterop() {
|
|
|
344
772
|
|
|
345
773
|
var resp = b.tsa.parseResponse(tsr);
|
|
346
774
|
check("openssl interop: response granted", resp.granted === true && resp.status === 0);
|
|
347
|
-
var out = b.tsa.verifyToken(resp.token, { data: Buffer.from("hello world"), hashAlg: "SHA-512", nonce: req.nonce });
|
|
775
|
+
var out = b.tsa.verifyToken(resp.token, { allowUntrustedIssuer: true, data: Buffer.from("hello world"), hashAlg: "SHA-512", nonce: req.nonce });
|
|
348
776
|
check("openssl interop: real token verifies", out.genTime instanceof Date && out.policy === "1.2.3.4.1");
|
|
349
777
|
var out2 = b.tsa.verifyToken(resp.token, { data: Buffer.from("hello world"), hashAlg: "SHA-512", trustAnchorsPem: [anchor] });
|
|
350
778
|
check("openssl interop: chain verifies to the TSA cert", out2.genTime instanceof Date);
|
|
351
779
|
var e1 = null;
|
|
352
|
-
try { b.tsa.verifyToken(resp.token, { data: Buffer.from("tampered"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
780
|
+
try { b.tsa.verifyToken(resp.token, { allowUntrustedIssuer: true, data: Buffer.from("tampered"), hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
353
781
|
check("openssl interop: wrong data refused", e1 && e1.code === "tsa/imprint-mismatch");
|
|
354
782
|
}
|
|
355
783
|
|
|
784
|
+
// Trust-anchor posture — the signer certificate is embedded in the token and
|
|
785
|
+
// attacker-controlled, so verifyToken must not accept a self-signed timestamp
|
|
786
|
+
// as valid by default (RFC 3161 §2.4.2; mirrors b.mdoc.verifyIssuerSigned).
|
|
787
|
+
function testTsaTrustAnchorRequiredByDefault() {
|
|
788
|
+
var data = Buffer.from("timestamp-this-payload");
|
|
789
|
+
var vt = _validTokenFor(data);
|
|
790
|
+
// (1) No anchors + no explicit opt-out → REFUSED (a self-signed forgery would
|
|
791
|
+
// otherwise pass on its self-contained signature + timeStamping EKU).
|
|
792
|
+
var e1 = null;
|
|
793
|
+
try { b.tsa.verifyToken(vt.token, { data: data, hashAlg: "SHA-512" }); } catch (e) { e1 = e; }
|
|
794
|
+
check("verifyToken: trust anchors required by default (self-signed token refused)",
|
|
795
|
+
e1 !== null && e1.code === "tsa/trust-anchors-required");
|
|
796
|
+
// (2) Explicit opt-out → accepted, but issuerTrusted:false surfaces the
|
|
797
|
+
// unauthenticated posture so a caller can't mistake it for anchored.
|
|
798
|
+
var outUn = b.tsa.verifyToken(vt.token, { data: data, hashAlg: "SHA-512", allowUntrustedIssuer: true });
|
|
799
|
+
check("verifyToken: allowUntrustedIssuer accepts but flags issuerTrusted:false",
|
|
800
|
+
outUn && outUn.issuerTrusted === false && outUn.genTime instanceof Date);
|
|
801
|
+
// (3) Anchored to the signer cert → accepted with issuerTrusted:true.
|
|
802
|
+
var anchorPem = new nodeCrypto.X509Certificate(vt.cert.certDer).toString();
|
|
803
|
+
var outTr = b.tsa.verifyToken(vt.token, { data: data, hashAlg: "SHA-512", trustAnchorsPem: [anchorPem] });
|
|
804
|
+
check("verifyToken: valid trust anchor → issuerTrusted:true",
|
|
805
|
+
outTr && outTr.issuerTrusted === true);
|
|
806
|
+
}
|
|
807
|
+
|
|
356
808
|
async function run() {
|
|
357
809
|
testSurface();
|
|
358
810
|
testBuildRequest();
|
|
811
|
+
testBuildRequestExtras();
|
|
359
812
|
testVerifyHappyPath("rsa", OID_RSA_ENCRYPTION, "RSA(rsaEncryption)");
|
|
360
813
|
testVerifyHappyPath("rsa", "1.2.840.113549.1.1.13", "RSA(sha512WithRSA)");
|
|
361
814
|
testVerifyHappyPath("ec", OID_ECDSA_SHA256, "ECDSA");
|
|
815
|
+
testVerifyWithPrecomputedHash();
|
|
362
816
|
testEkuRefusals();
|
|
817
|
+
testVerifyStructuralRefusals();
|
|
818
|
+
testVerifyAttrAndSigRefusals();
|
|
819
|
+
testTstInfoParsing();
|
|
820
|
+
testCandidateSigners();
|
|
363
821
|
testChainVerify();
|
|
822
|
+
testTsaTrustAnchorRequiredByDefault();
|
|
823
|
+
testChainWalkAndValidity();
|
|
824
|
+
testParseResponseBranches();
|
|
364
825
|
testParseResponseAndInputGuards();
|
|
365
826
|
testOpensslInterop();
|
|
366
827
|
}
|