mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-10 17:38:53 +00:00
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:
@@ -619,3 +619,8 @@ func (c *Connector) GenerateCRL(ctx context.Context, revokedCerts []issuer.Revok
|
||||
func (c *Connector) SignOCSPResponse(ctx context.Context, req issuer.OCSPSignRequest) ([]byte, error) {
|
||||
return nil, fmt.Errorf("ACME issuers do not support OCSP response signing")
|
||||
}
|
||||
|
||||
// GetCACertPEM is not supported by ACME issuers (the CA chain is returned per-issuance).
|
||||
func (c *Connector) GetCACertPEM(ctx context.Context) (string, error) {
|
||||
return "", fmt.Errorf("ACME issuers do not provide a static CA certificate; chain is returned per-issuance")
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ type Connector interface {
|
||||
// SignOCSPResponse signs an OCSP response for the given certificate serial.
|
||||
// Returns nil if the issuer does not support OCSP (e.g., ACME).
|
||||
SignOCSPResponse(ctx context.Context, req OCSPSignRequest) ([]byte, error)
|
||||
|
||||
// GetCACertPEM returns the PEM-encoded CA certificate chain for this issuer.
|
||||
// Used by the EST /cacerts endpoint. Returns empty string if not available.
|
||||
GetCACertPEM(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
// IssuanceRequest contains the parameters for issuing a new certificate.
|
||||
|
||||
@@ -664,3 +664,12 @@ func (c *Connector) SignOCSPResponse(ctx context.Context, req issuer.OCSPSignReq
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
// GetCACertPEM returns the PEM-encoded CA certificate for this issuer.
|
||||
// Used by the EST /cacerts endpoint to distribute the CA trust chain.
|
||||
func (c *Connector) GetCACertPEM(ctx context.Context) (string, error) {
|
||||
if err := c.ensureCA(ctx); err != nil {
|
||||
return "", fmt.Errorf("CA initialization failed: %w", err)
|
||||
}
|
||||
return c.caCertPEM, nil
|
||||
}
|
||||
|
||||
@@ -358,6 +358,11 @@ func (c *Connector) SignOCSPResponse(ctx context.Context, req issuer.OCSPSignReq
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetCACertPEM is not supported by the custom CA connector (no CA cert access).
|
||||
func (c *Connector) GetCACertPEM(ctx context.Context) (string, error) {
|
||||
return "", fmt.Errorf("custom CA connector does not provide CA certificate access")
|
||||
}
|
||||
|
||||
// --- Helper Methods ---
|
||||
|
||||
// writeTempFile writes data to a temporary file and returns its path.
|
||||
|
||||
@@ -467,5 +467,10 @@ func (c *Connector) SignOCSPResponse(ctx context.Context, req issuer.OCSPSignReq
|
||||
return nil, fmt.Errorf("step-ca provides its own OCSP responder; use step-ca's /ocsp directly")
|
||||
}
|
||||
|
||||
// GetCACertPEM is not directly supported; step-ca serves its own /root endpoint.
|
||||
func (c *Connector) GetCACertPEM(ctx context.Context) (string, error) {
|
||||
return "", fmt.Errorf("step-ca serves its own CA certificate at /root; use step-ca's endpoint directly")
|
||||
}
|
||||
|
||||
// Ensure Connector implements the issuer.Connector interface.
|
||||
var _ issuer.Connector = (*Connector)(nil)
|
||||
|
||||
Reference in New Issue
Block a user