Skip to content

Commit

Permalink
Merge "[FAB-6808] Add mutual TLS config option for peer"
Browse files Browse the repository at this point in the history
  • Loading branch information
hacera-jonathan authored and Gerrit Code Review committed Oct 31, 2017
2 parents f2caf57 + 1404a8b commit 2773a8e
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 68 deletions.
37 changes: 22 additions & 15 deletions core/peer/config.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Copyright IBM Corp. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/

// The 'viper' package for configuration handling is very flexible, but has
Expand All @@ -33,6 +23,7 @@ import (
"fmt"
"io/ioutil"
"net"
"path/filepath"

"github.com/spf13/viper"

Expand Down Expand Up @@ -129,18 +120,34 @@ func GetSecureConfig() (comm.SecureServerConfig, error) {
if secureConfig.UseTLS {
// get the certs from the file system
serverKey, err := ioutil.ReadFile(config.GetPath("peer.tls.key.file"))
if err != nil {
return secureConfig, fmt.Errorf("error loading TLS key (%s)", err)
}
serverCert, err := ioutil.ReadFile(config.GetPath("peer.tls.cert.file"))
// must have both key and cert file
if err != nil {
return secureConfig, fmt.Errorf("Error loading TLS key and/or certificate (%s)", err)
return secureConfig, fmt.Errorf("error loading TLS certificate (%s)", err)
}
secureConfig.ServerCertificate = serverCert
secureConfig.ServerKey = serverKey
secureConfig.RequireClientCert = viper.GetBool("peer.tls.clientAuthRequired")
if secureConfig.RequireClientCert {
var clientRoots [][]byte
for _, file := range viper.GetStringSlice("peer.tls.clientRootCAs.files") {
clientRoot, err := ioutil.ReadFile(
config.TranslatePath(filepath.Dir(viper.ConfigFileUsed()), file))
if err != nil {
return secureConfig,
fmt.Errorf("error loading client root CAs (%s)", err)
}
clientRoots = append(clientRoots, clientRoot)
}
secureConfig.ClientRootCAs = clientRoots
}
// check for root cert
if config.GetPath("peer.tls.rootcert.file") != "" {
rootCert, err := ioutil.ReadFile(config.GetPath("peer.tls.rootcert.file"))
if err != nil {
return secureConfig, fmt.Errorf("Error loading TLS root certificate (%s)", err)
return secureConfig, fmt.Errorf("error loading TLS root certificate (%s)", err)
}
secureConfig.ServerRootCAs = [][]byte{rootCert}
}
Expand Down
55 changes: 43 additions & 12 deletions core/peer/config_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Copyright IBM Corp. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package peer

import (
"net"
"path/filepath"
"testing"

"github.com/spf13/viper"
Expand Down Expand Up @@ -123,3 +114,43 @@ func TestConfiguration(t *testing.T) {
})
}
}

func TestGetSecureConfig(t *testing.T) {

// good config without TLS
viper.Set("peer.tls.enabled", false)
sc, _ := GetSecureConfig()
assert.Equal(t, false, sc.UseTLS, "SecureConfig.UseTLS should be false")

// good config with TLS
viper.Set("peer.tls.enabled", true)
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org1-cert.pem"))
sc, _ = GetSecureConfig()
assert.Equal(t, true, sc.UseTLS, "SecureConfig.UseTLS should be true")
assert.Equal(t, false, sc.RequireClientCert,
"SecureConfig.RequireClientCert should be false")
viper.Set("peer.tls.clientAuthRequired", true)
viper.Set("peer.tls.clientRootCAs.files",
[]string{filepath.Join("testdata", "Org1-cert.pem"),
filepath.Join("testdata", "Org2-cert.pem")})
sc, _ = GetSecureConfig()
assert.Equal(t, true, sc.RequireClientCert,
"SecureConfig.RequireClientCert should be true")
assert.Equal(t, 2, len(sc.ClientRootCAs),
"SecureConfig.ClientRootCAs should contain 2 entries")

// bad config with TLS
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org11-cert.pem"))
_, err := GetSecureConfig()
assert.Error(t, err, "GetSecureConfig should return error with bad root cert path")
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org11-cert.pem"))
_, err = GetSecureConfig()
assert.Error(t, err, "GetSecureConfig should return error with bad tls cert path")

// disable TLS for remaining tests
viper.Set("peer.tls.enabled", false)
viper.Set("peer.tls.clientAuthRequired", false)

}
43 changes: 2 additions & 41 deletions core/peer/peer_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Copyright IBM Corp. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/

package peer
Expand All @@ -20,7 +10,6 @@ import (
"fmt"
"net"
"os"
"path/filepath"
"testing"

configtxtest "github.com/hyperledger/fabric/common/configtx/test"
Expand Down Expand Up @@ -83,34 +72,6 @@ func TestCreatePeerServer(t *testing.T) {

}

func TestGetSecureConfig(t *testing.T) {

// good config without TLS
viper.Set("peer.tls.enabled", false)
sc, _ := GetSecureConfig()
assert.Equal(t, false, sc.UseTLS, "SecureConfig.UseTLS should be false")

// good config with TLS
viper.Set("peer.tls.enabled", true)
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org1-cert.pem"))
sc, _ = GetSecureConfig()
assert.Equal(t, true, sc.UseTLS, "SecureConfig.UseTLS should be true")

// bad config with TLS
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org11-cert.pem"))
_, err := GetSecureConfig()
assert.Error(t, err, "GetSecureConfig should return error with bad root cert path")
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org11-cert.pem"))
_, err = GetSecureConfig()
assert.Error(t, err, "GetSecureConfig should return error with bad tls cert path")

// disable TLS for remaining tests
viper.Set("peer.tls.enabled", false)

}

func TestInitChain(t *testing.T) {

chainId := "testChain"
Expand Down
14 changes: 14 additions & 0 deletions sampleconfig/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,27 @@ peer:
# Note that peer-chaincode connections through chaincodeListenAddress is
# not mutual TLS auth. See comments on chaincodeListenAddress for more info
tls:
# require server-side TLS
enabled: false
# require client certificates / mutual TLS.
# note that clients that are not configured to use a certificate will
# fail to connect to the peer.
clientAuthRequired: false
# X.509 certificate used for TLS server (and client if clientAuthEnabled
# is set to true
cert:
file: tls/server.crt
# private key used for TLS server (and client if clientAuthEnabled
# is set to true
key:
file: tls/server.key
# trusted root certificate chain for tls.cert
rootcert:
file: tls/ca.crt
# set of root certificate authorities used to verify client certificates
clientRootCAs:
files:
- tls/ca.crt

# The server name use to verify the hostname returned by TLS handshake
serverhostoverride:
Expand Down

0 comments on commit 2773a8e

Please sign in to comment.