142 lines
3.8 KiB
Go
142 lines
3.8 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package comm
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"sync"
|
|
|
|
"github.com/hyperledger/fabric/common/channelconfig"
|
|
"github.com/hyperledger/fabric/common/flogging"
|
|
"github.com/hyperledger/fabric/msp"
|
|
"google.golang.org/grpc/credentials"
|
|
)
|
|
|
|
var commLogger = flogging.MustGetLogger("comm")
|
|
|
|
// CredentialSupport type manages credentials used for gRPC client connections
|
|
type CredentialSupport struct {
|
|
mutex sync.RWMutex
|
|
appRootCAsByChain map[string][][]byte
|
|
serverRootCAs [][]byte
|
|
clientCert tls.Certificate
|
|
}
|
|
|
|
// NewCredentialSupport creates a CredentialSupport instance.
|
|
func NewCredentialSupport(rootCAs ...[]byte) *CredentialSupport {
|
|
return &CredentialSupport{
|
|
appRootCAsByChain: make(map[string][][]byte),
|
|
serverRootCAs: rootCAs,
|
|
}
|
|
}
|
|
|
|
// SetClientCertificate sets the tls.Certificate to use for gRPC client
|
|
// connections
|
|
func (cs *CredentialSupport) SetClientCertificate(cert tls.Certificate) {
|
|
cs.mutex.Lock()
|
|
cs.clientCert = cert
|
|
cs.mutex.Unlock()
|
|
}
|
|
|
|
// GetClientCertificate returns the client certificate of the CredentialSupport
|
|
func (cs *CredentialSupport) GetClientCertificate() tls.Certificate {
|
|
cs.mutex.RLock()
|
|
defer cs.mutex.RUnlock()
|
|
return cs.clientCert
|
|
}
|
|
|
|
// GetPeerCredentials returns gRPC transport credentials for use by gRPC
|
|
// clients which communicate with remote peer endpoints.
|
|
func (cs *CredentialSupport) GetPeerCredentials() credentials.TransportCredentials {
|
|
cs.mutex.RLock()
|
|
defer cs.mutex.RUnlock()
|
|
|
|
var appRootCAs [][]byte
|
|
appRootCAs = append(appRootCAs, cs.serverRootCAs...)
|
|
for _, appRootCA := range cs.appRootCAsByChain {
|
|
appRootCAs = append(appRootCAs, appRootCA...)
|
|
}
|
|
|
|
certPool := x509.NewCertPool()
|
|
for _, appRootCA := range appRootCAs {
|
|
if !certPool.AppendCertsFromPEM(appRootCA) {
|
|
commLogger.Warningf("Failed adding certificates to peer's client TLS trust pool")
|
|
}
|
|
}
|
|
|
|
return credentials.NewTLS(&tls.Config{
|
|
Certificates: []tls.Certificate{cs.clientCert},
|
|
RootCAs: certPool,
|
|
})
|
|
}
|
|
|
|
func (cs *CredentialSupport) AppRootCAsByChain() [][]byte {
|
|
cs.mutex.RLock()
|
|
defer cs.mutex.RUnlock()
|
|
|
|
var trustedRoots [][]byte
|
|
// iterate over all roots for all app and orderer channels
|
|
for _, roots := range cs.appRootCAsByChain {
|
|
trustedRoots = append(trustedRoots, roots...)
|
|
}
|
|
return trustedRoots
|
|
}
|
|
|
|
// BuildTrustedRootsForChain populates the appRootCAs and orderRootCAs maps by
|
|
// getting the root and intermediate certs for all msps associated with the
|
|
// MSPManager.
|
|
func (cs *CredentialSupport) BuildTrustedRootsForChain(cm channelconfig.Resources) {
|
|
appOrgMSPs := make(map[string]struct{})
|
|
if ac, ok := cm.ApplicationConfig(); ok {
|
|
for _, appOrg := range ac.Organizations() {
|
|
appOrgMSPs[appOrg.MSPID()] = struct{}{}
|
|
}
|
|
}
|
|
|
|
ordOrgMSPs := make(map[string]struct{})
|
|
if ac, ok := cm.OrdererConfig(); ok {
|
|
for _, ordOrg := range ac.Organizations() {
|
|
ordOrgMSPs[ordOrg.MSPID()] = struct{}{}
|
|
}
|
|
}
|
|
|
|
cid := cm.ConfigtxValidator().ChannelID()
|
|
msps, err := cm.MSPManager().GetMSPs()
|
|
if err != nil {
|
|
commLogger.Errorf("Error getting root CAs for channel %s (%s)", cid, err)
|
|
return
|
|
}
|
|
|
|
var appRootCAs [][]byte
|
|
for k, v := range msps {
|
|
// we only support the fabric MSP
|
|
if v.GetType() != msp.FABRIC {
|
|
continue
|
|
}
|
|
|
|
for _, root := range v.GetTLSRootCerts() {
|
|
// check to see of this is an app org MSP
|
|
if _, ok := appOrgMSPs[k]; ok {
|
|
commLogger.Debugf("adding app root CAs for MSP [%s]", k)
|
|
appRootCAs = append(appRootCAs, root)
|
|
}
|
|
}
|
|
for _, intermediate := range v.GetTLSIntermediateCerts() {
|
|
// check to see of this is an app org MSP
|
|
if _, ok := appOrgMSPs[k]; ok {
|
|
commLogger.Debugf("adding app root CAs for MSP [%s]", k)
|
|
appRootCAs = append(appRootCAs, intermediate)
|
|
}
|
|
}
|
|
}
|
|
|
|
cs.mutex.Lock()
|
|
cs.appRootCAsByChain[cid] = appRootCAs
|
|
cs.mutex.Unlock()
|
|
}
|