Skip to content

Commit

Permalink
Merge "[FAB-2714] Enable peer to start with TLS enabled"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Yellick authored and Gerrit Code Review committed Mar 10, 2017
2 parents a976c50 + 1f49bfb commit 3295920
Show file tree
Hide file tree
Showing 17 changed files with 412 additions and 8 deletions.
5 changes: 3 additions & 2 deletions core/comm/testdata/certs/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ func genServerCertificateECDSA(name string, signKey *ecdsa.PrivateKey, signCert
return err
}

template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth}

//set the organization for the subject
subject := subjectTemplate()
Expand Down Expand Up @@ -262,7 +263,7 @@ func main() {
}
}
//generate client certificates for the org
for k := 1; k <= *numServerCerts; k++ {
for k := 1; k <= *numClientCerts; k++ {
err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-client%d", i, k), signKey, signCert)
if err != nil {
fmt.Printf("error generating client certificate for %s%d-client%d : %s\n",
Expand Down
21 changes: 21 additions & 0 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import (

var peerLogger = logging.MustGetLogger("peer")

var peerServer comm.GRPCServer

type chainSupport struct {
configtxapi.Manager
config.Application
Expand Down Expand Up @@ -404,3 +406,22 @@ func (c *channelPolicyManagerGetter) Manager(channelID string) (policies.Manager
policyManager := GetPolicyManager(channelID)
return policyManager, policyManager != nil
}

// CreatePeerServer creates an instance of comm.GRPCServer
// This server is used for peer communications
func CreatePeerServer(listenAddress string,
secureConfig comm.SecureServerConfig) (comm.GRPCServer, error) {

var err error
peerServer, err = comm.NewGRPCServer(listenAddress, secureConfig)
if err != nil {
peerLogger.Errorf("Failed to create peer server (%s)", err)
return nil, err
}
return peerServer, nil
}

// GetPeerServer returns the peer server instance
func GetPeerServer() comm.GRPCServer {
return peerServer
}
215 changes: 215 additions & 0 deletions core/peer/pkg_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
Copyright IBM Corp. 2017 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.
*/

package peer_test

import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"path/filepath"
"testing"
"time"

"google.golang.org/grpc/credentials"

"golang.org/x/net/context"
"google.golang.org/grpc"

"github.com/hyperledger/fabric/core/comm"
testpb "github.com/hyperledger/fabric/core/comm/testdata/grpc"
"github.com/hyperledger/fabric/core/peer"
"github.com/stretchr/testify/assert"
)

// default timeout for grpc connections
var timeout = time.Second * 1

// test server to be registered with the GRPCServer
type testServiceServer struct{}

func (tss *testServiceServer) EmptyCall(context.Context, *testpb.Empty) (*testpb.Empty, error) {
return new(testpb.Empty), nil
}

// createCertPool creates an x509.CertPool from an array of PEM-encoded certificates
func createCertPool(rootCAs [][]byte) (*x509.CertPool, error) {

certPool := x509.NewCertPool()
for _, rootCA := range rootCAs {
if !certPool.AppendCertsFromPEM(rootCA) {
return nil, errors.New("Failed to load root certificates")
}
}
return certPool, nil
}

// helper function to invoke the EmptyCall againt the test service
func invokeEmptyCall(address string, dialOptions []grpc.DialOption) (*testpb.Empty, error) {

//add DialOptions
dialOptions = append(dialOptions, grpc.WithBlock())
dialOptions = append(dialOptions, grpc.WithTimeout(timeout))
//create GRPC client conn
clientConn, err := grpc.Dial(address, dialOptions...)
if err != nil {
return nil, err
}
defer clientConn.Close()

//create GRPC client
client := testpb.NewTestServiceClient(clientConn)

ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()

//invoke service
empty, err := client.EmptyCall(ctx, new(testpb.Empty))
if err != nil {
return nil, err
}

return empty, nil
}

func TestCreatePeerServer(t *testing.T) {

t.Parallel()

// load test certs from testdata
org1CA, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-cert.pem"))
org1Server1Key, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-server1-key.pem"))
org1Server1Cert, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-server1-cert.pem"))
org2CA, err := ioutil.ReadFile(filepath.Join("testdata", "Org2-cert.pem"))
org2Server1Key, err := ioutil.ReadFile(filepath.Join("testdata", "Org2-server1-key.pem"))
org2Server1Cert, err := ioutil.ReadFile(filepath.Join("testdata", "Org2-server1-cert.pem"))

if err != nil {
t.Fatalf("Failed to load test certificates: %v", err)
}

org1CertPool, err := createCertPool([][]byte{org1CA})
org2CertPool, err := createCertPool([][]byte{org2CA})

if err != nil {
t.Fatalf("Failed to load root certificates into pool: %v", err)
}

org1Creds := credentials.NewClientTLSFromCert(org1CertPool, "")
org2Creds := credentials.NewClientTLSFromCert(org2CertPool, "")

// use server cert as client cert
org2ClientCert, err := tls.X509KeyPair(org2Server1Cert, org2Server1Key)
if err != nil {
t.Fatalf("Failed to load client certificate: %v", err)
}
org1Org2Creds := credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{org2ClientCert},
RootCAs: org1CertPool,
})

// basic function tests
var tests = []struct {
name string
listenAddress string
secureConfig comm.SecureServerConfig
expectError bool
goodOptions []grpc.DialOption
badOptions []grpc.DialOption
}{
{
name: "NoTLS",
listenAddress: fmt.Sprintf("localhost:%d", 4050),
secureConfig: comm.SecureServerConfig{
UseTLS: false,
},
expectError: false,
goodOptions: []grpc.DialOption{grpc.WithInsecure()},
badOptions: []grpc.DialOption{grpc.WithTransportCredentials(org1Creds)},
},
{
name: "BadAddress",
listenAddress: "badaddress",
secureConfig: comm.SecureServerConfig{
UseTLS: false,
},
expectError: true,
},
{
name: "ServerTLSOrg1",
listenAddress: fmt.Sprintf("localhost:%d", 4051),
secureConfig: comm.SecureServerConfig{
UseTLS: true,
ServerCertificate: org1Server1Cert,
ServerKey: org1Server1Key,
ServerRootCAs: [][]byte{org1CA},
},
expectError: false,
goodOptions: []grpc.DialOption{grpc.WithTransportCredentials(org1Creds)},
badOptions: []grpc.DialOption{grpc.WithTransportCredentials(org2Creds)},
},
{
name: "MutualTLSOrg1Org2",
listenAddress: fmt.Sprintf("localhost:%d", 4052),
secureConfig: comm.SecureServerConfig{
UseTLS: true,
ServerCertificate: org1Server1Cert,
ServerKey: org1Server1Key,
ServerRootCAs: [][]byte{org1CA},
ClientRootCAs: [][]byte{org1CA, org2CA},
RequireClientCert: true,
},
expectError: false,
goodOptions: []grpc.DialOption{grpc.WithTransportCredentials(org1Org2Creds)},
badOptions: []grpc.DialOption{grpc.WithTransportCredentials(org1Creds)},
},
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
t.Logf("Running test %s ...", test.name)

_, err := peer.CreatePeerServer(test.listenAddress, test.secureConfig)
// check to see whether to not we expect an error
// we don't check the exact error because the comm package covers these cases
if test.expectError {
assert.Error(t, err, "CreatePeerServer should have returned an error")
} else {
assert.NoError(t, err, "CreatePeerServer should not have returned an error")
// get the server from peer
peerServer := peer.GetPeerServer()
assert.NotNil(t, peerServer, "GetPeerServer should not return a nil value")
// register a GRPC test service
testpb.RegisterTestServiceServer(peerServer.Server(), &testServiceServer{})
go peerServer.Start()
defer peerServer.Stop()

//invoke the EmptyCall service with good options
_, err = invokeEmptyCall(test.listenAddress, test.goodOptions)
assert.NoError(t, err, "Failed to invoke the EmptyCall service")
//invoke the EmptyCall service with bad options
_, err = invokeEmptyCall(test.listenAddress, test.badOptions)
assert.Error(t, err, "Expected error using bad dial options")

}
})
}
}
13 changes: 13 additions & 0 deletions core/peer/testdata/Org1-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB4jCCAYigAwIBAgIQGm/MiEzhl9NQB7VQsWTwpzAKBggqhkjOPQQDAjBYMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzENMAsGA1UEChMET3JnMTENMAsGA1UEAxMET3JnMTAeFw0xNzAzMDkx
MjE4NDBaFw0yNzAzMDcxMjE4NDBaMFgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
YWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKEwRPcmcx
MQ0wCwYDVQQDEwRPcmcxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEU70ukwCU
MIU7v7GTm2iQDPansRjHctQXiz3wLwTjnkxmCnvWG6DzkkOUTFrGQgC/BuUXnT+e
pVVYPHv3pyxXV6M0MDIwDgYDVR0PAQH/BAQDAgGmMA8GA1UdJQQIMAYGBFUdJQAw
DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiBAQXkEp2iDIrgjOg2U
Uc/NMTxHOapzr4c7a2//HrUN/QIhAP4C4dOzqw2WZSL5yaKGsDwVYXTzIX8VEzgH
S/iulKlP
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions core/peer/testdata/Org1-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPV6aiHMGDfHF6Ub+iKVcnDwyacwtZp5SMUnnMPWsYJtoAoGCCqGSM49
AwEHoUQDQgAEU70ukwCUMIU7v7GTm2iQDPansRjHctQXiz3wLwTjnkxmCnvWG6Dz
kkOUTFrGQgC/BuUXnT+epVVYPHv3pyxXVw==
-----END EC PRIVATE KEY-----
13 changes: 13 additions & 0 deletions core/peer/testdata/Org1-server1-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB/DCCAaGgAwIBAgIRANHBGVHQ24Z7DyTeCJy0hkAwCgYIKoZIzj0EAwIwWDEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xDTALBgNVBAoTBE9yZzExDTALBgNVBAMTBE9yZzEwHhcNMTcwMzA5
MTIxODQwWhcNMjcwMzA3MTIxODQwWjBlMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMT3Jn
MS1zZXJ2ZXIxMRIwEAYDVQQDEwlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAAQK2y+RWueR/DA1azaTAOCWg2V5OQvaV/Z5w5eM0pnxFNigvL2M2587
K9TyIko/q/FSugFcRlpwqluOfRNrS/pgoz8wPTAOBgNVHQ8BAf8EBAMCBaAwHQYD
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCgYIKoZI
zj0EAwIDSQAwRgIhAOCcZX387r7wcIhGjugCa30FLfNt+JuzVmI1u6mQlyAhAiEA
hHaqckAlaGrf2RZ22JfuruIeBFspvynLo/R8wnWUgTU=
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions core/peer/testdata/Org1-server1-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFs7jdTFvAvefiEmo/l12AxECeajntSHWIEBWITL4TbloAoGCCqGSM49
AwEHoUQDQgAECtsvkVrnkfwwNWs2kwDgloNleTkL2lf2ecOXjNKZ8RTYoLy9jNuf
OyvU8iJKP6vxUroBXEZacKpbjn0Ta0v6YA==
-----END EC PRIVATE KEY-----
13 changes: 13 additions & 0 deletions core/peer/testdata/Org1-server2-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB+zCCAaCgAwIBAgIQUXz+3XMkFuny6scdi93EOTAKBggqhkjOPQQDAjBYMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzENMAsGA1UEChMET3JnMTENMAsGA1UEAxMET3JnMTAeFw0xNzAzMDkx
MjE4NDBaFw0yNzAzMDcxMjE4NDBaMGUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
YWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxPcmcx
LXNlcnZlcjIxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABOn36rJJ1NWZ6ghuzsx/KCtmY+yBHP6J/nDloqvUAGsPxtL/D0Wdn9c1
pHeYBTkpqkpEuQiq2fxKCjH0rClh9YqjPzA9MA4GA1UdDwEB/wQEAwIFoDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAKBggqhkjO
PQQDAgNJADBGAiEAvtuTYx/9wVuuhDWl0P0PMmgSvpcWV1jIj2LT7xFdq/cCIQCp
s2LlnqyCJ1t6lBNpNbn/HYPYn46FQmvjhHGCzwW9kw==
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions core/peer/testdata/Org1-server2-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKWbEerXeYWnExsy0baJPL8RChzY/7JVz0QQbs0efZjnoAoGCCqGSM49
AwEHoUQDQgAE6ffqsknU1ZnqCG7OzH8oK2Zj7IEc/on+cOWiq9QAaw/G0v8PRZ2f
1zWkd5gFOSmqSkS5CKrZ/EoKMfSsKWH1ig==
-----END EC PRIVATE KEY-----
13 changes: 13 additions & 0 deletions core/peer/testdata/Org2-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB4zCCAYigAwIBAgIQctpUUW4DlMMhPEDnOcZBsDAKBggqhkjOPQQDAjBYMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzENMAsGA1UEChMET3JnMjENMAsGA1UEAxMET3JnMjAeFw0xNzAzMDkx
MjE4NDBaFw0yNzAzMDcxMjE4NDBaMFgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
YWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKEwRPcmcy
MQ0wCwYDVQQDEwRPcmcyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4t3xokqU
oq6M+cneFK5r/MLT/vAYFfu/67AGYWaFJKN7xPzlREO1VbGqz6AvNSBJsq1+k8Mq
uw8YtJyQnfghD6M0MDIwDgYDVR0PAQH/BAQDAgGmMA8GA1UdJQQIMAYGBFUdJQAw
DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEAoTYAwlEu2g/fvwmb
v6wgVs6lAN0nDfttySDZqfJdOJ8CIQCcYOqoXVxPvHS5re4UhcBU+pu+7rRYuH6t
37f6tMOgKQ==
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions core/peer/testdata/Org2-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDNhajAyPe7+ofYFs/9ZYtOsHSoYC6FWtNiF3VaDWkILoAoGCCqGSM49
AwEHoUQDQgAE4t3xokqUoq6M+cneFK5r/MLT/vAYFfu/67AGYWaFJKN7xPzlREO1
VbGqz6AvNSBJsq1+k8Mquw8YtJyQnfghDw==
-----END EC PRIVATE KEY-----
13 changes: 13 additions & 0 deletions core/peer/testdata/Org2-server1-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB+zCCAaCgAwIBAgIQUZ/QyyHUYl4zIuKxdxcHCTAKBggqhkjOPQQDAjBYMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzENMAsGA1UEChMET3JnMjENMAsGA1UEAxMET3JnMjAeFw0xNzAzMDkx
MjE4NDBaFw0yNzAzMDcxMjE4NDBaMGUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
YWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxPcmcy
LXNlcnZlcjExEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABPGTbJUzh8uE81pbJfd3cO0MU94I87IPLQwe1weEC3aCcZ+awF4kIT5T
Z/SmTiDGHf1BH3CONUaTGYXKtioL2mqjPzA9MA4GA1UdDwEB/wQEAwIFoDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAKBggqhkjO
PQQDAgNJADBGAiEAjJ9iEz1dix1j+t+TMJtDLsLwFpnmcRUsrTlUfh1Fzg0CIQCx
K5rXgKTR48yMQ1mTizTNljd3I+DsNGWPDrbKHgIg+g==
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions core/peer/testdata/Org2-server1-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJZHiy1JhS/mosbf1VGOuus63/XsG2rBug79RmUOlcU5oAoGCCqGSM49
AwEHoUQDQgAE8ZNslTOHy4TzWlsl93dw7QxT3gjzsg8tDB7XB4QLdoJxn5rAXiQh
PlNn9KZOIMYd/UEfcI41RpMZhcq2Kgvaag==
-----END EC PRIVATE KEY-----
13 changes: 13 additions & 0 deletions core/peer/testdata/Org2-server2-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB+zCCAaGgAwIBAgIRALSYDDlVt7w7Fw7cdP8F9LMwCgYIKoZIzj0EAwIwWDEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xDTALBgNVBAoTBE9yZzIxDTALBgNVBAMTBE9yZzIwHhcNMTcwMzA5
MTIxODQwWhcNMjcwMzA3MTIxODQwWjBlMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMT3Jn
Mi1zZXJ2ZXIyMRIwEAYDVQQDEwlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAAQttx8Y8K31yCxoHX+iQLF7fu0ZU2EHtkAaD9T69emDiWLA5qCpksjr
0IwoLvJymwa2OR+2rrMzqI65+CvZNT4koz8wPTAOBgNVHQ8BAf8EBAMCBaAwHQYD
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCgYIKoZI
zj0EAwIDSAAwRQIgeciUm1lmT+nOawKmgEBeiP53VczMtT7S5MHZOCBgroUCIQCN
8RSB44VgUwjfZfdW9Kr5xB5R6ufzAkGC6xlPbqiYPQ==
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions core/peer/testdata/Org2-server2-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIBn9Ftx1gfZXp8bCP2yOHv2y7fX1vlIluXavEl4RQqYIoAoGCCqGSM49
AwEHoUQDQgAELbcfGPCt9cgsaB1/okCxe37tGVNhB7ZAGg/U+vXpg4liwOagqZLI
69CMKC7ycpsGtjkftq6zM6iOufgr2TU+JA==
-----END EC PRIVATE KEY-----
Loading

0 comments on commit 3295920

Please sign in to comment.