Skip to content

Commit

Permalink
[FAB-6155] Add multiple certs for peer client TLS
Browse files Browse the repository at this point in the history
The GetPeerCredentials function only adds only a single
certificate to the pool, but it should add multiple in
order to handle certificates issued by an intermediate CA.
Add it in such a way so that we get more specific warning messages
if it fails.

Change-Id: Ia708775ff852ca3355c4693bc2ee739f5dadaf20
Signed-off-by: Keith Smith <[email protected]>
  • Loading branch information
Keith Smith committed Sep 15, 2017
1 parent b02e9f4 commit 239ac67
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 42 deletions.
15 changes: 4 additions & 11 deletions core/comm/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,12 @@ func (cas *CASupport) GetPeerCredentials(tlsCert tls.Certificate) credentials.Tr
Certificates: []tls.Certificate{tlsCert},
}
var certPool = x509.NewCertPool()
// loop through the orderer CAs
// loop through the server root 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")
err := AddPemToCertPool(root, certPool)
if err != nil {
commLogger.Warningf("Failed adding certificates to peer's client TLS trust pool: %s", err)
}
}
tlsConfig.RootCAs = certPool
Expand Down
31 changes: 0 additions & 31 deletions core/comm/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package comm
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"net"
Expand Down Expand Up @@ -332,33 +331,3 @@ func (gServer *grpcServerImpl) SetClientRootCAs(clientRoots [][]byte) error {
gServer.tlsConfig.ClientCAs = certPool
return nil
}

//utility function to parse PEM-encoded certs
func pemToX509Certs(pemCerts []byte) ([]*x509.Certificate, []string, error) {

//it's possible that multiple certs are encoded
certs := []*x509.Certificate{}
subjects := []string{}
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
/** TODO: check why msp does not add type to PEM header
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}
*/

cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, subjects, err
} else {
certs = append(certs, cert)
//extract and append the subject
subjects = append(subjects, string(cert.RawSubject))
}
}
return certs, subjects, nil
}
54 changes: 54 additions & 0 deletions core/comm/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package comm

import (
"crypto/x509"
"encoding/pem"
)

// AddPemToCertPool adds PEM-encoded certs to a cert pool
func AddPemToCertPool(pemCerts []byte, pool *x509.CertPool) error {
certs, _, err := pemToX509Certs(pemCerts)
if err != nil {
return err
}
for _, cert := range certs {
pool.AddCert(cert)
}
return nil
}

//utility function to parse PEM-encoded certs
func pemToX509Certs(pemCerts []byte) ([]*x509.Certificate, []string, error) {

//it's possible that multiple certs are encoded
certs := []*x509.Certificate{}
subjects := []string{}
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
/** TODO: check why msp does not add type to PEM header
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}
*/

cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, subjects, err
} else {
certs = append(certs, cert)
//extract and append the subject
subjects = append(subjects, string(cert.RawSubject))
}
}
return certs, subjects, nil
}

0 comments on commit 239ac67

Please sign in to comment.