feat: M12 — sub-CA mode, ACME DNS-01 challenges, step-ca issuer connector

Sub-CA mode: Local CA loads CA cert+key from disk (CERTCTL_CA_CERT_PATH +
CERTCTL_CA_KEY_PATH) to operate as subordinate CA under enterprise root
(e.g., ADCS). Supports RSA, ECDSA, PKCS#8 keys. Validates IsCA and
KeyUsageCertSign. Falls back to self-signed when paths unset.

DNS-01 challenges: Pluggable DNSSolver interface with script-based hook
implementation. User-provided scripts create/cleanup _acme-challenge TXT
records for any DNS provider. Configurable propagation wait. Enables
wildcard certs and non-HTTP-accessible hosts.

step-ca connector: Smallstep private CA via native /sign API with JWK
provisioner auth. Issuance, renewal, revocation. Registered as iss-stepca.

23 new tests across 3 files. CI test path widened to ./internal/connector/issuer/...

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shankar0123
2026-03-21 22:55:50 -04:00
parent d7a4d40d47
commit f5fed74d6f
14 changed files with 1827 additions and 45 deletions
+33
View File
@@ -19,6 +19,7 @@ type Config struct {
RateLimit RateLimitConfig
CORS CORSConfig
Keygen KeygenConfig
CA CAConfig
}
// KeygenConfig controls where private keys are generated.
@@ -29,6 +30,34 @@ type KeygenConfig struct {
Mode string
}
// CAConfig controls the Local CA's operating mode.
type CAConfig struct {
// CertPath is the path to a PEM-encoded CA certificate for sub-CA mode.
// When set with KeyPath, the Local CA loads this cert instead of generating a self-signed root.
CertPath string
// KeyPath is the path to a PEM-encoded CA private key for sub-CA mode.
// Supports RSA, ECDSA, and PKCS#8 encoded keys.
KeyPath string
}
// StepCAConfig contains step-ca issuer connector configuration.
type StepCAConfig struct {
URL string
ProvisionerName string
ProvisionerKeyPath string
ProvisionerPassword string
}
// ACMEConfig contains ACME issuer connector configuration.
type ACMEConfig struct {
DirectoryURL string
Email string
ChallengeType string // "http-01" (default) or "dns-01"
DNSPresentScript string
DNSCleanUpScript string
}
// ServerConfig contains HTTP server configuration.
type ServerConfig struct {
Host string
@@ -113,6 +142,10 @@ func Load() (*Config, error) {
Keygen: KeygenConfig{
Mode: getEnv("CERTCTL_KEYGEN_MODE", "agent"),
},
CA: CAConfig{
CertPath: getEnv("CERTCTL_CA_CERT_PATH", ""),
KeyPath: getEnv("CERTCTL_CA_KEY_PATH", ""),
},
}
if err := cfg.Validate(); err != nil {