github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/common/ccprovider/sigcdspackage_test.go (about)

     1  /*
     2  Copyright hechain. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package ccprovider
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/hechain20/hechain/bccsp/sw"
    15  	"github.com/hechain20/hechain/core/common/ccpackage"
    16  	"github.com/hechain20/hechain/protoutil"
    17  	"github.com/hyperledger/fabric-protos-go/common"
    18  	pb "github.com/hyperledger/fabric-protos-go/peer"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func processSignedCDS(cds *pb.ChaincodeDeploymentSpec, policy *common.SignaturePolicyEnvelope, tofs bool) (*SignedCDSPackage, []byte, *ChaincodeData, error) {
    23  	env, err := ccpackage.OwnerCreateSignedCCDepSpec(cds, policy, nil)
    24  	if err != nil {
    25  		return nil, nil, nil, fmt.Errorf("could not create package %s", err)
    26  	}
    27  
    28  	b := protoutil.MarshalOrPanic(env)
    29  
    30  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    31  	if err != nil {
    32  		return nil, nil, nil, fmt.Errorf("could not create bootBCCSP %s", cryptoProvider)
    33  	}
    34  	ccpack := &SignedCDSPackage{GetHasher: cryptoProvider}
    35  	cd, err := ccpack.InitFromBuffer(b)
    36  	if err != nil {
    37  		return nil, nil, nil, fmt.Errorf("error owner creating package %s", err)
    38  	}
    39  
    40  	if tofs {
    41  		if err = ccpack.PutChaincodeToFS(); err != nil {
    42  			return nil, nil, nil, fmt.Errorf("error putting package on the FS %s", err)
    43  		}
    44  	}
    45  
    46  	return ccpack, b, cd, nil
    47  }
    48  
    49  func TestPutSigCDSCC(t *testing.T) {
    50  	ccdir := setupccdir()
    51  	defer os.RemoveAll(ccdir)
    52  
    53  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
    54  
    55  	ccpack, _, cd, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
    56  	if err != nil {
    57  		t.Fatalf("cannot create package %s", err)
    58  		return
    59  	}
    60  
    61  	if err = ccpack.ValidateCC(cd); err != nil {
    62  		t.Fatalf("error validating package %s", err)
    63  		return
    64  	}
    65  }
    66  
    67  func TestPutSignedCDSErrorPaths(t *testing.T) {
    68  	ccdir := setupccdir()
    69  	defer os.RemoveAll(ccdir)
    70  
    71  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
    72  		Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
    73  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
    74  	}, CodePackage: []byte("code")}
    75  
    76  	ccpack, b, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
    77  	if err != nil {
    78  		t.Fatalf("cannot create package %s", err)
    79  		return
    80  	}
    81  
    82  	// remove the buffer
    83  	ccpack.buf = nil
    84  	err = ccpack.PutChaincodeToFS()
    85  	require.Error(t, err)
    86  	require.Contains(t, err.Error(), "uninitialized package", "Unexpected error putting package on the FS")
    87  
    88  	// put back the buffer
    89  	ccpack.buf = b
    90  	id := ccpack.id
    91  	ccpack.id = nil // remove the id
    92  	err = ccpack.PutChaincodeToFS()
    93  	require.Error(t, err)
    94  	require.Contains(t, err.Error(), "id cannot be nil if buf is not nil", "Unexpected error putting package on the FS")
    95  
    96  	require.Panics(t, func() {
    97  		ccpack.GetId()
    98  	}, "GetId should have paniced if chaincode package ID is nil")
    99  
   100  	// put back the id
   101  	ccpack.id = id
   102  	id1 := ccpack.GetId()
   103  	require.Equal(t, id, id1)
   104  
   105  	savDepSpec := ccpack.sDepSpec
   106  	ccpack.sDepSpec = nil // remove the signed chaincode deployment spec
   107  	err = ccpack.PutChaincodeToFS()
   108  	require.Error(t, err)
   109  	require.Contains(t, err.Error(), "depspec cannot be nil if buf is not nil", "Unexpected error putting package on the FS")
   110  	require.Panics(t, func() {
   111  		ccpack.GetInstantiationPolicy()
   112  	}, "GetChaincodeData should have paniced if signed chaincode deployment spec is nil")
   113  	require.Panics(t, func() {
   114  		ccpack.GetDepSpecBytes()
   115  	}, "GetDepSpecBytes should have paniced if signed chaincode deployment spec is nil")
   116  	ccpack.sDepSpec = savDepSpec // put back dep spec
   117  	sdepspec1 := ccpack.GetInstantiationPolicy()
   118  	require.NotNil(t, sdepspec1)
   119  	depspecBytes := ccpack.GetDepSpecBytes()
   120  	require.NotNil(t, depspecBytes)
   121  
   122  	// put back the signed chaincode deployment spec
   123  	depSpec := ccpack.depSpec
   124  	ccpack.depSpec = nil // remove the chaincode deployment spec
   125  	require.Panics(t, func() {
   126  		ccpack.GetDepSpec()
   127  	}, "GetDepSec should have paniced if chaincode deployment spec is nil")
   128  	require.Panics(t, func() {
   129  		ccpack.GetChaincodeData()
   130  	}, "GetChaincodeData should have paniced if chaincode deployment spec is nil")
   131  	ccpack.depSpec = depSpec // put back the chaincode deployment spec
   132  	depSpec1 := ccpack.GetDepSpec()
   133  	require.NotNil(t, depSpec1)
   134  
   135  	env := ccpack.env
   136  	ccpack.env = nil // remove the envelope
   137  	err = ccpack.PutChaincodeToFS()
   138  	require.Error(t, err)
   139  	require.Contains(t, err.Error(), "env cannot be nil if buf and depspec are not nil", "Unexpected error putting package on the FS")
   140  	ccpack.env = env // put back the envelope
   141  	env1 := ccpack.GetPackageObject()
   142  	require.Equal(t, env, env1)
   143  
   144  	data := ccpack.data
   145  	ccpack.data = nil // remove the data
   146  	err = ccpack.PutChaincodeToFS()
   147  	require.Error(t, err)
   148  	require.Contains(t, err.Error(), "nil data", "Unexpected error putting package on the FS")
   149  	ccpack.data = data // put back the data
   150  
   151  	datab := ccpack.datab
   152  	ccpack.datab = nil // remove the data bytes
   153  	err = ccpack.PutChaincodeToFS()
   154  	require.Error(t, err)
   155  	require.Contains(t, err.Error(), "nil data bytes", "Unexpected error putting package on the FS")
   156  	ccpack.datab = datab // put back the data bytes
   157  
   158  	// remove the chaincode directory
   159  	os.RemoveAll(ccdir)
   160  	err = ccpack.PutChaincodeToFS()
   161  	require.Error(t, err, "Expected error putting package on the FS")
   162  }
   163  
   164  func TestGetCDSDataErrorPaths(t *testing.T) {
   165  	ccdir := setupccdir()
   166  	defer os.RemoveAll(ccdir)
   167  
   168  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
   169  		Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   170  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
   171  	}, CodePackage: []byte("code")}
   172  
   173  	ccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   174  	if err != nil {
   175  		t.Fatalf("cannot create package %s", err)
   176  		return
   177  	}
   178  
   179  	// Error case 1: signed chaincode deployment spec passed to getCDSData is nil
   180  	require.Panics(t, func() {
   181  		_, _, _, err = ccpack.getCDSData(nil)
   182  	}, "getCDSData should have paniced when called with nil signed chaincode deployment spec")
   183  
   184  	// Error case 2: bad chaincode deployment spec
   185  	scdp := &pb.SignedChaincodeDeploymentSpec{ChaincodeDeploymentSpec: []byte("bad spec")}
   186  	_, _, _, err = ccpack.getCDSData(scdp)
   187  	require.Error(t, err)
   188  
   189  	// Error case 3: instantiation policy is nil
   190  	instPolicy := ccpack.sDepSpec.InstantiationPolicy
   191  	ccpack.sDepSpec.InstantiationPolicy = nil
   192  	_, _, _, err = ccpack.getCDSData(ccpack.sDepSpec)
   193  	require.Error(t, err)
   194  	require.Contains(t, err.Error(), "instantiation policy cannot be nil for chaincode", "Unexpected error returned by getCDSData")
   195  	ccpack.sDepSpec.InstantiationPolicy = instPolicy
   196  
   197  	ccpack.sDepSpec.OwnerEndorsements = make([]*pb.Endorsement, 1)
   198  	ccpack.sDepSpec.OwnerEndorsements[0] = &pb.Endorsement{}
   199  	_, _, _, err = ccpack.getCDSData(ccpack.sDepSpec)
   200  	require.NoError(t, err)
   201  }
   202  
   203  func TestInitFromBufferErrorPaths(t *testing.T) {
   204  	ccdir := setupccdir()
   205  	defer os.RemoveAll(ccdir)
   206  
   207  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
   208  		Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   209  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
   210  	}, CodePackage: []byte("code")}
   211  
   212  	ccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   213  	if err != nil {
   214  		t.Fatalf("cannot create package %s", err)
   215  		return
   216  	}
   217  
   218  	_, err = ccpack.InitFromBuffer([]byte("bad buffer"))
   219  	require.Error(t, err)
   220  	require.Contains(t, err.Error(), "failed to unmarshal envelope from bytes", "Unexpected error returned by InitFromBuffer")
   221  }
   222  
   223  func TestValidateSignedCCErrorPaths(t *testing.T) {
   224  	ccdir := setupccdir()
   225  	defer os.RemoveAll(ccdir)
   226  
   227  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
   228  		Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   229  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
   230  	}, CodePackage: []byte("code")}
   231  
   232  	ccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   233  	if err != nil {
   234  		t.Fatalf("cannot create package %s", err)
   235  		return
   236  	}
   237  
   238  	// validate with invalid name
   239  	cd := &ChaincodeData{Name: "invalname", Version: "0"}
   240  	err = ccpack.ValidateCC(cd)
   241  	require.Error(t, err)
   242  	require.Contains(t, err.Error(), "invalid chaincode data", "Unexpected error validating package")
   243  
   244  	savDepSpec := ccpack.sDepSpec
   245  	ccpack.sDepSpec = nil
   246  	err = ccpack.ValidateCC(cd)
   247  	require.Error(t, err)
   248  	require.Contains(t, err.Error(), "uninitialized package", "Unexpected error validating package")
   249  	ccpack.sDepSpec = savDepSpec
   250  
   251  	cdspec := ccpack.sDepSpec.ChaincodeDeploymentSpec
   252  	ccpack.sDepSpec.ChaincodeDeploymentSpec = nil
   253  	err = ccpack.ValidateCC(cd)
   254  	require.Error(t, err)
   255  	require.Contains(t, err.Error(), "signed chaincode deployment spec cannot be nil in a package", "Unexpected error validating package")
   256  	ccpack.sDepSpec.ChaincodeDeploymentSpec = cdspec
   257  
   258  	depspec := ccpack.depSpec
   259  	ccpack.depSpec = nil
   260  	err = ccpack.ValidateCC(cd)
   261  	require.Error(t, err)
   262  	require.Contains(t, err.Error(), "chaincode deployment spec cannot be nil in a package", "Unexpected error validating package")
   263  	ccpack.depSpec = depspec
   264  
   265  	cd = &ChaincodeData{Name: "\027", Version: "0"}
   266  	err = ccpack.ValidateCC(cd)
   267  	require.Error(t, err)
   268  	require.Contains(t, err.Error(), `invalid chaincode name: "\x17"`)
   269  }
   270  
   271  func TestSigCDSGetCCPackage(t *testing.T) {
   272  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   273  
   274  	env, err := ccpackage.OwnerCreateSignedCCDepSpec(cds, &common.SignaturePolicyEnvelope{Version: 1}, nil)
   275  	if err != nil {
   276  		t.Fatalf("cannot create package")
   277  		return
   278  	}
   279  
   280  	b := protoutil.MarshalOrPanic(env)
   281  
   282  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   283  	require.NoError(t, err)
   284  
   285  	ccpack, err := GetCCPackage(b, cryptoProvider)
   286  	if err != nil {
   287  		t.Fatalf("failed to get CCPackage %s", err)
   288  		return
   289  	}
   290  
   291  	cccdspack, ok := ccpack.(*CDSPackage)
   292  	if ok || cccdspack != nil {
   293  		t.Fatalf("expected CDSPackage type cast to fail but succeeded")
   294  		return
   295  	}
   296  
   297  	ccsignedcdspack, ok := ccpack.(*SignedCDSPackage)
   298  	if !ok || ccsignedcdspack == nil {
   299  		t.Fatalf("failed to get Signed CDS CCPackage")
   300  		return
   301  	}
   302  
   303  	cds2 := ccsignedcdspack.GetDepSpec()
   304  	if cds2 == nil {
   305  		t.Fatalf("nil dep spec in Signed CDS CCPackage")
   306  		return
   307  	}
   308  
   309  	if cds2.ChaincodeSpec.ChaincodeId.Name != cds.ChaincodeSpec.ChaincodeId.Name || cds2.ChaincodeSpec.ChaincodeId.Version != cds.ChaincodeSpec.ChaincodeId.Version {
   310  		t.Fatalf("dep spec in Signed CDS CCPackage does not match %v != %v", cds, cds2)
   311  		return
   312  	}
   313  }
   314  
   315  func TestInvalidSigCDSGetCCPackage(t *testing.T) {
   316  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   317  
   318  	b := protoutil.MarshalOrPanic(cds)
   319  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   320  	require.NoError(t, err)
   321  	ccpack, err := GetCCPackage(b, cryptoProvider)
   322  	if err != nil {
   323  		t.Fatalf("failed to get CCPackage %s", err)
   324  	}
   325  
   326  	ccsignedcdspack, ok := ccpack.(*SignedCDSPackage)
   327  	if ok || ccsignedcdspack != nil {
   328  		t.Fatalf("expected failure to get Signed CDS CCPackage but succeeded")
   329  	}
   330  }
   331  
   332  // switch the chaincodes on the FS and validate
   333  func TestSignedCDSSwitchChaincodes(t *testing.T) {
   334  	ccdir := setupccdir()
   335  	defer os.RemoveAll(ccdir)
   336  
   337  	// someone modifyed the code on the FS with "badcode"
   338  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("badcode")}
   339  
   340  	// write the bad code to the fs
   341  	badccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   342  	if err != nil {
   343  		t.Fatalf("error putting CDS to FS %s", err)
   344  		return
   345  	}
   346  
   347  	// mimic the good code ChaincodeData from the instantiate...
   348  	cds.CodePackage = []byte("goodcode")
   349  
   350  	//...and generate the CD for it (don't overwrite the bad code)
   351  	_, _, goodcd, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, false)
   352  	if err != nil {
   353  		t.Fatalf("error putting CDS to FS %s", err)
   354  		return
   355  	}
   356  
   357  	if err = badccpack.ValidateCC(goodcd); err == nil {
   358  		t.Fatalf("expected goodcd to fail against bad package but succeeded!")
   359  		return
   360  	}
   361  }