Skip to content

Commit 1404a8b

Browse files
committed
[FAB-6808] Add mutual TLS config option for peer
Prior to this change, there was no way to actually configure the peer endpoints to use mutual TLS. * add config items to core.yaml for mutual TLS * modify GetSecureConfig to use these config items * moved TestGetSecureConfig function from peer_test.go to config_test.go where it belongs Change-Id: I1d03a383076f1f9358018626005fb85930ea3ecd Signed-off-by: Gari Singh <gari.r.singh@gmail.com>
1 parent 4fb3abd commit 1404a8b

File tree

4 files changed

+81
-68
lines changed

4 files changed

+81
-68
lines changed

core/peer/config.go

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166

177
// The 'viper' package for configuration handling is very flexible, but has
@@ -33,6 +23,7 @@ import (
3323
"fmt"
3424
"io/ioutil"
3525
"net"
26+
"path/filepath"
3627

3728
"github.com/spf13/viper"
3829

@@ -129,18 +120,34 @@ func GetSecureConfig() (comm.SecureServerConfig, error) {
129120
if secureConfig.UseTLS {
130121
// get the certs from the file system
131122
serverKey, err := ioutil.ReadFile(config.GetPath("peer.tls.key.file"))
123+
if err != nil {
124+
return secureConfig, fmt.Errorf("error loading TLS key (%s)", err)
125+
}
132126
serverCert, err := ioutil.ReadFile(config.GetPath("peer.tls.cert.file"))
133-
// must have both key and cert file
134127
if err != nil {
135-
return secureConfig, fmt.Errorf("Error loading TLS key and/or certificate (%s)", err)
128+
return secureConfig, fmt.Errorf("error loading TLS certificate (%s)", err)
136129
}
137130
secureConfig.ServerCertificate = serverCert
138131
secureConfig.ServerKey = serverKey
132+
secureConfig.RequireClientCert = viper.GetBool("peer.tls.clientAuthRequired")
133+
if secureConfig.RequireClientCert {
134+
var clientRoots [][]byte
135+
for _, file := range viper.GetStringSlice("peer.tls.clientRootCAs.files") {
136+
clientRoot, err := ioutil.ReadFile(
137+
config.TranslatePath(filepath.Dir(viper.ConfigFileUsed()), file))
138+
if err != nil {
139+
return secureConfig,
140+
fmt.Errorf("error loading client root CAs (%s)", err)
141+
}
142+
clientRoots = append(clientRoots, clientRoot)
143+
}
144+
secureConfig.ClientRootCAs = clientRoots
145+
}
139146
// check for root cert
140147
if config.GetPath("peer.tls.rootcert.file") != "" {
141148
rootCert, err := ioutil.ReadFile(config.GetPath("peer.tls.rootcert.file"))
142149
if err != nil {
143-
return secureConfig, fmt.Errorf("Error loading TLS root certificate (%s)", err)
150+
return secureConfig, fmt.Errorf("error loading TLS root certificate (%s)", err)
144151
}
145152
secureConfig.ServerRootCAs = [][]byte{rootCert}
146153
}

core/peer/config_test.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
11
/*
2-
Copyright IBM Corp. 2017 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166
package peer
177

188
import (
199
"net"
10+
"path/filepath"
2011
"testing"
2112

2213
"github.com/spf13/viper"
@@ -123,3 +114,43 @@ func TestConfiguration(t *testing.T) {
123114
})
124115
}
125116
}
117+
118+
func TestGetSecureConfig(t *testing.T) {
119+
120+
// good config without TLS
121+
viper.Set("peer.tls.enabled", false)
122+
sc, _ := GetSecureConfig()
123+
assert.Equal(t, false, sc.UseTLS, "SecureConfig.UseTLS should be false")
124+
125+
// good config with TLS
126+
viper.Set("peer.tls.enabled", true)
127+
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
128+
viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
129+
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org1-cert.pem"))
130+
sc, _ = GetSecureConfig()
131+
assert.Equal(t, true, sc.UseTLS, "SecureConfig.UseTLS should be true")
132+
assert.Equal(t, false, sc.RequireClientCert,
133+
"SecureConfig.RequireClientCert should be false")
134+
viper.Set("peer.tls.clientAuthRequired", true)
135+
viper.Set("peer.tls.clientRootCAs.files",
136+
[]string{filepath.Join("testdata", "Org1-cert.pem"),
137+
filepath.Join("testdata", "Org2-cert.pem")})
138+
sc, _ = GetSecureConfig()
139+
assert.Equal(t, true, sc.RequireClientCert,
140+
"SecureConfig.RequireClientCert should be true")
141+
assert.Equal(t, 2, len(sc.ClientRootCAs),
142+
"SecureConfig.ClientRootCAs should contain 2 entries")
143+
144+
// bad config with TLS
145+
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org11-cert.pem"))
146+
_, err := GetSecureConfig()
147+
assert.Error(t, err, "GetSecureConfig should return error with bad root cert path")
148+
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org11-cert.pem"))
149+
_, err = GetSecureConfig()
150+
assert.Error(t, err, "GetSecureConfig should return error with bad tls cert path")
151+
152+
// disable TLS for remaining tests
153+
viper.Set("peer.tls.enabled", false)
154+
viper.Set("peer.tls.clientAuthRequired", false)
155+
156+
}

core/peer/peer_test.go

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166

177
package peer
@@ -20,7 +10,6 @@ import (
2010
"fmt"
2111
"net"
2212
"os"
23-
"path/filepath"
2413
"testing"
2514

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

8473
}
8574

86-
func TestGetSecureConfig(t *testing.T) {
87-
88-
// good config without TLS
89-
viper.Set("peer.tls.enabled", false)
90-
sc, _ := GetSecureConfig()
91-
assert.Equal(t, false, sc.UseTLS, "SecureConfig.UseTLS should be false")
92-
93-
// good config with TLS
94-
viper.Set("peer.tls.enabled", true)
95-
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
96-
viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
97-
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org1-cert.pem"))
98-
sc, _ = GetSecureConfig()
99-
assert.Equal(t, true, sc.UseTLS, "SecureConfig.UseTLS should be true")
100-
101-
// bad config with TLS
102-
viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org11-cert.pem"))
103-
_, err := GetSecureConfig()
104-
assert.Error(t, err, "GetSecureConfig should return error with bad root cert path")
105-
viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org11-cert.pem"))
106-
_, err = GetSecureConfig()
107-
assert.Error(t, err, "GetSecureConfig should return error with bad tls cert path")
108-
109-
// disable TLS for remaining tests
110-
viper.Set("peer.tls.enabled", false)
111-
112-
}
113-
11475
func TestInitChain(t *testing.T) {
11576

11677
chainId := "testChain"

sampleconfig/core.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,27 @@ peer:
223223
# Note that peer-chaincode connections through chaincodeListenAddress is
224224
# not mutual TLS auth. See comments on chaincodeListenAddress for more info
225225
tls:
226+
# require server-side TLS
226227
enabled: false
228+
# require client certificates / mutual TLS.
229+
# note that clients that are not configured to use a certificate will
230+
# fail to connect to the peer.
231+
clientAuthRequired: false
232+
# X.509 certificate used for TLS server (and client if clientAuthEnabled
233+
# is set to true
227234
cert:
228235
file: tls/server.crt
236+
# private key used for TLS server (and client if clientAuthEnabled
237+
# is set to true
229238
key:
230239
file: tls/server.key
240+
# trusted root certificate chain for tls.cert
231241
rootcert:
232242
file: tls/ca.crt
243+
# set of root certificate authorities used to verify client certificates
244+
clientRootCAs:
245+
files:
246+
- tls/ca.crt
233247

234248
# The server name use to verify the hostname returned by TLS handshake
235249
serverhostoverride:

0 commit comments

Comments
 (0)