feat: add EST server (RFC 7030) for device certificate enrollment (M23)

Implement Enrollment over Secure Transport protocol with 4 endpoints under
/.well-known/est/ — cacerts (CA chain distribution), simpleenroll (initial
enrollment), simplereenroll (certificate renewal), and csrattrs (CSR
attributes). PKCS#7 certs-only wire format with hand-rolled ASN.1, accepts
both PEM and base64-encoded DER CSRs, configurable issuer and profile
binding, full audit trail. 28 new tests (18 handler + 10 service).

Also includes:
- GetCACertPEM added to issuer connector interface (all 4 issuers updated)
- EST integration tests wired into e2e test suite (13 test cases)
- QA testing guide Part 26 (15 manual EST test cases)
- All docs updated: README, features, architecture, concepts, connectors,
  quickstart, demo-advanced (endpoint counts, MCP wording, agent IDs,
  issuer interface, resource lists, OpenSSL status)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Shankar
2026-03-25 15:31:06 -04:00
parent 42fa9c7791
commit e4ba8d4de2
27 changed files with 1807 additions and 20 deletions
+14
View File
@@ -22,6 +22,7 @@ type Config struct {
CA CAConfig
Notifiers NotifierConfig
NetworkScan NetworkScanConfig
EST ESTConfig
}
// NotifierConfig contains configuration for notification connectors.
@@ -81,6 +82,14 @@ type OpenSSLConfig struct {
TimeoutSeconds int
}
// ESTConfig controls the RFC 7030 Enrollment over Secure Transport server.
type ESTConfig struct {
Enabled bool // Enable EST endpoints (default false)
IssuerID string // Which issuer connector to use for EST enrollment (e.g., "iss-local")
// ProfileID optionally constrains EST enrollments to a specific certificate profile.
ProfileID string
}
// NetworkScanConfig controls the server-side active TLS scanner.
type NetworkScanConfig struct {
Enabled bool // Enable network scanning (default false)
@@ -189,6 +198,11 @@ func Load() (*Config, error) {
Enabled: getEnvBool("CERTCTL_NETWORK_SCAN_ENABLED", false),
ScanInterval: getEnvDuration("CERTCTL_NETWORK_SCAN_INTERVAL", 6*time.Hour),
},
EST: ESTConfig{
Enabled: getEnvBool("CERTCTL_EST_ENABLED", false),
IssuerID: getEnv("CERTCTL_EST_ISSUER_ID", "iss-local"),
ProfileID: getEnv("CERTCTL_EST_PROFILE_ID", ""),
},
}
if err := cfg.Validate(); err != nil {