Skip to content

Commit

Permalink
Merge pull request #696 from luraproject/improve_client_tls_config
Browse files Browse the repository at this point in the history
Name explicitly the client certificate and private key
  • Loading branch information
kpacha authored Oct 31, 2023
2 parents 4d07104 + 63204b0 commit 6ca4f01
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 33 deletions.
23 changes: 15 additions & 8 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,21 @@ type TLS struct {

// ClientTLS defines the configuration params for an HTTP Client
type ClientTLS struct {
AllowInsecureConnections bool `mapstructure:"allow_insecure_connections"`
CaCerts []string `mapstructure:"ca_certs"`
DisableSystemCaPool bool `mapstructure:"disable_system_ca_pool"`
MinVersion string `mapstructure:"min_version"`
MaxVersion string `mapstructure:"max_version"`
CurvePreferences []uint16 `mapstructure:"curve_preferences"`
CipherSuites []uint16 `mapstructure:"cipher_suites"`
ClientCerts [][]string `mapstructure:"client_certs"`
AllowInsecureConnections bool `mapstructure:"allow_insecure_connections"`
CaCerts []string `mapstructure:"ca_certs"`
DisableSystemCaPool bool `mapstructure:"disable_system_ca_pool"`
MinVersion string `mapstructure:"min_version"`
MaxVersion string `mapstructure:"max_version"`
CurvePreferences []uint16 `mapstructure:"curve_preferences"`
CipherSuites []uint16 `mapstructure:"cipher_suites"`
ClientCerts []ClientTLSCert `mapstructure:"client_certs"`
}

// ClientTLSCert holds a certificate with its private key to be
// used for mTLS against the backend services
type ClientTLSCert struct {
Certificate string `mapstructure:"certificate"`
PrivateKey string `mapstructure:"private_key"`
}

// ExtraConfig is a type to store extra configurations for customized behaviours
Expand Down
26 changes: 17 additions & 9 deletions config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ func (p *parseableServiceConfig) normalize() ServiceConfig {
MaxVersion: p.ClientTLS.MaxVersion,
CurvePreferences: p.ClientTLS.CurvePreferences,
CipherSuites: p.ClientTLS.CipherSuites,
ClientCerts: p.ClientTLS.ClientCerts,
ClientCerts: make([]ClientTLSCert, 0, len(p.ClientTLS.ClientCerts)),
}
for _, cc := range p.ClientTLS.ClientCerts {
cfg.ClientTLS.ClientCerts = append(cfg.ClientTLS.ClientCerts, ClientTLSCert(cc))
}
}
if p.ExtraConfig != nil {
Expand Down Expand Up @@ -252,14 +255,19 @@ type parseableTLS struct {
}

type parseableClientTLS struct {
AllowInsecureConnections bool `json:"allow_insecure_connections"`
CaCerts []string `json:"ca_certs"`
DisableSystemCaPool bool `json:"disable_system_ca_pool"`
MinVersion string `json:"min_version"`
MaxVersion string `json:"max_version"`
CurvePreferences []uint16 `json:"curve_preferences"`
CipherSuites []uint16 `json:"cipher_suites"`
ClientCerts [][]string `json:"client_certs"`
AllowInsecureConnections bool `json:"allow_insecure_connections"`
CaCerts []string `json:"ca_certs"`
DisableSystemCaPool bool `json:"disable_system_ca_pool"`
MinVersion string `json:"min_version"`
MaxVersion string `json:"max_version"`
CurvePreferences []uint16 `json:"curve_preferences"`
CipherSuites []uint16 `json:"cipher_suites"`
ClientCerts []parseableClientTLSCert `json:"client_certs"`
}

type parseableClientTLSCert struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"private_key"`
}

type parseableEndpointConfig struct {
Expand Down
18 changes: 4 additions & 14 deletions transport/http/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,23 +234,13 @@ func loadCertPool(disableSystemCaPool bool, caCerts []string, logger logging.Log
return certPool
}

func loadClientCerts(certFiles [][]string, logger logging.Logger) []tls.Certificate {
func loadClientCerts(certFiles []config.ClientTLSCert, logger logging.Logger) []tls.Certificate {
certs := make([]tls.Certificate, 0, len(certFiles))
for idx, certAndKey := range certFiles {
if len(certAndKey) < 2 {
logger.Error(fmt.Sprintf("%s Missing cert and key at idx %d: %v",
loggerPrefix, idx, certAndKey))
continue
}
if len(certAndKey) > 2 {
logger.Warning(fmt.Sprintf("%s Extra fields at idx %d: %v",
loggerPrefix, idx, certAndKey))
}

cert, err := tls.LoadX509KeyPair(certAndKey[0], certAndKey[1])
for _, certAndKey := range certFiles {
cert, err := tls.LoadX509KeyPair(certAndKey.Certificate, certAndKey.PrivateKey)
if err != nil {
logger.Error(fmt.Sprintf("%s Cannot load client certificate %s, %s: %s",
loggerPrefix, certAndKey[0], certAndKey[1], err.Error()))
loggerPrefix, certAndKey.Certificate, certAndKey.PrivateKey, err.Error()))
continue
}
certs = append(certs, cert)
Expand Down
7 changes: 5 additions & 2 deletions transport/http/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,11 @@ func TestRunServer_MTLS(t *testing.T) {
ClientTLS: &config.ClientTLS{
AllowInsecureConnections: false, // we do not check the server cert
CaCerts: []string{"ca.pem"},
ClientCerts: [][]string{
[]string{"cert.pem", "key.pem"},
ClientCerts: []config.ClientTLSCert{
config.ClientTLSCert{
Certificate: "cert.pem",
PrivateKey: "key.pem",
},
},
},
}
Expand Down

0 comments on commit 6ca4f01

Please sign in to comment.