ca

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

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

View Source
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

View Source
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

func Generate(realm string, lifetime time.Duration) (*CA, error)

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

func Load(certPEM string, keyDER []byte) (*CA, error)

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

func (c *CA) CertificatePEM() string

CertificatePEM returns the CA certificate in PEM form (the `ca_crt` delivered to devices).

func (*CA) PrivateKeyDER

func (c *CA) PrivateKeyDER() []byte

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

func (c *CA) Verify(certPEM string, at time.Time) (until time.Time, err error)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL