package connect
import (
"fmt"
"io/ioutil"
"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 )
require := require . New ( 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 := ioutil . TempDir ( "" , "consul" )
require . NoError ( err )
defer os . RemoveAll ( td )
// Write the cert
require . NoError ( ioutil . WriteFile ( filepath . Join ( td , "ca.pem" ) , [ ] byte ( ca . RootCert ) , 0644 ) )
require . NoError ( ioutil . 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 ( err )
}
// Test cross-signing.
func testCAAndLeaf_xc ( t * testing . T , keyType string , keyBits int ) {
skipIfMissingOpenSSL ( t )
assert := assert . New ( 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 := ioutil . TempDir ( "" , "consul" )
assert . Nil ( err )
defer os . RemoveAll ( td )
// Write the cert
xcbundle := [ ] byte ( ca1 . RootCert )
xcbundle = append ( xcbundle , '\n' )
xcbundle = append ( xcbundle , [ ] byte ( ca2 . SigningCert ) ... )
assert . Nil ( ioutil . WriteFile ( filepath . Join ( td , "ca.pem" ) , xcbundle , 0644 ) )
assert . Nil ( ioutil . WriteFile ( filepath . Join ( td , "leaf1.pem" ) , [ ] byte ( leaf1 ) , 0644 ) )
assert . Nil ( ioutil . 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 ( 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 ( err )
}
}
func TestTestCAAndLeaf ( t * testing . T ) {
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 ) {
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 )
} )
}
}