Certificate resolvers.

Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
Co-authored-by: Jean-Baptiste Doumenjou <jb.doumenjou@gmail.com>
This commit is contained in:
Ludovic Fernandez 2019-07-19 11:52:04 +02:00 committed by Traefiker Bot
parent e3627e9cba
commit f75f73f3d2
47 changed files with 1573 additions and 1249 deletions

View file

@ -74,17 +74,22 @@ func (m *Manager) Get(storeName string, configName string) (*tls.Config, error)
m.lock.RLock()
defer m.lock.RUnlock()
var tlsConfig *tls.Config
var err error
config, ok := m.configs[configName]
if !ok {
return nil, fmt.Errorf("unknown TLS options: %s", configName)
err = fmt.Errorf("unknown TLS options: %s", configName)
tlsConfig = &tls.Config{}
}
store := m.getStore(storeName)
tlsConfig, err := buildTLSConfig(config)
if err != nil {
log.Error(err)
tlsConfig = &tls.Config{}
if err == nil {
tlsConfig, err = buildTLSConfig(config)
if err != nil {
tlsConfig = &tls.Config{}
}
}
tlsConfig.GetCertificate = func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
@ -113,7 +118,8 @@ func (m *Manager) Get(storeName string, configName string) (*tls.Config, error)
log.WithoutContext().Debugf("Serving default certificate for request: %q", domainToCheck)
return store.DefaultCertificate, nil
}
return tlsConfig, nil
return tlsConfig, err
}
func (m *Manager) getStore(storeName string) *CertificateStore {
@ -143,7 +149,7 @@ func buildCertificateStore(tlsStore Store) (*CertificateStore, error) {
}
certificateStore.DefaultCertificate = cert
} else {
log.Debug("No default certificate, generate one")
log.Debug("No default certificate, generating one")
cert, err := generate.DefaultCertificate()
if err != nil {
return certificateStore, err

View file

@ -152,11 +152,21 @@ func TestManager_Get(t *testing.T) {
func TestClientAuth(t *testing.T) {
tlsConfigs := map[string]Options{
"eca": {ClientAuth: ClientAuth{}},
"ecat": {ClientAuth: ClientAuth{ClientAuthType: ""}},
"ncc": {ClientAuth: ClientAuth{ClientAuthType: "NoClientCert"}},
"rcc": {ClientAuth: ClientAuth{ClientAuthType: "RequestClientCert"}},
"racc": {ClientAuth: ClientAuth{ClientAuthType: "RequireAnyClientCert"}},
"eca": {
ClientAuth: ClientAuth{},
},
"ecat": {
ClientAuth: ClientAuth{ClientAuthType: ""},
},
"ncc": {
ClientAuth: ClientAuth{ClientAuthType: "NoClientCert"},
},
"rcc": {
ClientAuth: ClientAuth{ClientAuthType: "RequestClientCert"},
},
"racc": {
ClientAuth: ClientAuth{ClientAuthType: "RequireAnyClientCert"},
},
"vccig": {
ClientAuth: ClientAuth{
CAFiles: []FileOrContent{localhostCert},
@ -166,7 +176,9 @@ func TestClientAuth(t *testing.T) {
"vccigwca": {
ClientAuth: ClientAuth{ClientAuthType: "VerifyClientCertIfGiven"},
},
"ravcc": {ClientAuth: ClientAuth{ClientAuthType: "RequireAndVerifyClientCert"}},
"ravcc": {
ClientAuth: ClientAuth{ClientAuthType: "RequireAndVerifyClientCert"},
},
"ravccwca": {
ClientAuth: ClientAuth{
CAFiles: []FileOrContent{localhostCert},
@ -179,7 +191,9 @@ func TestClientAuth(t *testing.T) {
ClientAuthType: "RequireAndVerifyClientCert",
},
},
"ucat": {ClientAuth: ClientAuth{ClientAuthType: "Unknown"}},
"ucat": {
ClientAuth: ClientAuth{ClientAuthType: "Unknown"},
},
}
block, _ := pem.Decode([]byte(localhostCert))
@ -191,6 +205,7 @@ func TestClientAuth(t *testing.T) {
tlsOptionsName string
expectedClientAuth tls.ClientAuthType
expectedRawSubject []byte
expectedError bool
}{
{
desc: "Empty ClientAuth option should get a tls.NoClientCert (default value)",
@ -223,14 +238,16 @@ func TestClientAuth(t *testing.T) {
expectedClientAuth: tls.VerifyClientCertIfGiven,
},
{
desc: "VerifyClientCertIfGiven option without CAFiles yields a default ClientAuthType (NoClientCert)",
desc: "VerifyClientCertIfGiven option without CAFiles yields a default ClientAuthType (NoClientCert)",
tlsOptionsName: "vccigwca",
expectedClientAuth: tls.NoClientCert,
expectedError: true,
},
{
desc: "RequireAndVerifyClientCert option without CAFiles yields a default ClientAuthType (NoClientCert)",
desc: "RequireAndVerifyClientCert option without CAFiles yields a default ClientAuthType (NoClientCert)",
tlsOptionsName: "ravcc",
expectedClientAuth: tls.NoClientCert,
expectedError: true,
},
{
desc: "RequireAndVerifyClientCert option should get a tls.RequireAndVerifyClientCert as ClientAuthType with CA files",
@ -242,11 +259,13 @@ func TestClientAuth(t *testing.T) {
desc: "Unknown option yields a default ClientAuthType (NoClientCert)",
tlsOptionsName: "ucat",
expectedClientAuth: tls.NoClientCert,
expectedError: true,
},
{
desc: "Bad CA certificate content yields a default ClientAuthType (NoClientCert)",
tlsOptionsName: "ravccwbca",
expectedClientAuth: tls.NoClientCert,
expectedError: true,
},
}
@ -259,6 +278,12 @@ func TestClientAuth(t *testing.T) {
t.Parallel()
config, err := tlsManager.Get("default", test.tlsOptionsName)
if test.expectedError {
assert.Error(t, err)
return
}
assert.NoError(t, err)
if test.expectedRawSubject != nil {