Skip to content

Commit

Permalink
Merge "[FAB-2745] Update e2e_cli to work with TLS"
Browse files Browse the repository at this point in the history
  • Loading branch information
yacovm authored and Gerrit Code Review committed Mar 12, 2017
2 parents 783b24f + f8a49c0 commit 96b1b90
Show file tree
Hide file tree
Showing 20 changed files with 440 additions and 108 deletions.
23 changes: 14 additions & 9 deletions core/chaincode/platforms/platforms.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,22 @@ func GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) {
}

func getPeerTLSCert() ([]byte, error) {
path := viper.GetString("peer.tls.cert.file")
if _, err := os.Stat(path); err != nil {

if os.IsNotExist(err) && viper.GetBool("peer.tls.enabled") == false {
// It's not an error if the file doesn't exist but TLS is disabled anyway
return nil, nil
}

if viper.GetBool("peer.tls.enabled") == false {
// no need for certificates if TLS is not enabled
return nil, nil
}
var path string
// first we check for the rootcert
path = viper.GetString("peer.tls.rootcert.file")
if path == "" {
// check for tls cert
path = viper.GetString("peer.tls.cert.file")
}
// this should not happen if the peer is running with TLS enabled
if _, err := os.Stat(path); err != nil {
return nil, err
}

// FIXME: FAB-2037 - ensure we sanely resolve relative paths specified in the yaml
return ioutil.ReadFile(path)
}
Expand Down Expand Up @@ -119,7 +124,7 @@ func generateDockerfile(platform Platform, cds *pb.ChaincodeDeploymentSpec, tls
if tls {
const guestTLSPath = "/etc/hyperledger/fabric/peer.crt"

buf = append(buf, "ENV CORE_PEER_TLS_CERT_FILE="+guestTLSPath)
buf = append(buf, "ENV CORE_PEER_TLS_ROOTCERT_FILE="+guestTLSPath)
buf = append(buf, "COPY peer.crt "+guestTLSPath)
}

Expand Down
107 changes: 105 additions & 2 deletions core/comm/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ limitations under the License.
package comm

import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"os"
"sync"
"time"

"google.golang.org/grpc"
Expand All @@ -31,6 +35,105 @@ import (
const defaultTimeout = time.Second * 3

var commLogger = logging.MustGetLogger("comm")
var caSupport *CASupport
var once sync.Once

// CASupport type manages certificate authorities scoped by channel
type CASupport struct {
sync.RWMutex
AppRootCAsByChain map[string][][]byte
OrdererRootCAsByChain map[string][][]byte
ClientRootCAs [][]byte
ServerRootCAs [][]byte
}

// GetCASupport returns the signleton CASupport instance
func GetCASupport() *CASupport {

once.Do(func() {
caSupport = &CASupport{
AppRootCAsByChain: make(map[string][][]byte),
OrdererRootCAsByChain: make(map[string][][]byte),
}
})
return caSupport
}

// GetServerRootCAs returns the PEM-encoded root certificates for all of the
// application and orderer organizations defined for all chains. The root
// certificates returned should be used to set the trusted server roots for
// TLS clients.
func (cas *CASupport) GetServerRootCAs() (appRootCAs, ordererRootCAs [][]byte) {
cas.RLock()
defer cas.RUnlock()

appRootCAs = [][]byte{}
ordererRootCAs = [][]byte{}

for _, appRootCA := range cas.AppRootCAsByChain {
appRootCAs = append(appRootCAs, appRootCA...)
}

for _, ordererRootCA := range cas.AppRootCAsByChain {
ordererRootCAs = append(ordererRootCAs, ordererRootCA...)
}

// also need to append statically configured root certs
appRootCAs = append(appRootCAs, cas.ServerRootCAs...)
ordererRootCAs = append(ordererRootCAs, cas.ServerRootCAs...)
return appRootCAs, ordererRootCAs
}

// GetDeliverServiceCredentials returns GRPC transport credentials for use by GRPC
// clients which communicate with ordering service endpoints.
func (cas *CASupport) GetDeliverServiceCredentials() credentials.TransportCredentials {
var creds credentials.TransportCredentials
var tlsConfig = &tls.Config{}
var certPool = x509.NewCertPool()
// loop through the orderer CAs
_, roots := cas.GetServerRootCAs()
for _, root := range roots {
block, _ := pem.Decode(root)
if block != nil {
cert, err := x509.ParseCertificate(block.Bytes)
if err == nil {
certPool.AddCert(cert)
} else {
commLogger.Warningf("Failed to add root cert to credentials (%s)", err)
}
} else {
commLogger.Warning("Failed to add root cert to credentials")
}
}
tlsConfig.RootCAs = certPool
creds = credentials.NewTLS(tlsConfig)
return creds
}

// GetClientRootCAs returns the PEM-encoded root certificates for all of the
// application and orderer organizations defined for all chains. The root
// certificates returned should be used to set the trusted client roots for
// TLS servers.
func (cas *CASupport) GetClientRootCAs() (appRootCAs, ordererRootCAs [][]byte) {
cas.RLock()
defer cas.RUnlock()

appRootCAs = [][]byte{}
ordererRootCAs = [][]byte{}

for _, appRootCA := range cas.AppRootCAsByChain {
appRootCAs = append(appRootCAs, appRootCA...)
}

for _, ordererRootCA := range cas.AppRootCAsByChain {
ordererRootCAs = append(ordererRootCAs, ordererRootCA...)
}

// also need to append statically configured root certs
appRootCAs = append(appRootCAs, cas.ClientRootCAs...)
ordererRootCAs = append(ordererRootCAs, cas.ClientRootCAs...)
return appRootCAs, ordererRootCAs
}

func getEnv(key, def string) string {
val := os.Getenv(key)
Expand Down Expand Up @@ -71,9 +174,9 @@ func InitTLSForPeer() credentials.TransportCredentials {
sn = viper.GetString("peer.tls.serverhostoverride")
}
var creds credentials.TransportCredentials
if viper.GetString("peer.tls.cert.file") != "" {
if viper.GetString("peer.tls.rootcert.file") != "" {
var err error
creds, err = credentials.NewClientTLSFromFile(viper.GetString("peer.tls.cert.file"), sn)
creds, err = credentials.NewClientTLSFromFile(viper.GetString("peer.tls.rootcert.file"), sn)
if err != nil {
grpclog.Fatalf("Failed to create TLS credentials %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions core/deliverservice/deliveryclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ func NewDeliverService(gossip blocksprovider.GossipServiceAdapter, endpoints []s
dialOpts := []grpc.DialOption{grpc.WithTimeout(3 * time.Second), grpc.WithBlock()}

if comm.TLSEnabled() {
dialOpts = append(dialOpts, grpc.WithTransportCredentials(comm.InitTLSForPeer()))
dialOpts = append(dialOpts, grpc.WithTransportCredentials(comm.GetCASupport().GetDeliverServiceCredentials()))
} else {
dialOpts = append(dialOpts, grpc.WithInsecure())
}

grpc.EnableTracing = true
conn, err := grpc.Dial(endpoints[idx], dialOpts...)
if err != nil {
logger.Errorf("Cannot dial to %s, because of %s", endpoints[idx], err)
Expand Down
48 changes: 6 additions & 42 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,8 @@ var peerLogger = logging.MustGetLogger("peer")

var peerServer comm.GRPCServer

var rootCASupport = struct {
sync.RWMutex
appRootCAsByChain map[string][][]byte
ordererRootCAsByChain map[string][][]byte
}{
appRootCAsByChain: make(map[string][][]byte),
ordererRootCAsByChain: make(map[string][][]byte),
}
// singleton instance to manage CAs for the peer across channel config changes
var rootCASupport = comm.GetCASupport()

type chainSupport struct {
configtxapi.Manager
Expand Down Expand Up @@ -317,7 +311,7 @@ func GetCurrConfigBlock(cid string) *common.Block {
// updates the trusted roots for the peer based on updates to channels
func updateTrustedRoots(cm configtxapi.Manager) {
// this is triggered on per channel basis so first update the roots for the channel

peerLogger.Debugf("Updating trusted root authorities for channel %s", cm.ChainID())
var secureConfig comm.SecureServerConfig
var err error
// only run is TLS is enabled
Expand All @@ -329,7 +323,7 @@ func updateTrustedRoots(cm configtxapi.Manager) {
trustedRoots := [][]byte{}
rootCASupport.RLock()
defer rootCASupport.RUnlock()
for _, roots := range rootCASupport.appRootCAsByChain {
for _, roots := range rootCASupport.AppRootCAsByChain {
trustedRoots = append(trustedRoots, roots...)
}
// also need to append statically configured root certs
Expand Down Expand Up @@ -395,41 +389,11 @@ func buildTrustedRootsForChain(cm configtxapi.Manager) {
}
// TODO: separate app and orderer CAs
ordererRootCAs = appRootCAs
rootCASupport.appRootCAsByChain[cid] = appRootCAs
rootCASupport.ordererRootCAsByChain[cid] = ordererRootCAs
rootCASupport.AppRootCAsByChain[cid] = appRootCAs
rootCASupport.OrdererRootCAsByChain[cid] = ordererRootCAs
}
}

// GetRootCAs returns the PEM-encoded root certificates for all of the
// application and orderer organizations defined for all chains
func GetRootCAs() (appRootCAs, ordererRootCAs [][]byte) {
rootCASupport.RLock()
defer rootCASupport.RUnlock()

appRootCAs = [][]byte{}
ordererRootCAs = [][]byte{}

for _, appRootCA := range rootCASupport.appRootCAsByChain {
appRootCAs = append(appRootCAs, appRootCA...)
}
// also need to append statically configured root certs
secureConfig, err := GetSecureConfig()
if err == nil {
if len(secureConfig.ClientRootCAs) > 0 {
appRootCAs = append(appRootCAs, secureConfig.ClientRootCAs...)
}
if len(secureConfig.ServerRootCAs) > 0 {
appRootCAs = append(appRootCAs, secureConfig.ServerRootCAs...)
}
}

for _, ordererRootCA := range rootCASupport.appRootCAsByChain {
ordererRootCAs = append(ordererRootCAs, ordererRootCA...)
}

return appRootCAs, ordererRootCAs
}

// GetMSPIDs returns the ID of each application MSP defined on this chain
func GetMSPIDs(cid string) []string {
chains.RLock()
Expand Down
6 changes: 0 additions & 6 deletions core/peer/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@ func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []s
return &mockDeliveryClient{}, nil
}

func TestGetRootCAsNoChains(t *testing.T) {
appRootCAs, ordererRootCAs := GetRootCAs()
assert.Equal(t, len(appRootCAs), 0, "Expected zero appRootCAs")
assert.Equal(t, len(ordererRootCAs), 0, "Expected zero ordererRootCAs")
}

func TestInitialize(t *testing.T) {
viper.Set("peer.fileSystemPath", "/var/hyperledger/test/")

Expand Down
2 changes: 1 addition & 1 deletion core/peer/pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func TestCreatePeerServer(t *testing.T) {
t.Fatalf("Failed to create config block (%s)", err)
}
t.Logf("Channel %s MSPIDs: (%s)", cid, peer.GetMSPIDs(cid))
appCAs, orgCAs := peer.GetRootCAs()
appCAs, orgCAs := comm.GetCASupport().GetClientRootCAs()
t.Logf("appCAs after update for channel %s: %d", cid, len(appCAs))
t.Logf("orgCAs after update for channel %s: %d", cid, len(orgCAs))
}
Expand Down
2 changes: 1 addition & 1 deletion examples/ccchecker/ccchecker.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func CCCheckerInit() {
//CCCheckerRun main loops that will run the tests and cleanup
func CCCheckerRun(orderingEndpoint string, report bool, verbose bool) error {
//connect with Broadcast client
bc, err := common.GetBroadcastClient(orderingEndpoint)
bc, err := common.GetBroadcastClient(orderingEndpoint, false, "")
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion examples/e2e_cli/configtx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Orderer: &OrdererDefaults
OrdererType: solo

Addresses:
- orderer:7050
- orderer0:7050

# Batch Timeout: The amount of time to wait before creating a batch
BatchTimeout: 10s
Expand Down
Loading

0 comments on commit 96b1b90

Please sign in to comment.