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 }