Standards
A tooled self-assessment, not a certification. Every ISO/IEC, ITU-T and IETF standard pkinative touches, the evidence that holds each — a test, a rule or a conformance level — and the gaps it leaves.
No body has audited or certified pkinative against any standard on this page. What each row records is the evidence the repository itself runs — a test file, a verify:docs rule or a level of the conformance gate — and the gaps that evidence leaves. Every path and rule named here is checked to exist by the standards-evidence rule, so the page cannot cite evidence that has gone away; whether the evidence is sufficient is your judgement.
The claimed profile is the IETF one: RFC 5280 for certificates, and the RFCs below for everything built on them. The ISO/IEC and ITU-T standards appear because RFC 5280 is written on top of them. Most ISO/IEC standards on this page are published as common text with an ITU-T Recommendation; both numbers are given, and the editions are the ones in force when this page was written (X.680 and X.690: 02/2021; X.509 and X.520: 10/2019).
How to read the status column: applies — pkinative implements the standard for what it claims and holds itself to it; partial — it implements part, and the gap column says which; not claimed — the standard concerns an organisation or an artefact pkinative does not produce, and nothing in the repository claims it.
ASN.1 and the directory #
| Standard | Scope for pkinative | Status | Evidence | Gaps |
|---|---|---|---|---|
| ITU-T X.690 | ISO/IEC 8825-1 — BER, CER and DER | Decoding DER (strict, the default) and BER (on request); encoding DER | applies | src/asn1/; tests/asn1/asn1-decode.test.ts, tests/asn1/asn1-encode.test.ts, tests/asn1/asn1-read.test.ts; tests/fuzzing/asn1-lengths-tags-nesting.test.ts, tests/fuzzing/asn1-values.test.ts; tests/property/asn1-roundtrip.test.ts; byte identity at L2 against scripts/lib/raw-der.ts, an independent walker; the §11.6 and §11.2.2 clauses x690-11.6-rdn-set-sorted and x690-11.2.2-named-bits-trimmed at L5 |
§11.2.2, §11.5 and §11.6 departures are diagnostics, refused only under strict: true (decided: real issuers commit them, and they read the same in every parser). CER is neither implemented nor claimed. The X.690 quotes in scripts/lib/clauses.ts are not machine-checked against a pinned text, as the RFC 5280 ones are. |
| ITU-T X.680 | ISO/IEC 8824-1 — ASN.1 notation | The universal tags and the value sets the readers accept | applies | src/asn1/asn1-tags.ts, src/core/text.ts (the PrintableString set, diagnostic PKI_DIAG_PRINTABLE_STRING_CHARSET); a typed reader for every universal type a PKI structure carries, ENUMERATED (readEnumerated, X.690 §8.4) and RELATIVE-OID (readRelativeOid, encodeRelativeOid, X.690 §8.20) included; tests/asn1/asn1-tags.test.ts, tests/asn1/asn1-read.test.ts, tests/asn1/asn1-oid.test.ts, tests/asn1/asn1-time.test.ts, tests/property/asn1-roundtrip.test.ts |
Not read, because no PKI structure pkinative reads carries them: REAL has no reader, and under BER the GeneralizedTime forms X.680 allows beyond RFC 5280 §4.1.2.5.2 — hour-only times, fractions of a minute or an hour, numeric offsets — are refused. |
| ITU-T X.509 | ISO/IEC 9594-8 — certificate framework | Read through the RFC 5280 profile, never beyond it | partial | Everything under RFC 5280 below | Extensions X.509 defines and RFC 5280 does not are kept undecoded (kind: 'unknown'). Attribute certificates are not read. |
| ITU-T X.520 | ISO/IEC 9594-6 — attribute types | Names: every DirectoryString choice is read, each attribute held to its syntax and its upper bound | applies | src/x509/x509-name.ts, with the RFC 5280 Appendix A.1 syntax and ub-* table in src/core/name-oids.ts and the ISO 3166-1 codes in src/x509/iso3166.ts; tests/x509/x509-name.test.ts (PKI_DIAG_NAME_ATTRIBUTE_STRING_TYPE, PKI_DIAG_COUNTRY_NAME_SIZE, PKI_DIAG_NAME_ATTRIBUTE_TOO_LONG, PKI_DIAG_NAME_COUNTRY_UNKNOWN), tests/x509/iso3166.test.ts, tests/build/build-structures.test.ts; the attribute names in src/oid/ |
Diagnosed, never enforced when reading: a value outside its Appendix A.1 string type raises PKI_DIAG_NAME_ATTRIBUTE_STRING_TYPE and a countryName that is not two characters PKI_DIAG_COUNTRY_NAME_SIZE, each refused only under strict: true; a value past its ub-* upper bound, counted in characters, raises PKI_DIAG_NAME_ATTRIBUTE_TOO_LONG and is read as it is, information even under strict. The bounds are RFC 5280 Appendix A.1's (the five X520name attributes at ub-name, 32768), not the X.400 personal-name lengths. encodeNameAttribute refuses a wrong type or size when writing. |
| ITU-T X.660 | ISO/IEC 9834-1 — object identifier arcs | Encoding, decoding and validating OIDs | applies | src/asn1/asn1-oid.ts; tests/asn1/asn1-oid.test.ts, tests/oid/oid-registry.test.ts; tests/fuzzing/asn1-values.test.ts |
— |
Character sets and data formats #
| Standard | Scope for pkinative | Status | Evidence | Gaps |
|---|---|---|---|---|
| ISO/IEC 10646 (the Unicode repertoire) | UTF8String, BMPString and UniversalString decoding | applies | src/core/text.ts; tests/core/text.test.ts: overlong UTF-8, surrogates and values past U+10FFFF are refused; tests/asn1/asn1-read.test.ts: odd lengths are refused; tests/asn1/asn1-read-iso10646.test.ts: a byte-order signature and an ISO/IEC 2022 escape control are diagnosed (PKI_DIAG_STRING_SIGNATURE, PKI_DIAG_STRING_ESCAPE_SEQUENCE) |
A byte-order signature at the start of a BMPString or UniversalString, or an escape control inside any of the three types, is diagnosed and decoded as it is; it is refused only under strict: true. |
| ITU-T T.61 (TeletexString) | Read for interoperability only | partial, by design | PKI_DIAG_TELETEX_AS_LATIN1, in docs/data/diagnostics.json |
T.61 is not implemented: a TeletexString is read as Latin-1 and the diagnostic says so. |
| ISO 3166-1 alpha-2 (country codes) | countryName values |
applies | src/x509/iso3166.ts (the 249 officially assigned codes of ISO 3166-1:2020; the user-assigned range AA, QM–QZ, XA–XZ, ZZ of §8.1.3 admitted), src/x509/x509-name.ts; tests/x509/iso3166.test.ts (the count, the range, the reserved codes UK, EU, AN refused), tests/x509/x509-name.test.ts (PKI_DIAG_NAME_COUNTRY_UNKNOWN), tests/build/build-structures.test.ts |
Information, not refusal: a two-letter code the list does not hold is reported (PKI_DIAG_NAME_COUNTRY_UNKNOWN) and read as it is, even under strict: true; a wrong size is PKI_DIAG_COUNTRY_NAME_SIZE. The table follows the ISO 3166 Maintenance Agency by hand, so a code assigned after it was written is reported as unknown until the table does. encodeNameAttribute checks the size, not the list. |
| RFC 5280 §4.1.2.5 time profile (and ISO 8601 in spirit) | UTCTime and GeneralizedTime in certificates, lists and messages | applies | src/asn1/asn1-time.ts; tests/asn1/asn1-time.test.ts; the clauses 4.1.2.5-generalized-time-only-from-2050 and 4.1.2.5.2-generalized-time-no-fraction at L5 |
— |
The RFCs pkinative claims #
| Standard | Scope for pkinative | Status | Evidence | Gaps |
|---|---|---|---|---|
| RFC 5280 — certificates and CRLs | Parsing, §6 path validation, §5 revocation | applies | L0 to L8 in the conformance guide: x509-limbo, NIST PKITS and its S/MIME messages; the pinned text of §4.1–4.2 held clause by clause (scripts/lib/clauses.ts, scripts/data/rfc5280-requirements.json, tests/conformance/clauses.test.ts, tests/conformance/rfc-requirements.test.ts); tests/x509/x509-certificate.test.ts, tests/path/path-validate.test.ts, tests/revocation/crl-check.test.ts; the rules clause-table-complete and refusal-baseline-frozen |
The reviewed deviations of scripts/data/pkits-score.json and scripts/data/limbo-score.json; distinguished names compared by encoded bytes rather than by §7.1 preparation (ADR 0005). |
RFC 2986 — PKCS#10 certification requests (with RFC 2985 §5.4 for extensionRequest and challengePassword) |
Reading, verifying the proof of possession, and building | applies | src/x509/x509-csr.ts, src/verify/verify-csr.ts; tests/x509/x509-csr.test.ts, tests/verify/verify-csr.test.ts, tests/fuzzing/csr.test.ts, tests/build/build-certificate.test.ts; recipes/csr.ts; the openssl:csr case of the interoperability matrix reads back and verifies every request openssl req -new writes, and OpenSSL, .NET, GnuTLS, Go, Python cryptography and Java read the ones pkinative writes |
Attributes other than extensionRequest and challengePassword are kept as DER (CsrAttribute); a request is held to the certificate's codes and bounds, so a version other than 0 is PKI_X509_VERSION_INVALID and the attributes count against maxExtensions. A valid request proves possession of a key and nothing about who sent it. |
| RFC 5652 — CMS SignedData | Reading, building and verifying | applies | tests/cms/cms-signed-data.test.ts, tests/cms/cms-check.test.ts, tests/verify/verify-signed-data.test.ts, tests/fuzzing/cms.test.ts; L8, 224 PKITS S/MIME messages verified whole; the pinned text of §5 and §11.1–11.4 held sentence by sentence to a named test (scripts/data/rfc5652-requirements.json) |
DSA signers are not verified (ADR 0004); an Ed448 signer is verified, and written by createSignedData, where the host has Ed448 — Node.js — and reported unchecked, or refused with PKI_CRYPTO_KEY_UNSUPPORTED, where it does not — Bun, Chromium (ADR 0022); countersignatures are carried, not verified — their signed attributes are looked into only as far as the §11.4 diagnostics need. |
| RFC 6211 — CMS algorithm protection; RFC 5035 — signing-certificate-v2 | Checked on verification | applies | tests/cms/cms-check.test.ts, tests/cms/cms-attributes.test.ts |
— |
| RFC 3161 and RFC 5816 — timestamps | Requests, responses, tokens and their verification | applies | tests/cms/tsp-request.test.ts, tests/cms/tsp-response.test.ts, tests/cms/tsp-tst-info.test.ts, tests/verify/verify-timestamp.test.ts; recipes/timestamp.ts; the pinned text of RFC 3161 §2.3–2.4 held sentence by sentence (scripts/data/rfc3161-requirements.json) |
One level of evidence: no ETSI long-term formats (ADR 0009); the certReq contract between request and token is a diagnostic of verifyTimeStampToken, never a reason. |
| RFC 6960 — OCSP | Requests, responses and the client's §3.2 checks | applies | tests/revocation/ocsp.test.ts, tests/revocation/ocsp-check.test.ts, tests/fuzzing/reports.test.ts; the pinned text of §4.1–4.2 held sentence by sentence (scripts/data/rfc6960-requirements.json) |
No network I/O: the caller fetches (ADR 0006); the responderID is compared with the signer only when checkOcspStatus is given it, as verifyCertificateChain does, and the comparison is a diagnostic, never a reason. |
| RFC 7468 — PEM | Strict and lax decoding, encoding | applies | tests/pem/pem.test.ts, tests/fuzzing/pem-malformed.test.ts; the pinned text of §2–5 held sentence by sentence (scripts/data/rfc7468-requirements.json) |
Strict mode refuses the whitespace §2 asks parsers to ignore; lax mode accepts it with a diagnostic. |
| RFC 5958 — PKCS#8; RFC 8018 — PBES2 and PBKDF2 | Reading and opening keys | applies, read only | tests/keys/key-pkcs8.test.ts, tests/keys/key-pbes2.test.ts, tests/keys/key-import.test.ts; the rule key-operation-parity |
No writer (ADR 0003); PBES2 with AES-CBC only. |
| RFC 7292 — PKCS#12; RFC 9579 — PBMAC1 | Opening .p12 files |
partial, by design | tests/keys/key-pkcs12.test.ts, tests/verify/verify-pkcs12.test.ts, tests/crypto/webcrypto-password.test.ts, tests/fuzzing/pkcs12.test.ts; the rule pkcs12-policy-parity; the pinned text of §4–5 held sentence by sentence (scripts/data/rfc7292-requirements.json) |
PBES2 only: the Appendix B KDF and the Appendix C ciphers are refused (ADR 0002), so an Appendix B MAC is reported unverified. |
| RFC 3279, RFC 4055, RFC 5480, RFC 8410, RFC 8017 — algorithms and keys | Reading key and algorithm identifiers; signatures through Web Crypto | applies | tests/x509/x509-spki.test.ts, tests/crypto/crypto-algorithms.test.ts, tests/crypto/x509-verify.test.ts, tests/build/build-structures.test.ts |
An id-RSASSA-PSS public key, which no conforming Web Crypto imports under that identifier, is handed to the host under rsaEncryption once the signature has been held to the key's parameters (RFC 4055 §1.2, §3.3), so what it signed verifies everywhere; an id-RSASSA-PSS private key under PBES2 still depends on the host, since a shrouded key is never re-wrapped. No default RSA scheme (ADR 0015). |
| FIPS 204 — ML-DSA keys | Reading the SubjectPublicKeyInfo | applies, read only | tests/x509/x509-spki.test.ts |
ML-DSA signatures are not verified. |
| RFC 6125 — host names | Matching a certificate to a host | applies | tests/path/path-server-name.test.ts |
No public suffix list, by design. |
Process and supply chain #
| Standard | Scope for pkinative | Status | Evidence | Gaps |
|---|---|---|---|---|
| ECMA-424 (CycloneDX) | The SBOM attached to each GitHub release | partial | .github/workflows/publish.yml writes it with npm sbom --sbom-format cyclonedx |
npm sbom writes CycloneDX 1.5 (measured with npm 10.9.2); the current edition of ECMA-424 (December 2025) specifies CycloneDX 1.7. The SBOM is CycloneDX, not claimed as ECMA-424. |
| ISO/IEC 5962 (SPDX) | Licence identification of every file, and an SPDX SBOM of each release | applies | REUSE.toml gives every file an SPDX licence identifier and copyright (REUSE 3.3; reuse lint reports the project compliant), held by the rule reuse-shape; .github/workflows/publish.yml writes an SPDX SBOM (pkinative-X.Y.Z.spdx.json) beside the CycloneDX one, attested and attached to the release (tests/tools/workflows.test.ts) |
The SBOM of the runtime is empty by design (zero dependencies); the build toolchain has its own CycloneDX SBOM, not an SPDX one. |
| ISO/IEC 5230 and ISO/IEC 18974 (OpenChain) | Open source licence compliance and security assurance programmes | not claimed | LICENSE, REUSE.toml (every file's licence, the foreign fixtures under their own terms, rule reuse-shape), THIRD-PARTY-NOTICES.md (the corpora, their licences and pins, held by the rule corpus-pin-parity); zero runtime dependencies |
These certify an organisation's programme; a single-maintainer library has no such programme to certify. |
| ISO/IEC 29147 (vulnerability disclosure) and ISO/IEC 30111 (vulnerability handling) | How a report reaches the maintainer and is handled | applies (self-assessed) | SECURITY.md §ISO/IEC 29147 and 30111 self-assessment: each clause of 29147 §5–§7 and 30111 §7.1–§7.5 mapped to where the repository meets it — the policy and docs/.well-known/security.txt, the 48-hour receipt, the verification and remediation steps, the advisory, the CVE-class corpus docs/data/cve-classes.json |
A self-assessment by one maintainer against the clauses, with no certification and no second party: both standards describe an organisation's processes, and the evidence is the repository's own record, not an audited one. |
| ISO/IEC 40500 (WCAG) | The documentation site | applies (WCAG 2.2 A and AA, automated rules) | The rules contrast (4.5:1 text contrast in both palettes) and a11y-structure (skip link, one <main> and <h1>, heading levels, alt, button names); lang="en" on every page; the a11y job of the Docs workflow runs axe-core 4.13.0 (WCAG 2.0/2.1/2.2 A and AA plus best practices) over every page in the light and the dark palette, zero violations blocking (scripts/a11y-check.ts) |
Automated rules decide about half of WCAG; the manual criteria (meaningful sequence, reading level, consistent navigation) are reviewed, not measured. |
| ISO/IEC 27001 | Information security management | not claimed | — | It certifies an organisation's management system; a library cannot conform to it. |
What would change a row #
A row moves when its evidence moves: a new test or rule is added to the evidence column in the same commit, and a gap closed by a change is removed in that change. The page claims nothing that the repository does not run; a certification, if one is ever obtained, will be named here with its certificate number and scope.