diff --git a/command/operator_diagnose_test.go b/command/operator_diagnose_test.go index 8528637dc2e4..ddbcc204689a 100644 --- a/command/operator_diagnose_test.go +++ b/command/operator_diagnose_test.go @@ -10,11 +10,13 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "strings" "testing" "github.com/hashicorp/cli" "github.com/hashicorp/vault/helper/constants" + pkihelper "github.com/hashicorp/vault/helper/testhelpers/pki" "github.com/hashicorp/vault/vault/diagnose" ) @@ -31,8 +33,55 @@ func testOperatorDiagnoseCommand(tb testing.TB) *OperatorDiagnoseCommand { } } +func generateTLSConfigOk(t *testing.T, ca pkihelper.LeafWithIntermediary) string { + t.Helper() + tmpDir := t.TempDir() + configPath := filepath.Join(tmpDir, "tls_config_ok.hcl") + + templateFile := "./server/test-fixtures/tls_config_ok.hcl" + contents, err := os.ReadFile(templateFile) + if err != nil { + t.Fatalf("failed to read file %s: %v", templateFile, err) + } + contents = []byte(strings.ReplaceAll(string(contents), "{REPLACE_LEAF_CERT_FILE}", ca.Leaf.CertFile)) + contents = []byte(strings.ReplaceAll(string(contents), "{REPLACE_LEAF_KEY_FILE}", ca.Leaf.KeyFile)) + + err = os.WriteFile(configPath, contents, 0o644) + if err != nil { + t.Fatalf("failed to write file %s: %v", configPath, err) + } + + return configPath +} + +func generateTransitTLSCheck(t *testing.T, ca pkihelper.LeafWithIntermediary) string { + t.Helper() + tmpDir := t.TempDir() + configPath := filepath.Join(tmpDir, "diagnose_seal_transit_tls_check.hcl") + + templateFile := "./server/test-fixtures/diagnose_seal_transit_tls_check.hcl" + contents, err := os.ReadFile(templateFile) + if err != nil { + t.Fatalf("failed to read file %s: %v", templateFile, err) + } + contents = []byte(strings.ReplaceAll(string(contents), "{REPLACE_LEAF_CERT_FILE}", ca.Leaf.CertFile)) + contents = []byte(strings.ReplaceAll(string(contents), "{REPLACE_LEAF_KEY_FILE}", ca.Leaf.KeyFile)) + contents = []byte(strings.ReplaceAll(string(contents), "{REPLACE_COMBINED_CA_CHAIN_FILE}", ca.CombinedCaFile)) + + err = os.WriteFile(configPath, contents, 0o644) + if err != nil { + t.Fatalf("failed to write file %s: %v", configPath, err) + } + + return configPath +} + func TestOperatorDiagnoseCommand_Run(t *testing.T) { t.Parallel() + testca := pkihelper.GenerateCertWithIntermediaryRoot(t) + tlsConfigOkConfigFile := generateTLSConfigOk(t, testca) + transitTLSCheckConfigFile := generateTransitTLSCheck(t, testca) + cases := []struct { name string args []string @@ -349,7 +398,7 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) { { "diagnose_listener_config_ok", []string{ - "-config", "./server/test-fixtures/tls_config_ok.hcl", + "-config", tlsConfigOkConfigFile, }, []*diagnose.Result{ { @@ -461,7 +510,7 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) { { "diagnose_seal_transit_tls_check_fail", []string{ - "-config", "./server/test-fixtures/diagnose_seal_transit_tls_check.hcl", + "-config", transitTLSCheckConfigFile, }, []*diagnose.Result{ { diff --git a/command/server/test-fixtures/diagnose_seal_transit_tls_check.hcl b/command/server/test-fixtures/diagnose_seal_transit_tls_check.hcl index a7007d57313a..de632c152acc 100644 --- a/command/server/test-fixtures/diagnose_seal_transit_tls_check.hcl +++ b/command/server/test-fixtures/diagnose_seal_transit_tls_check.hcl @@ -20,9 +20,9 @@ backend "consul" { seal "transit" { // TLS Configuration - tls_ca_cert = "./../vault/diagnose/test-fixtures/chain.crt.pem" - tls_client_cert = "./../vault/diagnose/test-fixtures/goodcertwithroot.pem" - tls_client_key = "./../vault/diagnose//test-fixtures/goodkey.pem" + tls_ca_cert = "{REPLACE_COMBINED_CA_CHAIN_FILE}" + tls_client_cert = "{REPLACE_LEAF_CERT_FILE}" + tls_client_key = "{REPLACE_LEAF_KEY_FILE}" tls_server_name = "vault" tls_skip_verify = "false" } diff --git a/command/server/test-fixtures/tls_config_ok.hcl b/command/server/test-fixtures/tls_config_ok.hcl index 02a2733d4138..7babfff9ae8f 100644 --- a/command/server/test-fixtures/tls_config_ok.hcl +++ b/command/server/test-fixtures/tls_config_ok.hcl @@ -8,8 +8,8 @@ ui = true listener "tcp" { address = "127.0.0.1:1025" - tls_cert_file = "./../api/test-fixtures/keys/cert.pem" - tls_key_file = "./../api/test-fixtures/keys/key.pem" + tls_cert_file = "{REPLACE_LEAF_CERT_FILE}" + tls_key_file = "{REPLACE_LEAF_KEY_FILE}" } backend "consul" { diff --git a/helper/testhelpers/pki/pkihelper.go b/helper/testhelpers/pki/pkihelper.go new file mode 100644 index 000000000000..e76d4e54229b --- /dev/null +++ b/helper/testhelpers/pki/pkihelper.go @@ -0,0 +1,224 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package pki + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "math/big" + mathrand2 "math/rand/v2" + "net" + "os" + "path/filepath" + "testing" + "time" +) + +// This file contains helper functions for generating CA hierarchies for testing + +type LeafWithRoot struct { + RootCa GeneratedCert + Leaf GeneratedCert + CombinedLeafCaFile string +} + +type LeafWithIntermediary struct { + RootCa GeneratedCert + IntCa GeneratedCert + Leaf GeneratedCert + CombinedCaFile string +} + +type GeneratedCert struct { + KeyFile string + CertFile string + CertPem *pem.Block + Cert *x509.Certificate + Key *ecdsa.PrivateKey +} + +// GenerateCertWithIntermediaryRoot generates a leaf certificate signed by an intermediary root CA +func GenerateCertWithIntermediaryRoot(t testing.TB) LeafWithIntermediary { + t.Helper() + tempDir := t.TempDir() + template := &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "localhost", + }, + SerialNumber: big.NewInt(mathrand2.Int64()), + DNSNames: []string{"localhost"}, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + NotBefore: time.Now().Add(-30 * time.Second), + NotAfter: time.Now().Add(60 * 24 * time.Hour), + } + + ca := GenerateRootCa(t) + caIntTemplate := &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "Intermediary CA", + }, + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + SerialNumber: big.NewInt(mathrand2.Int64()), + NotBefore: time.Now().Add(-30 * time.Second), + NotAfter: time.Now().Add(262980 * time.Hour), + BasicConstraintsValid: true, + IsCA: true, + } + caInt := generateCertAndSign(t, caIntTemplate, ca, tempDir, "int_") + leafCert := generateCertAndSign(t, template, caInt, tempDir, "leaf_") + + combinedCasFile := filepath.Join(tempDir, "cas.pem") + err := os.WriteFile(combinedCasFile, append(pem.EncodeToMemory(caInt.CertPem), pem.EncodeToMemory(ca.CertPem)...), 0o644) + if err != nil { + t.Fatal(err) + } + + return LeafWithIntermediary{ + RootCa: ca, + IntCa: caInt, + Leaf: leafCert, + CombinedCaFile: combinedCasFile, + } +} + +// generateCertAndSign generates a certificate and associated key signed by a CA +func generateCertAndSign(t testing.TB, template *x509.Certificate, ca GeneratedCert, tempDir string, filePrefix string) GeneratedCert { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + certBytes, err := x509.CreateCertificate(rand.Reader, template, ca.Cert, key.Public(), ca.Key) + if err != nil { + t.Fatal(err) + } + cert, err := x509.ParseCertificate(certBytes) + if err != nil { + t.Fatal(err) + } + certPEMBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: certBytes, + } + certFile := filepath.Join(tempDir, filePrefix+"cert.pem") + err = os.WriteFile(certFile, pem.EncodeToMemory(certPEMBlock), 0o644) + if err != nil { + t.Fatal(err) + } + marshaledKey, err := x509.MarshalECPrivateKey(key) + if err != nil { + t.Fatal(err) + } + keyPEMBlock := &pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: marshaledKey, + } + keyFile := filepath.Join(tempDir, filePrefix+"key.pem") + err = os.WriteFile(keyFile, pem.EncodeToMemory(keyPEMBlock), 0o644) + if err != nil { + t.Fatal(err) + } + return GeneratedCert{ + KeyFile: keyFile, + CertFile: certFile, + CertPem: certPEMBlock, + Cert: cert, + Key: key, + } +} + +// GenerateCertWithRoot generates a leaf certificate signed by a root CA +func GenerateCertWithRoot(t testing.TB) LeafWithRoot { + t.Helper() + tempDir := t.TempDir() + leafTemplate := &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "localhost", + }, + SerialNumber: big.NewInt(mathrand2.Int64()), + DNSNames: []string{"localhost"}, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + NotBefore: time.Now().Add(-30 * time.Second), + NotAfter: time.Now().Add(60 * 24 * time.Hour), + } + + ca := GenerateRootCa(t) + leafCert := generateCertAndSign(t, leafTemplate, ca, tempDir, "leaf_") + + combinedCaLeafFile := filepath.Join(tempDir, "leaf-ca.pem") + err := os.WriteFile(combinedCaLeafFile, append(pem.EncodeToMemory(leafCert.CertPem), pem.EncodeToMemory(ca.CertPem)...), 0o644) + if err != nil { + t.Fatal(err) + } + + return LeafWithRoot{ + RootCa: ca, + Leaf: leafCert, + CombinedLeafCaFile: combinedCaLeafFile, + } +} + +// GenerateRootCa generates a self-signed root CA certificate and key +func GenerateRootCa(t testing.TB) GeneratedCert { + t.Helper() + tempDir := t.TempDir() + + caCertTemplate := &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "Root CA", + }, + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + SerialNumber: big.NewInt(mathrand2.Int64()), + NotBefore: time.Now().Add(-30 * time.Second), + NotAfter: time.Now().Add(262980 * time.Hour), + BasicConstraintsValid: true, + IsCA: true, + } + caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + caBytes, err := x509.CreateCertificate(rand.Reader, caCertTemplate, caCertTemplate, caKey.Public(), caKey) + if err != nil { + t.Fatal(err) + } + caCert, err := x509.ParseCertificate(caBytes) + if err != nil { + t.Fatal(err) + } + caCertPEMBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: caBytes, + } + caFile := filepath.Join(tempDir, "ca_root_cert.pem") + err = os.WriteFile(caFile, pem.EncodeToMemory(caCertPEMBlock), 0o644) + if err != nil { + t.Fatal(err) + } + marshaledCAKey, err := x509.MarshalECPrivateKey(caKey) + if err != nil { + t.Fatal(err) + } + caKeyPEMBlock := &pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: marshaledCAKey, + } + caKeyFile := filepath.Join(tempDir, "ca_root_key.pem") + err = os.WriteFile(caKeyFile, pem.EncodeToMemory(caKeyPEMBlock), 0o644) + if err != nil { + t.Fatal(err) + } + return GeneratedCert{ + CertPem: caCertPEMBlock, + CertFile: caFile, + KeyFile: caKeyFile, + Cert: caCert, + Key: caKey, + } +} diff --git a/vault/diagnose/test-fixtures/goodcertwithroot.pem b/vault/diagnose/test-fixtures/goodcertwithroot.pem deleted file mode 100644 index 6e4baf613a39..000000000000 --- a/vault/diagnose/test-fixtures/goodcertwithroot.pem +++ /dev/null @@ -1,42 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIUf+jhKTFBnqSs34II0WS1L4QsbbAwDQYJKoZIhvcNAQEL -BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzQxWhcNMjUw -MTA1MTAyODExWjAbMRkwFwYDVQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsZx0Svr82YJpFpIy4fJNW5fKA6B8mhxS -TRAVnygAftetT8puHflY0ss7Y6X2OXjsU0PRn+1PswtivhKi+eLtgWkUF9cFYFGn -SgMld6ZWRhNheZhA6ZfQmeM/BF2pa5HK2SDF36ljgjL9T+nWrru2Uv0BCoHzLAmi -YYMiIWplidMmMO5NTRG3k+3AN0TkfakB6JVzjLGhTcXdOcVEMXkeQVqJMAuGouU5 -donyqtnaHuIJGuUdy54YDnX86txhOQhAv6r7dHXzZxS4pmLvw8UI1rsSf/GLcUVG -B+5+AAGF5iuHC3N2DTl4xz3FcN4Cb4w9pbaQ7+mCzz+anqiJfyr2nwIDAQABo4H1 -MIHyMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUm++e -HpyM3p708bgZJuRYEdX1o+UwHwYDVR0jBBgwFoAUncSzT/6HMexyuiU9/7EgHu+o -k5swOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzAChh9odHRwOi8vMTI3LjAuMC4x -OjgyMDAvdjEvcGtpL2NhMCEGA1UdEQQaMBiCEGNlcnQuZXhhbXBsZS5jb22HBH8A -AAEwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovLzEyNy4wLjAuMTo4MjAwL3YxL3Br -aS9jcmwwDQYJKoZIhvcNAQELBQADggEBABsuvmPSNjjKTVN6itWzdQy+SgMIrwfs -X1Yb9Lefkkwmp9ovKFNQxa4DucuCuzXcQrbKwWTfHGgR8ct4rf30xCRoA7dbQWq4 -aYqNKFWrRaBRAaaYZ/O1ApRTOrXqRx9Eqr0H1BXLsoAq+mWassL8sf6siae+CpwA -KqBko5G0dNXq5T4i2LQbmoQSVetIrCJEeMrU+idkuqfV2h1BQKgSEhFDABjFdTCN -QDAHsEHsi2M4/jRW9fqEuhHSDfl2n7tkFUI8wTHUUCl7gXwweJ4qtaSXIwKXYzNj -xqKHA8Purc1Yfybz4iE1JCROi9fInKlzr5xABq8nb9Qc/J9DIQM+Xmk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDPDCCAiSgAwIBAgIUb5id+GcaMeMnYBv3MvdTGWigyJ0wDQYJKoZIhvcNAQEL -BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzI5WhcNMjYw -MjI2MDIyNzU5WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAOxTMvhTuIRc2YhxZpmPwegP86cgnqfT1mXxi1A7 -Q7qax24Nqbf00I3oDMQtAJlj2RB3hvRSCb0/lkF7i1Bub+TGxuM7NtZqp2F8FgG0 -z2md+W6adwW26rlxbQKjmRvMn66G9YPTkoJmPmxt2Tccb9+apmwW7lslL5j8H48x -AHJTMb+PMP9kbOHV5Abr3PT4jXUPUr/mWBvBiKiHG0Xd/HEmlyOEPeAThxK+I5tb -6m+eB+7cL9BsvQpy135+2bRAxUphvFi5NhryJ2vlAvoJ8UqigsNK3E28ut60FAoH -SWRfFUFFYtfPgTDS1yOKU/z/XMU2giQv2HrleWt0mp4jqBUCAwEAAaOBgTB/MA4G -A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSdxLNP/ocx -7HK6JT3/sSAe76iTmzAfBgNVHSMEGDAWgBSdxLNP/ocx7HK6JT3/sSAe76iTmzAc -BgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEA -wHThDRsXJunKbAapxmQ6bDxSvTvkLA6m97TXlsFgL+Q3Jrg9HoJCNowJ0pUTwhP2 -U946dCnSCkZck0fqkwVi4vJ5EQnkvyEbfN4W5qVsQKOFaFVzep6Qid4rZT6owWPa -cNNzNcXAee3/j6hgr6OQ/i3J6fYR4YouYxYkjojYyg+CMdn6q8BoV0BTsHdnw1/N -ScbnBHQIvIZMBDAmQueQZolgJcdOuBLYHe/kRy167z8nGg+PUFKIYOL8NaOU1+CJ -t2YaEibVq5MRqCbRgnd9a2vG0jr5a3Mn4CUUYv+5qIjP3hUusYenW1/EWtn1s/gk -zehNe5dFTjFpylg1o6b8Ow== ------END CERTIFICATE----- diff --git a/vault/diagnose/tls_verification_test.go b/vault/diagnose/tls_verification_test.go index 70f506c9377a..769330fb776d 100644 --- a/vault/diagnose/tls_verification_test.go +++ b/vault/diagnose/tls_verification_test.go @@ -5,23 +5,29 @@ package diagnose import ( "context" + "encoding/pem" "fmt" + "os" + "path/filepath" "strings" "testing" + pkihelper "github.com/hashicorp/vault/helper/testhelpers/pki" "github.com/hashicorp/vault/internalshared/configutil" ) // TestTLSValidCert is the positive test case to show that specifying a valid cert and key // passes all checks. func TestTLSValidCert(t *testing.T) { + tlsFiles := pkihelper.GenerateCertWithRoot(t) + listeners := []*configutil.Listener{ { Type: "tcp", Address: "127.0.0.1:443", ClusterAddress: "127.0.0.1:8201", - TLSCertFile: "./test-fixtures/goodcertwithroot.pem", - TLSKeyFile: "./test-fixtures/goodkey.pem", + TLSCertFile: tlsFiles.CombinedLeafCaFile, + TLSKeyFile: tlsFiles.Leaf.KeyFile, TLSMinVersion: "tls10", TLSDisableClientCerts: true, }, @@ -390,14 +396,15 @@ func TestTLSClientCAVerfiyMutualExclusion(t *testing.T) { // TestTLSClientCAVerfiy checks that a listener which has TLS client certs checks enabled works as expected func TestTLSClientCAFileCheck(t *testing.T) { + testCaFiles := pkihelper.GenerateCertWithRoot(t) listeners := []*configutil.Listener{ { Type: "tcp", Address: "127.0.0.1:443", ClusterAddress: "127.0.0.1:8201", - TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", - TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", - TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem", + TLSCertFile: testCaFiles.Leaf.CertFile, + TLSKeyFile: testCaFiles.Leaf.KeyFile, + TLSClientCAFile: testCaFiles.RootCa.CertFile, TLSMaxVersion: "tls10", TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: false, @@ -414,14 +421,25 @@ func TestTLSClientCAFileCheck(t *testing.T) { // TestTLSLeafCertInClientCAFile checks if a leafCert exist in TLSClientCAFile func TestTLSLeafCertInClientCAFile(t *testing.T) { + testCaFiles := pkihelper.GenerateCertWithRoot(t) + + tempDir := t.TempDir() + + otherRoot := pkihelper.GenerateRootCa(t) + mixedLeafWithRoot := filepath.Join(tempDir, "goodcertbadroot.pem") + err := os.WriteFile(mixedLeafWithRoot, append(pem.EncodeToMemory(testCaFiles.Leaf.CertPem), pem.EncodeToMemory(otherRoot.CertPem)...), 0o644) + if err != nil { + t.Fatalf("Failed to write file %s: %v", mixedLeafWithRoot, err) + } + listeners := []*configutil.Listener{ { Type: "tcp", Address: "127.0.0.1:443", ClusterAddress: "127.0.0.1:8201", - TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", - TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", - TLSClientCAFile: "./test-fixtures/goodcertbadroot.pem", + TLSCertFile: testCaFiles.CombinedLeafCaFile, + TLSKeyFile: testCaFiles.Leaf.KeyFile, + TLSClientCAFile: mixedLeafWithRoot, TLSMaxVersion: "tls10", TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: false, @@ -430,10 +448,10 @@ func TestTLSLeafCertInClientCAFile(t *testing.T) { warnings, errs := ListenerChecks(context.Background(), listeners) fmt.Println(warnings) if errs == nil || len(errs) != 1 { - t.Fatalf("TLS Config check on bad ClientCAFile certificate should fail once") + t.Fatalf("TLS Config check on bad ClientCAFile certificate should fail once: got %v", errs) } if warnings == nil || len(warnings) != 1 { - t.Fatalf("TLS Config check on bad ClientCAFile certificate should warn once") + t.Fatalf("TLS Config check on bad ClientCAFile certificate should warn once: got %v", warnings) } if !strings.Contains(warnings[0], "Found at least one leaf certificate in the CA certificate file.") { t.Fatalf("Bad error message: %s", warnings[0]) @@ -445,14 +463,15 @@ func TestTLSLeafCertInClientCAFile(t *testing.T) { // TestTLSNoRootInClientCAFile checks if no Root cert exist in TLSClientCAFile func TestTLSNoRootInClientCAFile(t *testing.T) { + testCa := pkihelper.GenerateCertWithIntermediaryRoot(t) listeners := []*configutil.Listener{ { Type: "tcp", Address: "127.0.0.1:443", ClusterAddress: "127.0.0.1:8201", - TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", - TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", - TLSClientCAFile: "./test-fixtures/intermediateCert.pem", + TLSCertFile: testCa.Leaf.CertFile, + TLSKeyFile: testCa.Leaf.KeyFile, + TLSClientCAFile: testCa.IntCa.CertFile, TLSMaxVersion: "tls10", TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: false, @@ -469,14 +488,15 @@ func TestTLSNoRootInClientCAFile(t *testing.T) { // TestTLSIntermediateCertInClientCAFile checks if an intermediate cert is included in TLSClientCAFile func TestTLSIntermediateCertInClientCAFile(t *testing.T) { + testCa := pkihelper.GenerateCertWithIntermediaryRoot(t) listeners := []*configutil.Listener{ { Type: "tcp", Address: "127.0.0.1:443", ClusterAddress: "127.0.0.1:8201", - TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", - TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", - TLSClientCAFile: "./test-fixtures/chain.crt.pem", + TLSCertFile: testCa.Leaf.CertFile, + TLSKeyFile: testCa.Leaf.KeyFile, + TLSClientCAFile: testCa.CombinedCaFile, TLSMaxVersion: "tls10", TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: false, @@ -491,16 +511,25 @@ func TestTLSIntermediateCertInClientCAFile(t *testing.T) { } } -// TestTLSMultipleRootInClietCACert checks if multiple roots included in TLSClientCAFile -func TestTLSMultipleRootInClietCACert(t *testing.T) { +// TestTLSMultipleRootInClientCACert checks if multiple roots included in TLSClientCAFile +func TestTLSMultipleRootInClientCACert(t *testing.T) { + testCa := pkihelper.GenerateCertWithRoot(t) + otherRoot := pkihelper.GenerateRootCa(t) + tempDir := t.TempDir() + mixedRoots := filepath.Join(tempDir, "twoRootCA.pem") + err := os.WriteFile(mixedRoots, append(pem.EncodeToMemory(testCa.RootCa.CertPem), pem.EncodeToMemory(otherRoot.CertPem)...), 0o644) + if err != nil { + t.Fatalf("Failed to write file %s: %v", mixedRoots, err) + } + listeners := []*configutil.Listener{ { Type: "tcp", Address: "127.0.0.1:443", ClusterAddress: "127.0.0.1:8201", - TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", - TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", - TLSClientCAFile: "./test-fixtures/twoRootCA.pem", + TLSCertFile: testCa.Leaf.CertFile, + TLSKeyFile: testCa.Leaf.KeyFile, + TLSClientCAFile: mixedRoots, TLSMinVersion: "tls10", TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: false, @@ -508,7 +537,7 @@ func TestTLSMultipleRootInClietCACert(t *testing.T) { } warnings, errs := ListenerChecks(context.Background(), listeners) if errs != nil { - t.Fatalf("TLS Config check on valid certificate should not fail") + t.Fatalf("TLS Config check on valid certificate should not fail got: %v", errs) } if warnings == nil { t.Fatalf("TLS Config check on valid but bad certificate should warn")