Skip to content

Commit

Permalink
Replace test cert fixtures with generated certs
Browse files Browse the repository at this point in the history
Instead of regenerating a bunch of fixtures to include the required SAN
extensions for TLS, use the `tlsgen` package to create certificates.
Where files are required, write the generated certificates to a
temporary directory that gets removed at the end of the test.

Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
  • Loading branch information
sykesm authored and Jason Yellick committed Feb 15, 2021
1 parent aa7ad4f commit 5f19a00
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 241 deletions.
88 changes: 63 additions & 25 deletions core/peer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ package peer

import (
"crypto/tls"
"io/ioutil"
"net"
"os"
"path/filepath"
"runtime"
"testing"
"time"

"github.com/hyperledger/fabric/common/crypto/tlsgen"
"github.com/hyperledger/fabric/internal/pkg/comm"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -94,10 +96,15 @@ func TestPeerAddress(t *testing.T) {
}

func TestGetServerConfig(t *testing.T) {
tempdir, err := ioutil.TempDir("", "peer-clientcert")
assert.NoError(t, err)
defer os.RemoveAll(tempdir)

// good config without TLS
viper.Set("peer.tls.enabled", false)
viper.Set("peer.connectiontimeout", "7s")
sc, _ := GetServerConfig()
sc, err := GetServerConfig()
assert.NoError(t, err)
assert.Equal(t, false, sc.SecOpts.UseTLS, "ServerConfig.SecOpts.UseTLS should be false")
assert.Equal(t, sc.ConnectionTimeout, 7*time.Second, "ServerConfig.ConnectionTimeout should be 7 seconds")

Expand All @@ -114,27 +121,47 @@ func TestGetServerConfig(t *testing.T) {
assert.Equal(t, time.Duration(2)*time.Minute, sc.KaOpts.ServerMinInterval, "ServerConfig.KaOpts.ServerMinInterval should be set to 2 min")

// good config with TLS
org1CA, err := tlsgen.NewCA()
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tempdir, "org1-ca-cert.pem"), org1CA.CertBytes(), 0o644)
assert.NoError(t, err)
org2CA, err := tlsgen.NewCA()
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tempdir, "org2-ca-cert.pem"), org2CA.CertBytes(), 0o644)
assert.NoError(t, err)

org1ServerKP, err := org1CA.NewServerCertKeyPair("localhost")
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tempdir, "org1-server1-cert.pem"), org1ServerKP.Cert, 0o644)
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tempdir, "org1-server1-key.pem"), org1ServerKP.Key, 0o600)
assert.NoError(t, err)

viper.Set("peer.tls.enabled", true)
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org1-cert.pem"))
sc, _ = GetServerConfig()
viper.Set("peer.tls.cert.file", filepath.Join(tempdir, "org1-server1-cert.pem"))
viper.Set("peer.tls.key.file", filepath.Join(tempdir, "org1-server1-key.pem"))
viper.Set("peer.tls.rootcert.file", filepath.Join(tempdir, "org1-ca-cert.pem"))

sc, err = GetServerConfig()
assert.NoError(t, err, "failed to build server config")
assert.Equal(t, true, sc.SecOpts.UseTLS, "ServerConfig.SecOpts.UseTLS should be true")
assert.Equal(t, false, sc.SecOpts.RequireClientCert, "ServerConfig.SecOpts.RequireClientCert should be false")
viper.Set("peer.tls.clientAuthRequired", true)
viper.Set("peer.tls.clientRootCAs.files", []string{
filepath.Join("testdata", "Org1-cert.pem"),
filepath.Join("testdata", "Org2-cert.pem"),
filepath.Join(tempdir, "org1-ca-cert.pem"),
filepath.Join(tempdir, "org2-ca-cert.pem"),
})
sc, _ = GetServerConfig()
assert.Equal(t, true, sc.SecOpts.RequireClientCert, "ServerConfig.SecOpts.RequireClientCert should be true")
assert.Equal(t, 2, len(sc.SecOpts.ClientRootCAs), "ServerConfig.SecOpts.ClientRootCAs should contain 2 entries")

// bad config with TLS
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org11-cert.pem"))
_, err := GetServerConfig()
viper.Set("peer.tls.rootcert.file", "non-existent-file.pem")
_, err = GetServerConfig()
assert.Error(t, err, "GetServerConfig should return error with bad root cert path")
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org11-cert.pem"))

viper.Set("peer.tls.rootcert.file", filepath.Join(tempdir, "org1-ca-cert.pem"))
viper.Set("peer.tls.cert.file", "non-existent-file.pem")
_, err = GetServerConfig()
assert.Error(t, err, "GetServerConfig should return error with bad tls cert path")

Expand All @@ -144,52 +171,65 @@ func TestGetServerConfig(t *testing.T) {
}

func TestGetClientCertificate(t *testing.T) {
tempdir, err := ioutil.TempDir("", "peer-clientcert")
assert.NoError(t, err)
defer os.RemoveAll(tempdir)

ca, err := tlsgen.NewCA()
assert.NoError(t, err)
kp, err := ca.NewServerCertKeyPair("localhost")
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tempdir, "server1-cert.pem"), kp.Cert, 0o644)
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tempdir, "server1-key.pem"), kp.Key, 0o600)
assert.NoError(t, err)

viper.Set("peer.tls.key.file", "")
viper.Set("peer.tls.cert.file", "")
viper.Set("peer.tls.clientKey.file", "")
viper.Set("peer.tls.clientCert.file", "")

// neither client nor server key pairs set - expect error
_, err := GetClientCertificate()
_, err = GetClientCertificate()
assert.Error(t, err)

viper.Set("peer.tls.key.file", "")
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
viper.Set("peer.tls.cert.file", filepath.Join(tempdir, "server1-cert.pem"))
// missing server key file - expect error
_, err = GetClientCertificate()
assert.Error(t, err)

viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
viper.Set("peer.tls.key.file", filepath.Join(tempdir, "server1-key.pem"))
viper.Set("peer.tls.cert.file", "")
// missing server cert file - expect error
_, err = GetClientCertificate()
assert.Error(t, err)

// set server TLS settings to ensure we get the client TLS settings
// when they are set properly
viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
viper.Set("peer.tls.key.file", filepath.Join(tempdir, "server1-key.pem"))
viper.Set("peer.tls.cert.file", filepath.Join(tempdir, "server1-cert.pem"))

// peer.tls.clientCert.file not set - expect error
viper.Set("peer.tls.clientKey.file", filepath.Join("testdata", "Org2-server1-key.pem"))
viper.Set("peer.tls.clientKey.file", filepath.Join(tempdir, "server1-key.pem"))
_, err = GetClientCertificate()
assert.Error(t, err)

// peer.tls.clientKey.file not set - expect error
viper.Set("peer.tls.clientKey.file", "")
viper.Set("peer.tls.clientCert.file", filepath.Join("testdata", "Org2-server1-cert.pem"))
viper.Set("peer.tls.clientCert.file", filepath.Join(tempdir, "server1-cert.pem"))
_, err = GetClientCertificate()
assert.Error(t, err)

// client auth required and clientKey/clientCert set
expected, err := tls.LoadX509KeyPair(
filepath.Join("testdata", "Org2-server1-cert.pem"),
filepath.Join("testdata", "Org2-server1-key.pem"),
filepath.Join(tempdir, "server1-cert.pem"),
filepath.Join(tempdir, "server1-key.pem"),
)
if err != nil {
t.Fatalf("Failed to load test certificate (%s)", err)
}
viper.Set("peer.tls.clientKey.file", filepath.Join("testdata", "Org2-server1-key.pem"))
viper.Set("peer.tls.clientKey.file", filepath.Join(tempdir, "server1-key.pem"))
cert, err := GetClientCertificate()
assert.NoError(t, err)
assert.Equal(t, expected, cert)
Expand All @@ -199,12 +239,10 @@ func TestGetClientCertificate(t *testing.T) {
viper.Set("peer.tls.clientKey.file", "")
viper.Set("peer.tls.clientCert.file", "")
expected, err = tls.LoadX509KeyPair(
filepath.Join("testdata", "Org1-server1-cert.pem"),
filepath.Join("testdata", "Org1-server1-key.pem"),
filepath.Join(tempdir, "server1-cert.pem"),
filepath.Join(tempdir, "server1-key.pem"),
)
if err != nil {
t.Fatalf("Failed to load test certificate (%s)", err)
}
assert.NoError(t, err, "failed to load test certificate")
cert, err = GetClientCertificate()
assert.NoError(t, err)
assert.Equal(t, expected, cert)
Expand Down
19 changes: 8 additions & 11 deletions core/peer/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric/bccsp/sw"
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
"github.com/hyperledger/fabric/common/crypto/tlsgen"
"github.com/hyperledger/fabric/common/metrics/disabled"
"github.com/hyperledger/fabric/core/committer/txvalidator/plugin"
"github.com/hyperledger/fabric/core/deliverservice"
Expand Down Expand Up @@ -123,27 +124,23 @@ func TestInitialize(t *testing.T) {
peerInstance, cleanup := NewTestPeer(t)
defer cleanup()

org1CA, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-cert.pem"))
org1CA, err := tlsgen.NewCA()
require.NoError(t, err)
org1Server1Key, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-server1-key.pem"))
require.NoError(t, err)
org1Server1Cert, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-server1-cert.pem"))
org1Server1KeyPair, err := org1CA.NewServerCertKeyPair("localhost", "127.0.0.1", "::1")
require.NoError(t, err)

serverConfig := comm.ServerConfig{
SecOpts: comm.SecureOptions{
UseTLS: true,
Certificate: org1Server1Cert,
Key: org1Server1Key,
ServerRootCAs: [][]byte{org1CA},
Certificate: org1Server1KeyPair.Cert,
Key: org1Server1KeyPair.Key,
ServerRootCAs: [][]byte{org1CA.CertBytes()},
RequireClientCert: true,
},
}

server, err := comm.NewGRPCServer("localhost:0", serverConfig)
if err != nil {
t.Fatalf("NewGRPCServer failed with error [%s]", err)
return
}
require.NoError(t, err, "failed to create gRPC server")

peerInstance.Initialize(
nil,
Expand Down
Loading

0 comments on commit 5f19a00

Please sign in to comment.