diff --git a/pkg/common/providers/fab/network.go b/pkg/common/providers/fab/network.go index 4ae2cd4c7b..0659dd04fb 100644 --- a/pkg/common/providers/fab/network.go +++ b/pkg/common/providers/fab/network.go @@ -23,7 +23,6 @@ type NetworkConfig struct { Orderers map[string]OrdererConfig Peers map[string]PeerConfig CertificateAuthorities map[string]msp.CAConfig - EntityMatchers map[string][]MatchConfig } // ChannelNetworkConfig provides the definition of channels for the network diff --git a/pkg/common/providers/fab/provider.go b/pkg/common/providers/fab/provider.go index fa39c3ed0c..8644e61b35 100644 --- a/pkg/common/providers/fab/provider.go +++ b/pkg/common/providers/fab/provider.go @@ -80,8 +80,6 @@ type CommManager interface { //EndpointConfig contains endpoint network configurations type EndpointConfig interface { Timeout(TimeoutType) time.Duration - MSPID(org string) (string, bool) - PeerMSPID(name string) (string, bool) OrderersConfig() ([]OrdererConfig, bool) OrdererConfig(nameOrURL string) (*OrdererConfig, bool) PeersConfig(org string) ([]PeerConfig, bool) diff --git a/pkg/common/providers/test/mockfab/mockfab.gen.go b/pkg/common/providers/test/mockfab/mockfab.gen.go index a7ae351cd8..91be39bd7c 100644 --- a/pkg/common/providers/test/mockfab/mockfab.gen.go +++ b/pkg/common/providers/test/mockfab/mockfab.gen.go @@ -101,19 +101,6 @@ func (mr *MockEndpointConfigMockRecorder) EventServiceType() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventServiceType", reflect.TypeOf((*MockEndpointConfig)(nil).EventServiceType)) } -// MSPID mocks base method -func (m *MockEndpointConfig) MSPID(arg0 string) (string, bool) { - ret := m.ctrl.Call(m, "MSPID", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// MSPID indicates an expected call of MSPID -func (mr *MockEndpointConfigMockRecorder) MSPID(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MSPID", reflect.TypeOf((*MockEndpointConfig)(nil).MSPID), arg0) -} - // NetworkConfig mocks base method func (m *MockEndpointConfig) NetworkConfig() (*fab.NetworkConfig, bool) { ret := m.ctrl.Call(m, "NetworkConfig") @@ -179,19 +166,6 @@ func (mr *MockEndpointConfigMockRecorder) PeerConfig(arg0 interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerConfig", reflect.TypeOf((*MockEndpointConfig)(nil).PeerConfig), arg0) } -// PeerMSPID mocks base method -func (m *MockEndpointConfig) PeerMSPID(arg0 string) (string, bool) { - ret := m.ctrl.Call(m, "PeerMSPID", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// PeerMSPID indicates an expected call of PeerMSPID -func (mr *MockEndpointConfigMockRecorder) PeerMSPID(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerMSPID", reflect.TypeOf((*MockEndpointConfig)(nil).PeerMSPID), arg0) -} - // PeersConfig mocks base method func (m *MockEndpointConfig) PeersConfig(arg0 string) ([]fab.PeerConfig, bool) { ret := m.ctrl.Call(m, "PeersConfig", arg0) diff --git a/pkg/core/config/endpoint/endpoint.go b/pkg/core/config/endpoint/endpoint.go index c4a232127e..65bc9669c9 100644 --- a/pkg/core/config/endpoint/endpoint.go +++ b/pkg/core/config/endpoint/endpoint.go @@ -77,43 +77,40 @@ type TLSConfig struct { // If Path is available, then it will be used to load the cert // if Pem is available, then it has the raw data of the cert it will be used as-is // Certificate root certificate path + // If both Path and Pem are available, pem takes the precedence Path string // Certificate actual content Pem string + //bytes from Pem/Path + bytes []byte } -// Bytes returns the tls certificate as a byte array by loading it either from the embedded Pem or Path -func (cfg TLSConfig) Bytes() ([]byte, error) { - var bytes []byte - var err error +// Bytes returns the tls certificate as a byte array +func (cfg *TLSConfig) Bytes() []byte { + return cfg.bytes +} +//LoadBytes preloads bytes from Pem/Path +//Pem takes precedence over Path +//TODO to be removed since separate TLSConfig should only be used in parsing +func (cfg *TLSConfig) LoadBytes() error { + var err error if cfg.Pem != "" { - bytes = []byte(cfg.Pem) + cfg.bytes = []byte(cfg.Pem) } else if cfg.Path != "" { - bytes, err = ioutil.ReadFile(cfg.Path) - + cfg.bytes, err = ioutil.ReadFile(cfg.Path) if err != nil { - return nil, errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path) + return errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path) } } - - return bytes, nil + return nil } // TLSCert returns the tls certificate as a *x509.Certificate by loading it either from the embedded Pem or Path -func (cfg TLSConfig) TLSCert() (*x509.Certificate, error) { - bytes, err := cfg.Bytes() - - if err != nil { - return nil, err - } - - return loadCert(bytes) -} +//TODO to be removed since separate TLSConfig should only be used in parsing +func (cfg *TLSConfig) TLSCert() (*x509.Certificate, error) { -// loadCAKey -func loadCert(rawData []byte) (*x509.Certificate, error) { - block, _ := pem.Decode(rawData) + block, _ := pem.Decode(cfg.bytes) if block != nil { pub, err := x509.ParseCertificate(block.Bytes) diff --git a/pkg/core/config/endpoint/endpoint_test.go b/pkg/core/config/endpoint/endpoint_test.go index c5029e7ae9..a2915c160c 100644 --- a/pkg/core/config/endpoint/endpoint_test.go +++ b/pkg/core/config/endpoint/endpoint_test.go @@ -9,6 +9,8 @@ package endpoint import ( "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestIsTLSEnabled(t *testing.T) { @@ -105,10 +107,11 @@ O94CDp7l2k7hMQI0zQ== Pem: pPem, } - b, e := tlsConfig.Bytes() + e := tlsConfig.LoadBytes() if e != nil { t.Fatalf("error loading bytes for sample cert %s", e) } + b := tlsConfig.Bytes() if len(b) == 0 { t.Fatalf("cert's Bytes() call returned empty byte array") } @@ -118,20 +121,23 @@ O94CDp7l2k7hMQI0zQ== // test with empty pem tlsConfig.Pem = "" - b, e = tlsConfig.Bytes() + tlsConfig.Path = "../testdata/config_test.yaml" + e = tlsConfig.LoadBytes() if e != nil { t.Fatalf("error loading bytes for empty pem cert %s", e) } - if len(b) > 0 { - t.Fatalf("cert's Bytes() call returned non empty byte array for empty pem") + b = tlsConfig.Bytes() + if len(b) == 0 { + t.Fatalf("cert's Bytes() call returned empty byte array") } // test with wrong pem tlsConfig.Pem = "wrongpemvalue" - b, e = tlsConfig.Bytes() + e = tlsConfig.LoadBytes() if e != nil { t.Fatalf("error loading bytes for wrong pem cert %s", e) } + b = tlsConfig.Bytes() if len(b) != len([]byte("wrongpemvalue")) { t.Fatalf("cert's Bytes() call returned different byte array for wrong pem") } @@ -143,6 +149,11 @@ func TestTLSConfig_TLSCertPostive(t *testing.T) { Pem: "", } + e := tlsConfig.LoadBytes() + if e != nil { + t.Fatalf("error loading certificate for sample cert path %s", e) + } + c, e := tlsConfig.TLSCert() if e != nil { t.Fatalf("error loading certificate for sample cert path %s", e) @@ -215,3 +226,35 @@ func TestTLSConfig_TLSCertNegative(t *testing.T) { } } + +func TestTLSConfigBytes(t *testing.T) { + + // test with wrong path + tlsConfig := &TLSConfig{ + Path: "../testdata/config_test.yaml", + Pem: "", + } + + err := tlsConfig.LoadBytes() + bytes1 := tlsConfig.Bytes() + assert.Nil(t, err, "tlsConfig.Bytes supposed to succeed") + assert.NotEmpty(t, bytes1, "supposed to get valid bytes") + + tlsConfig.Path = "../testdata/config_test_pem.yaml" + bytes2 := tlsConfig.Bytes() + assert.Nil(t, err, "tlsConfig.Bytes supposed to succeed") + assert.NotEmpty(t, bytes2, "supposed to get valid bytes") + + //even after changing path, it should return previous bytes + assert.Equal(t, bytes1, bytes2, "any update to tlsconfig path after load bytes call should not take effect") + + //call preload now + err = tlsConfig.LoadBytes() + bytes2 = tlsConfig.Bytes() + assert.Nil(t, err, "tlsConfig.Bytes supposed to succeed") + assert.NotEmpty(t, bytes2, "supposed to get valid bytes") + + //even after changing path, it should return previous bytes + assert.NotEqual(t, bytes1, bytes2, "tlsConfig.LoadBytes() should refresh bytes") + +} diff --git a/pkg/core/config/lookup/lookup_test.go b/pkg/core/config/lookup/lookup_test.go index cee0618981..cdeae34c7f 100644 --- a/pkg/core/config/lookup/lookup_test.go +++ b/pkg/core/config/lookup/lookup_test.go @@ -31,6 +31,10 @@ const orgChannelID = "orgchannel" var backend *mocks.MockConfigBackend +type testEntityMatchers struct { + matchers map[string][]fab.MatchConfig +} + func TestMain(m *testing.M) { backend = setupCustomBackend("key") r := m.Run() @@ -227,10 +231,12 @@ func TestUnmarshalWithMultipleBackend(t *testing.T) { //output struct networkConfig := fab.NetworkConfig{} + entityMatchers := testEntityMatchers{} + assert.Nil(t, testLookup.UnmarshalKey("client", &networkConfig.Client), "unmarshalKey supposed to succeed") assert.Nil(t, testLookup.UnmarshalKey("channels", &networkConfig.Channels), "unmarshalKey supposed to succeed") assert.Nil(t, testLookup.UnmarshalKey("certificateAuthorities", &networkConfig.CertificateAuthorities), "unmarshalKey supposed to succeed") - assert.Nil(t, testLookup.UnmarshalKey("entityMatchers", &networkConfig.EntityMatchers), "unmarshalKey supposed to succeed") + assert.Nil(t, testLookup.UnmarshalKey("entityMatchers", &entityMatchers.matchers), "unmarshalKey supposed to succeed") assert.Nil(t, testLookup.UnmarshalKey("organizations", &networkConfig.Organizations), "unmarshalKey supposed to succeed") assert.Nil(t, testLookup.UnmarshalKey("orderers", &networkConfig.Orderers), "unmarshalKey supposed to succeed") assert.Nil(t, testLookup.UnmarshalKey("peers", &networkConfig.Peers), "unmarshalKey supposed to succeed") @@ -253,15 +259,15 @@ func TestUnmarshalWithMultipleBackend(t *testing.T) { assert.Equal(t, networkConfig.CertificateAuthorities["local.ca.org2.example.com"].URL, "https://ca.org2.example.com:8054") //EntityMatchers - assert.Equal(t, len(networkConfig.EntityMatchers), 4) - assert.Equal(t, len(networkConfig.EntityMatchers["peer"]), 8) - assert.Equal(t, networkConfig.EntityMatchers["peer"][0].MappedHost, "local.peer0.org1.example.com") - assert.Equal(t, len(networkConfig.EntityMatchers["orderer"]), 4) - assert.Equal(t, networkConfig.EntityMatchers["orderer"][0].MappedHost, "local.orderer.example.com") - assert.Equal(t, len(networkConfig.EntityMatchers["certificateauthority"]), 2) - assert.Equal(t, networkConfig.EntityMatchers["certificateauthority"][0].MappedHost, "local.ca.org1.example.com") - assert.Equal(t, len(networkConfig.EntityMatchers["channel"]), 1) - assert.Equal(t, networkConfig.EntityMatchers["channel"][0].MappedName, "ch1") + assert.Equal(t, len(entityMatchers.matchers), 4) + assert.Equal(t, len(entityMatchers.matchers["peer"]), 8) + assert.Equal(t, entityMatchers.matchers["peer"][0].MappedHost, "local.peer0.org1.example.com") + assert.Equal(t, len(entityMatchers.matchers["orderer"]), 4) + assert.Equal(t, entityMatchers.matchers["orderer"][0].MappedHost, "local.orderer.example.com") + assert.Equal(t, len(entityMatchers.matchers["certificateauthority"]), 2) + assert.Equal(t, entityMatchers.matchers["certificateauthority"][0].MappedHost, "local.ca.org1.example.com") + assert.Equal(t, len(entityMatchers.matchers["channel"]), 1) + assert.Equal(t, entityMatchers.matchers["channel"][0].MappedName, "ch1") //Organizations assert.Equal(t, len(networkConfig.Organizations), 3) @@ -331,15 +337,17 @@ func TestLookupUnmarshalAgainstViperUnmarshal(t *testing.T) { /* TEST NETWORK CONFIG ENTITY MATCHERS */ + entityMatchers := testEntityMatchers{} //get entityMatchers backend lookup - err = testLookup.UnmarshalKey("entityMatchers", &networkConfig.EntityMatchers) + err = testLookup.UnmarshalKey("entityMatchers", &entityMatchers.matchers) if err != nil { t.Fatal(err) } //get entityMatchers from viper - sampleViper.UnmarshalKey("entityMatchers", &networkConfigViper.EntityMatchers) + viperEntityMatchers := testEntityMatchers{} + sampleViper.UnmarshalKey("entityMatchers", &viperEntityMatchers.matchers) //now compare - assert.True(t, reflect.DeepEqual(&networkConfig.EntityMatchers, &networkConfigViper.EntityMatchers), "unmarshalled value from config lookup supposed to match unmarshalled value from viper") + assert.True(t, reflect.DeepEqual(&entityMatchers, &viperEntityMatchers), "unmarshalled value from config lookup supposed to match unmarshalled value from viper") /* TEST NETWORK CONFIG ORGANIZATIONS @@ -382,10 +390,10 @@ func TestLookupUnmarshalAgainstViperUnmarshal(t *testing.T) { //Just to make sure that empty values are not being compared assert.True(t, len(networkConfigViper.Channels) > 0, "expected to get valid unmarshalled value") - assert.True(t, len(networkConfigViper.Organizations) > 0, "expected to get valid unmarshalled value") + assert.True(t, len(viperEntityMatchers.matchers) > 0, "expected to get valid unmarshalled value") assert.True(t, len(networkConfigViper.Orderers) > 0, "expected to get valid unmarshalled value") assert.True(t, len(networkConfigViper.Peers) > 0, "expected to get valid unmarshalled value") - assert.True(t, len(networkConfigViper.EntityMatchers) > 0, "expected to get valid unmarshalled value") + assert.True(t, len(entityMatchers.matchers) > 0, "expected to get valid unmarshalled value") assert.True(t, networkConfigViper.Client.Organization != "", "expected to get valid unmarshalled value") } diff --git a/pkg/core/config/testdata/config_test.yaml b/pkg/core/config/testdata/config_test.yaml index 0fb7590b2b..f6a771f427 100755 --- a/pkg/core/config/testdata/config_test.yaml +++ b/pkg/core/config/testdata/config_test.yaml @@ -330,4 +330,5 @@ certificateAuthorities: enrollId: admin enrollSecret: adminpw # [Optional] The optional name of the CA. - caName: ca.org2.example.com \ No newline at end of file + caName: ca.org2.example.com + #first one \ No newline at end of file diff --git a/pkg/core/config/testdata/config_test_pem.yaml b/pkg/core/config/testdata/config_test_pem.yaml index fd3c8600fd..5e87ae6863 100755 --- a/pkg/core/config/testdata/config_test_pem.yaml +++ b/pkg/core/config/testdata/config_test_pem.yaml @@ -382,3 +382,4 @@ certificateAuthorities: enrollSecret: adminpw # [Optional] The optional name of the CA. caName: ca.org2.example.com +#second one \ No newline at end of file diff --git a/pkg/fab/comm/network.go b/pkg/fab/comm/network.go index 0be95a2f53..a7f15162ac 100644 --- a/pkg/fab/comm/network.go +++ b/pkg/fab/comm/network.go @@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package comm import ( + "strings" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/pkg/errors" ) @@ -63,3 +65,18 @@ func SearchPeerConfigFromURL(cfg fab.EndpointConfig, url string) (*fab.PeerConfi return nil, errors.Errorf("unable to get peerconfig for given url : %s", url) } + +// MSPID returns the MSP ID for the requested organization +func MSPID(cfg fab.EndpointConfig, org string) (string, bool) { + networkConfig, ok := cfg.NetworkConfig() + if !ok { + return "", false + } + // viper lowercases all key maps, org is lower case + mspID := networkConfig.Organizations[strings.ToLower(org)].MSPID + if mspID == "" { + return "", false + } + + return mspID, true +} diff --git a/pkg/fab/comm/network_test.go b/pkg/fab/comm/network_test.go index e5952221cc..74deabcac4 100644 --- a/pkg/fab/comm/network_test.go +++ b/pkg/fab/comm/network_test.go @@ -88,3 +88,24 @@ func TestSearchPeerConfigFromURL(t *testing.T) { assert.Equal(t, peer0Org1.EventURL, peerConfig.EventURL) } + +func TestMSPID(t *testing.T) { + configBackend, err := config.FromFile(configTestFilePath)() + if err != nil { + t.Fatalf("Unexpected error reading config backend: %v", err) + } + + sampleConfig, err := fabImpl.ConfigFromBackend(configBackend...) + if err != nil { + t.Fatalf("Unexpected error reading config: %v", err) + } + + mspID, ok := MSPID(sampleConfig, "invalid") + assert.False(t, ok, "supposed to fail for invalid org name") + assert.Empty(t, mspID, "supposed to get valid MSP ID") + + mspID, ok = MSPID(sampleConfig, "org1") + assert.True(t, ok, "supposed to pass with valid org name") + assert.NotEmpty(t, mspID, "supposed to get valid MSP ID") + assert.Equal(t, "Org1MSP", mspID, "supposed to get valid MSP ID") +} diff --git a/pkg/fab/endpointconfig.go b/pkg/fab/endpointconfig.go index d462fdf92f..ec13a03181 100644 --- a/pkg/fab/endpointconfig.go +++ b/pkg/fab/endpointconfig.go @@ -9,7 +9,6 @@ package fab import ( "crypto/tls" "crypto/x509" - "io/ioutil" "reflect" "regexp" "sort" @@ -52,8 +51,7 @@ const ( defaultChannelConfigRefreshInterval = time.Second * 90 defaultChannelMemshpRefreshInterval = time.Second * 60 defaultDiscoveryRefreshInterval = time.Second * 10 - - defaultCacheSweepInterval = time.Second * 15 + defaultCacheSweepInterval = time.Second * 15 ) //ConfigFromBackend returns endpoint config implementation for given backend @@ -99,58 +97,23 @@ type EndpointConfig struct { backend *lookup.ConfigLookup networkConfig *fab.NetworkConfig tlsCertPool commtls.CertPool + entityMatchers *entityMatchers peerMatchers map[int]*regexp.Regexp ordererMatchers map[int]*regexp.Regexp channelMatchers map[int]*regexp.Regexp } +//entityMatchers for endpoint configuration +type entityMatchers struct { + matchers map[string][]fab.MatchConfig +} + // Timeout reads timeouts for the given timeout type, if type is not found in the config // then default is set as per the const value above for the corresponding type func (c *EndpointConfig) Timeout(tType fab.TimeoutType) time.Duration { return c.getTimeout(tType) } -// MSPID returns the MSP ID for the requested organization -func (c *EndpointConfig) MSPID(org string) (string, bool) { - config, ok := c.NetworkConfig() - if !ok { - return "", false - } - // viper lowercases all key maps, org is lower case - mspID := config.Organizations[strings.ToLower(org)].MSPID - if mspID == "" { - return "", false - } - - return mspID, true -} - -// PeerMSPID returns msp that peer belongs to -func (c *EndpointConfig) PeerMSPID(name string) (string, bool) { - netConfig, ok := c.NetworkConfig() - if !ok { - return "", false - } - - // Find organisation/msp that peer belongs to - for _, org := range netConfig.Organizations { - for i := 0; i < len(org.Peers); i++ { - if strings.EqualFold(org.Peers[i], name) { - // peer belongs to this org add org msp - return org.MSPID, true - } - - peer, ok := c.findMatchingPeer(org.Peers[i]) - if ok && strings.EqualFold(peer, name) { - return org.MSPID, true - } - } - } - - return "", false - -} - // OrderersConfig returns a list of defined orderers func (c *EndpointConfig) OrderersConfig() ([]fab.OrdererConfig, bool) { @@ -168,11 +131,13 @@ func (c *EndpointConfig) OrderersConfig() ([]fab.OrdererConfig, bool) { orderer = *matchedOrderer } - if orderer.TLSCACerts.Path != "" { - orderer.TLSCACerts.Path = pathvar.Subst(orderer.TLSCACerts.Path) - } else if len(orderer.TLSCACerts.Pem) == 0 && !c.backend.GetBool("client.tlsCerts.systemCertPool") { - logger.Debugf("Orderer has no certs configured. Make sure TLSCACerts.Pem or TLSCACerts.Path is set for %s", orderer.URL) - return nil, false + if len(orderer.TLSCACerts.Bytes()) == 0 && !c.backend.GetBool("client.tlsCerts.systemCertPool") { + //check for TLS config only if secured connection is enabled + allowInSecure := orderer.GRPCOptions["allow-insecure"] == true + if endpoint.AttemptSecured(orderer.URL, allowInSecure) { + logger.Debugf("Orderer has no certs configured. Make sure TLSCACerts.Pem or TLSCACerts.Path is set for %s", orderer.URL) + return nil, false + } } orderers = append(orderers, orderer) } @@ -212,10 +177,6 @@ func (c *EndpointConfig) OrdererConfig(nameOrURL string) (*fab.OrdererConfig, bo orderer = *matchingOrdererConfig } - if orderer.TLSCACerts.Path != "" { - orderer.TLSCACerts.Path = pathvar.Subst(orderer.TLSCACerts.Path) - } - return &orderer, true } @@ -242,10 +203,6 @@ func (c *EndpointConfig) PeersConfig(org string) ([]fab.PeerConfig, bool) { logger.Debugf("Found a matchingPeerConfig for [%s]", peerName) p = *matchingPeerConfig } - if p.TLSCACerts.Path != "" { - p.TLSCACerts.Path = pathvar.Subst(p.TLSCACerts.Path) - } - peers = append(peers, p) } @@ -295,10 +252,6 @@ func (c *EndpointConfig) PeerConfig(nameOrURL string) (*fab.PeerConfig, bool) { logger.Debugf("Found MatchingPeerConfig for name/url [%s]", nameOrURL) - if matchPeerConfig.TLSCACerts.Path != "" { - matchPeerConfig.TLSCACerts.Path = pathvar.Subst(peerConfig.TLSCACerts.Path) - } - return matchPeerConfig, true } @@ -364,7 +317,7 @@ func (c *EndpointConfig) mappedChannelName(networkConfig *fab.NetworkConfig, cha v := c.channelMatchers[k] if v.MatchString(channelName) { // get the matching matchConfig from the index number - channelMatchConfig := networkConfig.EntityMatchers["channel"][k] + channelMatchConfig := c.entityMatchers.matchers["channel"][k] return channelMatchConfig.MappedName } } @@ -431,11 +384,7 @@ func (c *EndpointConfig) ChannelPeers(name string) ([]fab.ChannelPeer, bool) { return nil, false } - if p.TLSCACerts.Path != "" { - p.TLSCACerts.Path = pathvar.Subst(p.TLSCACerts.Path) - } - - mspID, ok := c.PeerMSPID(peerName) + mspID, ok := c.peerMSPID(peerName) if !ok { return nil, false } @@ -495,17 +444,13 @@ func (c *EndpointConfig) EventServiceType() fab.EventServiceType { // TLSClientCerts loads the client's certs for mutual TLS // It checks the config for embedded pem files before looking for cert files func (c *EndpointConfig) TLSClientCerts() ([]tls.Certificate, error) { - clientConfig, err := c.client() - if err != nil { - return nil, err - } - var clientCerts tls.Certificate - var cb []byte - cb, err = clientConfig.TLSCerts.Client.Cert.Bytes() - if err != nil { - return nil, errors.Wrapf(err, "failed to load tls client cert") + networkConfig, ok := c.NetworkConfig() + if !ok { + return nil, errors.New("failed to get network config") } + var clientCerts tls.Certificate + cb := networkConfig.Client.TLSCerts.Client.Cert.Bytes() if len(cb) == 0 { // if no cert found in the config, return empty cert chain return []tls.Certificate{clientCerts}, nil @@ -518,7 +463,7 @@ func (c *EndpointConfig) TLSClientCerts() ([]tls.Certificate, error) { // If CryptoSuite fails to load private key from cert then load private key from config if err != nil || pk == nil { logger.Debugf("Reading pk from config, unable to retrieve from cert: %s", err) - return c.loadPrivateKeyFromConfig(clientConfig, clientCerts, cb) + return c.loadPrivateKeyFromConfig(&networkConfig.Client, clientCerts, cb) } // private key was retrieved from cert @@ -531,19 +476,11 @@ func (c *EndpointConfig) TLSClientCerts() ([]tls.Certificate, error) { } func (c *EndpointConfig) loadPrivateKeyFromConfig(clientConfig *msp.ClientConfig, clientCerts tls.Certificate, cb []byte) ([]tls.Certificate, error) { - var kb []byte - var err error - if clientConfig.TLSCerts.Client.Key.Pem != "" { - kb = []byte(clientConfig.TLSCerts.Client.Key.Pem) - } else if clientConfig.TLSCerts.Client.Key.Path != "" { - kb, err = loadByteKeyOrCertFromFile(clientConfig, true) - if err != nil { - return nil, errors.Wrapf(err, "Failed to load key from file path '%s'", clientConfig.TLSCerts.Client.Key.Path) - } - } + + kb := clientConfig.TLSCerts.Client.Key.Bytes() // load the key/cert pair from []byte - clientCerts, err = tls.X509KeyPair(cb, kb) + clientCerts, err := tls.X509KeyPair(cb, kb) if err != nil { return nil, errors.Errorf("Error loading cert/key pair as TLS client credentials: %v", err) } @@ -658,6 +595,7 @@ func (c *EndpointConfig) getTimeout(tType fab.TimeoutType) time.Duration { //nol } func (c *EndpointConfig) loadNetworkConfiguration() error { + networkConfig := fab.NetworkConfig{} networkConfig.Name = c.backend.GetString("name") networkConfig.Description = c.backend.GetString("description") @@ -699,16 +637,144 @@ func (c *EndpointConfig) loadNetworkConfiguration() error { return errors.WithMessage(err, "failed to parse 'certificateAuthorities' config item to networkConfig.CertificateAuthorities type") } - err = c.backend.UnmarshalKey("entityMatchers", &networkConfig.EntityMatchers) - logger.Debugf("Matchers are: %+v", networkConfig.EntityMatchers) + err = c.preLoadAllTLSConfig(&networkConfig) if err != nil { - return errors.WithMessage(err, "failed to parse 'entityMatchers' config item to networkConfig.EntityMatchers type") + return errors.WithMessage(err, "failed to load network TLSConfig ") } c.networkConfig = &networkConfig return nil } +//preLoadAllTLSConfig pre-loads all network TLS Configs +func (c *EndpointConfig) preLoadAllTLSConfig(networkConfig *fab.NetworkConfig) error { + err := c.preLoadClientTLSConfig(networkConfig) + if err != nil { + return errors.WithMessage(err, "failed to load client TLSConfig ") + } + + err = c.preLoadOrgTLSConfig(networkConfig) + if err != nil { + return errors.WithMessage(err, "failed to load org TLSConfig ") + } + + err = c.preLoadOrdererPeerTLSConfig(networkConfig) + if err != nil { + return errors.WithMessage(err, "failed to load orderer/peer TLSConfig ") + } + + err = c.preLoadCATLSConfig(networkConfig) + if err != nil { + return errors.WithMessage(err, "failed to load CA TLSConfig ") + } + + return nil +} + +//preLoadClientTLSConfig pre-loads all TLSConfig bytes in client config +func (c *EndpointConfig) preLoadClientTLSConfig(networkConfig *fab.NetworkConfig) error { + //Clients Config + //resolve paths and org name + networkConfig.Client.Organization = strings.ToLower(networkConfig.Client.Organization) + networkConfig.Client.TLSCerts.Path = pathvar.Subst(networkConfig.Client.TLSCerts.Path) + networkConfig.Client.TLSCerts.Client.Key.Path = pathvar.Subst(networkConfig.Client.TLSCerts.Client.Key.Path) + networkConfig.Client.TLSCerts.Client.Cert.Path = pathvar.Subst(networkConfig.Client.TLSCerts.Client.Cert.Path) + + //pre load client key and cert bytes + err := networkConfig.Client.TLSCerts.Client.Key.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load client key") + } + + err = networkConfig.Client.TLSCerts.Client.Cert.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load client cert") + } + + return nil +} + +//preLoadOrgTLSConfig pre-loads all TLSConfig bytes in organizations +func (c *EndpointConfig) preLoadOrgTLSConfig(networkConfig *fab.NetworkConfig) error { + + //Organizations Config + for org, orgConfig := range networkConfig.Organizations { + for user, userConfig := range orgConfig.Users { + //resolve paths + userConfig.Key.Path = pathvar.Subst(userConfig.Key.Path) + userConfig.Cert.Path = pathvar.Subst(userConfig.Cert.Path) + //pre load key and cert bytes + err := userConfig.Key.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load org key") + } + + err = userConfig.Cert.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load org cert") + } + orgConfig.Users[user] = userConfig + } + networkConfig.Organizations[org] = orgConfig + } + + return nil +} + +//preLoadTLSConfig pre-loads all TLSConfig bytes in Orderer and Peer configs +func (c *EndpointConfig) preLoadOrdererPeerTLSConfig(networkConfig *fab.NetworkConfig) error { + + //Orderers Config + for orderer, ordererConfig := range networkConfig.Orderers { + //resolve paths + ordererConfig.TLSCACerts.Path = pathvar.Subst(ordererConfig.TLSCACerts.Path) + //pre load key and cert bytes + err := ordererConfig.TLSCACerts.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load orderer cert") + } + networkConfig.Orderers[orderer] = ordererConfig + } + + //Peer Config + for peer, peerConfig := range networkConfig.Peers { + //resolve paths + peerConfig.TLSCACerts.Path = pathvar.Subst(peerConfig.TLSCACerts.Path) + //pre load key and cert bytes + err := peerConfig.TLSCACerts.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load peer cert") + } + networkConfig.Peers[peer] = peerConfig + } + + return nil +} + +//preLoadCATLSConfig pre-loads all TLSConfig bytes in certificate authorities +func (c *EndpointConfig) preLoadCATLSConfig(networkConfig *fab.NetworkConfig) error { + //CA Config + for ca, caConfig := range networkConfig.CertificateAuthorities { + //resolve paths + caConfig.TLSCACerts.Path = pathvar.Subst(caConfig.TLSCACerts.Path) + caConfig.TLSCACerts.Client.Key.Path = pathvar.Subst(caConfig.TLSCACerts.Client.Key.Path) + caConfig.TLSCACerts.Client.Cert.Path = pathvar.Subst(caConfig.TLSCACerts.Client.Cert.Path) + //pre load key and cert bytes + err := caConfig.TLSCACerts.Client.Key.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load ca key") + } + + err = caConfig.TLSCACerts.Client.Cert.LoadBytes() + if err != nil { + return errors.WithMessage(err, "failed to load ca cert") + } + networkConfig.CertificateAuthorities[ca] = caConfig + } + + return nil +} + func (c *EndpointConfig) getPortIfPresent(url string) (int, bool) { s := strings.Split(url, ":") if len(s) > 1 { @@ -746,7 +812,7 @@ func (c *EndpointConfig) tryMatchingPeerConfig(networkConfig *fab.NetworkConfig, func (c *EndpointConfig) matchPeer(networkConfig *fab.NetworkConfig, peerName string, k int, v *regexp.Regexp) *fab.PeerConfig { // get the matching matchConfig from the index number - peerMatchConfig := networkConfig.EntityMatchers["peer"][k] + peerMatchConfig := c.entityMatchers.matchers["peer"][k] //Get the peerConfig from mapped host peerConfig, ok := networkConfig.Peers[strings.ToLower(peerMatchConfig.MappedHost)] if !ok { @@ -849,7 +915,7 @@ func (c *EndpointConfig) tryMatchingOrdererConfig(networkConfig *fab.NetworkConf func (c *EndpointConfig) matchOrderer(networkConfig *fab.NetworkConfig, ordererName string, k int, v *regexp.Regexp) *fab.OrdererConfig { // get the matching matchConfig from the index number - ordererMatchConfig := networkConfig.EntityMatchers["orderer"][k] + ordererMatchConfig := c.entityMatchers.matchers["orderer"][k] //Get the ordererConfig from mapped host ordererConfig, ok := networkConfig.Orderers[strings.ToLower(ordererMatchConfig.MappedHost)] if !ok { @@ -931,65 +997,45 @@ func copyPropertiesMap(origMap map[string]interface{}) map[string]interface{} { return newMap } -func (c *EndpointConfig) findMatchingPeer(peerName string) (string, bool) { - networkConfig, ok := c.NetworkConfig() - if !ok { - return "", false - } - - //Return if no peerMatchers are configured - if len(c.peerMatchers) == 0 { - return "", false - } - - //sort the keys - var keys []int - for k := range c.peerMatchers { - keys = append(keys, k) - } - sort.Ints(keys) - - //loop over peerentityMatchers to find the matching peer - for _, k := range keys { - v := c.peerMatchers[k] - if v.MatchString(peerName) { - // get the matching matchConfig from the index number - peerMatchConfig := networkConfig.EntityMatchers["peer"][k] - return peerMatchConfig.MappedHost, true - } - } +func (c *EndpointConfig) compileMatchers() error { - return "", false -} + entityMatchers := entityMatchers{} -func (c *EndpointConfig) compileMatchers() error { - networkConfig, ok := c.NetworkConfig() - if !ok { - return errors.New("failed to get network config") + err := c.backend.UnmarshalKey("entityMatchers", &entityMatchers.matchers) + logger.Debugf("Matchers are: %+v", entityMatchers) + if err != nil { + return errors.WithMessage(err, "failed to parse 'entityMatchers' config item") } //return no error if entityMatchers is not configured - if networkConfig.EntityMatchers == nil { + if len(entityMatchers.matchers) == 0 { + logger.Debugf("Entity matchers are not configured") return nil } - err := c.compilePeerMatcher(networkConfig) + err = c.compilePeerMatcher(&entityMatchers) if err != nil { return err } - err = c.compileOrdererMatcher(networkConfig) + + err = c.compileOrdererMatcher(&entityMatchers) + if err != nil { + return err + } + + err = c.compileChannelMatcher(&entityMatchers) if err != nil { return err } - err = c.compileChannelMatcher(networkConfig) - return err + c.entityMatchers = &entityMatchers + return nil } -func (c *EndpointConfig) compileChannelMatcher(networkConfig *fab.NetworkConfig) error { +func (c *EndpointConfig) compileChannelMatcher(matcherConfig *entityMatchers) error { var err error - if networkConfig.EntityMatchers["channel"] != nil { - channelMatchers := networkConfig.EntityMatchers["channel"] + if matcherConfig.matchers["channel"] != nil { + channelMatchers := matcherConfig.matchers["channel"] for i, matcher := range channelMatchers { if matcher.Pattern != "" { c.channelMatchers[i], err = regexp.Compile(matcher.Pattern) @@ -1002,10 +1048,10 @@ func (c *EndpointConfig) compileChannelMatcher(networkConfig *fab.NetworkConfig) return nil } -func (c *EndpointConfig) compileOrdererMatcher(networkConfig *fab.NetworkConfig) error { +func (c *EndpointConfig) compileOrdererMatcher(matcherConfig *entityMatchers) error { var err error - if networkConfig.EntityMatchers["orderer"] != nil { - ordererMatchersConfig := networkConfig.EntityMatchers["orderer"] + if matcherConfig.matchers["orderer"] != nil { + ordererMatchersConfig := matcherConfig.matchers["orderer"] for i := 0; i < len(ordererMatchersConfig); i++ { if ordererMatchersConfig[i].Pattern != "" { c.ordererMatchers[i], err = regexp.Compile(ordererMatchersConfig[i].Pattern) @@ -1018,10 +1064,10 @@ func (c *EndpointConfig) compileOrdererMatcher(networkConfig *fab.NetworkConfig) return nil } -func (c *EndpointConfig) compilePeerMatcher(networkConfig *fab.NetworkConfig) error { +func (c *EndpointConfig) compilePeerMatcher(matcherConfig *entityMatchers) error { var err error - if networkConfig.EntityMatchers["peer"] != nil { - peerMatchersConfig := networkConfig.EntityMatchers["peer"] + if matcherConfig.matchers["peer"] != nil { + peerMatchersConfig := matcherConfig.matchers["peer"] for i := 0; i < len(peerMatchersConfig); i++ { if peerMatchersConfig[i].Pattern != "" { c.peerMatchers[i], err = regexp.Compile(peerMatchersConfig[i].Pattern) @@ -1075,45 +1121,65 @@ func (c *EndpointConfig) loadTLSCerts() ([]*x509.Certificate, error) { return certs, errs.ToError() } -// Client returns the Client config -func (c *EndpointConfig) client() (*msp.ClientConfig, error) { - config, ok := c.NetworkConfig() +//ResetNetworkConfig clears network config cache +func (c *EndpointConfig) ResetNetworkConfig() error { + c.networkConfig = nil + return c.loadNetworkConfiguration() +} + +// PeerMSPID returns msp that peer belongs to +func (c *EndpointConfig) peerMSPID(name string) (string, bool) { + networkConfig, ok := c.NetworkConfig() if !ok { - return nil, errors.New("failed to get network config") + return "", false } - client := config.Client - - client.Organization = strings.ToLower(client.Organization) - client.TLSCerts.Path = pathvar.Subst(client.TLSCerts.Path) - client.TLSCerts.Client.Key.Path = pathvar.Subst(client.TLSCerts.Client.Key.Path) - client.TLSCerts.Client.Cert.Path = pathvar.Subst(client.TLSCerts.Client.Cert.Path) + var mspID string + // Find organisation/msp that peer belongs to + for _, org := range networkConfig.Organizations { + for i := 0; i < len(org.Peers); i++ { + if strings.EqualFold(org.Peers[i], name) { + // peer belongs to this org add org msp + mspID = org.MSPID + break + } else { + peer, ok := c.findMatchingPeer(org.Peers[i]) + if ok && strings.EqualFold(peer, name) { + mspID = org.MSPID + break + } + } + } + } - return &client, nil + return mspID, mspID != "" } -//ResetNetworkConfig clears network config cache -func (c *EndpointConfig) ResetNetworkConfig() error { - c.networkConfig = nil - return c.loadNetworkConfiguration() -} +func (c *EndpointConfig) findMatchingPeer(peerName string) (string, bool) { -func loadByteKeyOrCertFromFile(c *msp.ClientConfig, isKey bool) ([]byte, error) { - var path string - a := "key" - if isKey { - path = pathvar.Subst(c.TLSCerts.Client.Key.Path) - c.TLSCerts.Client.Key.Path = path - } else { - a = "cert" - path = pathvar.Subst(c.TLSCerts.Client.Cert.Path) - c.TLSCerts.Client.Cert.Path = path + //Return if no peerMatchers are configured + if len(c.peerMatchers) == 0 { + return "", false } - bts, err := ioutil.ReadFile(path) - if err != nil { - return nil, errors.Errorf("Error loading %s file from '%s' err: %v", a, path, err) + + //sort the keys + var keys []int + for k := range c.peerMatchers { + keys = append(keys, k) } - return bts, nil + sort.Ints(keys) + + //loop over peerentityMatchers to find the matching peer + for _, k := range keys { + v := c.peerMatchers[k] + if v.MatchString(peerName) { + // get the matching matchConfig from the index number + peerMatchConfig := c.entityMatchers.matchers["peer"][k] + return peerMatchConfig.MappedHost, true + } + } + + return "", false } //peerChannelConfigHookFunc returns hook function for unmarshalling 'fab.PeerChannelConfig' diff --git a/pkg/fab/endpointconfig_test.go b/pkg/fab/endpointconfig_test.go index 9b2a0f7be1..e388549393 100644 --- a/pkg/fab/endpointconfig_test.go +++ b/pkg/fab/endpointconfig_test.go @@ -25,7 +25,9 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/core/config" + "github.com/hyperledger/fabric-sdk-go/pkg/core/config/lookup" "github.com/hyperledger/fabric-sdk-go/pkg/core/mocks" + "github.com/hyperledger/fabric-sdk-go/pkg/fab/comm" "github.com/hyperledger/fabric-sdk-go/pkg/util/pathvar" "github.com/spf13/viper" "github.com/stretchr/testify/assert" @@ -98,7 +100,7 @@ func TestCAConfigFailsByNetworkConfig(t *testing.T) { } //Testing MSPID failure scenario - mspID, ok := sampleEndpointConfig.MSPID("peerorg1") + mspID, ok := comm.MSPID(sampleEndpointConfig, "peerorg1") if mspID != "" || ok { t.Fatal("Get MSP ID supposed to fail") } @@ -501,7 +503,6 @@ func TestPeersConfig(t *testing.T) { } pc, ok := endpointConfig.PeersConfig(org2) - fmt.Println(ok, pc) assert.True(t, ok) for _, value := range pc { @@ -886,26 +887,27 @@ func TestTLSClientCertsFromFiles(t *testing.T) { } func TestTLSClientCertsFromFilesIncorrectPaths(t *testing.T) { - config, err := ConfigFromBackend(configBackend) - if err != nil { - t.Fatal(err) - } - endpointConfig := config.(*EndpointConfig) - // incorrect paths to files - endpointConfig.networkConfig.Client.TLSCerts.Client.Cert.Path = "/test/fixtures/config/mutual_tls/client_sdk_go.pem" - endpointConfig.networkConfig.Client.TLSCerts.Client.Key.Path = "/test/fixtures/config/mutual_tls/client_sdk_go-key.pem" - endpointConfig.networkConfig.Client.TLSCerts.Client.Cert.Pem = "" - endpointConfig.networkConfig.Client.TLSCerts.Client.Key.Pem = "" + nwConfig := fab.NetworkConfig{} + testlookup := lookup.New(configBackend) + testlookup.UnmarshalKey("client", &nwConfig.Client) - _, err = endpointConfig.TLSClientCerts() - if err == nil { - t.Fatalf("Expected error but got no errors instead") - } + //Set client tls paths to empty strings + nwConfig.Client.TLSCerts.Client.Cert.Path = "/test/fixtures/config/mutual_tls/client_sdk_go.pem" + nwConfig.Client.TLSCerts.Client.Key.Path = "/test/fixtures/config/mutual_tls/client_sdk_go-key.pem" + nwConfig.Client.TLSCerts.Client.Cert.Pem = "" + nwConfig.Client.TLSCerts.Client.Key.Pem = "" + + //Create backend override + configBackendOverride := &mocks.MockConfigBackend{} + configBackendOverride.KeyValueMap = make(map[string]interface{}) + configBackendOverride.KeyValueMap["client"] = nwConfig.Client - if !strings.Contains(err.Error(), "no such file or directory") { - t.Fatalf("Expected no such file or directory error") + _, err := ConfigFromBackend(configBackendOverride, configBackend) + if err == nil || !strings.Contains(err.Error(), "failed to load client key: failed to load pem bytes from path") { + t.Fatal(err) } + } func TestTLSClientCertsFromPem(t *testing.T) { @@ -1096,18 +1098,28 @@ YZjcDi7YEOZ3Fs1hxKmIxR+TTR2vf9I= } func TestTLSClientCertsNoCerts(t *testing.T) { - config, err := ConfigFromBackend(configBackend) + + nwConfig := fab.NetworkConfig{} + testlookup := lookup.New(configBackend) + testlookup.UnmarshalKey("client", &nwConfig.Client) + + //Set client tls paths to empty strings + nwConfig.Client.TLSCerts.Client.Cert.Path = "" + nwConfig.Client.TLSCerts.Client.Key.Path = "" + nwConfig.Client.TLSCerts.Client.Cert.Pem = "" + nwConfig.Client.TLSCerts.Client.Key.Pem = "" + + //Create backend override + configBackendOverride := &mocks.MockConfigBackend{} + configBackendOverride.KeyValueMap = make(map[string]interface{}) + configBackendOverride.KeyValueMap["client"] = nwConfig.Client + + config, err := ConfigFromBackend(configBackendOverride, configBackend) if err != nil { t.Fatal(err) } - endpointConfig := config.(*EndpointConfig) - endpointConfig.networkConfig.Client.TLSCerts.Client.Cert.Path = "" - endpointConfig.networkConfig.Client.TLSCerts.Client.Key.Path = "" - endpointConfig.networkConfig.Client.TLSCerts.Client.Cert.Pem = "" - endpointConfig.networkConfig.Client.TLSCerts.Client.Key.Pem = "" - - certs, err := endpointConfig.TLSClientCerts() + certs, err := config.TLSClientCerts() if err != nil { t.Fatalf("Expected no errors but got error instead: %s", err) } @@ -1226,17 +1238,6 @@ func TestEndpointConfigWithMultipleBackends(t *testing.T) { assert.Equal(t, networkConfig.CertificateAuthorities["local.ca.org1.example.com"].URL, "https://ca.org1.example.com:7054") assert.Equal(t, networkConfig.CertificateAuthorities["local.ca.org2.example.com"].URL, "https://ca.org2.example.com:8054") - //EntityMatchers - assert.Equal(t, len(networkConfig.EntityMatchers), 4) - assert.Equal(t, len(networkConfig.EntityMatchers["peer"]), 8) - assert.Equal(t, networkConfig.EntityMatchers["peer"][0].MappedHost, "local.peer0.org1.example.com") - assert.Equal(t, len(networkConfig.EntityMatchers["orderer"]), 4) - assert.Equal(t, networkConfig.EntityMatchers["orderer"][0].MappedHost, "local.orderer.example.com") - assert.Equal(t, len(networkConfig.EntityMatchers["certificateauthority"]), 2) - assert.Equal(t, networkConfig.EntityMatchers["certificateauthority"][0].MappedHost, "local.ca.org1.example.com") - assert.Equal(t, len(networkConfig.EntityMatchers["channel"]), 1) - assert.Equal(t, networkConfig.EntityMatchers["channel"][0].MappedName, "ch1") - //Organizations assert.Equal(t, len(networkConfig.Organizations), 3) assert.Equal(t, networkConfig.Organizations["org1"].MSPID, "Org1MSP") @@ -1250,6 +1251,18 @@ func TestEndpointConfigWithMultipleBackends(t *testing.T) { assert.Equal(t, networkConfig.Peers["local.peer0.org1.example.com"].URL, "peer0.org1.example.com:7051") assert.Equal(t, networkConfig.Peers["local.peer0.org1.example.com"].EventURL, "peer0.org1.example.com:7053") + //EntityMatchers + endpointConfigImpl := endpointConfig.(*EndpointConfig) + assert.Equal(t, len(endpointConfigImpl.entityMatchers.matchers), 4) + assert.Equal(t, len(endpointConfigImpl.entityMatchers.matchers["peer"]), 8) + assert.Equal(t, endpointConfigImpl.entityMatchers.matchers["peer"][0].MappedHost, "local.peer0.org1.example.com") + assert.Equal(t, len(endpointConfigImpl.entityMatchers.matchers["orderer"]), 4) + assert.Equal(t, endpointConfigImpl.entityMatchers.matchers["orderer"][0].MappedHost, "local.orderer.example.com") + assert.Equal(t, len(endpointConfigImpl.entityMatchers.matchers["certificateauthority"]), 2) + assert.Equal(t, endpointConfigImpl.entityMatchers.matchers["certificateauthority"][0].MappedHost, "local.ca.org1.example.com") + assert.Equal(t, len(endpointConfigImpl.entityMatchers.matchers["channel"]), 1) + assert.Equal(t, endpointConfigImpl.entityMatchers.matchers["channel"][0].MappedName, "ch1") + } func TestNetworkPeers(t *testing.T) { diff --git a/pkg/fab/mocks/mockconfig.go b/pkg/fab/mocks/mockconfig.go index 783554bbcd..6e51e74be1 100644 --- a/pkg/fab/mocks/mockconfig.go +++ b/pkg/fab/mocks/mockconfig.go @@ -208,16 +208,6 @@ func (c *MockConfig) OrdererConfig(name string) (*fab.OrdererConfig, bool) { return &oConfig, true } -// MSPID not implemented -func (c *MockConfig) MSPID(org string) (string, bool) { - return "", false -} - -// PeerMSPID not implemented -func (c *MockConfig) PeerMSPID(name string) (string, bool) { - return "", false -} - // KeyStorePath ... func (c *MockConfig) KeyStorePath() string { return "/tmp/fabsdkgo_test" diff --git a/pkg/fab/opts.go b/pkg/fab/opts.go index c2e1173186..c86f612eef 100644 --- a/pkg/fab/opts.go +++ b/pkg/fab/opts.go @@ -19,8 +19,6 @@ import ( // if a function is not overridden, the default EndpointConfig implementation will be used. type EndpointConfigOptions struct { timeout - mspID - peerMSPID orderersConfig ordererConfig peersConfig @@ -45,16 +43,6 @@ type timeout interface { Timeout(fab.TimeoutType) time.Duration } -// mspID interface allows to uniquely override EndpointConfig interface's MSPID() function -type mspID interface { - MSPID(org string) (string, bool) -} - -// peerMSPID interface allows to uniquely override EndpointConfig interface's PeerMSPID() function -type peerMSPID interface { - PeerMSPID(name string) (string, bool) -} - // orderersConfig interface allows to uniquely override EndpointConfig interface's OrderersConfig() function type orderersConfig interface { OrderersConfig() ([]fab.OrdererConfig, bool) @@ -142,8 +130,6 @@ func UpdateMissingOptsWithDefaultConfig(c *EndpointConfigOptions, d fab.Endpoint s := &setter{} s.set(c.timeout, nil, func() { c.timeout = d }) - s.set(c.mspID, nil, func() { c.mspID = d }) - s.set(c.peerMSPID, nil, func() { c.peerMSPID = d }) s.set(c.orderersConfig, nil, func() { c.orderersConfig = d }) s.set(c.ordererConfig, nil, func() { c.ordererConfig = d }) s.set(c.peersConfig, nil, func() { c.peersConfig = d }) @@ -164,7 +150,7 @@ func UpdateMissingOptsWithDefaultConfig(c *EndpointConfigOptions, d fab.Endpoint // IsEndpointConfigFullyOverridden will return true if all of the argument's sub interfaces is not nil // (ie EndpointConfig interface not fully overridden) func IsEndpointConfigFullyOverridden(c *EndpointConfigOptions) bool { - return !anyNil(c.timeout, c.mspID, c.peerMSPID, c.orderersConfig, c.ordererConfig, c.peersConfig, c.peerConfig, c.networkConfig, + return !anyNil(c.timeout, c.orderersConfig, c.ordererConfig, c.peersConfig, c.peerConfig, c.networkConfig, c.networkPeers, c.channelConfig, c.channelPeers, c.channelOrderers, c.tlsCACertPool, c.eventServiceType, c.tlsClientCerts, c.cryptoConfigPath) } @@ -173,8 +159,6 @@ func setEndpointConfigWithOptionInterface(c *EndpointConfigOptions, o interface{ s := &setter{} s.set(c.timeout, func() bool { _, ok := o.(timeout); return ok }, func() { c.timeout = o.(timeout) }) - s.set(c.mspID, func() bool { _, ok := o.(mspID); return ok }, func() { c.mspID = o.(mspID) }) - s.set(c.peerMSPID, func() bool { _, ok := o.(peerMSPID); return ok }, func() { c.peerMSPID = o.(peerMSPID) }) s.set(c.orderersConfig, func() bool { _, ok := o.(orderersConfig); return ok }, func() { c.orderersConfig = o.(orderersConfig) }) s.set(c.ordererConfig, func() bool { _, ok := o.(ordererConfig); return ok }, func() { c.ordererConfig = o.(ordererConfig) }) s.set(c.peersConfig, func() bool { _, ok := o.(peersConfig); return ok }, func() { c.peersConfig = o.(peersConfig) }) diff --git a/pkg/fab/opts_test.go b/pkg/fab/opts_test.go index 23d5ecb25a..229e607de9 100644 --- a/pkg/fab/opts_test.go +++ b/pkg/fab/opts_test.go @@ -19,8 +19,6 @@ import ( var ( m0 = &EndpointConfig{} m1 = &mockTimeoutConfig{} - m2 = &mockMspID{} - m3 = &mockPeerMSPID{} m4 = &mockrderersConfig{} m5 = &mockOrdererConfig{} m6 = &mockPeersConfig{} @@ -51,7 +49,7 @@ func TestCreateCustomFullEndpointConfig(t *testing.T) { func TestCreateCustomEndpointConfig(t *testing.T) { // try to build with partial interfaces - endpointConfigOption, err := BuildConfigEndpointFromOptions(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10) + endpointConfigOption, err := BuildConfigEndpointFromOptions(m1, m4, m5, m6, m7, m8, m9, m10) if err != nil { t.Fatalf("BuildConfigEndpointFromOptions returned unexpected error %s", err) } @@ -67,20 +65,6 @@ func TestCreateCustomEndpointConfig(t *testing.T) { if tmout < 0 { t.Fatalf("EndpointConfig was supposed to have Timeout function overridden from Options but was not %+v. Timeout: %s", eco, tmout) } - m, ok := eco.MSPID("") - if !ok { - t.Fatalf("Failed to get MSP ID") - } - if m != "testMSP" { - t.Fatalf("MSPID did not return expected interface value. Expected: %s, Received: %s", "testMSP", m) - } - m, ok = eco.PeerMSPID("") - if !ok { - t.Fatalf("PeerMSPID supposed to pass") - } - if m != "testPeerMSP" { - t.Fatalf("MSPID did not return expected interface value. Expected: %s, Received: %s", "testPeerMSP", m) - } // verify if an interface was not passed as an option but was not nil, it should be nil if eco.channelPeers != nil { @@ -134,7 +118,7 @@ func TestCreateCustomEndpointConfigRemainingFunctions(t *testing.T) { func TestCreateCustomEndpointConfigWithSomeDefaultFunctions(t *testing.T) { // create a config with the first 7 interfaces to be overridden - endpointConfigOption, err := BuildConfigEndpointFromOptions(m1, m2, m3, m4, m5, m6, m7) + endpointConfigOption, err := BuildConfigEndpointFromOptions(m1, m4, m5, m6, m7) if err != nil { t.Fatalf("BuildConfigEndpointFromOptions returned unexpected error %s", err) } @@ -157,13 +141,6 @@ func TestCreateCustomEndpointConfigWithSomeDefaultFunctions(t *testing.T) { if tmout != expectedTimeout { t.Fatalf("EndpointConfig was supposed to have Timeout function overridden from Options but was not %+v. Timeout: [expected: %s, received: %s]", eco, expectedTimeout, tmout) } - m, ok := endpointConfigOptionWithSomeDefaults.MSPID("") - if !ok { - t.Fatalf("Failed to get MSPID") - } - if m != "testMSP" { - t.Fatalf("MSPID did not return expected interface value. Expected: %s, Received: %s", "testMSP", m) - } // now check if interfaces that are not updated are defaulted with m0 if eco, ok = endpointConfigOptionWithSomeDefaults.(*EndpointConfigOptions); !ok { @@ -181,7 +158,7 @@ func TestCreateCustomEndpointConfigWithSomeDefaultFunctions(t *testing.T) { func TestIsEndpointConfigFullyOverridden(t *testing.T) { // test with the some interfaces - endpointConfigOption, err := BuildConfigEndpointFromOptions(m1, m2, m3) + endpointConfigOption, err := BuildConfigEndpointFromOptions(m1) if err != nil { t.Fatalf("BuildConfigEndpointFromOptions returned unexpected error %s", err) } @@ -214,7 +191,7 @@ func TestIsEndpointConfigFullyOverridden(t *testing.T) { } // now try with all opts, expected value is true this time - endpointConfigOption, err = BuildConfigEndpointFromOptions(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16) + endpointConfigOption, err = BuildConfigEndpointFromOptions(m1, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16) if err != nil { t.Fatalf("BuildConfigEndpointFromOptions returned unexpected error %s", err) } @@ -266,18 +243,6 @@ func (m *mockTimeoutConfig) Timeout(timeoutType fab.TimeoutType) time.Duration { return 10 * time.Second } -type mockMspID struct{} - -func (m *mockMspID) MSPID(org string) (string, bool) { - return "testMSP", true -} - -type mockPeerMSPID struct{} - -func (m *mockPeerMSPID) PeerMSPID(name string) (string, bool) { - return "testPeerMSP", true -} - type mockrderersConfig struct{} func (m *mockrderersConfig) OrderersConfig() ([]fab.OrdererConfig, bool) { diff --git a/pkg/fab/orderer/orderer_test.go b/pkg/fab/orderer/orderer_test.go index 5fd5ac720e..a293455edb 100644 --- a/pkg/fab/orderer/orderer_test.go +++ b/pkg/fab/orderer/orderer_test.go @@ -139,9 +139,12 @@ func startCustomizedMockServer(t *testing.T, serverURL string, grpcServer *grpc. func TestNewOrdererWithTLS(t *testing.T) { tlsConfig := endpoint.TLSConfig{Path: "../../../test/fixtures/fabricca/tls/ca/ca_root.pem"} + err := tlsConfig.LoadBytes() + if err != nil { + t.Fatalf("tlsConfig.LoadBytes() failed, cause [%s]", err) + } cert, err := tlsConfig.TLSCert() - if err != nil { t.Fatalf("Testing New with TLS failed, cause [%s]", err) } @@ -162,6 +165,10 @@ func TestNewOrdererWithTLS(t *testing.T) { func TestNewOrdererWithMutualTLS(t *testing.T) { //Positive Test case tlsConfig := endpoint.TLSConfig{Path: "../../../test/fixtures/fabricca/tls/ca/ca_root.pem"} + err := tlsConfig.LoadBytes() + if err != nil { + t.Fatalf("tlsConfig.LoadBytes() failed, cause [%s]", err) + } cert, err := tlsConfig.TLSCert() diff --git a/pkg/msp/caclient.go b/pkg/msp/caclient.go index b44f0f3668..e7dd884a35 100644 --- a/pkg/msp/caclient.go +++ b/pkg/msp/caclient.go @@ -62,14 +62,12 @@ func NewCAClient(orgName string, ctx contextApi.Client) (*CAClientImpl, error) { return nil, errors.New("no CAs configured") } - var caConfig *msp.CAConfig var adapter *fabricCAAdapter var registrar msp.EnrollCredentials - var err error // Currently, an organization can be associated with only one CA caName := orgConfig.CertificateAuthorities[0] - caConfig, err = ctx.IdentityConfig().CAConfig(orgName) + caConfig, err := ctx.IdentityConfig().CAConfig(orgName) if err == nil { adapter, err = newFabricCAAdapter(orgName, ctx.CryptoSuite(), ctx.IdentityConfig()) if err == nil { diff --git a/pkg/msp/getsigid.go b/pkg/msp/getsigid.go index 251d221f14..ec6ecb8ca4 100644 --- a/pkg/msp/getsigid.go +++ b/pkg/msp/getsigid.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/hyperledger/fabric-sdk-go/pkg/core/config/cryptoutil" + "github.com/hyperledger/fabric-sdk-go/pkg/fab/comm" fabricCaUtil "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric-ca/util" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" @@ -107,7 +108,7 @@ func (mgr *IdentityManager) GetUser(username string) (*User, error) { //nolint if privateKey == nil { return nil, fmt.Errorf("unable to find private key for user [%s]", username) } - mspID, ok := mgr.config.MSPID(mgr.orgName) + mspID, ok := comm.MSPID(mgr.config, mgr.orgName) if !ok { return nil, errors.New("MSP ID config read failed") } diff --git a/pkg/msp/identityconfig.go b/pkg/msp/identityconfig.go index 1fdd94ad28..e67db66b40 100644 --- a/pkg/msp/identityconfig.go +++ b/pkg/msp/identityconfig.go @@ -58,23 +58,22 @@ func ConfigFromEndpointConfig(endpointConfig fab.EndpointConfig, coreBackend ... type IdentityConfig struct { endpointConfig fab.EndpointConfig backend *lookup.ConfigLookup + entityMatchers *entityMatchers caMatchers map[int]*regexp.Regexp } +//entityMatchers for identity configuration +type entityMatchers struct { + matchers map[string][]fab.MatchConfig +} + // Client returns the Client config func (c *IdentityConfig) Client() (*msp.ClientConfig, error) { config, err := c.networkConfig() if err != nil { return nil, err } - client := config.Client - - client.Organization = strings.ToLower(client.Organization) - client.TLSCerts.Path = pathvar.Subst(client.TLSCerts.Path) - client.TLSCerts.Client.Key.Path = pathvar.Subst(client.TLSCerts.Client.Key.Path) - client.TLSCerts.Client.Cert.Path = pathvar.Subst(client.TLSCerts.Client.Cert.Path) - - return &client, nil + return &config.Client, nil } // CAConfig returns the CA configuration. @@ -83,7 +82,6 @@ func (c *IdentityConfig) CAConfig(org string) (*msp.CAConfig, error) { if err != nil { return nil, err } - return c.getCAConfig(networkConfig, org) } @@ -128,10 +126,7 @@ func (c *IdentityConfig) CAClientCert(org string) ([]byte, error) { return nil, err } - //subst path - caConfig.TLSCACerts.Client.Cert.Path = pathvar.Subst(caConfig.TLSCACerts.Client.Cert.Path) - - return caConfig.TLSCACerts.Client.Cert.Bytes() + return caConfig.TLSCACerts.Client.Cert.Bytes(), err } //CAClientKey read configuration for the fabric CA client key bytes for given org @@ -146,10 +141,7 @@ func (c *IdentityConfig) CAClientKey(org string) ([]byte, error) { return nil, err } - //subst path - caConfig.TLSCACerts.Client.Key.Path = pathvar.Subst(caConfig.TLSCACerts.Client.Key.Path) - - return caConfig.TLSCACerts.Client.Key.Bytes() + return caConfig.TLSCACerts.Client.Key.Bytes(), err } // CAServerCerts Read configuration option for the server certificates @@ -239,7 +231,7 @@ func (c *IdentityConfig) tryMatchingCAConfig(networkConfig *fab.NetworkConfig, c func (c *IdentityConfig) findMatchingCert(networkConfig *fab.NetworkConfig, caName string, v *regexp.Regexp, k int) (*msp.CAConfig, string) { // get the matching Config from the index number - certAuthorityMatchConfig := networkConfig.EntityMatchers["certificateauthority"][k] + certAuthorityMatchConfig := c.entityMatchers.matchers["certificateauthority"][k] //Get the certAuthorityMatchConfig from mapped host caConfig, ok := networkConfig.CertificateAuthorities[strings.ToLower(certAuthorityMatchConfig.MappedHost)] if !ok { @@ -279,12 +271,16 @@ func (c *IdentityConfig) getPortIfPresent(url string) (int, bool) { } func (c *IdentityConfig) compileMatchers() error { - networkConfig, ok := c.endpointConfig.NetworkConfig() - if !ok { - return errors.New("failed to get network config") + entityMatchers := entityMatchers{} + + err := c.backend.UnmarshalKey("entityMatchers", &entityMatchers.matchers) + logger.Debugf("Matchers are: %+v", entityMatchers) + if err != nil { + return errors.WithMessage(err, "failed to parse 'entityMatchers' config item") } - if networkConfig.EntityMatchers["certificateauthority"] != nil { - certMatchersConfig := networkConfig.EntityMatchers["certificateauthority"] + + if entityMatchers.matchers["certificateauthority"] != nil { + certMatchersConfig := entityMatchers.matchers["certificateauthority"] var err error for i := 0; i < len(certMatchersConfig); i++ { if certMatchersConfig[i].Pattern != "" { @@ -295,5 +291,6 @@ func (c *IdentityConfig) compileMatchers() error { } } } + c.entityMatchers = &entityMatchers return nil } diff --git a/pkg/msp/identityconfig_test.go b/pkg/msp/identityconfig_test.go index 01011a9f2e..ab26c91d5d 100644 --- a/pkg/msp/identityconfig_test.go +++ b/pkg/msp/identityconfig_test.go @@ -18,6 +18,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint" "github.com/hyperledger/fabric-sdk-go/pkg/core/mocks" "github.com/hyperledger/fabric-sdk-go/pkg/fab" + "github.com/hyperledger/fabric-sdk-go/pkg/fab/comm" "github.com/hyperledger/fabric-sdk-go/pkg/util/pathvar" "github.com/spf13/viper" "github.com/stretchr/testify/assert" @@ -122,6 +123,11 @@ func TestTLSCAConfigFromPems(t *testing.T) { certPem, _ := identityConfig.CAClientCert(org1) certConfig := endpoint.TLSConfig{Pem: string(certPem)} + err = certConfig.LoadBytes() + if err != nil { + t.Fatalf("TLS CA cert parse failed, reason: %v", err) + } + cert, err := certConfig.TLSCert() if err != nil { @@ -363,12 +369,12 @@ func TestCAConfig(t *testing.T) { assert.True(t, pathvar.Subst(val.(string)) == identityConfig.endpointConfig.CryptoConfigPath(), "Incorrect crypto config path", t) //Testing MSPID - mspID, ok := identityConfig.endpointConfig.MSPID(org1) + mspID, ok := comm.MSPID(identityConfig.endpointConfig, org1) assert.True(t, ok, "Get MSP ID failed") assert.True(t, mspID == "Org1MSP", "Get MSP ID failed") // testing empty OrgMSP - _, ok = identityConfig.endpointConfig.MSPID("dummyorg1") + _, ok = comm.MSPID(identityConfig.endpointConfig, "dummyorg1") assert.False(t, ok, "Get MSP ID did not fail for dummyorg1") //Testing CAConfig @@ -414,12 +420,12 @@ func TestCAConfigWithCustomEndpointConfig(t *testing.T) { assert.True(t, pathvar.Subst(val.(string)) == identityConfig.endpointConfig.CryptoConfigPath(), "Incorrect crypto config path", t) //Testing MSPID - mspID, ok := identityConfig.endpointConfig.MSPID(org1) + mspID, ok := comm.MSPID(identityConfig.endpointConfig, org1) assert.True(t, ok, "Get MSP ID failed") assert.True(t, mspID == "Org1MSP", "Get MSP ID failed") // testing empty OrgMSP - _, ok = identityConfig.endpointConfig.MSPID("dummyorg1") + _, ok = comm.MSPID(identityConfig.endpointConfig, "dummyorg1") assert.False(t, ok, "Get MSP ID did not fail for dummyorg1") //Testing CAConfig @@ -437,7 +443,7 @@ func TestCAConfigWithCustomEndpointConfig(t *testing.T) { client, err := identityConfig.Client() assert.Nil(t, err) - assert.Equal(t, "custom-org1", client.Organization, "supposed to get custom org name from custom endpointconfig") + assert.Equal(t, "CUSTOM-ORG1", client.Organization, "supposed to get custom org name from custom endpointconfig") //make sure 2 certpool instances are not created actualCertPool, err := identityConfig.endpointConfig.TLSCACertPool() diff --git a/test/integration/base_test_setup.go b/test/integration/base_test_setup.go index 309a6def5f..17188cc568 100644 --- a/test/integration/base_test_setup.go +++ b/test/integration/base_test_setup.go @@ -19,6 +19,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" "github.com/hyperledger/fabric-sdk-go/pkg/fab" packager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager" + "github.com/hyperledger/fabric-sdk-go/pkg/fab/comm" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl" "github.com/pkg/errors" @@ -146,7 +147,7 @@ func InstallAndInstantiateCC(sdk *fabsdk.FabricSDK, user fabsdk.ContextOption, o return resmgmt.InstantiateCCResponse{}, errors.WithMessage(err, "failed to get endpoint config") } - mspID, ok := endpointConfig.MSPID(orgName) + mspID, ok := comm.MSPID(endpointConfig, orgName) if !ok { return resmgmt.InstantiateCCResponse{}, errors.New("looking up MSP ID failed") } diff --git a/test/integration/e2e/configless/endpointconfig_override_test.go b/test/integration/e2e/configless/endpointconfig_override_test.go index 34dd5438e4..45fd49584f 100644 --- a/test/integration/e2e/configless/endpointconfig_override_test.go +++ b/test/integration/e2e/configless/endpointconfig_override_test.go @@ -9,7 +9,6 @@ package configless import ( "crypto/tls" "crypto/x509" - "io/ioutil" "os" "regexp" "strings" @@ -236,8 +235,6 @@ var ( // creating instances of each interface to be referenced in the integration tests: timeoutImpl = &exampleTimeout{} - mspIDImpl = &exampleMSPID{} - peerMSPIDImpl = &examplePeerMSPID{} orderersConfigImpl = newOrderersConfigImpl() ordererConfigImpl = &exampleOrdererConfig{} peersConfigImpl = newPeersConfigImpl() @@ -253,8 +250,6 @@ var ( cryptoConfigPathImpl = &exampleCryptoConfigPath{} endpointConfigImpls = []interface{}{ timeoutImpl, - mspIDImpl, - peerMSPIDImpl, orderersConfigImpl, ordererConfigImpl, peersConfigImpl, @@ -304,23 +299,8 @@ func (m *exampleTimeout) Timeout(tType fab.TimeoutType) time.Duration { return t } -type exampleMSPID struct{} - -//MSPID overrides EndpointConfig's MSPID function which returns the mspID for the given org name in the arg -func (m *exampleMSPID) MSPID(org string) (string, bool) { - //lowercase org name to make it case insensitive, depends on application preference, for the sake of this example, make it case in-sensitive - mspID := orgsConfig[strings.ToLower(org)].MSPID - if mspID == "" { - return "", false - } - - return mspID, true -} - -type examplePeerMSPID struct{} - -//PeerMSPID overrides EndpointConfig's PeerMSPID function which returns the mspID for the given org name in the arg -func (m *examplePeerMSPID) PeerMSPID(name string) (string, bool) { +//PeerMSPID returns the mspID for the given org name in the arg +func PeerMSPID(name string) (string, bool) { // Find organisation/msp that peer belongs to for _, org := range orgsConfig { for i := 0; i < len(org.Peers); i++ { @@ -414,6 +394,10 @@ func (m *exampleOrderersConfig) OrderersConfig() ([]fab.OrdererConfig, bool) { } else if len(orderer.TLSCACerts.Pem) == 0 && !m.isSystemCertPool { return nil, false } + err := orderer.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } orderers = append(orderers, orderer) } @@ -438,7 +422,10 @@ func (m *exampleOrdererConfig) OrdererConfig(ordererNameOrURL string) (*fab.Orde if orderer.TLSCACerts.Path != "" { orderer.TLSCACerts.Path = pathvar.Subst(orderer.TLSCACerts.Path) } - + err := orderer.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } return &orderer, true } @@ -493,6 +480,10 @@ func (m *examplePeersConfig) PeersConfig(org string) ([]fab.PeerConfig, bool) { if p.TLSCACerts.Path != "" { p.TLSCACerts.Path = pathvar.Subst(p.TLSCACerts.Path) } + err := p.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } peers = append(peers, p) } @@ -520,6 +511,10 @@ func (m *examplePeerConfig) PeerConfig(nameOrURL string) (*fab.PeerConfig, bool) if pcfg.TLSCACerts.Path != "" { pcfg.TLSCACerts.Path = pathvar.Subst(pcfg.TLSCACerts.Path) } + err := pcfg.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } // EntityMatchers are not used in this implementation // see default implementation (pkg/fab/endpointconfig.go) to see how they're used @@ -541,7 +536,6 @@ type exampleNetworkPeers struct { func (m *exampleNetworkPeers) NetworkPeers() ([]fab.NetworkPeer, bool) { netPeers := []fab.NetworkPeer{} // referencing another interface to call PeerMSPID to match config yaml content - peerMSPID := &examplePeerMSPID{} for name, p := range networkConfig.Peers { @@ -553,7 +547,12 @@ func (m *exampleNetworkPeers) NetworkPeers() ([]fab.NetworkPeer, bool) { p.TLSCACerts.Path = pathvar.Subst(p.TLSCACerts.Path) } - mspID, ok := peerMSPID.PeerMSPID(name) + err := p.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } + + mspID, ok := PeerMSPID(name) if !ok { return nil, false } @@ -599,8 +598,6 @@ type exampleChannelPeers struct { // ChannelPeers overrides EndpointConfig's ChannelPeers function which returns the list of peers for the channel name arg func (m *exampleChannelPeers) ChannelPeers(channelName string) ([]fab.ChannelPeer, bool) { peers := []fab.ChannelPeer{} - // referencing another interface to call PeerMSPID to match config yaml content - peerMSPID := &examplePeerMSPID{} chConfig, ok := channelsConfig[strings.ToLower(channelName)] if !ok { @@ -637,7 +634,12 @@ func (m *exampleChannelPeers) ChannelPeers(channelName string) ([]fab.ChannelPee p.TLSCACerts.Path = pathvar.Subst(p.TLSCACerts.Path) } - mspID, ok := peerMSPID.PeerMSPID(peerName) + err := p.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } + + mspID, ok := PeerMSPID(peerName) if !ok { return nil, false } @@ -652,6 +654,7 @@ func (m *exampleChannelPeers) ChannelPeers(channelName string) ([]fab.ChannelPee return peers, true } + func (m *exampleChannelPeers) verifyPeerConfig(p fab.PeerConfig, peerName string, tlsEnabled bool) error { if p.URL == "" { return errors.Errorf("URL does not exist or empty for peer %s", peerName) @@ -681,7 +684,10 @@ func (m *exampleChannelOrderers) ChannelOrderers(channelName string) ([]fab.Orde if !ok || orderer == nil { return nil, false } - + err := orderer.TLSCACerts.LoadBytes() + if err != nil { + return nil, false + } orderers = append(orderers, *orderer) } @@ -726,11 +732,7 @@ func (m *exampleTLSClientCerts) TLSClientCerts() ([]tls.Certificate, error) { m.RWLock = &sync.RWMutex{} } var clientCerts tls.Certificate - var cb []byte - cb, err := clientConfig.TLSCerts.Client.Cert.Bytes() - if err != nil { - return nil, errors.Wrapf(err, "failed to load tls client cert") - } + cb := clientConfig.TLSCerts.Client.Cert.Bytes() if len(cb) == 0 { // if no cert found in the config, return empty cert chain @@ -757,42 +759,17 @@ func (m *exampleTLSClientCerts) TLSClientCerts() ([]tls.Certificate, error) { return []tls.Certificate{clientCerts}, nil } func (m *exampleTLSClientCerts) loadPrivateKeyFromConfig(clientConfig *msp.ClientConfig, clientCerts tls.Certificate, cb []byte) ([]tls.Certificate, error) { - var kb []byte - var err error - if clientConfig.TLSCerts.Client.Key.Pem != "" { - kb = []byte(clientConfig.TLSCerts.Client.Key.Pem) - } else if clientConfig.TLSCerts.Client.Key.Path != "" { - kb, err = loadByteKeyOrCertFromFile(clientConfig, true) - if err != nil { - return nil, errors.Wrapf(err, "Failed to load key from file path '%s'", clientConfig.TLSCerts.Client.Key.Path) - } - } + + kb := clientConfig.TLSCerts.Client.Key.Bytes() // load the key/cert pair from []byte - clientCerts, err = tls.X509KeyPair(cb, kb) + clientCerts, err := tls.X509KeyPair(cb, kb) if err != nil { return nil, errors.Errorf("Error loading cert/key pair as TLS client credentials: %v", err) } return []tls.Certificate{clientCerts}, nil } -func loadByteKeyOrCertFromFile(c *msp.ClientConfig, isKey bool) ([]byte, error) { - var path string - a := "key" - if isKey { - path = pathvar.Subst(c.TLSCerts.Client.Key.Path) - c.TLSCerts.Client.Key.Path = path - } else { - a = "cert" - path = pathvar.Subst(c.TLSCerts.Client.Cert.Path) - c.TLSCerts.Client.Cert.Path = path - } - bts, err := ioutil.ReadFile(path) - if err != nil { - return nil, errors.Errorf("Error loading %s file from '%s' err: %v", a, path, err) - } - return bts, nil -} type exampleCryptoConfigPath struct{} diff --git a/test/integration/e2e/configless/identityconfig_override_test.go b/test/integration/e2e/configless/identityconfig_override_test.go index 7352f57c74..1f318cf640 100644 --- a/test/integration/e2e/configless/identityconfig_override_test.go +++ b/test/integration/e2e/configless/identityconfig_override_test.go @@ -129,8 +129,9 @@ func (m *exampleCaClientKey) CAClientKey(org string) ([]byte, error) { //subst path caConfig.TLSCACerts.Client.Key.Path = pathvar.Subst(caConfig.TLSCACerts.Client.Key.Path) + err = caConfig.TLSCACerts.Client.Key.LoadBytes() - return caConfig.TLSCACerts.Client.Key.Bytes() + return caConfig.TLSCACerts.Client.Key.Bytes(), err } type exampleCaClientCert struct{} @@ -143,8 +144,9 @@ func (m *exampleCaClientCert) CAClientCert(org string) ([]byte, error) { //subst path caConfig.TLSCACerts.Client.Cert.Path = pathvar.Subst(caConfig.TLSCACerts.Client.Cert.Path) + err = caConfig.TLSCACerts.Client.Cert.LoadBytes() - return caConfig.TLSCACerts.Client.Cert.Bytes() + return caConfig.TLSCACerts.Client.Cert.Bytes(), err } type exampleCaKeyStorePath struct{}