Skip to content

Commit

Permalink
[FAB-8141] moved out impl from api
Browse files Browse the repository at this point in the history
	this was done for code found in
	fabric-sdk-go/pkg/context/api/core/network.go

	also renamed urlutil package to endpoint and moved
	TLSConfig impl in there

Change-Id: I179589a09d9ebc320d2a02558d250a4249f97808
Signed-off-by: Baha Shaaban <baha.shaaban@securekey.com>
  • Loading branch information
Baha Shaaban committed Mar 9, 2018
1 parent c2e04b5 commit c9bd65a
Show file tree
Hide file tree
Showing 17 changed files with 373 additions and 160 deletions.
6 changes: 3 additions & 3 deletions pkg/client/common/discovery/greylist/greylist.go
Expand Up @@ -11,7 +11,7 @@ import (
"time"

"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/urlutil"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/status"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
)
Expand All @@ -34,7 +34,7 @@ func New(expire time.Duration) *Filter {

// Accept returns whether or not to Accept a peer as a canditate for endorsement
func (b *Filter) Accept(peer fab.Peer) bool {
peerAddress := urlutil.ToAddress(peer.URL())
peerAddress := endpoint.ToAddress(peer.URL())
value, ok := b.greylistURLs.Load(peerAddress)
if ok {
timeAdded, ok := value.(time.Time)
Expand Down Expand Up @@ -75,7 +75,7 @@ func peerURLFromConnectionFailedStatus(details []interface{}) string {
if len(details) != 0 {
url, ok := details[0].(string)
if ok {
return urlutil.ToAddress(url)
return endpoint.ToAddress(url)
}
}
return ""
Expand Down
76 changes: 7 additions & 69 deletions pkg/context/api/core/network.go
Expand Up @@ -7,12 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package core

import (
"crypto/x509"
"encoding/pem"
"io/ioutil"

"github.com/hyperledger/fabric-sdk-go/pkg/errors/status"
"github.com/pkg/errors"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint"
)

// NetworkConfig provides a static definition of a Hyperledger Fabric network
Expand Down Expand Up @@ -102,23 +97,23 @@ type OrganizationConfig struct {
Users map[string]TLSKeyPair
Peers []string
CertificateAuthorities []string
AdminPrivateKey TLSConfig
SignedCert TLSConfig
AdminPrivateKey endpoint.TLSConfig
SignedCert endpoint.TLSConfig
}

// OrdererConfig defines an orderer configuration
type OrdererConfig struct {
URL string
GRPCOptions map[string]interface{}
TLSCACerts TLSConfig
TLSCACerts endpoint.TLSConfig
}

// PeerConfig defines a peer configuration
type PeerConfig struct {
URL string
EventURL string
GRPCOptions map[string]interface{}
TLSCACerts TLSConfig
TLSCACerts endpoint.TLSConfig
}

// CAConfig defines a CA configuration
Expand All @@ -136,63 +131,6 @@ type EnrollCredentials struct {
EnrollSecret string
}

// TLSConfig TLS configurations
type TLSConfig struct {
// the following two fields are interchangeable.
// If Path is available, then it will be used to load the cert
// if Pem is available, then it has the raw data of the cert it will be used as-is
// Certificate root certificate path
Path string
// Certificate actual content
Pem string
}

// Bytes returns the tls certificate as a byte array by loading it either from the embedded Pem or Path
func (cfg TLSConfig) Bytes() ([]byte, error) {
var bytes []byte
var err error

if cfg.Pem != "" {
bytes = []byte(cfg.Pem)
} else if cfg.Path != "" {
bytes, err = ioutil.ReadFile(cfg.Path)

if err != nil {
return nil, errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path)
}
}

return bytes, nil
}

// TLSCert returns the tls certificate as a *x509.Certificate by loading it either from the embedded Pem or Path
func (cfg TLSConfig) TLSCert() (*x509.Certificate, error) {
bytes, err := cfg.Bytes()

if err != nil {
return nil, err
}

return loadCert(bytes)
}

// loadCAKey
func loadCert(rawData []byte) (*x509.Certificate, error) {
block, _ := pem.Decode(rawData)

if block != nil {
pub, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.Wrap(err, "certificate parsing failed")
}

return pub, nil
}

// return an error with an error code for clients to test against status.EmptyCert code
return nil, status.New(status.ClientStatus, status.EmptyCert.ToInt32(), "pem data missing", nil)
}

// MutualTLSConfig Mutual TLS configurations
type MutualTLSConfig struct {
Pem []string
Expand All @@ -205,8 +143,8 @@ type MutualTLSConfig struct {

// TLSKeyPair contains the private key and certificate for TLS encryption
type TLSKeyPair struct {
Key TLSConfig
Cert TLSConfig
Key endpoint.TLSConfig
Cert endpoint.TLSConfig
}

// MatchConfig contains match pattern and substitution pattern
Expand Down
8 changes: 4 additions & 4 deletions pkg/core/config/config.go
Expand Up @@ -24,7 +24,7 @@ import (

"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/cryptoutil"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/urlutil"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
"github.com/pkg/errors"

Expand Down Expand Up @@ -652,7 +652,7 @@ func (c *Config) PeersConfig(org string) ([]core.PeerConfig, error) {

for _, peerName := range peersConfig {
p := config.Peers[strings.ToLower(peerName)]
if err = c.verifyPeerConfig(p, peerName, urlutil.IsTLSEnabled(p.URL)); err != nil {
if err = c.verifyPeerConfig(p, peerName, endpoint.IsTLSEnabled(p.URL)); err != nil {
matchingPeerConfig, matchErr := c.tryMatchingPeerConfig(peerName)
if matchErr != nil {
return nil, errors.WithMessage(err, "unable to find Peer Config")
Expand Down Expand Up @@ -1046,7 +1046,7 @@ func (c *Config) ChannelPeers(name string) ([]core.ChannelPeer, error) {
p = *matchingPeerConfig
}

if err = c.verifyPeerConfig(p, peerName, urlutil.IsTLSEnabled(p.URL)); err != nil {
if err = c.verifyPeerConfig(p, peerName, endpoint.IsTLSEnabled(p.URL)); err != nil {
return nil, err
}

Expand Down Expand Up @@ -1081,7 +1081,7 @@ func (c *Config) NetworkPeers() ([]core.NetworkPeer, error) {

for name, p := range netConfig.Peers {

if err = c.verifyPeerConfig(p, name, urlutil.IsTLSEnabled(p.URL)); err != nil {
if err = c.verifyPeerConfig(p, name, endpoint.IsTLSEnabled(p.URL)); err != nil {
return nil, err
}

Expand Down
13 changes: 7 additions & 6 deletions pkg/core/config/config_test.go
Expand Up @@ -20,6 +20,7 @@ import (
"reflect"

api "github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
"github.com/pkg/errors"
"github.com/spf13/viper"
Expand Down Expand Up @@ -286,7 +287,7 @@ func TestTLSCAConfig(t *testing.T) {
//Test TLSCA Cert Pool (Positive test case)

certFile, _ := configImpl.CAClientCertPath(org1)
certConfig := api.TLSConfig{Path: certFile}
certConfig := endpoint.TLSConfig{Path: certFile}

cert, err := certConfig.TLSCert()

Expand All @@ -301,7 +302,7 @@ func TestTLSCAConfig(t *testing.T) {
}
//Test TLSCA Cert Pool (Negative test case)

badCertConfig := api.TLSConfig{Path: "some random invalid path"}
badCertConfig := endpoint.TLSConfig{Path: "some random invalid path"}

badCert, err := badCertConfig.TLSCert()

Expand All @@ -313,7 +314,7 @@ func TestTLSCAConfig(t *testing.T) {

keyFile, _ := configImpl.CAClientKeyPath(org1)

keyConfig := api.TLSConfig{Path: keyFile}
keyConfig := endpoint.TLSConfig{Path: keyFile}

key, err := keyConfig.TLSCert()

Expand All @@ -333,7 +334,7 @@ func TestTLSCAConfigFromPems(t *testing.T) {
//Test TLSCA Cert Pool (Positive test case)

certPem, _ := c.CAClientCertPem(org1)
certConfig := api.TLSConfig{Pem: certPem}
certConfig := endpoint.TLSConfig{Pem: certPem}

cert, err := certConfig.TLSCert()

Expand All @@ -348,7 +349,7 @@ func TestTLSCAConfigFromPems(t *testing.T) {
}
//Test TLSCA Cert Pool (Negative test case)

badCertConfig := api.TLSConfig{Pem: "some random invalid pem"}
badCertConfig := endpoint.TLSConfig{Pem: "some random invalid pem"}

badCert, err := badCertConfig.TLSCert()

Expand All @@ -360,7 +361,7 @@ func TestTLSCAConfigFromPems(t *testing.T) {

keyPem, _ := configImpl.CAClientKeyPem(org1)

keyConfig := api.TLSConfig{Pem: keyPem}
keyConfig := endpoint.TLSConfig{Pem: keyPem}

key, err := keyConfig.TLSCert()

Expand Down
116 changes: 116 additions & 0 deletions pkg/core/config/endpoint/endpoint.go
@@ -0,0 +1,116 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package endpoint

import (
"crypto/x509"
"encoding/pem"
"io/ioutil"
"strings"

"regexp"

"github.com/hyperledger/fabric-sdk-go/pkg/errors/status"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
"github.com/pkg/errors"
)

var logger = logging.NewLogger("fabsdk/core")

// IsTLSEnabled is a generic function that expects a URL and verifies if it has
// a prefix HTTPS or GRPCS to return true for TLS Enabled URLs or false otherwise
func IsTLSEnabled(url string) bool {
tlsURL := strings.ToLower(url)
if strings.HasPrefix(tlsURL, "https://") || strings.HasPrefix(tlsURL, "grpcs://") {
return true
}
return false
}

// ToAddress is a utility function to trim the GRPC protocol prefix as it is not needed by GO
// if the GRPC protocol is not found, the url is returned unchanged
func ToAddress(url string) string {
if strings.HasPrefix(url, "grpc://") {
return strings.TrimPrefix(url, "grpc://")
}
if strings.HasPrefix(url, "grpcs://") {
return strings.TrimPrefix(url, "grpcs://")
}
return url
}

//AttemptSecured is a utility function which verifies URL and returns if secured connections needs to established
// for protocol 'grpcs' in URL returns true
// for protocol 'grpc' in URL returns false
// for no protocol mentioned, returns !allowInSecure
func AttemptSecured(url string, allowInSecure bool) bool {
ok, err := regexp.MatchString(".*(?i)s://", url)
if ok && err == nil {
return true
} else if strings.Contains(url, "://") {
return false
} else {
return !allowInSecure
}
}

// TLSConfig TLS configuration used in the sdk's configs.
type TLSConfig struct {
// the following two fields are interchangeable.
// If Path is available, then it will be used to load the cert
// if Pem is available, then it has the raw data of the cert it will be used as-is
// Certificate root certificate path
Path string
// Certificate actual content
Pem string
}

// Bytes returns the tls certificate as a byte array by loading it either from the embedded Pem or Path
func (cfg TLSConfig) Bytes() ([]byte, error) {
var bytes []byte
var err error

if cfg.Pem != "" {
bytes = []byte(cfg.Pem)
} else if cfg.Path != "" {
bytes, err = ioutil.ReadFile(cfg.Path)

if err != nil {
return nil, errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path)
}
}

return bytes, nil
}

// TLSCert returns the tls certificate as a *x509.Certificate by loading it either from the embedded Pem or Path
func (cfg TLSConfig) TLSCert() (*x509.Certificate, error) {
bytes, err := cfg.Bytes()

if err != nil {
return nil, err
}

return loadCert(bytes)
}

// loadCAKey
func loadCert(rawData []byte) (*x509.Certificate, error) {
block, _ := pem.Decode(rawData)

if block != nil {
pub, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.Wrap(err, "certificate parsing failed")
}

return pub, nil
}

// return an error with an error code for clients to test against status.EmptyCert code
return nil, status.New(status.ClientStatus, status.EmptyCert.ToInt32(), "pem data missing", nil)
}

0 comments on commit c9bd65a

Please sign in to comment.