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>
  • Loading branch information
yacovm authored Oct 20, 2020
1 parent 3c57d11 commit 48d532f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
21 changes: 16 additions & 5 deletions orderer/common/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -986,15 +986,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
30 changes: 28 additions & 2 deletions orderer/common/server/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ package server

import (
"fmt"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/orderer/common/filerepo"
"io/ioutil"
"net"
"net/http"
Expand All @@ -20,6 +18,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 @@ -37,6 +36,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"
"github.com/hyperledger/fabric/orderer/common/onboarding"
Expand Down Expand Up @@ -763,6 +763,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 48d532f

Please sign in to comment.