github.com/kaituanwang/hyperledger@v2.0.1+incompatible/core/comm/connection_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package comm
     8  
     9  import (
    10  	"context"
    11  	"crypto/tls"
    12  	"fmt"
    13  	"io/ioutil"
    14  	"net"
    15  	"path/filepath"
    16  	"sync/atomic"
    17  	"testing"
    18  	"time"
    19  
    20  	"github.com/hyperledger/fabric/core/comm/testpb"
    21  	"github.com/stretchr/testify/assert"
    22  )
    23  
    24  const (
    25  	numOrgs      = 2
    26  	numChildOrgs = 2
    27  )
    28  
    29  //string for cert filenames
    30  var (
    31  	orgCACert   = filepath.Join("testdata", "certs", "Org%d-cert.pem")
    32  	childCACert = filepath.Join("testdata", "certs", "Org%d-child%d-cert.pem")
    33  )
    34  
    35  var badPEM = `-----BEGIN CERTIFICATE-----
    36  MIICRDCCAemgAwIBAgIJALwW//dz2ZBvMAoGCCqGSM49BAMCMH4xCzAJBgNVBAYT
    37  AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv
    38  MRgwFgYDVQQKDA9MaW51eEZvdW5kYXRpb24xFDASBgNVBAsMC0h5cGVybGVkZ2Vy
    39  MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTYxMjA0MjIzMDE4WhcNMjYxMjAyMjIz
    40  MDE4WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UE
    41  BwwNU2FuIEZyYW5jaXNjbzEYMBYGA1UECgwPTGludXhGb3VuZGF0aW9uMRQwEgYD
    42  VQQLDAtIeXBlcmxlZGdlcjESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0C
    43  -----END CERTIFICATE-----
    44  `
    45  
    46  // utility function to load up our test root certificates from testdata/certs
    47  func loadRootCAs() [][]byte {
    48  	rootCAs := [][]byte{}
    49  	for i := 1; i <= numOrgs; i++ {
    50  		root, err := ioutil.ReadFile(fmt.Sprintf(orgCACert, i))
    51  		if err != nil {
    52  			return [][]byte{}
    53  		}
    54  		rootCAs = append(rootCAs, root)
    55  		for j := 1; j <= numChildOrgs; j++ {
    56  			root, err := ioutil.ReadFile(fmt.Sprintf(childCACert, i, j))
    57  			if err != nil {
    58  				return [][]byte{}
    59  			}
    60  			rootCAs = append(rootCAs, root)
    61  		}
    62  	}
    63  	return rootCAs
    64  }
    65  
    66  func TestNewCredentialSupport(t *testing.T) {
    67  	expected := &CredentialSupport{
    68  		appRootCAsByChain: make(map[string][][]byte),
    69  	}
    70  	assert.Equal(t, expected, NewCredentialSupport())
    71  
    72  	rootCAs := [][]byte{
    73  		[]byte("certificate-one"),
    74  		[]byte("certificate-two"),
    75  	}
    76  	expected.serverRootCAs = rootCAs[:]
    77  	assert.Equal(t, expected, NewCredentialSupport(rootCAs...))
    78  }
    79  
    80  func TestCredentialSupport(t *testing.T) {
    81  	t.Parallel()
    82  	rootCAs := loadRootCAs()
    83  	t.Logf("loaded %d root certificates", len(rootCAs))
    84  	if len(rootCAs) != 6 {
    85  		t.Fatalf("failed to load root certificates")
    86  	}
    87  
    88  	cs := &CredentialSupport{
    89  		appRootCAsByChain: make(map[string][][]byte),
    90  	}
    91  	cert := tls.Certificate{Certificate: [][]byte{}}
    92  	cs.SetClientCertificate(cert)
    93  	assert.Equal(t, cert, cs.clientCert)
    94  	assert.Equal(t, cert, cs.GetClientCertificate())
    95  
    96  	cs.appRootCAsByChain["channel1"] = [][]byte{rootCAs[0]}
    97  	cs.appRootCAsByChain["channel2"] = [][]byte{rootCAs[1]}
    98  	cs.appRootCAsByChain["channel3"] = [][]byte{rootCAs[2]}
    99  	cs.serverRootCAs = [][]byte{rootCAs[5]}
   100  
   101  	creds := cs.GetPeerCredentials()
   102  	assert.Equal(t, "1.2", creds.Info().SecurityVersion,
   103  		"Expected Security version to be 1.2")
   104  
   105  	// append some bad certs and make sure things still work
   106  	cs.serverRootCAs = append(cs.serverRootCAs, []byte("badcert"))
   107  	cs.serverRootCAs = append(cs.serverRootCAs, []byte(badPEM))
   108  	creds = cs.GetPeerCredentials()
   109  	assert.Equal(t, "1.2", creds.Info().SecurityVersion,
   110  		"Expected Security version to be 1.2")
   111  }
   112  
   113  type srv struct {
   114  	address string
   115  	*GRPCServer
   116  	caCert   []byte
   117  	serviced uint32
   118  }
   119  
   120  func (s *srv) assertServiced(t *testing.T) {
   121  	assert.Equal(t, uint32(1), atomic.LoadUint32(&s.serviced))
   122  	atomic.StoreUint32(&s.serviced, 0)
   123  }
   124  
   125  func (s *srv) EmptyCall(context.Context, *testpb.Empty) (*testpb.Empty, error) {
   126  	atomic.StoreUint32(&s.serviced, 1)
   127  	return &testpb.Empty{}, nil
   128  }
   129  
   130  func newServer(org string) *srv {
   131  	certs := map[string][]byte{
   132  		"ca.crt":     nil,
   133  		"server.crt": nil,
   134  		"server.key": nil,
   135  	}
   136  	for suffix := range certs {
   137  		fName := filepath.Join("testdata", "impersonation", org, suffix)
   138  		cert, err := ioutil.ReadFile(fName)
   139  		if err != nil {
   140  			panic(fmt.Errorf("Failed reading %s: %v", fName, err))
   141  		}
   142  		certs[suffix] = cert
   143  	}
   144  	l, err := net.Listen("tcp", "127.0.0.1:0")
   145  	if err != nil {
   146  		panic(fmt.Errorf("Failed to create listener: %v", err))
   147  	}
   148  	gSrv, err := NewGRPCServerFromListener(l, ServerConfig{
   149  		ConnectionTimeout: 250 * time.Millisecond,
   150  		SecOpts: SecureOptions{
   151  			Certificate: certs["server.crt"],
   152  			Key:         certs["server.key"],
   153  			UseTLS:      true,
   154  		},
   155  	})
   156  	if err != nil {
   157  		panic(fmt.Errorf("Failed starting gRPC server: %v", err))
   158  	}
   159  	s := &srv{
   160  		address:    l.Addr().String(),
   161  		caCert:     certs["ca.crt"],
   162  		GRPCServer: gSrv,
   163  	}
   164  	testpb.RegisterTestServiceServer(gSrv.Server(), s)
   165  	go s.Start()
   166  	return s
   167  }