github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/peer/pkg_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package peer_test 8 9 import ( 10 "context" 11 "crypto/tls" 12 "crypto/x509" 13 "errors" 14 "net" 15 "testing" 16 "time" 17 18 configtxtest "github.com/hechain20/hechain/common/configtx/test" 19 "github.com/hechain20/hechain/common/crypto/tlsgen" 20 "github.com/hechain20/hechain/core/ledger/mock" 21 "github.com/hechain20/hechain/core/peer" 22 "github.com/hechain20/hechain/internal/pkg/comm" 23 "github.com/hechain20/hechain/internal/pkg/comm/testpb" 24 "github.com/hechain20/hechain/internal/pkg/txflags" 25 "github.com/hechain20/hechain/msp" 26 "github.com/hechain20/hechain/protoutil" 27 cb "github.com/hyperledger/fabric-protos-go/common" 28 mspproto "github.com/hyperledger/fabric-protos-go/msp" 29 pb "github.com/hyperledger/fabric-protos-go/peer" 30 "github.com/stretchr/testify/require" 31 "google.golang.org/grpc" 32 "google.golang.org/grpc/credentials" 33 ) 34 35 // test server to be registered with the GRPCServer 36 type testServiceServer struct{} 37 38 func (tss *testServiceServer) EmptyCall(context.Context, *testpb.Empty) (*testpb.Empty, error) { 39 return new(testpb.Empty), nil 40 } 41 42 // createCertPool creates an x509.CertPool from an array of PEM-encoded certificates 43 func createCertPool(rootCAs [][]byte) (*x509.CertPool, error) { 44 certPool := x509.NewCertPool() 45 for _, rootCA := range rootCAs { 46 if !certPool.AppendCertsFromPEM(rootCA) { 47 return nil, errors.New("Failed to load root certificates") 48 } 49 } 50 return certPool, nil 51 } 52 53 // helper function to invoke the EmptyCall againt the test service 54 func invokeEmptyCall(address string, dialOptions []grpc.DialOption) (*testpb.Empty, error) { 55 // add DialOptions 56 dialOptions = append(dialOptions, grpc.WithBlock()) 57 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 58 defer cancel() 59 60 // create GRPC client conn 61 clientConn, err := grpc.DialContext(ctx, address, dialOptions...) 62 if err != nil { 63 return nil, err 64 } 65 defer clientConn.Close() 66 67 // create GRPC client 68 client := testpb.NewTestServiceClient(clientConn) 69 70 // invoke service 71 empty, err := client.EmptyCall(context.Background(), new(testpb.Empty)) 72 if err != nil { 73 return nil, err 74 } 75 76 return empty, nil 77 } 78 79 // helper function to build an MSPConfig given root certs 80 func createMSPConfig(mspID string, rootCerts, tlsRootCerts, tlsIntermediateCerts [][]byte) (*mspproto.MSPConfig, error) { 81 fmspconf := &mspproto.FabricMSPConfig{ 82 RootCerts: rootCerts, 83 TlsRootCerts: tlsRootCerts, 84 TlsIntermediateCerts: tlsIntermediateCerts, 85 Name: mspID, 86 FabricNodeOus: &mspproto.FabricNodeOUs{ 87 Enable: true, 88 ClientOuIdentifier: &mspproto.FabricOUIdentifier{ 89 OrganizationalUnitIdentifier: "client", 90 }, 91 PeerOuIdentifier: &mspproto.FabricOUIdentifier{ 92 OrganizationalUnitIdentifier: "peer", 93 }, 94 AdminOuIdentifier: &mspproto.FabricOUIdentifier{ 95 OrganizationalUnitIdentifier: "admin", 96 }, 97 }, 98 } 99 100 return &mspproto.MSPConfig{ 101 Config: protoutil.MarshalOrPanic(fmspconf), 102 Type: int32(msp.FABRIC), 103 }, nil 104 } 105 106 func createConfigBlock(channelID string, appMSPConf, ordererMSPConf *mspproto.MSPConfig, 107 appOrgID, ordererOrgID string) (*cb.Block, error) { 108 block, err := configtxtest.MakeGenesisBlockFromMSPs(channelID, appMSPConf, ordererMSPConf, appOrgID, ordererOrgID) 109 if block == nil || err != nil { 110 return block, err 111 } 112 113 txsFilter := txflags.NewWithValues(len(block.Data.Data), pb.TxValidationCode_VALID) 114 block.Metadata.Metadata[cb.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter 115 116 return block, nil 117 } 118 119 func TestUpdateRootsFromConfigBlock(t *testing.T) { 120 org1CA, err := tlsgen.NewCA() 121 require.NoError(t, err) 122 org1Server1KeyPair, err := org1CA.NewServerCertKeyPair("localhost", "127.0.0.1", "::1") 123 require.NoError(t, err) 124 125 org2CA, err := tlsgen.NewCA() 126 require.NoError(t, err) 127 org2Server1KeyPair, err := org2CA.NewServerCertKeyPair("localhost", "127.0.0.1", "::1") 128 require.NoError(t, err) 129 130 org2IntermediateCA, err := org2CA.NewIntermediateCA() 131 require.NoError(t, err) 132 org2IntermediateServer1KeyPair, err := org2IntermediateCA.NewServerCertKeyPair("localhost", "127.0.0.1", "::1") 133 require.NoError(t, err) 134 135 ordererOrgCA, err := tlsgen.NewCA() 136 require.NoError(t, err) 137 ordererOrgServer1KeyPair, err := ordererOrgCA.NewServerCertKeyPair("localhost", "127.0.0.1", "::1") 138 require.NoError(t, err) 139 140 // create test MSPConfigs 141 org1MSPConf, err := createMSPConfig("Org1MSP", [][]byte{org2CA.CertBytes()}, [][]byte{org1CA.CertBytes()}, [][]byte{}) 142 require.NoError(t, err) 143 org2MSPConf, err := createMSPConfig("Org2MSP", [][]byte{org1CA.CertBytes()}, [][]byte{org2CA.CertBytes()}, [][]byte{}) 144 require.NoError(t, err) 145 org2IntermediateMSPConf, err := createMSPConfig("Org2IntermediateMSP", [][]byte{org1CA.CertBytes()}, [][]byte{org2CA.CertBytes()}, [][]byte{org2IntermediateCA.CertBytes()}) 146 require.NoError(t, err) 147 ordererOrgMSPConf, err := createMSPConfig("OrdererOrgMSP", [][]byte{org1CA.CertBytes()}, [][]byte{ordererOrgCA.CertBytes()}, [][]byte{}) 148 require.NoError(t, err) 149 150 // create test channel create blocks 151 channel1Block, err := createConfigBlock("channel1", org1MSPConf, ordererOrgMSPConf, "Org1MSP", "OrdererOrgMSP") 152 require.NoError(t, err) 153 channel2Block, err := createConfigBlock("channel2", org2MSPConf, ordererOrgMSPConf, "Org2MSP", "OrdererOrgMSP") 154 require.NoError(t, err) 155 channel3Block, err := createConfigBlock("channel3", org2IntermediateMSPConf, ordererOrgMSPConf, "Org2IntermediateMSP", "OrdererOrgMSP") 156 require.NoError(t, err) 157 158 serverConfig := comm.ServerConfig{ 159 SecOpts: comm.SecureOptions{ 160 UseTLS: true, 161 Certificate: org1Server1KeyPair.Cert, 162 Key: org1Server1KeyPair.Key, 163 ServerRootCAs: [][]byte{org1CA.CertBytes()}, 164 RequireClientCert: true, 165 }, 166 } 167 168 peerInstance, cleanup := peer.NewTestPeer(t) 169 defer cleanup() 170 peerInstance.CredentialSupport = comm.NewCredentialSupport() 171 172 createChannel := func(t *testing.T, cid string, block *cb.Block) { 173 err = peerInstance.CreateChannel(cid, block, &mock.DeployedChaincodeInfoProvider{}, nil, nil) 174 require.NoError(t, err, "failed to create channel from block") 175 t.Logf("Channel %s MSPIDs: (%s)", cid, peerInstance.GetMSPIDs(cid)) 176 } 177 178 org1CertPool, err := createCertPool([][]byte{org1CA.CertBytes()}) 179 require.NoError(t, err) 180 181 // use server cert as client cert 182 org1ClientCert, err := tls.X509KeyPair(org1Server1KeyPair.Cert, org1Server1KeyPair.Key) 183 require.NoError(t, err) 184 185 org1Creds := credentials.NewTLS(&tls.Config{ 186 Certificates: []tls.Certificate{org1ClientCert}, 187 RootCAs: org1CertPool, 188 }) 189 190 org2ClientCert, err := tls.X509KeyPair(org2Server1KeyPair.Cert, org2Server1KeyPair.Key) 191 require.NoError(t, err) 192 org2Creds := credentials.NewTLS(&tls.Config{ 193 Certificates: []tls.Certificate{org2ClientCert}, 194 RootCAs: org1CertPool, 195 }) 196 197 org2IntermediateClientCert, err := tls.X509KeyPair(org2IntermediateServer1KeyPair.Cert, org2IntermediateServer1KeyPair.Key) 198 require.NoError(t, err) 199 org2IntermediateCreds := credentials.NewTLS(&tls.Config{ 200 Certificates: []tls.Certificate{org2IntermediateClientCert}, 201 RootCAs: org1CertPool, 202 }) 203 204 ordererOrgClientCert, err := tls.X509KeyPair(ordererOrgServer1KeyPair.Cert, ordererOrgServer1KeyPair.Key) 205 require.NoError(t, err) 206 207 ordererOrgCreds := credentials.NewTLS(&tls.Config{ 208 Certificates: []tls.Certificate{ordererOrgClientCert}, 209 RootCAs: org1CertPool, 210 }) 211 212 // basic function tests 213 tests := []struct { 214 name string 215 serverConfig comm.ServerConfig 216 createChannel func(*testing.T) 217 goodOptions []grpc.DialOption 218 badOptions []grpc.DialOption 219 numAppCAs int 220 numOrdererCAs int 221 }{ 222 { 223 name: "MutualTLSOrg1Org1", 224 serverConfig: serverConfig, 225 createChannel: func(t *testing.T) { createChannel(t, "channel1", channel1Block) }, 226 goodOptions: []grpc.DialOption{grpc.WithTransportCredentials(org1Creds)}, 227 badOptions: []grpc.DialOption{grpc.WithTransportCredentials(ordererOrgCreds)}, 228 numAppCAs: 3, // each channel also has a DEFAULT MSP 229 numOrdererCAs: 1, 230 }, 231 { 232 name: "MutualTLSOrg1Org2", 233 serverConfig: serverConfig, 234 createChannel: func(t *testing.T) { createChannel(t, "channel2", channel2Block) }, 235 goodOptions: []grpc.DialOption{ 236 grpc.WithTransportCredentials(org2Creds), 237 }, 238 badOptions: []grpc.DialOption{ 239 grpc.WithTransportCredentials(ordererOrgCreds), 240 }, 241 numAppCAs: 6, 242 numOrdererCAs: 2, 243 }, 244 { 245 name: "MutualTLSOrg1Org2Intermediate", 246 serverConfig: serverConfig, 247 createChannel: func(t *testing.T) { createChannel(t, "channel3", channel3Block) }, 248 goodOptions: []grpc.DialOption{ 249 grpc.WithTransportCredentials(org2IntermediateCreds), 250 }, 251 badOptions: []grpc.DialOption{ 252 grpc.WithTransportCredentials(ordererOrgCreds), 253 }, 254 numAppCAs: 10, 255 numOrdererCAs: 3, 256 }, 257 } 258 259 for _, test := range tests { 260 test := test 261 t.Run(test.name, func(t *testing.T) { 262 server, err := comm.NewGRPCServer("localhost:0", test.serverConfig) 263 require.NoError(t, err, "failed to create gRPC server") 264 require.NotNil(t, server) 265 266 peerInstance.SetServer(server) 267 peerInstance.ServerConfig = test.serverConfig 268 269 // register a GRPC test service 270 testpb.RegisterTestServiceServer(server.Server(), &testServiceServer{}) 271 go server.Start() 272 defer server.Stop() 273 274 // extract dynamic listen port 275 _, port, err := net.SplitHostPort(server.Listener().Addr().String()) 276 require.NoError(t, err, "unable to extract listener port") 277 testAddress := "localhost:" + port 278 279 // invoke the EmptyCall service with good options but should fail 280 // until channel is created and root CAs are updated 281 _, err = invokeEmptyCall(testAddress, test.goodOptions) 282 require.Error(t, err, "Expected error invoking the EmptyCall service ") 283 284 // creating channel should update the trusted client roots 285 test.createChannel(t) 286 287 // invoke the EmptyCall service with good options 288 _, err = invokeEmptyCall(testAddress, test.goodOptions) 289 require.NoError(t, err, "Failed to invoke the EmptyCall service") 290 291 // invoke the EmptyCall service with bad options 292 _, err = invokeEmptyCall(testAddress, test.badOptions) 293 require.Error(t, err, "Expected error using bad dial options") 294 }) 295 } 296 }