open-consul/agent/consul/auto_encrypt_endpoint_test.go
Daniel Nephin 3c60a46376 config: remove duplicate TLSConfig fields from agent/consul.Config
tlsutil.Config already presents an excellent structure for this
configuration. Copying the runtime config fields to agent/consul.Config
makes code harder to trace, and provides no advantage.

Instead of copying the fields around, use the tlsutil.Config struct
directly instead.

This is one small step in removing the many layers of duplicate
configuration.
2021-07-09 18:49:42 -04:00

140 lines
3.8 KiB
Go

package consul
import (
"crypto/x509"
"fmt"
"net"
"os"
"strings"
"testing"
msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/tlsutil"
)
func TestAutoEncryptSign(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
type test struct {
Name string
Config tlsutil.Config
ConnError bool
RPCError bool
Cert string
Key string
}
root := "../../test/ca/root.cer"
badRoot := "../../test/ca_path/cert1.crt"
tests := []test{
{Name: "Works with defaults", Config: tlsutil.Config{}, ConnError: false},
{Name: "Works with good root", Config: tlsutil.Config{CAFile: root}, ConnError: false},
{Name: "VerifyOutgoing fails because of bad root", Config: tlsutil.Config{CAFile: badRoot}, ConnError: true},
{Name: "VerifyServerHostname fails", Config: tlsutil.Config{VerifyServerHostname: true, CAFile: root}, ConnError: false, RPCError: true},
{Name: "VerifyServerHostname succeeds", Cert: "../../test/key/ourdomain_server.cer", Key: "../../test/key/ourdomain_server.key",
Config: tlsutil.Config{VerifyServerHostname: true, CAFile: root}, ConnError: false, RPCError: false},
}
for i, test := range tests {
t.Run(test.Name, func(t *testing.T) {
cert := test.Cert
key := test.Key
if cert == "" {
cert = "../../test/key/ourdomain.cer"
}
if key == "" {
key = "../../test/key/ourdomain.key"
}
dir, s := testServerWithConfig(t, func(c *Config) {
c.AutoEncryptAllowTLS = true
c.Bootstrap = true
c.TLSConfig.CAFile = root
c.TLSConfig.VerifyOutgoing = true
c.TLSConfig.CertFile = cert
c.TLSConfig.KeyFile = key
})
defer os.RemoveAll(dir)
defer s.Shutdown()
testrpc.WaitForLeader(t, s.RPC, "dc1")
info := fmt.Sprintf("case %d", i)
// Generate a CSR and request signing
id := &connect.SpiffeIDAgent{
Host: strings.TrimSuffix("domain", "."),
Datacenter: "dc1",
Agent: "uuid",
}
// Create a new private key
pk, _, err := connect.GeneratePrivateKey()
require.NoError(t, err, info)
// Create a CSR.
dnsNames := []string{"localhost"}
ipAddresses := []net.IP{net.ParseIP("127.0.0.1")}
csr, err := connect.CreateCSR(id, pk, dnsNames, ipAddresses)
require.NoError(t, err, info)
require.NotEmpty(t, csr, info)
args := &structs.CASignRequest{
Datacenter: "dc1",
CSR: csr,
}
cfg := test.Config
cfg.AutoTLS = true
cfg.Domain = "consul"
codec, err := insecureRPCClient(s, cfg)
if test.ConnError {
require.Error(t, err, info)
return
}
require.NoError(t, err, info)
var reply structs.SignedResponse
err = msgpackrpc.CallWithCodec(codec, "AutoEncrypt.Sign", args, &reply)
codec.Close()
if test.RPCError {
require.Error(t, err, info)
return
}
require.NoError(t, err, info)
// Get the current CA
state := s.fsm.State()
_, ca, err := state.CARootActive(nil)
require.NoError(t, err, info)
// Verify that the cert is signed by the CA
roots := x509.NewCertPool()
assert.True(t, roots.AppendCertsFromPEM([]byte(ca.RootCert)))
leaf, err := connect.ParseCert(reply.IssuedCert.CertPEM)
require.NoError(t, err, info)
_, err = leaf.Verify(x509.VerifyOptions{
Roots: roots,
})
require.NoError(t, err, info)
// Verify SANs
require.Equal(t, dnsNames, leaf.DNSNames)
require.Len(t, leaf.IPAddresses, 1)
require.True(t, ipAddresses[0].Equal(leaf.IPAddresses[0]))
// Verify other fields
require.Equal(t, "uuid", reply.IssuedCert.Agent, info)
require.Len(t, reply.ManualCARoots, 1, info)
require.Len(t, reply.ConnectCARoots.Roots, 1, info)
})
}
}