crl

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ChannelRevoke is the NATS subject for revocation broadcasts
	ChannelRevoke = "neuwerk.crl.revoke"
	// ChannelAck is the NATS subject for acknowledgments
	ChannelAck = "neuwerk.crl.ack"
	// ChannelRollback is the NATS subject for rollback broadcasts
	ChannelRollback = "neuwerk.crl.rollback"

	// RevocationTimeout is the maximum time to wait for all nodes to confirm
	RevocationTimeout = 5 * time.Second
)
View Source
const (
	// CRLBucketName is the JetStream KV bucket for CRL storage
	CRLBucketName = "neuwerk-crl"

	// BucketReplicas controls HA replication for CRL storage
	BucketReplicas = 3
)
View Source
const (
	// CRLValidityDuration is 24 hours (refreshed hourly to ensure NextUpdate stays current)
	CRLValidityDuration = 24 * time.Hour
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AckMessage

type AckMessage struct {
	RequestID string `json:"requestId"` // Correlate with RevocationBroadcast
	NodeName  string `json:"nodeName"`  // From cluster membership
	Success   bool   `json:"success"`   // True if applied successfully
	Error     string `json:"error"`     // Empty if success, error message otherwise
}

AckMessage represents an acknowledgment from a node

type Broadcaster

type Broadcaster struct {
	// contains filtered or unexported fields
}

Broadcaster implements atomic broadcast protocol for certificate revocation with two-phase commit semantics (broadcast + acknowledgments)

func NewBroadcaster

func NewBroadcaster(pubsub cluster.PubSub, membership cluster.Membership, store *Store, manager *Manager, natsVerifier *Verifier, apiServerVerifier *Verifier, logger logr.Logger) *Broadcaster

NewBroadcaster creates a new Broadcaster instance

func (*Broadcaster) BroadcastRevocation

func (b *Broadcaster) BroadcastRevocation(ctx context.Context, certType string, serialNumber *big.Int, reasonCode ReasonCode) error

BroadcastRevocation broadcasts a certificate revocation to all cluster nodes with atomic all-or-nothing semantics. Returns error if any node fails to confirm.

func (*Broadcaster) StartSubscriptions

func (b *Broadcaster) StartSubscriptions(ctx context.Context)

StartSubscriptions subscribes to revocation and rollback channels Should be called during controller startup after NATS store is initialized

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager handles CRL generation, signing, and revocation operations

func NewManager

func NewManager(bootstrapToken token.SecureToken, caManager *ca.Manager, store *Store, logger logr.Logger) *Manager

NewManager creates a new CRL manager instance The bootstrap token is used to decrypt CA private keys for CRL signing

func (*Manager) AddRevocation

func (m *Manager) AddRevocation(ctx context.Context, caType ca.CAType, serialNumber *big.Int, reasonCode ReasonCode) ([]byte, error)

AddRevocation adds a certificate to the revocation list Idempotent: if certificate already revoked, returns nil without error Returns new CRL DER bytes after adding revocation

func (*Manager) GenerateInitialCRL

func (m *Manager) GenerateInitialCRL(ctx context.Context, caType ca.CAType) ([]byte, error)

GenerateInitialCRL creates an empty CRL for the given CA type Called during bootstrap ceremony after CA generation Returns DER-encoded CRL bytes ready for storage

func (*Manager) GetStore

func (m *Manager) GetStore() *Store

GetStore returns the CRL store for downstream use

func (*Manager) RefreshCRL

func (m *Manager) RefreshCRL(ctx context.Context, caType ca.CAType) ([]byte, error)

RefreshCRL regenerates CRL with same entries but fresh timestamps Called hourly by rotation scheduler to prevent CRL expiry Returns new CRL DER bytes with incremented number and updated ThisUpdate/NextUpdate

type ReasonCode

type ReasonCode int

ReasonCode represents X.509 CRL revocation reason codes per RFC 5280

const (
	// ReasonUnspecified - default when no specific reason provided
	ReasonUnspecified ReasonCode = 0
	// ReasonKeyCompromise - certificate private key compromised
	ReasonKeyCompromise ReasonCode = 1
	// ReasonCACompromise - CA private key compromised
	ReasonCACompromise ReasonCode = 2
	// ReasonAffiliationChanged - certificate subject changed affiliation
	ReasonAffiliationChanged ReasonCode = 3
	// ReasonSuperseded - certificate replaced by newer one
	ReasonSuperseded ReasonCode = 4
	// ReasonCessationOfOperation - certificate no longer used
	ReasonCessationOfOperation ReasonCode = 5
	// ReasonCertificateHold - temporary suspension (not used in neuwerk)
	ReasonCertificateHold ReasonCode = 6
	// ReasonRemoveFromCRL - unrevoke certificate (only valid for certificateHold)
	ReasonRemoveFromCRL ReasonCode = 8
	// ReasonPrivilegeWithdrawn - certificate privileges withdrawn
	ReasonPrivilegeWithdrawn ReasonCode = 9
	// ReasonAACompromise - attribute authority compromised
	ReasonAACompromise ReasonCode = 10
)

func ReasonCodeFromString

func ReasonCodeFromString(s string) (ReasonCode, error)

ReasonCodeFromString parses CLI flag value to ReasonCode

func (ReasonCode) String

func (r ReasonCode) String() string

String returns human-readable reason code name for CLI display

type RevocationBroadcast

type RevocationBroadcast struct {
	RequestID    string    `json:"requestId"`    // UUID for correlation
	CertType     string    `json:"certType"`     // "NATS", "API Server", "API Client"
	SerialNumber string    `json:"serialNumber"` // Certificate serial to revoke (base 10)
	ReasonCode   int       `json:"reasonCode"`   // RFC 5280 reason code
	CRLBytes     []byte    `json:"crlBytes"`     // Full updated CRL (DER encoded)
	CRLNumber    int64     `json:"crlNumber"`    // CRL revision number for rollback
	Timestamp    time.Time `json:"timestamp"`    // Revocation timestamp
}

RevocationBroadcast represents a revocation request broadcast to all nodes

type RevokedEntry

type RevokedEntry struct {
	// SerialNumber of the revoked certificate
	SerialNumber *big.Int
	// RevocationTime when certificate was revoked
	RevocationTime time.Time
	// ReasonCode explaining why certificate was revoked
	ReasonCode int
}

RevokedEntry represents a single revoked certificate entry Used for storing and manipulating revocations before CRL generation

type RollbackMessage

type RollbackMessage struct {
	RequestID string `json:"requestId"` // Correlate with original broadcast
	CRLNumber int64  `json:"crlNumber"` // Revert to this CRL revision
	Reason    string `json:"reason"`    // Why rollback (timeout, node failure, etc.)
}

RollbackMessage represents a rollback request

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store handles JetStream KV persistence for CRLs

func NewStore

func NewStore(js jetstream.JetStream, logger logr.Logger) *Store

NewStore creates a new CRL store backed by JetStream KV

func (*Store) FetchCRL

func (s *Store) FetchCRL(ctx context.Context, caType ca.CAType) ([]byte, error)

FetchCRL retrieves a CRL from JetStream KV Returns nil, nil if CRL doesn't exist yet (caller should generate initial CRL)

func (*Store) IncrementCRLNumber

func (s *Store) IncrementCRLNumber(ctx context.Context, caType ca.CAType) (int64, error)

IncrementCRLNumber atomically increments the CRL number for a given CA type Key format: "crl-number-{CA-type}" Returns the new CRL number (initialized to 1 on first call)

func (*Store) StoreCRL

func (s *Store) StoreCRL(ctx context.Context, caType ca.CAType, crlBytes []byte) error

StoreCRL stores a CRL in JetStream KV Key format: "crl-{CA-type}" (e.g., "crl-NATS", "crl-API Server")

type Verifier

type Verifier struct {
	// contains filtered or unexported fields
}

Verifier implements VerifyPeerCertificate callback for CRL checking during TLS handshakes. Uses atomic updates and O(1) revocation lookups via in-memory map. Thread-safe for concurrent TLS handshakes and CRL updates.

func NewVerifier

func NewVerifier(caCertPEM []byte, initialCRLBytes []byte, logger logr.Logger) (*Verifier, error)

NewVerifier creates a new CRL verifier with initial CRL. caCertPEM: CA certificate in PEM format for signature verification initialCRLBytes: Initial CRL in DER format (can be empty CRL) Returns error if CA certificate or CRL cannot be parsed or verified.

func (*Verifier) UpdateCRL

func (v *Verifier) UpdateCRL(crlBytes []byte) error

UpdateCRL updates the CRL atomically with signature verification. Validates signature, checks CRL number monotonically increases, then performs atomic swap. Thread-safe: Uses write lock during update. Returns error if signature invalid, CRL number not monotonic, or parsing fails.

func (*Verifier) VerifyPeerCertificate

func (v *Verifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error

VerifyPeerCertificate checks if any certificate in the chain is revoked. Implements tls.Config.VerifyPeerCertificate callback interface. Returns error if any certificate is revoked or CRL has expired. Thread-safe: Uses read lock for concurrent TLS handshakes.

Jump to

Keyboard shortcuts

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