Skip to content

Commit

Permalink
Deduplicate orderer server TLS root CAs (#2029)
Browse files Browse the repository at this point in the history
When the orderer TLS root CAs are updated, an aggregation of all root TLS CA certificates over all channels is injected into the PredicateDialer.
Then, upon client TLS handshake, a fresh TLS config object is built (for orthogonal purposes), however the operation entails parsing of all
root CAs all over again.

In case the orderer is part of too many channels, this induces a high and unnecessary processing overhead.

This commit simply performs a deduplication of the bespoken TLS root CA certificates prior to updating the root CAs.

Change-Id: I21b2ed483afc9595c2ccd7fbe9ec0cf475cc5f62
Signed-off-by: yacovm <yacovm@il.ibm.com>
(cherry picked from commit 48d532f)

# Conflicts:
#	orderer/common/server/main_test.go
  • Loading branch information
yacovm authored and mergify-bot committed Oct 21, 2020
1 parent 9c5b283 commit 0286414
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
21 changes: 16 additions & 5 deletions orderer/common/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -920,15 +920,26 @@ func (mgr *caManager) updateClusterDialer(

// Iterate over all orderer root CAs for all chains and add them
// to the root CAs
var clusterRootCAs [][]byte
for _, roots := range mgr.ordererRootCAsByChain {
clusterRootCAs = append(clusterRootCAs, roots...)
clusterRootCAs := make(cluster.StringSet)
for _, orgRootCAs := range mgr.ordererRootCAsByChain {
for _, rootCA := range orgRootCAs {
clusterRootCAs[string(rootCA)] = struct{}{}
}
}

// Add the local root CAs too
clusterRootCAs = append(clusterRootCAs, localClusterRootCAs...)
for _, localRootCA := range localClusterRootCAs {
clusterRootCAs[string(localRootCA)] = struct{}{}
}

// Convert StringSet to byte slice
var clusterRootCAsBytes [][]byte
for root := range clusterRootCAs {
clusterRootCAsBytes = append(clusterRootCAsBytes, []byte(root))
}

// Update the cluster config with the new root CAs
clusterDialer.UpdateRootCAs(clusterRootCAs)
clusterDialer.UpdateRootCAs(clusterRootCAsBytes)
}

func prettyPrintStruct(i interface{}) {
Expand Down
31 changes: 31 additions & 0 deletions orderer/common/server/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ package server

import (
"fmt"
<<<<<<< HEAD
"github.com/hyperledger/fabric/orderer/common/onboarding"
=======
>>>>>>> 48d532fd7... Deduplicate orderer server TLS root CAs (#2029)
"io/ioutil"
"net"
"net/http"
Expand All @@ -19,6 +22,7 @@ import (

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/bccsp/factory"
"github.com/hyperledger/fabric/bccsp/sw"
"github.com/hyperledger/fabric/common/channelconfig"
Expand All @@ -36,6 +40,7 @@ import (
"github.com/hyperledger/fabric/internal/pkg/identity"
"github.com/hyperledger/fabric/orderer/common/bootstrap/file"
"github.com/hyperledger/fabric/orderer/common/cluster"
"github.com/hyperledger/fabric/orderer/common/filerepo"
"github.com/hyperledger/fabric/orderer/common/localconfig"
"github.com/hyperledger/fabric/orderer/common/multichannel"
server_mocks "github.com/hyperledger/fabric/orderer/common/server/mocks"
Expand Down Expand Up @@ -643,6 +648,32 @@ func TestUpdateTrustedRoots(t *testing.T) {
grpcServer.Listener().Close()
}

func TestRootServerCertAggregation(t *testing.T) {
caMgr := &caManager{
appRootCAsByChain: make(map[string][][]byte),
ordererRootCAsByChain: make(map[string][][]byte),
}

predDialer := &cluster.PredicateDialer{
Config: comm.ClientConfig{},
}

ca1, err := tlsgen.NewCA()
require.NoError(t, err)

ca2, err := tlsgen.NewCA()
require.NoError(t, err)

caMgr.ordererRootCAsByChain["foo"] = [][]byte{ca1.CertBytes()}
caMgr.ordererRootCAsByChain["bar"] = [][]byte{ca1.CertBytes()}

caMgr.updateClusterDialer(predDialer, [][]byte{ca2.CertBytes(), ca2.CertBytes(), ca2.CertBytes()})

require.Len(t, predDialer.Config.SecOpts.ServerRootCAs, 2)
require.Contains(t, predDialer.Config.SecOpts.ServerRootCAs, ca1.CertBytes())
require.Contains(t, predDialer.Config.SecOpts.ServerRootCAs, ca2.CertBytes())
}

func TestConfigureClusterListener(t *testing.T) {
logEntries := make(chan string, 100)

Expand Down

0 comments on commit 0286414

Please sign in to comment.