Documentation ¶
Index ¶
- Constants
- Variables
- func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarderRoles []string, org string, ...) (string, error)
- func AuthorizeOrgAndRole(ctx context.Context, org string, ...) (string, error)
- func DefaultCAConfig() api.CAConfig
- func FormatRole(role string) (api.NodeRole, error)
- func GenerateJoinToken(rootCA *RootCA, fips bool) string
- func GenerateNewCSR() ([]byte, []byte, error)
- func GetAndValidateCertificateSubject(certs []tls.Certificate) (pkix.Name, error)
- func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x509.CertPool, ...) ([]byte, error)
- func LogTLSState(ctx context.Context, tlsState *tls.ConnectionState)
- func NewClientTLSConfig(certs []tls.Certificate, rootCAPool *x509.CertPool, serverName string) (*tls.Config, error)
- func NewExternalCATLSConfig(certs []tls.Certificate, rootPool *x509.CertPool) *tls.Config
- func NewServerTLSConfig(certs []tls.Certificate, rootCAPool *x509.CertPool) (*tls.Config, error)
- func NormalizePEMs(certs []byte) []byte
- func ParseRole(apiRole api.NodeRole) (string, error)
- func PrepareCSR(csrBytes []byte, cn, ou, org string) cfsigner.SignRequest
- func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *connectionbroker.Broker, ...) error
- func SaveRootCA(rootCA RootCA, paths CertPaths) error
- func SigningPolicy(certExpiry time.Duration) *cfconfig.Signing
- func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, [][]*x509.Certificate, error)
- func WithMetadataForwardTLSInfo(ctx context.Context) (context.Context, error)
- type CertPaths
- type CertificateRequestConfig
- type CertificateUpdate
- type ErrInvalidKEK
- type ExternalCA
- type IssuerInfo
- type KEKData
- type KeyReadWriter
- func (k *KeyReadWriter) DowngradeKey() error
- func (k *KeyReadWriter) GetCurrentState() (PEMKeyHeaders, KEKData)
- func (k *KeyReadWriter) Migrate() error
- func (k *KeyReadWriter) Read() ([]byte, []byte, error)
- func (k *KeyReadWriter) SetKeyFormatter(kf keyutils.Formatter)
- func (k *KeyReadWriter) Target() string
- func (k *KeyReadWriter) ViewAndRotateKEK(cb func(KEKData, PEMKeyHeaders) (KEKData, PEMKeyHeaders, error)) error
- func (k *KeyReadWriter) ViewAndUpdateHeaders(cb func(PEMKeyHeaders) (PEMKeyHeaders, error)) error
- func (k *KeyReadWriter) Write(certBytes, plaintextKeyBytes []byte, kekData *KEKData) error
- type KeyReader
- type KeyWriter
- type LocalSigner
- type MutableTLSCreds
- func (c *MutableTLSCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error)
- func (c *MutableTLSCreds) Clone() credentials.TransportCredentials
- func (c *MutableTLSCreds) Config() *tls.Config
- func (c *MutableTLSCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
- func (c *MutableTLSCreds) Info() credentials.ProtocolInfo
- func (c *MutableTLSCreds) NodeID() string
- func (c *MutableTLSCreds) Organization() string
- func (c *MutableTLSCreds) OverrideServerName(name string) error
- func (c *MutableTLSCreds) RequireTransportSecurity() bool
- func (c *MutableTLSCreds) Role() string
- func (c *MutableTLSCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error)
- type PEMKeyHeaders
- type ParsedJoinToken
- type RemoteNodeInfo
- type RootCA
- func CreateRootCA(rootCN string) (RootCA, error)
- func DownloadRootCA(ctx context.Context, paths CertPaths, token string, ...) (RootCA, error)
- func GetLocalRootCA(paths CertPaths) (RootCA, error)
- func GetRemoteCA(ctx context.Context, d digest.Digest, connBroker *connectionbroker.Broker) (RootCA, error)
- func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry time.Duration, ...) (RootCA, error)
- func RootCAFromAPI(ctx context.Context, apiRootCA *api.RootCA, expiry time.Duration) (RootCA, error)
- func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWriter, config CertificateRequestConfig) (*SecurityConfig, func() error, error)
- func (rca *RootCA) CrossSignCACertificate(otherCAPEM []byte) ([]byte, error)
- func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, *IssuerInfo, error)
- func (rootCA *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName string) (*MutableTLSCreds, error)
- func (rootCA *RootCA) NewServerTLSCredentials(cert *tls.Certificate) (*MutableTLSCreds, error)
- func (rca *RootCA) ParseValidateAndSignCSR(csrBytes []byte, cn, ou, org string) ([]byte, error)
- func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, *IssuerInfo, error)
- func (rca *RootCA) Signer() (*LocalSigner, error)
- type SecurityConfig
- func (s *SecurityConfig) IssuerInfo() *IssuerInfo
- func (s *SecurityConfig) KeyReader() KeyReader
- func (s *SecurityConfig) KeyWriter() KeyWriter
- func (s *SecurityConfig) RootCA() *RootCA
- func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA) error
- func (s *SecurityConfig) UpdateTLSCredentials(certificate *tls.Certificate, issuerInfo *IssuerInfo) error
- func (s *SecurityConfig) Watch() (chan events.Event, func())
- type SecurityConfigPaths
- type Server
- func (s *Server) ExternalCA() *ExternalCA
- func (s *Server) GetRootCACertificate(ctx context.Context, request *api.GetRootCACertificateRequest) (*api.GetRootCACertificateResponse, error)
- func (s *Server) GetUnlockKey(ctx context.Context, request *api.GetUnlockKeyRequest) (*api.GetUnlockKeyResponse, error)
- func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNodeCertificateRequest) (*api.IssueNodeCertificateResponse, error)
- func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCertificateStatusRequest) (*api.NodeCertificateStatusResponse, error)
- func (s *Server) Ready() <-chan struct{}
- func (s *Server) RootCA() *RootCA
- func (s *Server) Run(ctx context.Context) error
- func (s *Server) SetReconciliationRetryInterval(reconciliationRetryInterval time.Duration)
- func (s *Server) SetRootReconciliationInterval(interval time.Duration)
- func (s *Server) Stop() error
- func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster, reconciler *rootRotationReconciler) error
- type TLSRenewer
Constants ¶
const ( // RootKeySize is the default size of the root CA key // It would be ideal for the root key to use P-384, but in P-384 is not optimized in go yet :( RootKeySize = 256 // RootKeyAlgo defines the default algorithm for the root CA Key RootKeyAlgo = "ecdsa" // RootCAExpiration represents the default expiration for the root CA in seconds (20 years) RootCAExpiration = "630720000s" // DefaultNodeCertExpiration represents the default expiration for node certificates (3 months) DefaultNodeCertExpiration = 2160 * time.Hour // CertBackdate represents the amount of time each certificate is backdated to try to avoid // clock drift issues. CertBackdate = 1 * time.Hour // CertLowerRotationRange represents the minimum fraction of time that we will wait when randomly // choosing our next certificate rotation CertLowerRotationRange = 0.5 // CertUpperRotationRange represents the maximum fraction of time that we will wait when randomly // choosing our next certificate rotation CertUpperRotationRange = 0.8 // MinNodeCertExpiration represents the minimum expiration for node certificates MinNodeCertExpiration = 1 * time.Hour )
const ( // DefaultRootCN represents the root CN that we should create roots CAs with by default DefaultRootCN = "swarm-ca" // ManagerRole represents the Manager node type, and is used for authorization to endpoints ManagerRole = "swarm-manager" // WorkerRole represents the Worker node type, and is used for authorization to endpoints WorkerRole = "swarm-worker" // CARole represents the CA node type, and is used for clients attempting to get new certificates issued CARole = "swarm-ca" )
const ( // ExternalCrossSignProfile is the profile that we will be sending cross-signing CSR sign requests with ExternalCrossSignProfile = "CA" // CertificateMaxSize is the maximum expected size of a certificate. // While there is no specced upper limit to the size of an x509 certificate in PEM format, // one with a ridiculous RSA key size (16384) and 26 256-character DNS SAN fields is about 14k. // While there is no upper limit on the length of certificate chains, long chains are impractical. // To be conservative, and to also account for external CA certificate responses in JSON format // from CFSSL, we'll set the max to be 256KiB. CertificateMaxSize int64 = 256 << 10 )
const IssuanceStateRotateMaxBatchSize = 30
IssuanceStateRotateMaxBatchSize is the maximum number of nodes we'll tell to rotate their certificates in any given update
Variables ¶
var BasicConstraintsOID = asn1.ObjectIdentifier{2, 5, 29, 19}
BasicConstraintsOID is the ASN1 Object ID indicating a basic constraints extension
var ErrNoExternalCAURLs = errors.New("no external CA URLs")
ErrNoExternalCAURLs is an error used it indicate that an ExternalCA is configured with no URLs to which it can proxy certificate signing requests.
var ErrNoLocalRootCA = errors.New("local root CA certificate does not exist")
ErrNoLocalRootCA is an error type used to indicate that the local root CA certificate file does not exist.
var ErrNoValidSigner = recoverableErr{/* contains filtered or unexported fields */}
ErrNoValidSigner is an error type used to indicate that our RootCA doesn't have the ability to sign certificates.
var ( // GetCertRetryInterval is how long to wait before retrying a node // certificate or root certificate request. GetCertRetryInterval = 2 * time.Second )
var LocalRequestKey = localRequestKeyType{}
LocalRequestKey is a context key to mark a request that originating on the local node. The associated value is a RemoteNodeInfo structure describing the local node.
var RenewTLSExponentialBackoff = events.ExponentialBackoffConfig{ Base: time.Second * 5, Factor: time.Second * 5, Max: 1 * time.Hour, }
RenewTLSExponentialBackoff sets the exponential backoff when trying to renew TLS certificates that have expired
Functions ¶
func AuthorizeForwardedRoleAndOrg ¶
func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarderRoles []string, org string, blacklistedCerts map[string]*api.BlacklistedCertificate) (string, error)
AuthorizeForwardedRoleAndOrg checks for proper roles and organization of caller. The RPC may have been proxied by a manager, in which case the manager is authenticated and so is the certificate information that it forwarded. It returns the node ID of the original client.
func AuthorizeOrgAndRole ¶
func AuthorizeOrgAndRole(ctx context.Context, org string, blacklistedCerts map[string]*api.BlacklistedCertificate, ou ...string) (string, error)
AuthorizeOrgAndRole takes in a context and a list of roles, and returns the Node ID of the node.
func DefaultCAConfig ¶
DefaultCAConfig returns the default CA Config, with a default expiration.
func FormatRole ¶
FormatRole parses an internal role string into an apiRole
func GenerateJoinToken ¶
GenerateJoinToken creates a new join token. Current format is v2, but this is currently used only if the cluster requires mandatory FIPS, in order to facilitate mixed version clusters (the `fips` parameter is set to true). Otherwise, v1 is used so as to maintain compatibility in mixed version non-FIPS clusters. v1: SWMTKN-1-<SHA256 digest of root CA cert in base 36, 0-left-padded to 50 chars>-<16-byte secret in base 36 0-left-padded to 25 chars> v2: SWMTKN-2-<0/1 whether its FIPS or not>-<same rest of data as v1>
func GenerateNewCSR ¶
GenerateNewCSR returns a newly generated key and CSR signed with said key
func GetAndValidateCertificateSubject ¶
func GetAndValidateCertificateSubject(certs []tls.Certificate) (pkix.Name, error)
GetAndValidateCertificateSubject is a helper method to retrieve and validate the subject from the x509 certificate underlying a tls.Certificate
func GetRemoteSignedCertificate ¶
func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x509.CertPool, config CertificateRequestConfig) ([]byte, error)
GetRemoteSignedCertificate submits a CSR to a remote CA server address, and that is part of a CA identified by a specific certificate pool.
func LogTLSState ¶
func LogTLSState(ctx context.Context, tlsState *tls.ConnectionState)
LogTLSState logs information about the TLS connection and remote peers
func NewClientTLSConfig ¶
func NewClientTLSConfig(certs []tls.Certificate, rootCAPool *x509.CertPool, serverName string) (*tls.Config, error)
NewClientTLSConfig returns a tls.Config configured for a TLS Client, given a tls.Certificate the PEM-encoded root CA Certificate, and the name of the remote server the client wants to connect to.
func NewExternalCATLSConfig ¶
NewExternalCATLSConfig takes a TLS certificate and root pool and returns a TLS config that can be updated without killing existing connections
func NewServerTLSConfig ¶
NewServerTLSConfig returns a tls.Config configured for a TLS Server, given a tls.Certificate and the PEM-encoded root CA Certificate
func NormalizePEMs ¶
NormalizePEMs takes a bundle of PEM-encoded certificates in a certificate bundle, decodes them, removes headers, and re-encodes them to make sure that they have consistent whitespace. Note that this is intended to normalize x509 certificates in PEM format, hence the stripping out of headers.
func PrepareCSR ¶
func PrepareCSR(csrBytes []byte, cn, ou, org string) cfsigner.SignRequest
PrepareCSR creates a CFSSL Sign Request based on the given raw CSR and overrides the Subject and Hosts with the given extra args.
func RenewTLSConfigNow ¶
func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *connectionbroker.Broker, rootPaths CertPaths) error
RenewTLSConfigNow gets a new TLS cert and key, and updates the security config if provided. This is similar to RenewTLSConfig, except while that monitors for expiry, and periodically renews, this renews once and is blocking
func SaveRootCA ¶
SaveRootCA saves a RootCA object to disk
func SigningPolicy ¶
SigningPolicy creates a policy used by the signer to ensure that the only fields from the remote CSRs we trust are: PublicKey, PublicKeyAlgorithm and SignatureAlgorithm. It receives the duration a certificate will be valid for
func ValidateCertChain ¶
func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, [][]*x509.Certificate, error)
ValidateCertChain checks checks that the certificates provided chain up to the root pool provided. In addition it also enforces that every cert in the bundle certificates form a chain, each one certifying the one above, as per RFC5246 section 7.4.2, and that every certificate (whether or not it is necessary to form a chain to the root pool) is currently valid and not yet expired (unless allowExpiry is set to true). This is additional validation not required by go's Certificate.Verify (which allows invalid certs in the intermediate pool), because this function is intended to be used when reading certs from untrusted locations such as from disk or over a network when a CSR is signed, so it is extra pedantic. This function always returns all the parsed certificates in the bundle in order, which means there will always be at least 1 certificate if there is no error, and the valid chains found by Certificate.Verify
Types ¶
type CertPaths ¶
type CertPaths struct {
Cert, Key string
}
CertPaths is a helper struct that keeps track of the paths of a Cert and corresponding Key
type CertificateRequestConfig ¶
type CertificateRequestConfig struct { // Token is the join token that authenticates us with the CA. Token string // Availability allows a user to control the current scheduling status of a node Availability api.NodeSpec_Availability // ConnBroker provides connections to CAs. ConnBroker *connectionbroker.Broker // Credentials provides transport credentials for communicating with the // remote server. Credentials credentials.TransportCredentials // ForceRemote specifies that only a remote (TCP) connection should // be used to request the certificate. This may be necessary in cases // where the local node is running a manager, but is in the process of // being demoted. ForceRemote bool // NodeCertificateStatusRequestTimeout determines how long to wait for a node // status RPC result. If not provided (zero value), will default to 5 seconds. NodeCertificateStatusRequestTimeout time.Duration // RetryInterval specifies how long to delay between retries, if non-zero. RetryInterval time.Duration // Organization is the organization to use for a TLS certificate when creating // a security config from scratch. If not provided, a random ID is generated. // For swarm certificates, the organization is the cluster ID. Organization string }
CertificateRequestConfig contains the information needed to request a certificate from a remote CA.
type CertificateUpdate ¶
CertificateUpdate represents a change in the underlying TLS configuration being returned by a certificate renewal event.
type ErrInvalidKEK ¶
type ErrInvalidKEK struct {
Wrapped error
}
ErrInvalidKEK means that we cannot decrypt the TLS key for some reason
func (ErrInvalidKEK) Error ¶
func (e ErrInvalidKEK) Error() string
type ExternalCA ¶
type ExternalCA struct { ExternalRequestTimeout time.Duration // contains filtered or unexported fields }
ExternalCA is able to make certificate signing requests to one of a list remote CFSSL API endpoints.
func NewExternalCA ¶
func NewExternalCA(intermediates []byte, tlsConfig *tls.Config, urls ...string) *ExternalCA
NewExternalCA creates a new ExternalCA which uses the given tlsConfig to authenticate to any of the given URLS of CFSSL API endpoints.
func (*ExternalCA) CrossSignRootCA ¶
CrossSignRootCA takes a RootCA object, generates a CA CSR, sends a signing request with the CA CSR to the external CFSSL API server in order to obtain a cross-signed root
func (*ExternalCA) Sign ¶
func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert []byte, err error)
Sign signs a new certificate by proxying the given certificate signing request to an external CFSSL API server.
func (*ExternalCA) UpdateTLSConfig ¶
func (eca *ExternalCA) UpdateTLSConfig(tlsConfig *tls.Config)
UpdateTLSConfig updates the HTTP Client for this ExternalCA by creating a new client which uses the given tlsConfig.
func (*ExternalCA) UpdateURLs ¶
func (eca *ExternalCA) UpdateURLs(urls ...string)
UpdateURLs updates the list of CSR API endpoints by setting it to the given urls.
type IssuerInfo ¶
IssuerInfo contains the subject and public key of the issuer of a certificate
func IssuerFromAPIRootCA ¶
func IssuerFromAPIRootCA(rootCA *api.RootCA) (*IssuerInfo, error)
IssuerFromAPIRootCA returns the desired issuer given an API root CA object
type KEKData ¶
KEKData provides an optional update to the kek when writing. The structure is needed so that we can tell the difference between "do not encrypt anymore" and there is "no update".
type KeyReadWriter ¶
type KeyReadWriter struct {
// contains filtered or unexported fields
}
KeyReadWriter is an object that knows how to read and write TLS keys and certs to disk, optionally encrypted and optionally updating PEM headers. It should be the only object which can write the TLS key, to ensure that writes are serialized and that the TLS key, the KEK (key encrypting key), and any headers which need to be written are never out of sync. It accepts a PEMKeyHeaders object, which is used to serialize/encrypt and deserialize/decrypt the PEM headers when given the current headers and the current KEK.
func NewKeyReadWriter ¶
func NewKeyReadWriter(paths CertPaths, kek []byte, headersObj PEMKeyHeaders) *KeyReadWriter
NewKeyReadWriter creates a new KeyReadWriter
func (*KeyReadWriter) DowngradeKey ¶
func (k *KeyReadWriter) DowngradeKey() error
DowngradeKey converts the PKCS#8 key to PKCS#1 format and save it
func (*KeyReadWriter) GetCurrentState ¶
func (k *KeyReadWriter) GetCurrentState() (PEMKeyHeaders, KEKData)
GetCurrentState returns the current KEK data, including version
func (*KeyReadWriter) Migrate ¶
func (k *KeyReadWriter) Migrate() error
Migrate checks to see if a temporary key file exists. Older versions of swarmkit wrote temporary keys instead of temporary certificates, so migrate that temporary key if it exists. We want to write temporary certificates, instead of temporary keys, because we may need to periodically re-encrypt the keys and modify the headers, and it's easier to have a single canonical key location than two possible key locations.
func (*KeyReadWriter) Read ¶
func (k *KeyReadWriter) Read() ([]byte, []byte, error)
Read will read a TLS cert and key from the given paths
func (*KeyReadWriter) SetKeyFormatter ¶
func (k *KeyReadWriter) SetKeyFormatter(kf keyutils.Formatter)
SetKeyFormatter sets the keyformatter with which to encrypt and decrypt keys
func (*KeyReadWriter) Target ¶
func (k *KeyReadWriter) Target() string
Target returns a string representation of this KeyReadWriter, namely where it is writing to
func (*KeyReadWriter) ViewAndRotateKEK ¶
func (k *KeyReadWriter) ViewAndRotateKEK(cb func(KEKData, PEMKeyHeaders) (KEKData, PEMKeyHeaders, error)) error
ViewAndRotateKEK re-encrypts the key with a new KEK
func (*KeyReadWriter) ViewAndUpdateHeaders ¶
func (k *KeyReadWriter) ViewAndUpdateHeaders(cb func(PEMKeyHeaders) (PEMKeyHeaders, error)) error
ViewAndUpdateHeaders updates the header manager, and updates any headers on the existing key
func (*KeyReadWriter) Write ¶
func (k *KeyReadWriter) Write(certBytes, plaintextKeyBytes []byte, kekData *KEKData) error
Write attempts write a cert and key to text. This can also optionally update the KEK while writing, if an updated KEK is provided. If the pointer to the update KEK is nil, then we don't update. If the updated KEK itself is nil, then we update the KEK to be nil (data should be unencrypted).
type KeyReader ¶
type KeyReader interface { // Read reads and returns the certificate and the key PEM bytes that are on disk Read() ([]byte, []byte, error) // Target returns a string representation of where the cert data is being read from Target() string }
KeyReader reads a TLS cert and key from disk
type KeyWriter ¶
type KeyWriter interface { // Write accepts a certificate and key in PEM format, as well as an optional KEKData object. // If there is a current KEK, the key is encrypted using the current KEK. If the KEKData object // is provided (not nil), the key will be encrypted using the new KEK instead, and the current // KEK in memory will be replaced by the provided KEKData. The reason to allow changing key // material and KEK in a single step, as opposed to two steps, is to prevent the key material // from being written unencrypted or with an old KEK in the first place (when a node gets a // certificate from the CA, it will also request the current KEK so it won't have to immediately // do a KEK rotation after getting the key). Write([]byte, []byte, *KEKData) error // ViewAndUpdateHeaders is a function that reads and updates the headers of the key in a single // transaction (e.g. within a lock). It accepts a callback function which will be passed the // current header management object, and which must return a new, updated, or same header // management object. KeyReadWriter then performs the following actions: // - uses the old header management object and the current KEK to deserialize/decrypt // the existing PEM headers // - uses the new header management object and the current KEK to to reserialize/encrypt // the PEM headers // - writes the new PEM headers, as well as the key material, unchanged, to disk ViewAndUpdateHeaders(func(PEMKeyHeaders) (PEMKeyHeaders, error)) error // ViewAndRotateKEK is a function that just re-encrypts the TLS key and headers in a single // transaction (e.g. within a lock). It accepts a callback unction which will be passed the // current KEK and the current headers management object, and which should return a new // KEK and header management object. KeyReadWriter then performs the following actions: // - uses the old KEK and header management object to deserialize/decrypt the // TLS key and PEM headers // - uses the new KEK and header management object to serialize/encrypt the TLS key // and PEM headers // - writes the new PEM headers and newly encrypted TLS key to disk ViewAndRotateKEK(func(KEKData, PEMKeyHeaders) (KEKData, PEMKeyHeaders, error)) error // GetCurrentState returns the current header management object and the current KEK. GetCurrentState() (PEMKeyHeaders, KEKData) // Target returns a string representation of where the cert data is being read from Target() string }
KeyWriter writes a TLS key and cert to disk
type LocalSigner ¶
type LocalSigner struct { cfsigner.Signer // Key will only be used by the original manager to put the private // key-material in raft, no signing operations depend on it. Key []byte // Cert is one PEM encoded Certificate used as the signing CA. It must correspond to the key. Cert []byte // contains filtered or unexported fields }
LocalSigner is a signer that can sign CSRs
type MutableTLSCreds ¶
type MutableTLSCreds struct { // Mutex for the tls config sync.Mutex // contains filtered or unexported fields }
MutableTLSCreds is the credentials required for authenticating a connection using TLS.
func NewMutableTLS ¶
func NewMutableTLS(c *tls.Config) (*MutableTLSCreds, error)
NewMutableTLS uses c to construct a mutable TransportCredentials based on TLS.
func (*MutableTLSCreds) ClientHandshake ¶
func (c *MutableTLSCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error)
ClientHandshake implements the credentials.TransportCredentials interface
func (*MutableTLSCreds) Clone ¶
func (c *MutableTLSCreds) Clone() credentials.TransportCredentials
Clone returns new MutableTLSCreds created from underlying *tls.Config. It panics if validation of underlying config fails.
func (*MutableTLSCreds) Config ¶
func (c *MutableTLSCreds) Config() *tls.Config
Config returns the current underlying TLS config.
func (*MutableTLSCreds) GetRequestMetadata ¶
func (c *MutableTLSCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
GetRequestMetadata implements the credentials.TransportCredentials interface
func (*MutableTLSCreds) Info ¶
func (c *MutableTLSCreds) Info() credentials.ProtocolInfo
Info implements the credentials.TransportCredentials interface
func (*MutableTLSCreds) NodeID ¶
func (c *MutableTLSCreds) NodeID() string
NodeID returns the CN for the certificate encapsulated in this TransportCredentials
func (*MutableTLSCreds) Organization ¶
func (c *MutableTLSCreds) Organization() string
Organization returns the O for the certificate encapsulated in this TransportCredentials
func (*MutableTLSCreds) OverrideServerName ¶
func (c *MutableTLSCreds) OverrideServerName(name string) error
OverrideServerName overrides *tls.Config.ServerName.
func (*MutableTLSCreds) RequireTransportSecurity ¶
func (c *MutableTLSCreds) RequireTransportSecurity() bool
RequireTransportSecurity implements the credentials.TransportCredentials interface
func (*MutableTLSCreds) Role ¶
func (c *MutableTLSCreds) Role() string
Role returns the OU for the certificate encapsulated in this TransportCredentials
func (*MutableTLSCreds) ServerHandshake ¶
func (c *MutableTLSCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error)
ServerHandshake implements the credentials.TransportCredentials interface
type PEMKeyHeaders ¶
type PEMKeyHeaders interface { // UnmarshalHeaders loads the headers map given the current KEK UnmarshalHeaders(map[string]string, KEKData) (PEMKeyHeaders, error) // MarshalHeaders returns a header map given the current KEK MarshalHeaders(KEKData) (map[string]string, error) // UpdateKEK gets called whenever KeyReadWriter gets a KEK update. This allows the // PEMKeyHeaders to optionally update any internal state. It should return an // updated (if needed) versino of itself. UpdateKEK(KEKData, KEKData) PEMKeyHeaders }
PEMKeyHeaders is an interface for something that needs to know about PEM headers when reading or writing TLS keys in order to keep them updated with the latest KEK.
type ParsedJoinToken ¶
type ParsedJoinToken struct { // Version is the version of the join token that is being parsed Version int // RootDigest is the digest of the root CA certificate of the cluster, which // is always part of the join token so that the root CA can be verified // upon initial node join RootDigest digest.Digest // Secret is the randomly-generated secret part of the join token - when // rotating a join token, this is the value that is changed unless some other // property of the cluster (like the root CA) is changed. Secret string // FIPS indicates whether the join token specifies that the cluster mandates // that all nodes must have FIPS mode enabled. FIPS bool }
ParsedJoinToken is the data from a join token, once parsed
func ParseJoinToken ¶
func ParseJoinToken(token string) (*ParsedJoinToken, error)
ParseJoinToken parses a join token. Current format is v2, but this is currently used only if the cluster requires mandatory FIPS, in order to facilitate mixed version clusters. v1: SWMTKN-1-<SHA256 digest of root CA cert in base 36, 0-left-padded to 50 chars>-<16-byte secret in base 36 0-left-padded to 25 chars> v2: SWMTKN-2-<0/1 whether its FIPS or not>-<same rest of data as v1>
type RemoteNodeInfo ¶
type RemoteNodeInfo struct { // Roles is a list of roles contained in the node's certificate // (or forwarded by a trusted node). Roles []string // Organization is the organization contained in the node's certificate // (or forwarded by a trusted node). Organization string // NodeID is the node's ID, from the CN field in its certificate // (or forwarded by a trusted node). NodeID string // ForwardedBy contains information for the node that forwarded this // request. It is set to nil if the request was received directly. ForwardedBy *RemoteNodeInfo // RemoteAddr is the address that this node is connecting to the cluster // from. RemoteAddr string }
RemoteNodeInfo describes a node sending an RPC request.
func RemoteNode ¶
func RemoteNode(ctx context.Context) (RemoteNodeInfo, error)
RemoteNode returns the node ID and role from the client's TLS certificate. If the RPC was forwarded, the original client's ID and role is returned, as well as the forwarder's ID. This function does not do authorization checks - it only looks up the node ID.
type RootCA ¶
type RootCA struct { // Certs contains a bundle of self-signed, PEM encoded certificates for the Root CA to be used // as the root of trust. Certs []byte // Intermediates contains a bundle of PEM encoded intermediate CA certificates to append to any // issued TLS (leaf) certificates. The first one must have the same public key and subject as the // signing root certificate, and the rest must form a chain, each one certifying the one above it, // as per RFC5246 section 7.4.2. Intermediates []byte // Pool is the root pool used to validate TLS certificates Pool *x509.CertPool // Digest of the serialized bytes of the certificate(s) Digest digest.Digest // contains filtered or unexported fields }
RootCA is the representation of everything we need to sign certificates and/or to verify certificates
RootCA.Cert: [CA cert1][CA cert2] RootCA.Intermediates: [intermediate CA1][intermediate CA2][intermediate CA3] RootCA.signer.Cert: [signing CA cert] RootCA.signer.Key: [signing CA key]
Requirements:
- [signing CA key] must be the private key for [signing CA cert], and either both or none must be provided
- [intermediate CA1] must have the same public key and subject as [signing CA cert], because otherwise when appended to a leaf certificate, the intermediates will not form a chain (because [intermediate CA1] won't because the signer of the leaf certificate)
- [intermediate CA1] must be signed by [intermediate CA2], which must be signed by [intermediate CA3]
- When we issue a certificate, the intermediates will be appended so that the certificate looks like: [leaf signed by signing CA cert][intermediate CA1][intermediate CA2][intermediate CA3]
- [leaf signed by signing CA cert][intermediate CA1][intermediate CA2][intermediate CA3] is guaranteed to form a valid chain from [leaf signed by signing CA cert] to one of the root certs ([signing CA cert], [CA cert1], [CA cert2]) using zero or more of the intermediate certs ([intermediate CA1][intermediate CA2][intermediate CA3]) as intermediates
Example 1: Simple root rotation - Initial state:
- RootCA.Cert: [Root CA1 self-signed]
- RootCA.Intermediates: []
- RootCA.signer.Cert: [Root CA1 self-signed]
- Issued TLS cert: [leaf signed by Root CA1]
- Intermediate state (during root rotation):
- RootCA.Cert: [Root CA1 self-signed]
- RootCA.Intermediates: [Root CA2 signed by Root CA1]
- RootCA.signer.Cert: [Root CA2 signed by Root CA1]
- Issued TLS cert: [leaf signed by Root CA2][Root CA2 signed by Root CA1]
- Final state:
- RootCA.Cert: [Root CA2 self-signed]
- RootCA.Intermediates: []
- RootCA.signer.Cert: [Root CA2 self-signed]
- Issued TLS cert: [leaf signed by Root CA2]
func CreateRootCA ¶
CreateRootCA creates a Certificate authority for a new Swarm Cluster, potentially overwriting any existing CAs.
func DownloadRootCA ¶
func DownloadRootCA(ctx context.Context, paths CertPaths, token string, connBroker *connectionbroker.Broker) (RootCA, error)
DownloadRootCA tries to retrieve a remote root CA and matches the digest against the provided token.
func GetLocalRootCA ¶
GetLocalRootCA validates if the contents of the file are a valid self-signed CA certificate, and returns the PEM-encoded Certificate if so
func GetRemoteCA ¶
func GetRemoteCA(ctx context.Context, d digest.Digest, connBroker *connectionbroker.Broker) (RootCA, error)
GetRemoteCA returns the remote endpoint's CA certificate bundle
func NewRootCA ¶
func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry time.Duration, intermediates []byte) (RootCA, error)
NewRootCA creates a new RootCA object from unparsed PEM cert bundle and key byte slices. key may be nil, and in this case NewRootCA will return a RootCA without a signer.
func RootCAFromAPI ¶
func RootCAFromAPI(ctx context.Context, apiRootCA *api.RootCA, expiry time.Duration) (RootCA, error)
RootCAFromAPI creates a RootCA object from an api.RootCA object
func (RootCA) CreateSecurityConfig ¶
func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWriter, config CertificateRequestConfig) (*SecurityConfig, func() error, error)
CreateSecurityConfig creates a new key and cert for this node, either locally or via a remote CA.
func (*RootCA) CrossSignCACertificate ¶
CrossSignCACertificate takes a CA root certificate and generates an intermediate CA from it signed with the current root signer
func (*RootCA) IssueAndSaveNewCertificates ¶
func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, *IssuerInfo, error)
IssueAndSaveNewCertificates generates a new key-pair, signs it with the local root-ca, and returns a TLS certificate and the issuer information for the certificate.
func (*RootCA) NewClientTLSCredentials ¶
func (rootCA *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName string) (*MutableTLSCreds, error)
NewClientTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
func (*RootCA) NewServerTLSCredentials ¶
func (rootCA *RootCA) NewServerTLSCredentials(cert *tls.Certificate) (*MutableTLSCreds, error)
NewServerTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
func (*RootCA) ParseValidateAndSignCSR ¶
ParseValidateAndSignCSR returns a signed certificate from a particular rootCA and a CSR.
func (*RootCA) RequestAndSaveNewCertificates ¶
func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, *IssuerInfo, error)
RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is available, or by requesting them from the remote server at remoteAddr. This function returns the TLS certificate and the issuer information for the certificate.
func (*RootCA) Signer ¶
func (rca *RootCA) Signer() (*LocalSigner, error)
Signer is an accessor for the local signer that returns an error if this root cannot sign.
type SecurityConfig ¶
type SecurityConfig struct { ServerTLSCreds *MutableTLSCreds ClientTLSCreds *MutableTLSCreds // contains filtered or unexported fields }
SecurityConfig is used to represent a node's security configuration. It includes information about the RootCA and ServerTLSCreds/ClientTLSCreds transport authenticators to be used for MTLS
func LoadSecurityConfig ¶
func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter, allowExpired bool) (*SecurityConfig, func() error, error)
LoadSecurityConfig loads TLS credentials from disk, or returns an error if these credentials do not exist or are unusable.
func NewSecurityConfig ¶
func NewSecurityConfig(rootCA *RootCA, krw *KeyReadWriter, tlsKeyPair *tls.Certificate, issuerInfo *IssuerInfo) (*SecurityConfig, func() error, error)
NewSecurityConfig initializes and returns a new SecurityConfig.
func (*SecurityConfig) IssuerInfo ¶
func (s *SecurityConfig) IssuerInfo() *IssuerInfo
IssuerInfo returns the issuer subject and issuer public key
func (*SecurityConfig) KeyReader ¶
func (s *SecurityConfig) KeyReader() KeyReader
KeyReader returns the object that can read keys from disk
func (*SecurityConfig) KeyWriter ¶
func (s *SecurityConfig) KeyWriter() KeyWriter
KeyWriter returns the object that can write keys to disk
func (*SecurityConfig) RootCA ¶
func (s *SecurityConfig) RootCA() *RootCA
RootCA returns the root CA.
func (*SecurityConfig) UpdateRootCA ¶
func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA) error
UpdateRootCA replaces the root CA with a new root CA
func (*SecurityConfig) UpdateTLSCredentials ¶
func (s *SecurityConfig) UpdateTLSCredentials(certificate *tls.Certificate, issuerInfo *IssuerInfo) error
UpdateTLSCredentials updates the security config with an updated TLS certificate and issuer info
func (*SecurityConfig) Watch ¶
func (s *SecurityConfig) Watch() (chan events.Event, func())
Watch allows you to set a watch on the security config, in order to be notified of any changes
type SecurityConfigPaths ¶
type SecurityConfigPaths struct {
Node, RootCA CertPaths
}
SecurityConfigPaths is used as a helper to hold all the paths of security relevant files
func NewConfigPaths ¶
func NewConfigPaths(baseCertDir string) *SecurityConfigPaths
NewConfigPaths returns the absolute paths to all of the different types of files
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the CA and NodeCA API gRPC server. TODO(aaronl): At some point we may want to have separate implementations of CA, NodeCA, and other hypothetical future CA services. At the moment, breaking it apart doesn't seem worth it.
func NewServer ¶
func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig) *Server
NewServer creates a CA API server.
func (*Server) ExternalCA ¶
func (s *Server) ExternalCA() *ExternalCA
ExternalCA returns the current external CA - this is exposed to support unit testing only, and the external CA should really be a private field
func (*Server) GetRootCACertificate ¶
func (s *Server) GetRootCACertificate(ctx context.Context, request *api.GetRootCACertificateRequest) (*api.GetRootCACertificateResponse, error)
GetRootCACertificate returns the certificate of the Root CA. It is used as a convenience for distributing the root of trust for the swarm. Clients should be using the CA hash to verify if they weren't target to a MiTM. If they fail to do so, node bootstrap works with TOFU semantics.
func (*Server) GetUnlockKey ¶
func (s *Server) GetUnlockKey(ctx context.Context, request *api.GetUnlockKeyRequest) (*api.GetUnlockKeyResponse, error)
GetUnlockKey is responsible for returning the current unlock key used for encrypting TLS private keys and other at rest data. Access to this RPC call should only be allowed via mutual TLS from managers.
func (*Server) IssueNodeCertificate ¶
func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNodeCertificateRequest) (*api.IssueNodeCertificateResponse, error)
IssueNodeCertificate is responsible for gatekeeping both certificate requests from new nodes in the swarm, and authorizing certificate renewals. If a node presented a valid certificate, the corresponding certificate is set in a RENEW state. If a node failed to present a valid certificate, we check for a valid join token and set the role accordingly. A new random node ID is generated, and the corresponding node entry is created. IssueNodeCertificate is the only place where new node entries to raft should be created.
func (*Server) NodeCertificateStatus ¶
func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCertificateStatusRequest) (*api.NodeCertificateStatusResponse, error)
NodeCertificateStatus returns the current issuance status of an issuance request identified by the nodeID
func (*Server) Ready ¶
func (s *Server) Ready() <-chan struct{}
Ready waits on the ready channel and returns when the server is ready to serve.
func (*Server) RootCA ¶
RootCA returns the current local root CA - this is exposed to support unit testing only, and the root CA should really be a private field
func (*Server) Run ¶
Run runs the CA signer main loop. The CA signer can be stopped with cancelling ctx or calling Stop().
func (*Server) SetReconciliationRetryInterval ¶
SetReconciliationRetryInterval changes the time interval between reconciliation attempts. This function must be called before Run.
func (*Server) SetRootReconciliationInterval ¶
SetRootReconciliationInterval changes the time interval between root rotation reconciliation attempts. This function must be called before Run.
func (*Server) UpdateRootCA ¶
func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster, reconciler *rootRotationReconciler) error
UpdateRootCA is called when there are cluster changes, and it ensures that the local RootCA is always aware of changes in clusterExpiry and the Root CA key material - this can be called by anything to update the root CA material
type TLSRenewer ¶
type TLSRenewer struct {
// contains filtered or unexported fields
}
TLSRenewer handles renewing TLS certificates, either automatically or upon request.
func NewTLSRenewer ¶
func NewTLSRenewer(s *SecurityConfig, connBroker *connectionbroker.Broker, rootPaths CertPaths) *TLSRenewer
NewTLSRenewer creates a new TLS renewer. It must be started with Start.
func (*TLSRenewer) Renew ¶
func (t *TLSRenewer) Renew()
Renew causes the TLSRenewer to renew the certificate (nearly) right away, instead of waiting for the next automatic renewal.
func (*TLSRenewer) SetExpectedRole ¶
func (t *TLSRenewer) SetExpectedRole(role string)
SetExpectedRole sets the expected role. If a renewal is forced, and the role doesn't match this expectation, renewal will be retried with exponential backoff until it does match.
func (*TLSRenewer) Start ¶
func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate
Start will continuously monitor for the necessity of renewing the local certificates, either by issuing them locally if key-material is available, or requesting them from a remote CA.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package keyutils serves as a utility to parse, encrypt and decrypt PKCS#1 and PKCS#8 private keys based on current FIPS mode status, supporting only EC type keys.
|
Package keyutils serves as a utility to parse, encrypt and decrypt PKCS#1 and PKCS#8 private keys based on current FIPS mode status, supporting only EC type keys. |
Package pkcs8 implements functions to encrypt, decrypt, parse and to convert EC private keys to PKCS#8 format.
|
Package pkcs8 implements functions to encrypt, decrypt, parse and to convert EC private keys to PKCS#8 format. |