diff --git a/ecc_go/build.mk b/ecc_go/build.mk index 70d7aee2b..0d6f7f363 100644 --- a/ecc_go/build.mk +++ b/ecc_go/build.mk @@ -16,11 +16,12 @@ DOCKER_FILE ?= $(FPC_PATH)/ecc_go/Dockerfile EGO_CONFIG_FILE ?= $(FPC_PATH)/ecc_go/enclave.json ECC_BINARY ?= ecc ECC_BUNDLE ?= $(ECC_BINARY)-bundle +MAIN_GO_PATH ?= main.go build: ecc docker env ecc: ecc_dependencies - ego-go build $(GOTAGS) -o $(ECC_BINARY) main.go + ego-go build $(GOTAGS) -o $(ECC_BINARY) $(MAIN_GO_PATH) cp $(EGO_CONFIG_FILE) . ego sign ego uniqueid $(ECC_BINARY) > mrenclave @@ -28,7 +29,7 @@ ecc: ecc_dependencies .PHONY: with_go with_go: ecc_dependencies - $(GO) build $(GOTAGS) -o $(ECC_BUNDLE) main.go + $(GO) build $(GOTAGS) -o $(ECC_BUNDLE) $(MAIN_GO_PATH) echo "fake_mrenclave" > mrenclave ecc_dependencies: diff --git a/ecc_go/chaincode/enclave_go/enclave.go b/ecc_go/chaincode/enclave_go/enclave.go index 04545d894..3b25a8729 100644 --- a/ecc_go/chaincode/enclave_go/enclave.go +++ b/ecc_go/chaincode/enclave_go/enclave.go @@ -18,6 +18,7 @@ import ( "github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode/enclave_go/attestation" "github.com/hyperledger/fabric-private-chaincode/internal/crypto" "github.com/hyperledger/fabric-private-chaincode/internal/protos" + pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/factory" "github.com/hyperledger/fabric/common/flogging" @@ -37,6 +38,7 @@ type EnclaveStub struct { hostParams *protos.HostParameters chaincodeParams *protos.CCParameters fabricCryptoProvider bccsp.BCCSP + stubProvider func(shim.ChaincodeStubInterface, *pb.ChaincodeInput, *readWriteSet, StateEncryptionFunctions) shim.ChaincodeStubInterface } func NewEnclaveStub(cc shim.Chaincode) *EnclaveStub { @@ -49,6 +51,9 @@ func NewEnclaveStub(cc shim.Chaincode) *EnclaveStub { csp: crypto.GetDefaultCSP(), ccRef: cc, fabricCryptoProvider: cryptoProvider, + stubProvider: func(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface { + return NewFpcStubInterface(stub, input, rwset, sep) + }, } } @@ -161,7 +166,7 @@ func (e *EnclaveStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, chaincod // Invoke chaincode // we wrap the stub with our FpcStubInterface - fpcStub := NewFpcStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) + fpcStub := e.stubProvider(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) ccResponse := e.ccRef.Invoke(fpcStub) // marshal chaincode response diff --git a/ecc_go/chaincode/enclave_go/skvs_stub.go b/ecc_go/chaincode/enclave_go/skvs_stub.go new file mode 100644 index 000000000..5162fcf0a --- /dev/null +++ b/ecc_go/chaincode/enclave_go/skvs_stub.go @@ -0,0 +1,21 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package enclave_go + +import ( + "github.com/hyperledger/fabric-chaincode-go/shim" + pb "github.com/hyperledger/fabric-protos-go/peer" +) + +func NewSkvsStub(cc shim.Chaincode) *EnclaveStub { + logger.Warning("==== SKVS NewSkvsStub ====") + enclaveStub := NewEnclaveStub(cc) + enclaveStub.stubProvider = func(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface { + return NewSkvsStubInterface(stub, input, rwset, sep) + } + return enclaveStub +} diff --git a/ecc_go/chaincode/enclave_go/skvs_stub_interface.go b/ecc_go/chaincode/enclave_go/skvs_stub_interface.go new file mode 100644 index 000000000..64aa92ce3 --- /dev/null +++ b/ecc_go/chaincode/enclave_go/skvs_stub_interface.go @@ -0,0 +1,115 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package enclave_go + +import ( + "encoding/json" + + "github.com/hyperledger/fabric-chaincode-go/shim" + pb "github.com/hyperledger/fabric-protos-go/peer" + "github.com/pkg/errors" +) + +type SkvsStubInterface struct { + *FpcStubInterface + allDataOld map[string][]byte + allDataNew map[string][]byte + key string +} + +func NewSkvsStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) *SkvsStubInterface { + logger.Warning("==== Get New Skvs Interface =====") + fpcStub := NewFpcStubInterface(stub, input, rwset, sep) + skvsStub := SkvsStubInterface{fpcStub, map[string][]byte{}, map[string][]byte{}, "SKVS"} + err := skvsStub.InitSKVS() + if err != nil { + logger.Warningf("Error!! Initializing SKVS failed") + } + return &skvsStub +} + +func (s *SkvsStubInterface) InitSKVS() error { + logger.Warningf(" === Initializing SKVS === ") + + // get current state, this will only operate once + encValue, err := s.GetPublicState(s.key) + if err != nil { + return nil + } + + if len(encValue) == 0 { + logger.Warningf("SKVS is empty, Initiating.") + } else { + value, err := s.sep.DecryptState(encValue) + if err != nil { + return err + } + logger.Warningf("SKVS has default value, loading current value.") + + err = json.Unmarshal(value, &s.allDataOld) + if err != nil { + logger.Errorf("SKVS Json unmarshal error: %s", err) + return err + } + err = json.Unmarshal(value, &s.allDataNew) + if err != nil { + logger.Errorf("SKVS Json unmarshal error: %s", err) + return err + } + } + + logger.Warningf("SKVS Init finish, allDataOld: %s, allDataNew: %s", s.allDataOld, s.allDataNew) + return nil +} + +func (s *SkvsStubInterface) GetState(key string) ([]byte, error) { + logger.Warningf("Calling Get State (Start), key: %s, alldataOld: %s", key, s.allDataOld) + value, found := s.allDataOld[key] + if !found { + return nil, errors.New("skvs allDataOld key not found") + } + logger.Warningf("Calling Get State (End), key: %s, value: %x", key, value) + return value, nil +} + +func (s *SkvsStubInterface) PutState(key string, value []byte) error { + logger.Warningf("Calling Put State (Start), key: %s, value: %x, alldata: %s", key, value, s.allDataNew) + + s.allDataNew[key] = value + byteAllData, err := json.Marshal(s.allDataNew) + if err != nil { + return err + } + encValue, err := s.sep.EncryptState(byteAllData) + if err != nil { + return err + } + logger.Warningf("Calling Put State (End), put encValue: %x", encValue) + + return s.PutPublicState(s.key, encValue) +} + +func (s *SkvsStubInterface) DelState(key string) error { + delete(s.allDataNew, key) + byteAllData, err := json.Marshal(s.allDataNew) + if err != nil { + return err + } + encValue, err := s.sep.EncryptState(byteAllData) + if err != nil { + return err + } + return s.PutPublicState(s.key, encValue) +} + +func (s *SkvsStubInterface) GetStateByRange(startKey string, endKey string) (shim.StateQueryIteratorInterface, error) { + panic("not implemented") // TODO: Implement +} + +func (s *SkvsStubInterface) GetStateByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string) (shim.StateQueryIteratorInterface, *pb.QueryResponseMetadata, error) { + panic("not implemented") // TODO: Implement +} diff --git a/ecc_go/chaincode/singleKVS.go b/ecc_go/chaincode/singleKVS.go new file mode 100644 index 000000000..b78c54185 --- /dev/null +++ b/ecc_go/chaincode/singleKVS.go @@ -0,0 +1,29 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package chaincode + +import ( + "github.com/hyperledger/fabric-chaincode-go/shim" + "github.com/hyperledger/fabric-private-chaincode/ecc/chaincode" + "github.com/hyperledger/fabric-private-chaincode/ecc/chaincode/ercc" + "github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode/enclave_go" + "github.com/hyperledger/fabric-private-chaincode/internal/endorsement" + "github.com/hyperledger/fabric/common/flogging" +) + +var logger = flogging.MustGetLogger("enclave_go") + +func NewSkvsChaincode(cc shim.Chaincode) *chaincode.EnclaveChaincode { + logger.Info("Creating new SKVS Chaincode") + ecc := &chaincode.EnclaveChaincode{ + Enclave: enclave_go.NewSkvsStub(cc), + Validator: endorsement.NewValidator(), + Extractor: &chaincode.ExtractorImpl{}, + Ercc: &ercc.StubImpl{}, + } + return ecc +} diff --git a/samples/chaincode/secret-keeper-go/Makefile b/samples/chaincode/secret-keeper-go/Makefile index 8f80af00d..ab6d5f6b1 100644 --- a/samples/chaincode/secret-keeper-go/Makefile +++ b/samples/chaincode/secret-keeper-go/Makefile @@ -4,6 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 TOP = ../../.. -include $(TOP)/ecc_go/build.mk CC_NAME ?= fpc-secret-keeper-go + +# Define paths for cmd subdirectories +DEFAULT= cmd/naive/main.go +SKVS_PATH = cmd/skvs/main.go + +MAIN_GO_PATH ?=$(DEFAULT) + +include $(TOP)/ecc_go/build.mk diff --git a/samples/chaincode/secret-keeper-go/main.go b/samples/chaincode/secret-keeper-go/cmd/naive/main.go similarity index 100% rename from samples/chaincode/secret-keeper-go/main.go rename to samples/chaincode/secret-keeper-go/cmd/naive/main.go diff --git a/samples/chaincode/secret-keeper-go/cmd/skvs/main.go b/samples/chaincode/secret-keeper-go/cmd/skvs/main.go new file mode 100644 index 000000000..1dc1af38a --- /dev/null +++ b/samples/chaincode/secret-keeper-go/cmd/skvs/main.go @@ -0,0 +1,42 @@ +/* +Copyright IBM Corp. All Rights Reserved. +Copyright 2020 Intel Corporation + +SPDX-License-Identifier: Apache-2.0 +*/ + +package main + +import ( + "os" + + "github.com/hyperledger/fabric-chaincode-go/shim" + "github.com/hyperledger/fabric-contract-api-go/contractapi" + fpc "github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode" + "github.com/hyperledger/fabric-private-chaincode/samples/chaincode/secret-keeper-go/chaincode" +) + +func main() { + + ccid := os.Getenv("CHAINCODE_PKG_ID") + addr := os.Getenv("CHAINCODE_SERVER_ADDRESS") + + // create chaincode + secretChaincode, _ := contractapi.NewChaincode(&chaincode.SecretKeeper{}) + // chaincode := fpc.NewPrivateChaincode(secretChaincode) + skvsChaincode := fpc.NewSkvsChaincode(secretChaincode) + + // start chaincode as a service + server := &shim.ChaincodeServer{ + CCID: ccid, + Address: addr, + CC: skvsChaincode, + TLSProps: shim.TLSProperties{ + Disabled: true, // just for testing good enough + }, + } + + if err := server.Start(); err != nil { + panic(err) + } +}