Documentation
¶
Index ¶
- Constants
- type AckMessage
- type Broadcaster
- type Manager
- func (m *Manager) AddRevocation(ctx context.Context, caType ca.CAType, serialNumber *big.Int, ...) ([]byte, error)
- func (m *Manager) GenerateInitialCRL(ctx context.Context, caType ca.CAType) ([]byte, error)
- func (m *Manager) GetStore() *Store
- func (m *Manager) RefreshCRL(ctx context.Context, caType ca.CAType) ([]byte, error)
- type ReasonCode
- type RevocationBroadcast
- type RevokedEntry
- type RollbackMessage
- type Store
- type Verifier
Constants ¶
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 )
const ( // CRLBucketName is the JetStream KV bucket for CRL storage CRLBucketName = "neuwerk-crl" // BucketReplicas controls HA replication for CRL storage BucketReplicas = 3 )
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 ¶
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) RefreshCRL ¶
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 (*Store) FetchCRL ¶
FetchCRL retrieves a CRL from JetStream KV Returns nil, nil if CRL doesn't exist yet (caller should generate initial CRL)
func (*Store) IncrementCRLNumber ¶
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)
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 ¶
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 ¶
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.