Documentation
¶
Overview ¶
Package ca implements Astrate's embedded per-realm certificate authority (docs/DESIGN.md §4.3), replacing upstream Astarte's CFSSL sidecar. Each realm owns one ECDSA P-256 CA; the CA issues short-lived client certificates against device CSRs, treating the CSR purely as proof of key possession: every requested attribute, including the subject, is ignored and overridden, exactly as upstream does.
Index ¶
Constants ¶
const ( // DefaultCALifetime is the self-signed realm CA validity // (docs/DESIGN.md §4.3: default 10 years). DefaultCALifetime = 10 * 365 * 24 * time.Hour // DefaultCertTTL is the client certificate validity // (docs/DESIGN.md §4.3: default 30 days). DefaultCertTTL = 30 * 24 * time.Hour )
Variables ¶
var ( // ErrInvalidCSR reports a CSR that does not parse or whose // proof-of-possession signature does not verify. ErrInvalidCSR = errors.New("ca: invalid certificate signing request") // ErrCAExpired reports an issuance attempt outside the CA certificate's // own validity window. ErrCAExpired = errors.New("ca: realm CA certificate is not currently valid") // ErrCertificateExpired reports a client certificate outside its // validity window (wire cause EXPIRED). ErrCertificateExpired = errors.New("ca: certificate expired") // ErrCertificateInvalid reports a client certificate that does not // parse or does not chain to the realm CA (wire cause INVALID). ErrCertificateInvalid = errors.New("ca: certificate invalid") )
Sentinel errors. The pairing service maps them onto the wire causes (EXPIRED/INVALID) and HTTP statuses.
Functions ¶
func ParseCertificatePEM ¶
func ParseCertificatePEM(certPEM string) (*x509.Certificate, error)
ParseCertificatePEM decodes a single PEM-encoded X.509 certificate.
Types ¶
type CA ¶
type CA struct {
// contains filtered or unexported fields
}
CA is a realm certificate authority: the CA certificate plus its private key. Immutable and safe for concurrent use.
func Generate ¶
Generate creates a fresh self-signed ECDSA P-256 realm CA. A zero lifetime selects DefaultCALifetime; negative lifetimes are allowed (they produce an already-expired CA, used by tests).
func Load ¶
Load reconstructs a CA from its stored material: the PEM certificate and the PKCS#8 DER private key (the plaintext that store.KeySealer sealed). Operator-provided CA imports go through the same path.
func (*CA) CertificatePEM ¶
CertificatePEM returns the CA certificate in PEM form (the `ca_crt` delivered to devices).
func (*CA) PrivateKeyDER ¶
PrivateKeyDER returns the PKCS#8 DER encoding of the CA private key — the plaintext handed to store.KeySealer for at-rest encryption.
func (*CA) SignCSR ¶
func (c *CA) SignCSR(csrPEM, realm, deviceID string, ttl time.Duration) (certPEM, serial, aki string, err error)
SignCSR issues a client certificate for a device against csrPEM (docs/DESIGN.md §4.3):
- Subject CN is forced to "<realm>/<deviceID>"; everything the CSR requested (subject, extensions, attributes) is ignored;
- serial is 128-bit random; KeyUsage is digitalSignature only; ExtKeyUsage is clientAuth;
- validity is now-clockSkewBackdate .. now+ttl, clamped to the CA's own NotAfter; a non-positive ttl selects DefaultCertTTL;
- issuance is refused outside the CA certificate's validity window.
It returns the certificate PEM, its serial (decimal string) and its authority key identifier (lowercase hex) for the device row's latest-certificate trail.
func (*CA) Verify ¶
Verify checks a client certificate against this realm CA at the given instant (the `credentials/verify` endpoint backend). On success it returns the certificate's NotAfter. Failures wrap ErrCertificateExpired (outside the validity window) or ErrCertificateInvalid (parse failure, foreign CA, wrong usage) — the precedence is expiry first, so an expired certificate reports EXPIRED even when other problems coexist.