|
|
|
@ -3,6 +3,8 @@ package ca
|
|
|
|
|
import (
|
|
|
|
|
"crypto/tls"
|
|
|
|
|
"crypto/x509"
|
|
|
|
|
|
|
|
|
|
"github.com/smallstep/certificates/api"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// TLSOption defines the type of a function that modifies a tls.Config.
|
|
|
|
@ -12,15 +14,19 @@ type TLSOption func(ctx *TLSOptionCtx) error
|
|
|
|
|
type TLSOptionCtx struct {
|
|
|
|
|
Client *Client
|
|
|
|
|
Config *tls.Config
|
|
|
|
|
Sign *api.SignResponse
|
|
|
|
|
OnRenewFunc []TLSOption
|
|
|
|
|
mutableConfig *mutableTLSConfig
|
|
|
|
|
hasRootCA bool
|
|
|
|
|
hasClientCA bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// newTLSOptionCtx creates the TLSOption context.
|
|
|
|
|
func newTLSOptionCtx(c *Client, config *tls.Config) *TLSOptionCtx {
|
|
|
|
|
func newTLSOptionCtx(c *Client, config *tls.Config, sign *api.SignResponse) *TLSOptionCtx {
|
|
|
|
|
return &TLSOptionCtx{
|
|
|
|
|
Client: c,
|
|
|
|
|
Config: config,
|
|
|
|
|
Sign: sign,
|
|
|
|
|
mutableConfig: newMutableTLSConfig(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -34,6 +40,26 @@ func (ctx *TLSOptionCtx) apply(options []TLSOption) error {
|
|
|
|
|
|
|
|
|
|
// Initialize mutable config with the fully configured tls.Config
|
|
|
|
|
ctx.mutableConfig.Init(ctx.Config)
|
|
|
|
|
|
|
|
|
|
// Build RootCAs and ClientCAs with given root certificate if necessary
|
|
|
|
|
if root, err := RootCertificate(ctx.Sign); err == nil {
|
|
|
|
|
if !ctx.hasRootCA {
|
|
|
|
|
if ctx.Config.RootCAs == nil {
|
|
|
|
|
ctx.Config.RootCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
ctx.Config.RootCAs.AddCert(root)
|
|
|
|
|
ctx.mutableConfig.AddInmutableRootCACert(root)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !ctx.hasClientCA && ctx.Config.ClientAuth != tls.NoClientCert {
|
|
|
|
|
if ctx.Config.ClientCAs == nil {
|
|
|
|
|
ctx.Config.ClientCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
ctx.Config.ClientCAs.AddCert(root)
|
|
|
|
|
ctx.mutableConfig.AddInmutableClientCACert(root)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update tls.Config with mutable data
|
|
|
|
|
if ctx.Config.RootCAs == nil && len(ctx.mutableConfig.mutRootCerts) > 0 {
|
|
|
|
|
ctx.Config.RootCAs = x509.NewCertPool()
|
|
|
|
@ -41,6 +67,7 @@ func (ctx *TLSOptionCtx) apply(options []TLSOption) error {
|
|
|
|
|
if ctx.Config.ClientCAs == nil && len(ctx.mutableConfig.mutClientCerts) > 0 {
|
|
|
|
|
ctx.Config.ClientCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
// Add mutable certificates
|
|
|
|
|
for _, cert := range ctx.mutableConfig.mutRootCerts {
|
|
|
|
|
ctx.Config.RootCAs.AddCert(cert)
|
|
|
|
|
}
|
|
|
|
@ -120,16 +147,8 @@ func AddRootsToRootCAs() TLSOption {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if ctx.mutableConfig == nil {
|
|
|
|
|
if ctx.Config.RootCAs == nil {
|
|
|
|
|
ctx.Config.RootCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
for _, cert := range certs.Certificates {
|
|
|
|
|
ctx.Config.RootCAs.AddCert(cert.Certificate)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ctx.mutableConfig.AddRootCAs(certs.Certificates)
|
|
|
|
|
}
|
|
|
|
|
ctx.hasRootCA = true
|
|
|
|
|
ctx.mutableConfig.AddRootCAs(certs.Certificates)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return func(ctx *TLSOptionCtx) error {
|
|
|
|
@ -151,16 +170,8 @@ func AddRootsToClientCAs() TLSOption {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if ctx.mutableConfig == nil {
|
|
|
|
|
if ctx.Config.ClientCAs == nil {
|
|
|
|
|
ctx.Config.ClientCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
for _, cert := range certs.Certificates {
|
|
|
|
|
ctx.Config.ClientCAs.AddCert(cert.Certificate)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ctx.mutableConfig.AddClientCAs(certs.Certificates)
|
|
|
|
|
}
|
|
|
|
|
ctx.hasClientCA = true
|
|
|
|
|
ctx.mutableConfig.AddClientCAs(certs.Certificates)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return func(ctx *TLSOptionCtx) error {
|
|
|
|
@ -178,16 +189,7 @@ func AddFederationToRootCAs() TLSOption {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if ctx.mutableConfig == nil {
|
|
|
|
|
if ctx.Config.RootCAs == nil {
|
|
|
|
|
ctx.Config.RootCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
for _, cert := range certs.Certificates {
|
|
|
|
|
ctx.Config.RootCAs.AddCert(cert.Certificate)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ctx.mutableConfig.AddRootCAs(certs.Certificates)
|
|
|
|
|
}
|
|
|
|
|
ctx.mutableConfig.AddRootCAs(certs.Certificates)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return func(ctx *TLSOptionCtx) error {
|
|
|
|
@ -206,16 +208,7 @@ func AddFederationToClientCAs() TLSOption {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if ctx.mutableConfig == nil {
|
|
|
|
|
if ctx.Config.ClientCAs == nil {
|
|
|
|
|
ctx.Config.ClientCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
for _, cert := range certs.Certificates {
|
|
|
|
|
ctx.Config.ClientCAs.AddCert(cert.Certificate)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ctx.mutableConfig.AddClientCAs(certs.Certificates)
|
|
|
|
|
}
|
|
|
|
|
ctx.mutableConfig.AddClientCAs(certs.Certificates)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return func(ctx *TLSOptionCtx) error {
|
|
|
|
@ -233,21 +226,10 @@ func AddRootsToCAs() TLSOption {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if ctx.mutableConfig == nil {
|
|
|
|
|
if ctx.Config.RootCAs == nil {
|
|
|
|
|
ctx.Config.RootCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
if ctx.Config.ClientCAs == nil {
|
|
|
|
|
ctx.Config.ClientCAs = x509.NewCertPool()
|
|
|
|
|
}
|
|
|
|
|
for _, cert := range certs.Certificates {
|
|
|
|
|
ctx.Config.RootCAs.AddCert(cert.Certificate)
|
|
|
|
|
ctx.Config.ClientCAs.AddCert(cert.Certificate)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ctx.mutableConfig.AddRootCAs(certs.Certificates)
|
|
|
|
|
ctx.mutableConfig.AddClientCAs(certs.Certificates)
|
|
|
|
|
}
|
|
|
|
|
ctx.hasRootCA = true
|
|
|
|
|
ctx.hasClientCA = true
|
|
|
|
|
ctx.mutableConfig.AddRootCAs(certs.Certificates)
|
|
|
|
|
ctx.mutableConfig.AddClientCAs(certs.Certificates)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return func(ctx *TLSOptionCtx) error {
|
|
|
|
|