github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/gossip/comm/crypto_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 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 comm
    18  
    19  import (
    20  	"crypto/tls"
    21  	"fmt"
    22  	"net"
    23  	"os"
    24  	"sync"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/hyperledger/fabric/gossip/util"
    29  	proto "github.com/hyperledger/fabric/protos/gossip"
    30  	"github.com/stretchr/testify/assert"
    31  	"golang.org/x/net/context"
    32  	"google.golang.org/grpc"
    33  	"google.golang.org/grpc/credentials"
    34  )
    35  
    36  type gossipTestServer struct {
    37  	lock           sync.Mutex
    38  	remoteCertHash []byte
    39  	selfCertHash   []byte
    40  	ll             net.Listener
    41  	s              *grpc.Server
    42  }
    43  
    44  func init() {
    45  	util.SetupTestLogging()
    46  }
    47  
    48  func createTestServer(t *testing.T, cert *tls.Certificate) *gossipTestServer {
    49  	tlsConf := &tls.Config{
    50  		Certificates:       []tls.Certificate{*cert},
    51  		ClientAuth:         tls.RequestClientCert,
    52  		InsecureSkipVerify: true,
    53  	}
    54  	s := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConf)))
    55  	ll, err := net.Listen("tcp", fmt.Sprintf("%s:%d", "", 5611))
    56  	assert.NoError(t, err, "%v", err)
    57  
    58  	srv := &gossipTestServer{s: s, ll: ll, selfCertHash: certHashFromRawCert(cert.Certificate[0])}
    59  	proto.RegisterGossipServer(s, srv)
    60  	go s.Serve(ll)
    61  	return srv
    62  }
    63  
    64  func (s *gossipTestServer) stop() {
    65  	s.s.Stop()
    66  	s.ll.Close()
    67  }
    68  
    69  func (s *gossipTestServer) GossipStream(stream proto.Gossip_GossipStreamServer) error {
    70  	s.lock.Lock()
    71  	defer s.lock.Unlock()
    72  	s.remoteCertHash = extractCertificateHashFromContext(stream.Context())
    73  	return nil
    74  }
    75  
    76  func (s *gossipTestServer) getClientCertHash() []byte {
    77  	s.lock.Lock()
    78  	defer s.lock.Unlock()
    79  	return s.remoteCertHash
    80  }
    81  
    82  func (s *gossipTestServer) Ping(context.Context, *proto.Empty) (*proto.Empty, error) {
    83  	return &proto.Empty{}, nil
    84  }
    85  
    86  func TestCertificateExtraction(t *testing.T) {
    87  	err := generateCertificates("key.pem", "cert.pem")
    88  	defer os.Remove("cert.pem")
    89  	defer os.Remove("key.pem")
    90  	assert.NoError(t, err, "%v", err)
    91  	serverCert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    92  	assert.NoError(t, err, "%v", err)
    93  
    94  	srv := createTestServer(t, &serverCert)
    95  	defer srv.stop()
    96  
    97  	generateCertificates("key2.pem", "cert2.pem")
    98  	defer os.Remove("cert2.pem")
    99  	defer os.Remove("key2.pem")
   100  	clientCert, err := tls.LoadX509KeyPair("cert2.pem", "key2.pem")
   101  	clientCertHash := certHashFromRawCert(clientCert.Certificate[0])
   102  	assert.NoError(t, err)
   103  	ta := credentials.NewTLS(&tls.Config{
   104  		Certificates:       []tls.Certificate{clientCert},
   105  		InsecureSkipVerify: true,
   106  	})
   107  	assert.NoError(t, err, "%v", err)
   108  	ac := &authCreds{tlsCreds: ta}
   109  	assert.Equal(t, "1.2", ac.Info().SecurityVersion)
   110  	assert.Equal(t, "tls", ac.Info().SecurityProtocol)
   111  	conn, err := grpc.Dial("localhost:5611", grpc.WithTransportCredentials(ac), grpc.WithBlock(), grpc.WithTimeout(time.Second))
   112  	assert.NoError(t, err, "%v", err)
   113  
   114  	cl := proto.NewGossipClient(conn)
   115  	stream, err := cl.GossipStream(context.Background())
   116  	assert.NoError(t, err, "%v", err)
   117  	if err != nil {
   118  		return
   119  	}
   120  
   121  	time.Sleep(time.Second)
   122  	clientSideCertHash := extractCertificateHashFromContext(stream.Context())
   123  	serverSideCertHash := srv.getClientCertHash()
   124  
   125  	assert.NotNil(t, clientSideCertHash)
   126  	assert.NotNil(t, serverSideCertHash)
   127  
   128  	assert.Equal(t, 32, len(clientSideCertHash), "client side cert hash is %v", clientSideCertHash)
   129  	assert.Equal(t, 32, len(serverSideCertHash), "server side cert hash is %v", serverSideCertHash)
   130  
   131  	assert.Equal(t, clientSideCertHash, srv.selfCertHash, "Server self hash isn't equal to client side hash")
   132  	assert.Equal(t, clientCertHash, srv.remoteCertHash, "Server side and client hash aren't equal")
   133  }