194 lines
5.9 KiB
Go
194 lines
5.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"math/big"
|
|
"os"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/letsencrypt/boulder/metrics"
|
|
"github.com/letsencrypt/boulder/test"
|
|
)
|
|
|
|
func TestDBConfigURL(t *testing.T) {
|
|
tests := []struct {
|
|
conf DBConfig
|
|
expected string
|
|
}{
|
|
{
|
|
// Test with one config file that has no trailing newline
|
|
conf: DBConfig{DBConnectFile: "testdata/test_dburl"},
|
|
expected: "test@tcp(testhost:3306)/testDB?readTimeout=800ms&writeTimeout=800ms",
|
|
},
|
|
{
|
|
// Test with a config file that *has* a trailing newline
|
|
conf: DBConfig{DBConnectFile: "testdata/test_dburl_newline"},
|
|
expected: "test@tcp(testhost:3306)/testDB?readTimeout=800ms&writeTimeout=800ms",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
url, err := tc.conf.URL()
|
|
test.AssertNotError(t, err, "Failed calling URL() on DBConfig")
|
|
test.AssertEquals(t, url, tc.expected)
|
|
}
|
|
}
|
|
|
|
func TestPasswordConfig(t *testing.T) {
|
|
tests := []struct {
|
|
pc PasswordConfig
|
|
expected string
|
|
}{
|
|
{pc: PasswordConfig{}, expected: ""},
|
|
{pc: PasswordConfig{PasswordFile: "testdata/test_secret"}, expected: "secret"},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
password, err := tc.pc.Pass()
|
|
test.AssertNotError(t, err, "Failed to retrieve password")
|
|
test.AssertEquals(t, password, tc.expected)
|
|
}
|
|
}
|
|
|
|
func TestTLSConfigLoad(t *testing.T) {
|
|
null := "/dev/null"
|
|
nonExistent := "[nonexistent]"
|
|
tmp := t.TempDir()
|
|
cert := path.Join(tmp, "TestTLSConfigLoad.cert.pem")
|
|
key := path.Join(tmp, "TestTLSConfigLoad.key.pem")
|
|
caCert := path.Join(tmp, "TestTLSConfigLoad.cacert.pem")
|
|
|
|
rootKey, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
|
test.AssertNotError(t, err, "creating test root key")
|
|
rootTemplate := &x509.Certificate{
|
|
Subject: pkix.Name{CommonName: "test root"},
|
|
SerialNumber: big.NewInt(12345),
|
|
NotBefore: time.Now().Add(-24 * time.Hour),
|
|
NotAfter: time.Now().Add(24 * time.Hour),
|
|
IsCA: true,
|
|
}
|
|
rootCert, err := x509.CreateCertificate(rand.Reader, rootTemplate, rootTemplate, rootKey.Public(), rootKey)
|
|
test.AssertNotError(t, err, "creating test root cert")
|
|
err = os.WriteFile(caCert, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert}), os.ModeAppend)
|
|
test.AssertNotError(t, err, "writing test root cert to disk")
|
|
|
|
intKey, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
|
test.AssertNotError(t, err, "creating test intermediate key")
|
|
intKeyBytes, err := x509.MarshalECPrivateKey(intKey)
|
|
test.AssertNotError(t, err, "marshalling test intermediate key")
|
|
err = os.WriteFile(key, pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: intKeyBytes}), os.ModeAppend)
|
|
test.AssertNotError(t, err, "writing test intermediate key cert to disk")
|
|
|
|
intTemplate := &x509.Certificate{
|
|
Subject: pkix.Name{CommonName: "test intermediate"},
|
|
SerialNumber: big.NewInt(67890),
|
|
NotBefore: time.Now().Add(-12 * time.Hour),
|
|
NotAfter: time.Now().Add(12 * time.Hour),
|
|
IsCA: true,
|
|
}
|
|
intCert, err := x509.CreateCertificate(rand.Reader, intTemplate, rootTemplate, intKey.Public(), rootKey)
|
|
test.AssertNotError(t, err, "creating test intermediate cert")
|
|
err = os.WriteFile(cert, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: intCert}), os.ModeAppend)
|
|
test.AssertNotError(t, err, "writing test intermediate cert to disk")
|
|
|
|
testCases := []struct {
|
|
TLSConfig
|
|
want string
|
|
}{
|
|
{TLSConfig{"", null, null}, "nil CertFile in TLSConfig"},
|
|
{TLSConfig{null, "", null}, "nil KeyFile in TLSConfig"},
|
|
{TLSConfig{null, null, ""}, "nil CACertFile in TLSConfig"},
|
|
{TLSConfig{nonExistent, key, caCert}, "loading key pair.*no such file or directory"},
|
|
{TLSConfig{cert, nonExistent, caCert}, "loading key pair.*no such file or directory"},
|
|
{TLSConfig{cert, key, nonExistent}, "reading CA cert from.*no such file or directory"},
|
|
{TLSConfig{null, key, caCert}, "loading key pair.*failed to find any PEM data"},
|
|
{TLSConfig{cert, null, caCert}, "loading key pair.*failed to find any PEM data"},
|
|
{TLSConfig{cert, key, null}, "parsing CA certs"},
|
|
{TLSConfig{cert, key, caCert}, ""},
|
|
}
|
|
for _, tc := range testCases {
|
|
title := [3]string{tc.CertFile, tc.KeyFile, tc.CACertFile}
|
|
for i := range title {
|
|
if title[i] == "" {
|
|
title[i] = "nil"
|
|
}
|
|
}
|
|
t.Run(strings.Join(title[:], "_"), func(t *testing.T) {
|
|
_, err := tc.TLSConfig.Load(metrics.NoopRegisterer)
|
|
if err == nil && tc.want == "" {
|
|
return
|
|
}
|
|
if err == nil {
|
|
t.Errorf("got no error")
|
|
}
|
|
if matched, _ := regexp.MatchString(tc.want, err.Error()); !matched {
|
|
t.Errorf("got error %q, wanted %q", err, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHMACKeyConfigLoad(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
content string
|
|
expectedErr bool
|
|
}{
|
|
{
|
|
name: "Valid key",
|
|
content: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
expectedErr: false,
|
|
},
|
|
{
|
|
name: "Empty file",
|
|
content: "",
|
|
expectedErr: true,
|
|
},
|
|
{
|
|
name: "Just under 256-bit",
|
|
content: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab",
|
|
expectedErr: true,
|
|
},
|
|
{
|
|
name: "Just over 256-bit",
|
|
content: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01",
|
|
expectedErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tempKeyFile, err := os.CreateTemp("", "*")
|
|
if err != nil {
|
|
t.Fatalf("failed to create temp file: %v", err)
|
|
}
|
|
defer os.Remove(tempKeyFile.Name())
|
|
|
|
_, err = tempKeyFile.WriteString(tt.content)
|
|
if err != nil {
|
|
t.Fatalf("failed to write to temp file: %v", err)
|
|
}
|
|
tempKeyFile.Close()
|
|
|
|
hmacKeyConfig := HMACKeyConfig{KeyFile: tempKeyFile.Name()}
|
|
_, err = hmacKeyConfig.Load()
|
|
if (err != nil) != tt.expectedErr {
|
|
t.Errorf("expected error: %v, got: %v", tt.expectedErr, err)
|
|
}
|
|
})
|
|
}
|
|
}
|