consul/agent/connect/testing_ca_test.go

131 lines
3.5 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package connect
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var mustAlwaysRun = os.Getenv("CI") == "true"
func skipIfMissingOpenSSL(t *testing.T) {
openSSLBinaryName := "openssl"
_, err := exec.LookPath(openSSLBinaryName)
if err != nil {
if mustAlwaysRun {
t.Fatalf("%q not found on $PATH", openSSLBinaryName)
}
t.Skipf("%q not found on $PATH", openSSLBinaryName)
}
}
// Test that the TestCA and TestLeaf functions generate valid certificates.
func testCAAndLeaf(t *testing.T, keyType string, keyBits int) {
skipIfMissingOpenSSL(t)
// Create the certs
ca := TestCAWithKeyType(t, nil, keyType, keyBits)
leaf, _ := TestLeaf(t, "web", ca)
// Create a temporary directory for storing the certs
td, err := os.MkdirTemp("", "consul")
require.NoError(t, err)
defer os.RemoveAll(td)
// Write the cert
require.NoError(t, os.WriteFile(filepath.Join(td, "ca.pem"), []byte(ca.RootCert), 0644))
require.NoError(t, os.WriteFile(filepath.Join(td, "leaf.pem"), []byte(leaf[:]), 0644))
// Use OpenSSL to verify so we have an external, known-working process
// that can verify this outside of our own implementations.
cmd := exec.Command(
"openssl", "verify", "-verbose", "-CAfile", "ca.pem", "leaf.pem")
cmd.Dir = td
output, err := cmd.Output()
t.Log("STDOUT:", string(output))
if ee, ok := err.(*exec.ExitError); ok {
t.Log("STDERR:", string(ee.Stderr))
}
require.NoError(t, err)
}
// Test cross-signing.
func testCAAndLeaf_xc(t *testing.T, keyType string, keyBits int) {
skipIfMissingOpenSSL(t)
// Create the certs
ca1 := TestCAWithKeyType(t, nil, keyType, keyBits)
ca2 := TestCAWithKeyType(t, ca1, keyType, keyBits)
leaf1, _ := TestLeaf(t, "web", ca1)
leaf2, _ := TestLeaf(t, "web", ca2)
// Create a temporary directory for storing the certs
td, err := os.MkdirTemp("", "consul")
assert.Nil(t, err)
defer os.RemoveAll(td)
// Write the cert
xcbundle := []byte(ca1.RootCert)
xcbundle = append(xcbundle, '\n')
xcbundle = append(xcbundle, []byte(ca2.SigningCert)...)
assert.Nil(t, os.WriteFile(filepath.Join(td, "ca.pem"), xcbundle, 0644))
assert.Nil(t, os.WriteFile(filepath.Join(td, "leaf1.pem"), []byte(leaf1), 0644))
assert.Nil(t, os.WriteFile(filepath.Join(td, "leaf2.pem"), []byte(leaf2), 0644))
// OpenSSL verify the cross-signed leaf (leaf2)
{
cmd := exec.Command(
"openssl", "verify", "-verbose", "-CAfile", "ca.pem", "leaf2.pem")
cmd.Dir = td
output, err := cmd.Output()
t.Log(string(output))
assert.Nil(t, err)
}
// OpenSSL verify the old leaf (leaf1)
{
cmd := exec.Command(
"openssl", "verify", "-verbose", "-CAfile", "ca.pem", "leaf1.pem")
cmd.Dir = td
output, err := cmd.Output()
t.Log(string(output))
assert.Nil(t, err)
}
}
func TestTestCAAndLeaf(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
for _, params := range goodParams {
t.Run(fmt.Sprintf("TestTestCAAndLeaf-%s-%d", params.keyType, params.keyBits),
func(t *testing.T) {
testCAAndLeaf(t, params.keyType, params.keyBits)
})
}
}
func TestTestCAAndLeaf_xc(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
for _, params := range goodParams {
t.Run(fmt.Sprintf("TestTestCAAndLeaf_xc-%s-%d", params.keyType, params.keyBits),
func(t *testing.T) {
testCAAndLeaf_xc(t, params.keyType, params.keyBits)
})
}
}