Skip to content

Commit

Permalink
[FAB-9238] Identity Config - Resolving paths/pems
Browse files Browse the repository at this point in the history
- unified separate functions for Path & Pems
into CAServerCerts, CAClientKey & CAClientCert
functions which will always return pem bytes.
- internal fabric-ca updated to use bytes instead
of paths


Change-Id: I99bc8b0e927d7ffb4ac3fcc1000ddb669c132548
Signed-off-by: Sudesh Shetty <sudesh.shetty@securekey.com>
  • Loading branch information
sudeshrshetty committed Apr 18, 2018
1 parent 19d80fe commit 95c8574
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 370 deletions.
5 changes: 0 additions & 5 deletions internal/github.com/hyperledger/fabric-ca/lib/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,6 @@ func (c *Client) initHTTPClient() error {
if c.Config.TLS.Enabled {
log.Info("TLS Enabled")

err := tls.AbsTLSClient(&c.Config.TLS, c.HomeDir)
if err != nil {
return err
}

tlsConfig, err2 := tls.GetClientTLSConfig(&c.Config.TLS, c.csp)
if err2 != nil {
return fmt.Errorf("Failed to get client TLS config: %s", err2)
Expand Down
66 changes: 7 additions & 59 deletions internal/github.com/hyperledger/fabric-ca/lib/tls/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ package tls
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"time"

"github.com/pkg/errors"
Expand All @@ -34,31 +33,17 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
)

// ServerTLSConfig defines key material for a TLS server
type ServerTLSConfig struct {
Enabled bool `help:"Enable TLS on the listening port"`
CertFile string `def:"tls-cert.pem" help:"PEM-encoded TLS certificate file for server's listening port"`
KeyFile string `help:"PEM-encoded TLS key for server's listening port"`
ClientAuth ClientAuth
}

// ClientAuth defines the key material needed to verify client certificates
type ClientAuth struct {
Type string `def:"noclientcert" help:"Policy the server will follow for TLS Client Authentication."`
CertFiles []string `help:"A list of comma-separated PEM-encoded trusted certificate files (e.g. root1.pem,root2.pem)"`
}

// ClientTLSConfig defines the key material for a TLS client
type ClientTLSConfig struct {
Enabled bool `skip:"true"`
CertFiles []string `help:"A list of comma-separated PEM-encoded trusted certificate files (e.g. root1.pem,root2.pem)"`
CertFiles [][]byte `help:"A list of comma-separated PEM-encoded trusted certificate bytes"`
Client KeyCertFiles
}

// KeyCertFiles defines the files need for client on TLS
type KeyCertFiles struct {
KeyFile string `help:"PEM-encoded key file when mutual authentication is enabled"`
CertFile string `help:"PEM-encoded certificate file when mutual authenticate is enabled"`
KeyFile []byte `help:"PEM-encoded key bytes when mutual authentication is enabled"`
CertFile []byte `help:"PEM-encoded certificate bytes when mutual authenticate is enabled"`
}

// GetClientTLSConfig creates a tls.Config object from certs and roots
Expand All @@ -69,11 +54,7 @@ func GetClientTLSConfig(cfg *ClientTLSConfig, csp core.CryptoSuite) (*tls.Config
csp = factory.GetDefault()
}

log.Debugf("CA Files: %+v\n", cfg.CertFiles)
log.Debugf("Client Cert File: %s\n", cfg.Client.CertFile)
log.Debugf("Client Key File: %s\n", cfg.Client.KeyFile)

if cfg.Client.CertFile != "" {
if cfg.Client.CertFile != nil {
err := checkCertDates(cfg.Client.CertFile)
if err != nil {
return nil, err
Expand All @@ -94,13 +75,9 @@ func GetClientTLSConfig(cfg *ClientTLSConfig, csp core.CryptoSuite) (*tls.Config
}

for _, cacert := range cfg.CertFiles {
caCert, err := ioutil.ReadFile(cacert)
if err != nil {
return nil, errors.Wrapf(err, "Failed to read '%s'", cacert)
}
ok := rootCAPool.AppendCertsFromPEM(caCert)
ok := rootCAPool.AppendCertsFromPEM(cacert)
if !ok {
return nil, errors.Errorf("Failed to process certificate from file %s", cacert)
return nil, errors.New("Failed to process certificate")
}
}

Expand All @@ -112,37 +89,8 @@ func GetClientTLSConfig(cfg *ClientTLSConfig, csp core.CryptoSuite) (*tls.Config
return config, nil
}

// AbsTLSClient makes TLS client files absolute
func AbsTLSClient(cfg *ClientTLSConfig, configDir string) error {
var err error

for i := 0; i < len(cfg.CertFiles); i++ {
cfg.CertFiles[i], err = util.MakeFileAbs(cfg.CertFiles[i], configDir)
if err != nil {
return err
}

}

cfg.Client.CertFile, err = util.MakeFileAbs(cfg.Client.CertFile, configDir)
if err != nil {
return err
}

cfg.Client.KeyFile, err = util.MakeFileAbs(cfg.Client.KeyFile, configDir)
if err != nil {
return err
}

return nil
}

func checkCertDates(certFile string) error {
func checkCertDates(certPEM []byte) error {
log.Debug("Check client TLS certificate for valid dates")
certPEM, err := ioutil.ReadFile(certFile)
if err != nil {
return errors.Wrapf(err, "Failed to read file '%s'", certFile)
}

cert, err := util.GetX509CertificateFromPEM(certPEM)
if err != nil {
Expand Down
16 changes: 7 additions & 9 deletions internal/github.com/hyperledger/fabric-ca/util/csp.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func ImportBCCSPKeyFromPEM(keyFile string, myCSP core.CryptoSuite, temporary boo
// ImportBCCSPKeyFromPEMBytes attempts to create a private BCCSP key from a pem byte slice
func ImportBCCSPKeyFromPEMBytes(keyBuff []byte, myCSP core.CryptoSuite, temporary bool) (core.Key, error) {
keyFile := "pem bytes"

key, err := factory.PEMtoPrivateKey(keyBuff, nil)
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("Failed parsing private key from %s", keyFile))
Expand Down Expand Up @@ -172,12 +173,9 @@ func ImportBCCSPKeyFromPEMBytes(keyBuff []byte, myCSP core.CryptoSuite, temporar
//
// This function originated from crypto/tls/tls.go and was adapted to use a
// BCCSP Signer
func LoadX509KeyPair(certFile, keyFile string, csp core.CryptoSuite) (*tls.Certificate, error) {
func LoadX509KeyPair(certFile, keyFile []byte, csp core.CryptoSuite) (*tls.Certificate, error) {

certPEMBlock, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, err
}
certPEMBlock := certFile

cert := &tls.Certificate{}
var skippedBlockTypes []string
Expand All @@ -196,10 +194,10 @@ func LoadX509KeyPair(certFile, keyFile string, csp core.CryptoSuite) (*tls.Certi

if len(cert.Certificate) == 0 {
if len(skippedBlockTypes) == 0 {
return nil, errors.Errorf("Failed to find PEM block in file %s", certFile)
return nil, errors.New("Failed to find PEM block in bytes")
}
if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
return nil, errors.Errorf("Failed to find certificate PEM data in file %s, but did find a private key; PEM inputs may have been switched", certFile)
return nil, errors.New("Failed to find certificate PEM data in bytes, but did find a private key; PEM inputs may have been switched")
}
return nil, errors.Errorf("Failed to find \"CERTIFICATE\" PEM block in file %s after skipping PEM blocks of the following types: %v", certFile, skippedBlockTypes)
}
Expand All @@ -211,10 +209,10 @@ func LoadX509KeyPair(certFile, keyFile string, csp core.CryptoSuite) (*tls.Certi

_, cert.PrivateKey, err = GetSignerFromCert(x509Cert, csp)
if err != nil {
if keyFile != "" {
if keyFile != nil {
log.Debugf("Could not load TLS certificate with BCCSP: %s", err)
log.Debugf("Attempting fallback with certfile %s and keyfile %s", certFile, keyFile)
fallbackCerts, err := tls.LoadX509KeyPair(certFile, keyFile)
fallbackCerts, err := tls.X509KeyPair(certFile, keyFile)
if err != nil {
return nil, errors.Wrapf(err, "Could not get the private key %s that matches %s", keyFile, certFile)
}
Expand Down
9 changes: 3 additions & 6 deletions pkg/common/providers/msp/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ type IdentityManagerProvider interface {
type IdentityConfig interface {
Client() (*ClientConfig, error)
CAConfig(org string) (*CAConfig, error)
CAServerCertPems(org string) ([]string, error)
CAServerCertPaths(org string) ([]string, error)
CAClientKeyPem(org string) (string, error)
CAClientKeyPath(org string) (string, error)
CAClientCertPem(org string) (string, error)
CAClientCertPath(org string) (string, error)
CAServerCerts(org string) ([][]byte, error)
CAClientKey(org string) ([]byte, error)
CAClientCert(org string) ([]byte, error)
CAKeyStorePath() string
CredentialStorePath() string
}
Expand Down
81 changes: 21 additions & 60 deletions pkg/common/providers/test/mockmsp/mockmsp.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 7 additions & 22 deletions pkg/fab/mocks/mockconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,34 +97,19 @@ func (c *MockConfig) CAConfig(org string) (*msp.CAConfig, error) {
return &caConfig, nil
}

//CAServerCertPems Read configuration option for the server certificate embedded pems
func (c *MockConfig) CAServerCertPems(org string) ([]string, error) {
//CAServerCerts Read configuration option for the server certificates for given org
func (c *MockConfig) CAServerCerts(org string) ([][]byte, error) {
return nil, nil
}

//CAServerCertPaths Read configuration option for the server certificate files
func (c *MockConfig) CAServerCertPaths(org string) ([]string, error) {
//CAClientKey Read configuration option for the fabric CA client key for given org
func (c *MockConfig) CAClientKey(org string) ([]byte, error) {
return nil, nil
}

//CAClientKeyPem Read configuration option for the fabric CA client key from a string
func (c *MockConfig) CAClientKeyPem(org string) (string, error) {
return "", nil
}

//CAClientKeyPath Read configuration option for the fabric CA client key file
func (c *MockConfig) CAClientKeyPath(org string) (string, error) {
return "", nil
}

//CAClientCertPem Read configuration option for the fabric CA client cert from a string
func (c *MockConfig) CAClientCertPem(org string) (string, error) {
return "", nil
}

//CAClientCertPath Read configuration option for the fabric CA client cert file
func (c *MockConfig) CAClientCertPath(org string) (string, error) {
return "", nil
//CAClientCert Read configuration option for the fabric CA client cert for given org
func (c *MockConfig) CAClientCert(org string) ([]byte, error) {
return nil, nil
}

//TimeoutOrDefault not implemented
Expand Down
22 changes: 11 additions & 11 deletions pkg/msp/caclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func TestCAServerCertPathsError(t *testing.T) {
mockIdentityConfig := mockmspApi.NewMockIdentityConfig(mockCtrl)
mockIdentityConfig.EXPECT().CAConfig(org1).Return(&msp.CAConfig{}, nil).AnyTimes()
mockIdentityConfig.EXPECT().CredentialStorePath().Return(dummyUserStorePath).AnyTimes()
mockIdentityConfig.EXPECT().CAServerCertPaths(org1).Return(nil, errors.New("CAServerCertPaths error"))
mockIdentityConfig.EXPECT().CAServerCerts(org1).Return(nil, errors.New("CAServerCerts error"))

mockContext := mockcontext.NewMockClient(mockCtrl)
mockContext.EXPECT().EndpointConfig().Return(f.endpointConfig).AnyTimes()
Expand All @@ -336,7 +336,7 @@ func TestCAServerCertPathsError(t *testing.T) {
mockContext.EXPECT().CryptoSuite().Return(f.cryptoSuite).AnyTimes()

_, err := NewCAClient(org1, mockContext)
if err == nil || !strings.Contains(err.Error(), "CAServerCertPaths error") {
if err == nil || !strings.Contains(err.Error(), "CAServerCerts error") {
t.Fatalf("Expected error from CAServerCertPaths. Got: %v", err)
}
}
Expand All @@ -353,8 +353,8 @@ func TestCAClientCertPathError(t *testing.T) {
mockIdentityConfig := mockmspApi.NewMockIdentityConfig(mockCtrl)
mockIdentityConfig.EXPECT().CAConfig(org1).Return(&msp.CAConfig{}, nil).AnyTimes()
mockIdentityConfig.EXPECT().CredentialStorePath().Return(dummyUserStorePath).AnyTimes()
mockIdentityConfig.EXPECT().CAServerCertPaths(org1).Return([]string{"test"}, nil)
mockIdentityConfig.EXPECT().CAClientCertPath(org1).Return("", errors.New("CAClientCertPath error"))
mockIdentityConfig.EXPECT().CAServerCerts(org1).Return([][]byte{[]byte("test")}, nil)
mockIdentityConfig.EXPECT().CAClientCert(org1).Return(nil, errors.New("CAClientCertPath error"))

mockContext := mockcontext.NewMockClient(mockCtrl)
mockContext.EXPECT().EndpointConfig().Return(f.endpointConfig).AnyTimes()
Expand All @@ -381,9 +381,9 @@ func TestCAClientKeyPathError(t *testing.T) {
mockIdentityConfig := mockmspApi.NewMockIdentityConfig(mockCtrl)
mockIdentityConfig.EXPECT().CAConfig(org1).Return(&msp.CAConfig{}, nil).AnyTimes()
mockIdentityConfig.EXPECT().CredentialStorePath().Return(dummyUserStorePath).AnyTimes()
mockIdentityConfig.EXPECT().CAServerCertPaths(org1).Return([]string{"test"}, nil)
mockIdentityConfig.EXPECT().CAClientCertPath(org1).Return("", nil)
mockIdentityConfig.EXPECT().CAClientKeyPath(org1).Return("", errors.New("CAClientKeyPath error"))
mockIdentityConfig.EXPECT().CAServerCerts(org1).Return([][]byte{[]byte("test")}, nil)
mockIdentityConfig.EXPECT().CAClientCert(org1).Return([]byte(""), nil)
mockIdentityConfig.EXPECT().CAClientKey(org1).Return(nil, errors.New("CAClientKeyPath error"))

mockContext := mockcontext.NewMockClient(mockCtrl)
mockContext.EXPECT().EndpointConfig().Return(f.endpointConfig).AnyTimes()
Expand Down Expand Up @@ -472,13 +472,13 @@ func getNoRegistrarBackend() (*mocks.MockConfigBackend, error) {
}

//tamper URLs
ca1Config := networkConfig.CertificateAuthorities["ca.org1.example.com"]
ca1Config := networkConfig.CertificateAuthorities["local.ca.org1.example.com"]
ca1Config.Registrar = msp.EnrollCredentials{}
ca2Config := networkConfig.CertificateAuthorities["ca.org2.example.com"]
ca2Config := networkConfig.CertificateAuthorities["local.ca.org2.example.com"]
ca1Config.Registrar = msp.EnrollCredentials{}

networkConfig.CertificateAuthorities["ca.org1.example.com"] = ca1Config
networkConfig.CertificateAuthorities["ca.org2.example.com"] = ca2Config
networkConfig.CertificateAuthorities["local.ca.org1.example.com"] = ca1Config
networkConfig.CertificateAuthorities["local.ca.org2.example.com"] = ca2Config

//Override backend with this new CertificateAuthorities config
mockConfigBackend.KeyValueMap["certificateAuthorities"] = networkConfig.CertificateAuthorities
Expand Down
Loading

0 comments on commit 95c8574

Please sign in to comment.