49 lines
2.5 KiB
Markdown
49 lines
2.5 KiB
Markdown
# `helpers/has-name-match` — RFC 6125 host-name match
|
|
|
|
## Purpose
|
|
|
|
The `helpers/has-name-match` module exposes a pre-filtering / display helper around the parsed certificate data. It is independent of the path-validation algorithm: `validateChain` does not depend on it for correctness, and consumers can use it freely without invoking signature verify. The helper is convenient for UI display, candidate-issuer enumeration, and host-name matching outside the full path-validation path. The implementation operates exclusively on the parsed `X509Certificate` shape — no re-decoding, no cryptographic operations.
|
|
|
|
## Features
|
|
|
|
- Pure synchronous function, no I/O.
|
|
- No allocations beyond the boolean return.
|
|
- Idempotent — same input produces the same output.
|
|
- Compatible with the rest of the `@suaveplan/x509` public surface — the certificate, name, and extension types feed directly in.
|
|
- Defensive — missing fields (no SAN, no AKI/SKI) return `false` rather than throwing, so callers can drive their own branching logic.
|
|
|
|
## Usage: Basic Example
|
|
|
|
```ts
|
|
import { hasNameMatch, chainsTo, isIssuerOf } from "@suaveplan/x509/helpers";
|
|
import { parseCertificate } from "@suaveplan/x509/certificate";
|
|
|
|
const cert = parseCertificate(derBytes);
|
|
const anchor = parseCertificate(anchorBytes);
|
|
hasNameMatch(cert, "example.com");
|
|
chainsTo(cert, anchor);
|
|
isIssuerOf(cert, anchor);
|
|
```
|
|
|
|
## Usage: Advanced Example
|
|
|
|
```ts
|
|
import { chainsTo } from "@suaveplan/x509/helpers";
|
|
import { parseCertificate } from "@suaveplan/x509/certificate";
|
|
|
|
const candidates = await loadTrustAnchorBundle();
|
|
const candidate = candidates.find((a) => chainsTo(parsedLeaf, a));
|
|
```
|
|
|
|
## API Reference
|
|
|
|
- Helper function as named.
|
|
- Operates on `X509Certificate` values from `@suaveplan/x509/certificate`.
|
|
|
|
## Implementation Notes
|
|
|
|
- The helpers are intentionally heuristic. `hasNameMatch` follows RFC 6125 paragraph 6.4 — SAN dNSName entries take precedence; CN fallback only when SAN is absent. Wildcard matching honours the leftmost-label rule.
|
|
- `chainsTo` consults the AKI and SKI extensions; missing extensions yield `false` (the caller should fall back to a full subject/issuer-name match via `isIssuerOf` plus signature verify).
|
|
- `isIssuerOf` uses the canonical name comparison from `certificate/name`; the canonical form is whitespace-collapsed and case-folded so issuer/subject equality survives encoding choice (PrintableString vs UTF8String).
|
|
- None of the helpers replace `validateChain` — they are pre-filters and display helpers, not validators.
|