github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/core/peer/pkg_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     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.
    15  */
    16  
    17  package peer_test
    18  
    19  import (
    20  	"crypto/tls"
    21  	"crypto/x509"
    22  	"errors"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  	"testing"
    28  	"time"
    29  
    30  	"google.golang.org/grpc/credentials"
    31  
    32  	"golang.org/x/net/context"
    33  	"google.golang.org/grpc"
    34  
    35  	"github.com/golang/protobuf/proto"
    36  	configtxtest "github.com/hyperledger/fabric/common/configtx/test"
    37  	"github.com/hyperledger/fabric/core/comm"
    38  	testpb "github.com/hyperledger/fabric/core/comm/testdata/grpc"
    39  	"github.com/hyperledger/fabric/core/peer"
    40  	"github.com/hyperledger/fabric/msp"
    41  	cb "github.com/hyperledger/fabric/protos/common"
    42  	mspproto "github.com/hyperledger/fabric/protos/msp"
    43  	"github.com/spf13/viper"
    44  	"github.com/stretchr/testify/assert"
    45  )
    46  
    47  // default timeout for grpc connections
    48  var timeout = time.Second * 1
    49  
    50  // test server to be registered with the GRPCServer
    51  type testServiceServer struct{}
    52  
    53  func (tss *testServiceServer) EmptyCall(context.Context, *testpb.Empty) (*testpb.Empty, error) {
    54  	return new(testpb.Empty), nil
    55  }
    56  
    57  // createCertPool creates an x509.CertPool from an array of PEM-encoded certificates
    58  func createCertPool(rootCAs [][]byte) (*x509.CertPool, error) {
    59  
    60  	certPool := x509.NewCertPool()
    61  	for _, rootCA := range rootCAs {
    62  		if !certPool.AppendCertsFromPEM(rootCA) {
    63  			return nil, errors.New("Failed to load root certificates")
    64  		}
    65  	}
    66  	return certPool, nil
    67  }
    68  
    69  // helper function to invoke the EmptyCall againt the test service
    70  func invokeEmptyCall(address string, dialOptions []grpc.DialOption) (*testpb.Empty, error) {
    71  
    72  	//add DialOptions
    73  	dialOptions = append(dialOptions, grpc.WithBlock())
    74  	dialOptions = append(dialOptions, grpc.WithTimeout(timeout))
    75  	//create GRPC client conn
    76  	clientConn, err := grpc.Dial(address, dialOptions...)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	defer clientConn.Close()
    81  
    82  	//create GRPC client
    83  	client := testpb.NewTestServiceClient(clientConn)
    84  
    85  	ctx := context.Background()
    86  	ctx, cancel := context.WithTimeout(ctx, timeout)
    87  	defer cancel()
    88  
    89  	//invoke service
    90  	empty, err := client.EmptyCall(ctx, new(testpb.Empty))
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	return empty, nil
    96  }
    97  
    98  // helper function to build an MSPConfig given root certs
    99  func createMSPConfig(rootCerts, intermediateCerts [][]byte,
   100  	mspID string) (*mspproto.MSPConfig, error) {
   101  
   102  	fmspconf := &mspproto.FabricMSPConfig{
   103  		RootCerts:         rootCerts,
   104  		IntermediateCerts: intermediateCerts,
   105  		Name:              mspID}
   106  
   107  	fmpsjs, err := proto.Marshal(fmspconf)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	mspconf := &mspproto.MSPConfig{Config: fmpsjs, Type: int32(msp.FABRIC)}
   112  	return mspconf, nil
   113  }
   114  
   115  func createConfigBlock(chainID string, appMSPConf, ordererMSPConf *mspproto.MSPConfig,
   116  	appOrgID, ordererOrgID string) (*cb.Block, error) {
   117  	block, err := configtxtest.MakeGenesisBlockFromMSPs(chainID, appMSPConf, ordererMSPConf, appOrgID, ordererOrgID)
   118  	return block, err
   119  }
   120  
   121  func TestUpdateRootsFromConfigBlock(t *testing.T) {
   122  	// load test certs from testdata
   123  	org1CA, err := ioutil.ReadFile(filepath.Join("testdata", "Org1-cert.pem"))
   124  	org1Server1Key, err := ioutil.ReadFile(filepath.Join("testdata",
   125  		"Org1-server1-key.pem"))
   126  	org1Server1Cert, err := ioutil.ReadFile(filepath.Join("testdata",
   127  		"Org1-server1-cert.pem"))
   128  	org2CA, err := ioutil.ReadFile(filepath.Join("testdata", "Org2-cert.pem"))
   129  	org2Server1Key, err := ioutil.ReadFile(filepath.Join("testdata",
   130  		"Org2-server1-key.pem"))
   131  	org2Server1Cert, err := ioutil.ReadFile(filepath.Join("testdata",
   132  		"Org2-server1-cert.pem"))
   133  	org2IntermediateCA, err := ioutil.ReadFile(filepath.Join("testdata",
   134  		"Org2-child1-cert.pem"))
   135  	org2IntermediateServer1Key, err := ioutil.ReadFile(filepath.Join("testdata",
   136  		"Org2-child1-server1-key.pem"))
   137  	org2IntermediateServer1Cert, err := ioutil.ReadFile(filepath.Join("testdata",
   138  		"Org2-child1-server1-cert.pem"))
   139  	ordererOrgCA, err := ioutil.ReadFile(filepath.Join("testdata", "Org3-cert.pem"))
   140  	ordererOrgServer1Key, err := ioutil.ReadFile(filepath.Join("testdata",
   141  		"Org3-server1-key.pem"))
   142  	ordererOrgServer1Cert, err := ioutil.ReadFile(filepath.Join("testdata",
   143  		"Org3-server1-cert.pem"))
   144  
   145  	if err != nil {
   146  		t.Fatalf("Failed to load test certificates: %v", err)
   147  	}
   148  
   149  	// create test MSPConfigs
   150  	org1MSPConf, err := createMSPConfig([][]byte{org1CA}, [][]byte{}, "Org1MSP")
   151  	org2MSPConf, err := createMSPConfig([][]byte{org2CA}, [][]byte{}, "Org2MSP")
   152  	org2IntermediateMSPConf, err := createMSPConfig([][]byte{org2CA},
   153  		[][]byte{org2IntermediateCA}, "Org2IntermediateMSP")
   154  	ordererOrgMSPConf, err := createMSPConfig([][]byte{ordererOrgCA},
   155  		[][]byte{}, "OrdererOrgMSP")
   156  	if err != nil {
   157  		t.Fatalf("Failed to create MSPConfigs (%s)", err)
   158  	}
   159  
   160  	// create test channel create blocks
   161  	channel1Block, err := createConfigBlock("channel1", org1MSPConf,
   162  		ordererOrgMSPConf, "Org1MSP", "OrdererOrgMSP")
   163  	channel2Block, err := createConfigBlock("channel2", org2MSPConf,
   164  		ordererOrgMSPConf, "Org2MSP", "OrdererOrgMSP")
   165  	channel3Block, err := createConfigBlock("channel3", org2IntermediateMSPConf,
   166  		ordererOrgMSPConf, "Org2IntermediateMSP", "OrdererOrgMSP")
   167  
   168  	createChannel := func(cid string, block *cb.Block) {
   169  		viper.Set("peer.tls.enabled", true)
   170  		viper.Set("peer.tls.cert.file", filepath.Join("testdata",
   171  			"Org1-server1-cert.pem"))
   172  		viper.Set("peer.tls.key.file", filepath.Join("testdata",
   173  			"Org1-server1-key.pem"))
   174  		viper.Set("peer.tls.rootcert.file", filepath.Join("testdata",
   175  			"Org1-cert.pem"))
   176  		viper.Set("peer.fileSystemPath", "/var/hyperledger/test/")
   177  		defer os.RemoveAll("/var/hyperledger/test/")
   178  		err := peer.CreateChainFromBlock(block)
   179  		if err != nil {
   180  			t.Fatalf("Failed to create config block (%s)", err)
   181  		}
   182  		t.Logf("Channel %s MSPIDs: (%s)", cid, peer.GetMSPIDs(cid))
   183  	}
   184  
   185  	org1CertPool, err := createCertPool([][]byte{org1CA})
   186  
   187  	if err != nil {
   188  		t.Fatalf("Failed to load root certificates into pool: %v", err)
   189  	}
   190  
   191  	// use server cert as client cert
   192  	org1ClientCert, err := tls.X509KeyPair(org1Server1Cert, org1Server1Key)
   193  	if err != nil {
   194  		t.Fatalf("Failed to load client certificate: %v", err)
   195  	}
   196  	org1Creds := credentials.NewTLS(&tls.Config{
   197  		Certificates: []tls.Certificate{org1ClientCert},
   198  		RootCAs:      org1CertPool,
   199  	})
   200  	org2ClientCert, err := tls.X509KeyPair(org2Server1Cert, org2Server1Key)
   201  	if err != nil {
   202  		t.Fatalf("Failed to load client certificate: %v", err)
   203  	}
   204  	org2Creds := credentials.NewTLS(&tls.Config{
   205  		Certificates: []tls.Certificate{org2ClientCert},
   206  		RootCAs:      org1CertPool,
   207  	})
   208  	org2IntermediateClientCert, err := tls.X509KeyPair(
   209  		org2IntermediateServer1Cert, org2IntermediateServer1Key)
   210  	if err != nil {
   211  		t.Fatalf("Failed to load client certificate: %v", err)
   212  	}
   213  	org2IntermediateCreds := credentials.NewTLS(&tls.Config{
   214  		Certificates: []tls.Certificate{org2IntermediateClientCert},
   215  		RootCAs:      org1CertPool,
   216  	})
   217  	ordererOrgClientCert, err := tls.X509KeyPair(ordererOrgServer1Cert,
   218  		ordererOrgServer1Key)
   219  	if err != nil {
   220  		t.Fatalf("Failed to load client certificate: %v", err)
   221  	}
   222  	ordererOrgCreds := credentials.NewTLS(&tls.Config{
   223  		Certificates: []tls.Certificate{ordererOrgClientCert},
   224  		RootCAs:      org1CertPool,
   225  	})
   226  
   227  	// basic function tests
   228  	var tests = []struct {
   229  		name          string
   230  		listenAddress string
   231  		secureConfig  comm.SecureServerConfig
   232  		createChannel func()
   233  		goodOptions   []grpc.DialOption
   234  		badOptions    []grpc.DialOption
   235  		numAppCAs     int
   236  		numOrdererCAs int
   237  	}{
   238  
   239  		{
   240  			name:          "MutualTLSOrg1Org1",
   241  			listenAddress: fmt.Sprintf("localhost:%d", 4051),
   242  			secureConfig: comm.SecureServerConfig{
   243  				UseTLS:            true,
   244  				ServerCertificate: org1Server1Cert,
   245  				ServerKey:         org1Server1Key,
   246  				ServerRootCAs:     [][]byte{org1CA},
   247  				RequireClientCert: true,
   248  			},
   249  			createChannel: func() { createChannel("channel1", channel1Block) },
   250  			goodOptions:   []grpc.DialOption{grpc.WithTransportCredentials(org1Creds)},
   251  			badOptions:    []grpc.DialOption{grpc.WithTransportCredentials(ordererOrgCreds)},
   252  			numAppCAs:     2, // each channel also has a DEFAULT MSP
   253  			numOrdererCAs: 1,
   254  		},
   255  		{
   256  			name:          "MutualTLSOrg1Org2",
   257  			listenAddress: fmt.Sprintf("localhost:%d", 4052),
   258  			secureConfig: comm.SecureServerConfig{
   259  				UseTLS:            true,
   260  				ServerCertificate: org1Server1Cert,
   261  				ServerKey:         org1Server1Key,
   262  				ServerRootCAs:     [][]byte{org1CA},
   263  				RequireClientCert: true,
   264  			},
   265  			createChannel: func() { createChannel("channel2", channel2Block) },
   266  			goodOptions: []grpc.DialOption{
   267  				grpc.WithTransportCredentials(org2Creds)},
   268  			badOptions: []grpc.DialOption{
   269  				grpc.WithTransportCredentials(ordererOrgCreds)},
   270  			numAppCAs:     4,
   271  			numOrdererCAs: 2,
   272  		},
   273  		{
   274  			name:          "MutualTLSOrg1Org2Intermediate",
   275  			listenAddress: fmt.Sprintf("localhost:%d", 4053),
   276  			secureConfig: comm.SecureServerConfig{
   277  				UseTLS:            true,
   278  				ServerCertificate: org1Server1Cert,
   279  				ServerKey:         org1Server1Key,
   280  				ServerRootCAs:     [][]byte{org1CA},
   281  				RequireClientCert: true,
   282  			},
   283  			createChannel: func() { createChannel("channel3", channel3Block) },
   284  			goodOptions: []grpc.DialOption{
   285  				grpc.WithTransportCredentials(org2IntermediateCreds)},
   286  			badOptions: []grpc.DialOption{
   287  				grpc.WithTransportCredentials(ordererOrgCreds)},
   288  			numAppCAs:     7,
   289  			numOrdererCAs: 3,
   290  		},
   291  	}
   292  
   293  	for _, test := range tests {
   294  		test := test
   295  		t.Run(test.name, func(t *testing.T) {
   296  			t.Logf("Running test %s ...", test.name)
   297  			_, err := peer.CreatePeerServer(test.listenAddress, test.secureConfig)
   298  			if err != nil {
   299  				t.Fatalf("CreatePeerServer failed with error [%s]", err)
   300  			} else {
   301  				assert.NoError(t, err, "CreatePeerServer should not have returned an error")
   302  				// get the server from peer
   303  				server := peer.GetPeerServer()
   304  				assert.NotNil(t, server, "GetPeerServer should not return a nil value")
   305  				// register a GRPC test service
   306  				testpb.RegisterTestServiceServer(server.Server(), &testServiceServer{})
   307  				go server.Start()
   308  				defer server.Stop()
   309  
   310  				// invoke the EmptyCall service with good options but should fail
   311  				// until channel is created and root CAs are updated
   312  				_, err = invokeEmptyCall(test.listenAddress, test.goodOptions)
   313  				assert.Error(t, err, "Expected error invoking the EmptyCall service ")
   314  
   315  				// creating channel should update the trusted client roots
   316  				test.createChannel()
   317  
   318  				// make sure we have the expected number of CAs
   319  				appCAs, ordererCAs := comm.GetCASupport().GetClientRootCAs()
   320  				assert.Equal(t, test.numAppCAs, len(appCAs),
   321  					"Did not find expected number of app CAs for channel")
   322  				assert.Equal(t, test.numOrdererCAs, len(ordererCAs),
   323  					"Did not find expected number of orderer CAs for channel")
   324  
   325  				// invoke the EmptyCall service with good options
   326  				_, err = invokeEmptyCall(test.listenAddress, test.goodOptions)
   327  				assert.NoError(t, err, "Failed to invoke the EmptyCall service")
   328  
   329  				// invoke the EmptyCall service with bad options
   330  				_, err = invokeEmptyCall(test.listenAddress, test.badOptions)
   331  				assert.Error(t, err, "Expected error using bad dial options")
   332  			}
   333  		})
   334  	}
   335  }