fix: do not require a TLS client cert when InsecureSkipVerify is false
Co-authored-by: Tom Moulard <tom.moulard@traefik.io>
This commit is contained in:
parent
566b205758
commit
d3ff0c2cd4
21 changed files with 273 additions and 184 deletions
|
@ -4,12 +4,15 @@ import (
|
|||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/traefik/traefik/v2/pkg/log"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// ClientTLS holds TLS specific configurations as client
|
||||
// CA, Cert and Key can be either path or file contents.
|
||||
type ClientTLS struct {
|
||||
|
@ -42,7 +45,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig(ctx context.Context) (*tls.Config, e
|
|||
}
|
||||
|
||||
if !caPool.AppendCertsFromPEM(ca) {
|
||||
return nil, fmt.Errorf("failed to parse CA")
|
||||
return nil, errors.New("failed to parse CA")
|
||||
}
|
||||
|
||||
if clientTLS.CAOptional {
|
||||
|
@ -52,34 +55,24 @@ func (clientTLS *ClientTLS) CreateTLSConfig(ctx context.Context) (*tls.Config, e
|
|||
}
|
||||
}
|
||||
|
||||
if !clientTLS.InsecureSkipVerify && (len(clientTLS.Cert) == 0 || len(clientTLS.Key) == 0) {
|
||||
return nil, fmt.Errorf("TLS Certificate or Key file must be set when TLS configuration is created")
|
||||
hasCert := len(clientTLS.Cert) > 0
|
||||
hasKey := len(clientTLS.Key) > 0
|
||||
|
||||
if hasCert != hasKey {
|
||||
return nil, errors.New("both TLS cert and key must be defined")
|
||||
}
|
||||
|
||||
cert := tls.Certificate{}
|
||||
_, errKeyIsFile := os.Stat(clientTLS.Key)
|
||||
if !hasCert || !hasKey {
|
||||
return &tls.Config{
|
||||
RootCAs: caPool,
|
||||
InsecureSkipVerify: clientTLS.InsecureSkipVerify,
|
||||
ClientAuth: clientAuth,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(clientTLS.Cert) > 0 && len(clientTLS.Key) > 0 {
|
||||
var err error
|
||||
if _, errCertIsFile := os.Stat(clientTLS.Cert); errCertIsFile == nil {
|
||||
if errKeyIsFile == nil {
|
||||
cert, err = tls.LoadX509KeyPair(clientTLS.Cert, clientTLS.Key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load TLS keypair: %w", err)
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("TLS cert is a file, but tls key is not")
|
||||
}
|
||||
} else {
|
||||
if errKeyIsFile != nil {
|
||||
cert, err = tls.X509KeyPair([]byte(clientTLS.Cert), []byte(clientTLS.Key))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load TLS keypair: %w", err)
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("TLS key is a file, but tls cert is not")
|
||||
}
|
||||
}
|
||||
cert, err := loadKeyPair(clientTLS.Cert, clientTLS.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tls.Config{
|
||||
|
@ -89,3 +82,27 @@ func (clientTLS *ClientTLS) CreateTLSConfig(ctx context.Context) (*tls.Config, e
|
|||
ClientAuth: clientAuth,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func loadKeyPair(cert, key string) (tls.Certificate, error) {
|
||||
keyPair, err := tls.X509KeyPair([]byte(cert), []byte(key))
|
||||
if err == nil {
|
||||
return keyPair, nil
|
||||
}
|
||||
|
||||
_, err = os.Stat(cert)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, errors.New("cert file does not exist")
|
||||
}
|
||||
|
||||
_, err = os.Stat(key)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, errors.New("key file does not exist")
|
||||
}
|
||||
|
||||
keyPair, err = tls.LoadX509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
|
||||
return keyPair, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue