mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-25 16:41:12 +02:00
This change moves packages into more appropriate places. Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
131 lines
3.9 KiB
Go
131 lines
3.9 KiB
Go
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package tls
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/talos-systems/talos/pkg/userdata"
|
|
)
|
|
|
|
// Type represents the TLS authentication type.
|
|
type Type int
|
|
|
|
const (
|
|
// Mutual configures the server's policy for TLS Client Authentication to
|
|
// mutual TLS.
|
|
Mutual Type = 1 << iota
|
|
// ServerOnly configures the server's policy for TLS Client Authentication
|
|
// to server only.
|
|
ServerOnly
|
|
)
|
|
|
|
// ConfigOptionFunc describes a configuration option function for the TLS config
|
|
type ConfigOptionFunc func(*tls.Config) error
|
|
|
|
// WithClientAuthType declares the server's policy regardling TLS Client Authentication
|
|
func WithClientAuthType(t Type) func(*tls.Config) error {
|
|
return func(cfg *tls.Config) error {
|
|
switch t {
|
|
case Mutual:
|
|
cfg.ClientAuth = tls.RequireAndVerifyClientCert
|
|
case ServerOnly:
|
|
cfg.ClientAuth = tls.NoClientCert
|
|
default:
|
|
return errors.Errorf("unhandled client auth type %+v", t)
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithCertificateProvider declares a dynamic provider for the client
|
|
// certificate.
|
|
//
|
|
// NOTE: specifying this option will CLEAR any configured Certificates, since
|
|
// they would otherwise override this option
|
|
//
|
|
func WithCertificateProvider(p CertificateProvider) func(*tls.Config) error {
|
|
return func(cfg *tls.Config) error {
|
|
if p == nil {
|
|
return errors.New("no provider")
|
|
}
|
|
cfg.Certificates = nil
|
|
cfg.GetCertificate = p.GetCertificate
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithKeypair declares a specific TLS keypair to be used. This can be called
|
|
// multiple times to add additional keypairs.
|
|
func WithKeypair(cert tls.Certificate) func(*tls.Config) error {
|
|
return func(cfg *tls.Config) error {
|
|
cfg.Certificates = append(cfg.Certificates, cert)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// WithCACertPEM declares a PEM-encoded CA Certificate to be used.
|
|
func WithCACertPEM(ca []byte) func(*tls.Config) error {
|
|
return func(cfg *tls.Config) error {
|
|
if len(ca) == 0 {
|
|
return errors.New("no CA cert provided")
|
|
}
|
|
if ok := cfg.ClientCAs.AppendCertsFromPEM(ca); !ok {
|
|
return errors.New("failed to append CA certificate to ClientCAs pool")
|
|
}
|
|
if ok := cfg.RootCAs.AppendCertsFromPEM(ca); !ok {
|
|
return errors.New("failed to append CA certificate to RootCAs pool")
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func defaultConfig() *tls.Config {
|
|
return &tls.Config{
|
|
RootCAs: x509.NewCertPool(),
|
|
ClientCAs: x509.NewCertPool(),
|
|
// Use the X25519 elliptic curve for the ECDHE key exchange algorithm.
|
|
CurvePreferences: []tls.CurveID{tls.X25519},
|
|
SessionTicketsDisabled: true,
|
|
// TLS protocol, ECDHE key exchange algorithm, ECDSA digital signature algorithm, AES_256_GCM bulk encryption algorithm, and SHA384 hash algorithm.
|
|
CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
|
|
// Force the above cipher suites.
|
|
PreferServerCipherSuites: true,
|
|
// TLS 1.2
|
|
MinVersion: tls.VersionTLS12,
|
|
}
|
|
}
|
|
|
|
// NewConfigWithOpts returns a new TLS Configuration modified by any provided configuration options
|
|
func NewConfigWithOpts(opts ...ConfigOptionFunc) (cfg *tls.Config, err error) {
|
|
cfg = defaultConfig()
|
|
|
|
for _, f := range opts {
|
|
if err = f(cfg); err != nil {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// NewConfig initializes a TLS config for the specified type.
|
|
func NewConfig(t Type, data *userdata.OSSecurity) (config *tls.Config, err error) {
|
|
config = defaultConfig()
|
|
|
|
if err = WithClientAuthType(t)(config); err != nil {
|
|
return nil, errors.Wrap(err, "failed to apply ClientAuthType preference")
|
|
}
|
|
if err = WithCACertPEM(data.CA.Crt)(config); err != nil {
|
|
return nil, errors.Wrap(err, "failed to apply CA Certificate from UserData")
|
|
}
|
|
if err = WithCertificateProvider(&userDataCertificateProvider{data: data})(config); err != nil {
|
|
return nil, errors.Wrap(err, "failed to apply userdata-sourced CertificateProvider")
|
|
}
|
|
|
|
return
|
|
}
|