first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
# `extensions/basic-constraints` — RFC 5280 paragraph 4.2.1.9
## Purpose
Decodes the basic-constraints extension into `BasicConstraints { cA: boolean; pathLenConstraint?: number }`. During path validation, every non-leaf certificate in the chain SHALL have `cA: true`; the `pathLenConstraint` field bounds the number of non-self-issued intermediates beneath the issuer per RFC 5280 paragraph 6.1.4(h).
## Features
- Strict DER decode of the SEQUENCE wrapper.
- Default `cA: false` when the BOOLEAN field is absent (matches RFC 5280 paragraph 4.2.1.9 default).
- INTEGER decode for `pathLenConstraint` with bounded length (up to 4 bytes) and non-negative check.
- Rejects extra fields beyond `(cA, pathLenConstraint)` as `X509Error(EXTENSION_MALFORMED)`.
## Usage: Basic Example
```ts
import { decodeBasicConstraints } from "@suaveplan/x509/extensions";
const bc = decodeBasicConstraints(extensionValueBytes);
if (bc.cA && bc.pathLenConstraint !== undefined) {
console.log("CA with max", bc.pathLenConstraint, "non-self-issued intermediates");
}
```
## Usage: Advanced Example
```ts
import { decodeBasicConstraints } from "@suaveplan/x509/extensions";
import { parseCertificate } from "@suaveplan/x509/certificate";
const cert = parseCertificate(derBytes);
const ext = cert.tbs.extensions.find((e) => e.oid === "2.5.29.19");
if (ext !== undefined) {
const bc = decodeBasicConstraints(ext.value);
if (!bc.cA) {
throw new Error("issuer must have cA: true");
}
}
```
## API Reference
- `decodeBasicConstraints(value: Uint8Array): BasicConstraints` — decode an extension value (the OCTET STRING contents). Throws `X509Error(EXTENSION_MALFORMED)` on shape violation.
- `OID_BASIC_CONSTRAINTS` — string constant `"2.5.29.19"`.
## Implementation Notes
- `cA` defaults to `false` when the BOOLEAN field is absent; this is what RFC 5280 paragraph 4.2.1.9 mandates.
- The bound on `pathLenConstraint` length (4 bytes) is overgenerous — real-world values fit in a single byte — but matches the canonical DER encoding of small INTEGERs and rejects deliberately oversized values as malformed.
- The bound `n < 0` is also redundant since the bit-shift always produces non-negative values for content lengths up to 4 bytes; the check exists as defensive depth and is exercised by malformed-input tests.