2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 18:39:22 +00:00
|
|
|
|
2018-03-19 17:48:38 +00:00
|
|
|
package connect
|
|
|
|
|
|
|
|
import (
|
2019-07-30 21:47:39 +00:00
|
|
|
"fmt"
|
2018-03-19 17:48:38 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2019-11-01 13:20:26 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-03-19 17:48:38 +00:00
|
|
|
)
|
|
|
|
|
2020-03-23 21:02:13 +00:00
|
|
|
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)
|
2019-07-30 21:47:39 +00:00
|
|
|
}
|
2018-03-19 17:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Test that the TestCA and TestLeaf functions generate valid certificates.
|
2019-07-30 21:47:39 +00:00
|
|
|
func testCAAndLeaf(t *testing.T, keyType string, keyBits int) {
|
2020-03-23 21:02:13 +00:00
|
|
|
skipIfMissingOpenSSL(t)
|
2018-03-19 17:48:38 +00:00
|
|
|
|
|
|
|
// Create the certs
|
2019-07-30 21:47:39 +00:00
|
|
|
ca := TestCAWithKeyType(t, nil, keyType, keyBits)
|
2018-03-29 15:25:11 +00:00
|
|
|
leaf, _ := TestLeaf(t, "web", ca)
|
2018-03-19 17:48:38 +00:00
|
|
|
|
|
|
|
// Create a temporary directory for storing the certs
|
2022-11-10 16:26:01 +00:00
|
|
|
td, err := os.MkdirTemp("", "consul")
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
2018-03-19 17:48:38 +00:00
|
|
|
defer os.RemoveAll(td)
|
|
|
|
|
|
|
|
// Write the cert
|
2022-11-10 16:26:01 +00:00
|
|
|
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))
|
2018-03-19 17:48:38 +00:00
|
|
|
|
|
|
|
// 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()
|
2019-11-01 13:20:26 +00:00
|
|
|
t.Log("STDOUT:", string(output))
|
|
|
|
if ee, ok := err.(*exec.ExitError); ok {
|
|
|
|
t.Log("STDERR:", string(ee.Stderr))
|
|
|
|
}
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
2018-03-19 17:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Test cross-signing.
|
2019-07-30 21:47:39 +00:00
|
|
|
func testCAAndLeaf_xc(t *testing.T, keyType string, keyBits int) {
|
2020-03-23 21:02:13 +00:00
|
|
|
skipIfMissingOpenSSL(t)
|
2018-03-19 17:48:38 +00:00
|
|
|
|
|
|
|
// Create the certs
|
2019-07-30 21:47:39 +00:00
|
|
|
ca1 := TestCAWithKeyType(t, nil, keyType, keyBits)
|
|
|
|
ca2 := TestCAWithKeyType(t, ca1, keyType, keyBits)
|
2018-03-29 15:25:11 +00:00
|
|
|
leaf1, _ := TestLeaf(t, "web", ca1)
|
|
|
|
leaf2, _ := TestLeaf(t, "web", ca2)
|
2018-03-19 17:48:38 +00:00
|
|
|
|
|
|
|
// Create a temporary directory for storing the certs
|
2022-11-10 16:26:01 +00:00
|
|
|
td, err := os.MkdirTemp("", "consul")
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
assert.Nil(t, err)
|
2018-03-19 17:48:38 +00:00
|
|
|
defer os.RemoveAll(td)
|
|
|
|
|
|
|
|
// Write the cert
|
|
|
|
xcbundle := []byte(ca1.RootCert)
|
|
|
|
xcbundle = append(xcbundle, '\n')
|
|
|
|
xcbundle = append(xcbundle, []byte(ca2.SigningCert)...)
|
2022-11-10 16:26:01 +00:00
|
|
|
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))
|
2018-03-19 17:48:38 +00:00
|
|
|
|
|
|
|
// 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))
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
assert.Nil(t, err)
|
2018-03-19 17:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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))
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
assert.Nil(t, err)
|
2018-03-19 17:48:38 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-30 21:47:39 +00:00
|
|
|
|
|
|
|
func TestTestCAAndLeaf(t *testing.T) {
|
2020-12-07 18:42:55 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("too slow for testing.Short")
|
|
|
|
}
|
|
|
|
|
2019-07-30 21:47:39 +00:00
|
|
|
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) {
|
2020-12-07 18:42:55 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("too slow for testing.Short")
|
|
|
|
}
|
|
|
|
|
2019-07-30 21:47:39 +00:00
|
|
|
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)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|