2018-07-06 08:30:03 +00:00
|
|
|
package tls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/patrickmn/go-cache"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
2020-09-16 13:46:04 +00:00
|
|
|
"github.com/traefik/traefik/v2/pkg/safe"
|
2018-07-06 08:30:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestGetBestCertificate(t *testing.T) {
|
2022-08-31 06:24:08 +00:00
|
|
|
// TODO Add tests for defaultCert
|
2018-07-06 08:30:03 +00:00
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
domainToCheck string
|
|
|
|
dynamicCert string
|
|
|
|
expectedCert string
|
2018-11-26 09:38:03 +00:00
|
|
|
uppercase bool
|
2018-07-06 08:30:03 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "Empty Store, returns no certs",
|
|
|
|
domainToCheck: "snitest.com",
|
|
|
|
dynamicCert: "",
|
|
|
|
expectedCert: "",
|
|
|
|
},
|
|
|
|
{
|
2018-11-27 16:42:04 +00:00
|
|
|
desc: "Best Match with no corresponding",
|
2018-07-06 08:30:03 +00:00
|
|
|
domainToCheck: "snitest.com",
|
2018-11-27 16:42:04 +00:00
|
|
|
dynamicCert: "snitest.org",
|
|
|
|
expectedCert: "",
|
2018-07-06 08:30:03 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "Best Match",
|
|
|
|
domainToCheck: "snitest.com",
|
2018-11-27 16:42:04 +00:00
|
|
|
dynamicCert: "snitest.com",
|
2018-07-06 08:30:03 +00:00
|
|
|
expectedCert: "snitest.com",
|
|
|
|
},
|
|
|
|
{
|
2018-11-27 16:42:04 +00:00
|
|
|
desc: "Best Match with dynamic wildcard",
|
2018-07-06 08:30:03 +00:00
|
|
|
domainToCheck: "www.snitest.com",
|
|
|
|
dynamicCert: "*.snitest.com",
|
|
|
|
expectedCert: "*.snitest.com",
|
|
|
|
},
|
2018-11-26 09:38:03 +00:00
|
|
|
{
|
2024-09-13 09:40:04 +00:00
|
|
|
desc: "Best Match with dynamic wildcard only, case-insensitive",
|
2018-11-26 09:38:03 +00:00
|
|
|
domainToCheck: "bar.www.snitest.com",
|
|
|
|
dynamicCert: "*.www.snitest.com",
|
|
|
|
expectedCert: "*.www.snitest.com",
|
|
|
|
uppercase: true,
|
|
|
|
},
|
2018-07-06 08:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
dynamicMap := map[string]*tls.Certificate{}
|
|
|
|
|
|
|
|
if test.dynamicCert != "" {
|
2018-11-26 09:38:03 +00:00
|
|
|
cert, err := loadTestCert(test.dynamicCert, test.uppercase)
|
2018-07-06 08:30:03 +00:00
|
|
|
require.NoError(t, err)
|
2018-11-26 09:38:03 +00:00
|
|
|
dynamicMap[strings.ToLower(test.dynamicCert)] = cert
|
2018-07-06 08:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
store := &CertificateStore{
|
|
|
|
DynamicCerts: safe.New(dynamicMap),
|
|
|
|
CertCache: cache.New(1*time.Hour, 10*time.Minute),
|
|
|
|
}
|
|
|
|
|
|
|
|
var expected *tls.Certificate
|
|
|
|
if test.expectedCert != "" {
|
2018-11-26 09:38:03 +00:00
|
|
|
cert, err := loadTestCert(test.expectedCert, test.uppercase)
|
2018-07-06 08:30:03 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
expected = cert
|
|
|
|
}
|
|
|
|
|
|
|
|
clientHello := &tls.ClientHelloInfo{
|
|
|
|
ServerName: test.domainToCheck,
|
|
|
|
}
|
|
|
|
|
|
|
|
actual := store.GetBestCertificate(clientHello)
|
|
|
|
assert.Equal(t, expected, actual)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-26 09:38:03 +00:00
|
|
|
func loadTestCert(certName string, uppercase bool) (*tls.Certificate, error) {
|
|
|
|
replacement := "wildcard"
|
|
|
|
if uppercase {
|
|
|
|
replacement = "uppercase_wildcard"
|
|
|
|
}
|
|
|
|
|
2018-07-06 08:30:03 +00:00
|
|
|
staticCert, err := tls.LoadX509KeyPair(
|
2020-09-15 11:08:03 +00:00
|
|
|
fmt.Sprintf("../../integration/fixtures/https/%s.cert", strings.ReplaceAll(certName, "*", replacement)),
|
|
|
|
fmt.Sprintf("../../integration/fixtures/https/%s.key", strings.ReplaceAll(certName, "*", replacement)),
|
2018-07-06 08:30:03 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &staticCert, nil
|
|
|
|
}
|