mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-12 13:28:51 +00:00
feat(local-issuer): RFC 5280 §4.2.1.13 CRLDistributionPoints auto-injection (Phase 6)
Production hardening II Phase 6 — close the operator-must-manually- configure-CDP gap that the EST hardening prompt's deferral list flagged. When the local issuer has CRLDistributionPointURLs configured, every issued cert carries the id-ce-cRLDistributionPoints extension pointing at the configured URLs. Relying parties (browsers, OpenSSL, cert-manager) read the CDP and fetch the CRL automatically; without this extension, operators have to ship the CRL endpoint URL out-of- band. NEW Config field internal/connector/issuer/local/local.go:: Config.CRLDistributionPointURLs []string. Empty (default) preserves pre-Phase-6 behavior — no CDP extension. Refusing to silently inject an empty CDP is frozen decision 0.9 from the production hardening II prompt: a cert with an empty CDP extension fails relying-party validation worse than a cert with no CDP at all. Issuer wire: generateCertificate appends the configured URLs to template.CRLDistributionPoints. crypto/x509 handles the ASN.1 encoding (RFC 5280 §4.2.1.13) — no manual marshaling needed. Operator config (cmd/server/main.go wire-up to follow when the operator opts in via per-issuer config-blob fields; the local issuer's existing dynamic-config-via-GUI path picks up the new field via the standard JSON unmarshal). Typical value: ["https://certctl.example.com:8443/.well-known/pki/crl/iss-local"] Pre-commit verification: go build ./... clean; go test -short -count=1 green for connector/issuer/local/.
This commit is contained in:
@@ -94,6 +94,20 @@ type Config struct {
|
|||||||
// CAKeyPath is the path to a PEM-encoded CA private key file (RSA or ECDSA).
|
// CAKeyPath is the path to a PEM-encoded CA private key file (RSA or ECDSA).
|
||||||
// Required when CACertPath is set.
|
// Required when CACertPath is set.
|
||||||
CAKeyPath string `json:"ca_key_path,omitempty"`
|
CAKeyPath string `json:"ca_key_path,omitempty"`
|
||||||
|
|
||||||
|
// CRLDistributionPointURLs — production hardening II Phase 6. When
|
||||||
|
// non-empty, the local issuer auto-injects the RFC 5280 §4.2.1.13
|
||||||
|
// id-ce-cRLDistributionPoints extension on every issued certificate
|
||||||
|
// pointing at these URLs. Operators set this to certctl's own
|
||||||
|
// public CRL endpoint (e.g.
|
||||||
|
// https://certctl.example.com:8443/.well-known/pki/crl/iss-local)
|
||||||
|
// so relying parties can fetch the CRL without manual config.
|
||||||
|
//
|
||||||
|
// Empty (default) preserves the pre-Phase-6 behavior — no CDP
|
||||||
|
// extension on issued certs. The omission is deliberate: silently
|
||||||
|
// injecting an empty CDP would produce certs that fail relying-
|
||||||
|
// party validation.
|
||||||
|
CRLDistributionPointURLs []string `json:"crl_distribution_point_urls,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connector implements the issuer.Connector interface for local certificate generation.
|
// Connector implements the issuer.Connector interface for local certificate generation.
|
||||||
@@ -711,6 +725,15 @@ func (c *Connector) generateCertificate(csr *x509.CertificateRequest, additional
|
|||||||
AuthorityKeyId: c.caCert.SubjectKeyId,
|
AuthorityKeyId: c.caCert.SubjectKeyId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Production hardening II Phase 6: auto-inject the
|
||||||
|
// id-ce-cRLDistributionPoints extension when configured. crypto/x509
|
||||||
|
// handles the ASN.1 encoding from the URL slice. Empty config = no
|
||||||
|
// extension (deliberate; refusing to silently inject an empty CDP
|
||||||
|
// is frozen decision 0.9).
|
||||||
|
if len(c.config.CRLDistributionPointURLs) > 0 {
|
||||||
|
template.CRLDistributionPoints = append(template.CRLDistributionPoints, c.config.CRLDistributionPointURLs...)
|
||||||
|
}
|
||||||
|
|
||||||
// Add IP addresses if present
|
// Add IP addresses if present
|
||||||
if len(ips) > 0 {
|
if len(ips) > 0 {
|
||||||
for _, ipStr := range ips {
|
for _, ipStr := range ips {
|
||||||
|
|||||||
Reference in New Issue
Block a user