github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/core/comm/connection.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package comm
     8  
     9  import (
    10  	"crypto/tls"
    11  	"crypto/x509"
    12  	"sync"
    13  
    14  	"github.com/hyperledger/fabric/common/channelconfig"
    15  	"github.com/hyperledger/fabric/common/flogging"
    16  	"github.com/hyperledger/fabric/msp"
    17  	"google.golang.org/grpc/credentials"
    18  )
    19  
    20  var commLogger = flogging.MustGetLogger("comm")
    21  
    22  // CredentialSupport type manages credentials used for gRPC client connections
    23  type CredentialSupport struct {
    24  	mutex             sync.RWMutex
    25  	appRootCAsByChain map[string][][]byte
    26  	serverRootCAs     [][]byte
    27  	clientCert        tls.Certificate
    28  }
    29  
    30  // NewCredentialSupport creates a CredentialSupport instance.
    31  func NewCredentialSupport(rootCAs ...[]byte) *CredentialSupport {
    32  	return &CredentialSupport{
    33  		appRootCAsByChain: make(map[string][][]byte),
    34  		serverRootCAs:     rootCAs,
    35  	}
    36  }
    37  
    38  // SetClientCertificate sets the tls.Certificate to use for gRPC client
    39  // connections
    40  func (cs *CredentialSupport) SetClientCertificate(cert tls.Certificate) {
    41  	cs.mutex.Lock()
    42  	cs.clientCert = cert
    43  	cs.mutex.Unlock()
    44  }
    45  
    46  // GetClientCertificate returns the client certificate of the CredentialSupport
    47  func (cs *CredentialSupport) GetClientCertificate() tls.Certificate {
    48  	cs.mutex.RLock()
    49  	defer cs.mutex.RUnlock()
    50  	return cs.clientCert
    51  }
    52  
    53  // GetPeerCredentials returns gRPC transport credentials for use by gRPC
    54  // clients which communicate with remote peer endpoints.
    55  func (cs *CredentialSupport) GetPeerCredentials() credentials.TransportCredentials {
    56  	cs.mutex.RLock()
    57  	defer cs.mutex.RUnlock()
    58  
    59  	var appRootCAs [][]byte
    60  	appRootCAs = append(appRootCAs, cs.serverRootCAs...)
    61  	for _, appRootCA := range cs.appRootCAsByChain {
    62  		appRootCAs = append(appRootCAs, appRootCA...)
    63  	}
    64  
    65  	certPool := x509.NewCertPool()
    66  	for _, appRootCA := range appRootCAs {
    67  		err := AddPemToCertPool(appRootCA, certPool)
    68  		if err != nil {
    69  			commLogger.Warningf("Failed adding certificates to peer's client TLS trust pool: %s", err)
    70  		}
    71  	}
    72  
    73  	return credentials.NewTLS(&tls.Config{
    74  		Certificates: []tls.Certificate{cs.clientCert},
    75  		RootCAs:      certPool,
    76  	})
    77  }
    78  
    79  func (cs *CredentialSupport) AppRootCAsByChain() map[string][][]byte {
    80  	cs.mutex.RLock()
    81  	defer cs.mutex.RUnlock()
    82  	return cs.appRootCAsByChain
    83  }
    84  
    85  // BuildTrustedRootsForChain populates the appRootCAs and orderRootCAs maps by
    86  // getting the root and intermediate certs for all msps associated with the
    87  // MSPManager.
    88  func (cs *CredentialSupport) BuildTrustedRootsForChain(cm channelconfig.Resources) {
    89  	appOrgMSPs := make(map[string]struct{})
    90  	if ac, ok := cm.ApplicationConfig(); ok {
    91  		for _, appOrg := range ac.Organizations() {
    92  			appOrgMSPs[appOrg.MSPID()] = struct{}{}
    93  		}
    94  	}
    95  
    96  	ordOrgMSPs := make(map[string]struct{})
    97  	if ac, ok := cm.OrdererConfig(); ok {
    98  		for _, ordOrg := range ac.Organizations() {
    99  			ordOrgMSPs[ordOrg.MSPID()] = struct{}{}
   100  		}
   101  	}
   102  
   103  	cid := cm.ConfigtxValidator().ChannelID()
   104  	msps, err := cm.MSPManager().GetMSPs()
   105  	if err != nil {
   106  		commLogger.Errorf("Error getting root CAs for channel %s (%s)", cid, err)
   107  		return
   108  	}
   109  
   110  	var appRootCAs [][]byte
   111  	for k, v := range msps {
   112  		// we only support the fabric MSP
   113  		if v.GetType() != msp.FABRIC {
   114  			continue
   115  		}
   116  
   117  		for _, root := range v.GetTLSRootCerts() {
   118  			// check to see of this is an app org MSP
   119  			if _, ok := appOrgMSPs[k]; ok {
   120  				commLogger.Debugf("adding app root CAs for MSP [%s]", k)
   121  				appRootCAs = append(appRootCAs, root)
   122  			}
   123  		}
   124  		for _, intermediate := range v.GetTLSIntermediateCerts() {
   125  			// check to see of this is an app org MSP
   126  			if _, ok := appOrgMSPs[k]; ok {
   127  				commLogger.Debugf("adding app root CAs for MSP [%s]", k)
   128  				appRootCAs = append(appRootCAs, intermediate)
   129  			}
   130  		}
   131  	}
   132  
   133  	cs.mutex.Lock()
   134  	cs.appRootCAsByChain[cid] = appRootCAs
   135  	cs.mutex.Unlock()
   136  }