github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/core/common/ccprovider/sigcdspackage_test.go (about)

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