github.com/defanghe/fabric@v2.1.1+incompatible/internal/pkg/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 }