-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
de52035
commit dfad2c1
Showing
4 changed files
with
359 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package enclave_go | ||
|
||
import ( | ||
"crypto/sha256" | ||
|
||
"github.com/hyperledger/fabric-chaincode-go/shim" | ||
"github.com/hyperledger/fabric-private-chaincode/internal/protos" | ||
"github.com/hyperledger/fabric/protoutil" | ||
"github.com/pkg/errors" | ||
"google.golang.org/protobuf/proto" | ||
) | ||
|
||
type skvsStub struct { | ||
*EnclaveStub | ||
} | ||
|
||
func NewSkvsStub(cc shim.Chaincode) *skvsStub { | ||
enclaveStub := NewEnclaveStub(cc) | ||
return &skvsStub{enclaveStub} | ||
} | ||
|
||
func (e *skvsStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, chaincodeRequestMessageBytes []byte) ([]byte, error) { | ||
logger.Error("==== SKVS ChaincodeInvoke ====") | ||
|
||
signedProposal, err := stub.GetSignedProposal() | ||
if err != nil { | ||
shim.Error(err.Error()) | ||
} | ||
|
||
if err := e.verifySignedProposal(stub, chaincodeRequestMessageBytes); err != nil { | ||
return nil, errors.Wrap(err, "signed proposal verification failed") | ||
} | ||
|
||
// unmarshal chaincodeRequest | ||
chaincodeRequestMessage := &protos.ChaincodeRequestMessage{} | ||
err = proto.Unmarshal(chaincodeRequestMessageBytes, chaincodeRequestMessage) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// get key transport message including the encryption keys for request and response | ||
keyTransportMessage, err := e.extractKeyTransportMessage(chaincodeRequestMessage) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "cannot extract keyTransportMessage") | ||
} | ||
|
||
// decrypt request | ||
cleartextChaincodeRequest, err := e.extractCleartextChaincodeRequest(chaincodeRequestMessage, keyTransportMessage) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "cannot decrypt chaincode request") | ||
} | ||
|
||
// create a new instance of a FPC RWSet that we pass to the stub and later return with the response | ||
rwset := NewReadWriteSet() | ||
|
||
// Invoke chaincode | ||
// we wrap the stub with our FpcStubInterface | ||
// ** Implement our own FpcStubInterface | ||
skvsStub := NewSkvsStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) | ||
ccResponse := e.ccRef.Invoke(skvsStub) | ||
// ** | ||
// fpcStub := NewFpcStubInterface(stub, cleartextChaincodeRequest.GetInput(), rwset, e.ccKeys) | ||
// ccResponse := e.ccRef.Invoke(fpcStub) | ||
|
||
// marshal chaincode response | ||
ccResponseBytes, err := protoutil.Marshal(&ccResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
//encrypt response | ||
encryptedResponse, err := e.csp.EncryptMessage(keyTransportMessage.GetResponseEncryptionKey(), ccResponseBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
chaincodeRequestMessageHash := sha256.Sum256(chaincodeRequestMessageBytes) | ||
|
||
response := &protos.ChaincodeResponseMessage{ | ||
EncryptedResponse: encryptedResponse, | ||
FpcRwSet: rwset.ToFPCKVSet(), | ||
EnclaveId: e.identity.GetEnclaveId(), | ||
Proposal: signedProposal, | ||
ChaincodeRequestMessageHash: chaincodeRequestMessageHash[:], | ||
} | ||
|
||
responseBytes, err := proto.Marshal(response) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// create signature | ||
sig, err := e.identity.Sign(responseBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
signedResponse := &protos.SignedChaincodeResponseMessage{ | ||
ChaincodeResponseMessage: responseBytes, | ||
Signature: sig, | ||
} | ||
|
||
return proto.Marshal(signedResponse) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package enclave_go | ||
|
||
import ( | ||
"encoding/hex" | ||
"encoding/json" | ||
|
||
"github.com/hyperledger/fabric-chaincode-go/shim" | ||
pb "github.com/hyperledger/fabric-protos-go/peer" | ||
) | ||
|
||
var SingleKey = "SingleKey" | ||
|
||
type SkvsStubInterface struct { | ||
*FpcStubInterface | ||
} | ||
|
||
func NewSkvsStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) *SkvsStubInterface { | ||
fpcStub := NewFpcStubInterface(stub, input, rwset, sep) | ||
return &SkvsStubInterface{fpcStub} | ||
} | ||
|
||
func (s *SkvsStubInterface) GetState(key string) ([]byte, error) { | ||
logger.Warningf("Calling Get State (Start), key = %s", key) | ||
encValue, err := s.GetPublicState(SingleKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// in case the key does not exist, return early | ||
if len(encValue) == 0 { | ||
logger.Warningf("Calling Get State (End), data empty return.") | ||
return nil, nil | ||
} | ||
|
||
value, err := s.sep.DecryptState(encValue) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Create an interface{} value to hold the unmarshalled data | ||
var allData map[string]string | ||
|
||
// Unmarshal the JSON data into the interface{} value | ||
err = json.Unmarshal(value, &allData) | ||
if err != nil { | ||
logger.Errorf("SKVS Json unmarshal error: %s", err) | ||
return nil, err | ||
} | ||
logger.Warningf("Calling Get State (Mid), key = %s, decrypted done alldata = %s", key, allData) | ||
|
||
targetHex := allData[key] | ||
targetBytes, err := hex.DecodeString(targetHex) | ||
logger.Warningf("Calling Get State (End), Target: %s, TargetBytes: %x, err: %s", targetHex, targetBytes, err) | ||
return targetBytes, err | ||
// return s.sep.DecryptState(encValue) | ||
} | ||
|
||
func (s *SkvsStubInterface) PutState(key string, value []byte) error { | ||
logger.Warningf("Calling Put State (Start), key = %s, value = %x", key, value) | ||
// grab all data from the state. | ||
encAllValue, err := s.GetPublicState(SingleKey) | ||
if err != nil { | ||
return err | ||
} | ||
var allData map[string]string | ||
|
||
if len(encAllValue) == 0 { | ||
// current world state is empty | ||
allData = map[string]string{} | ||
} else { | ||
allValue, err := s.sep.DecryptState(encAllValue) | ||
if err != nil { | ||
return err | ||
} | ||
// Unmarshal the JSON data into the interface{} value | ||
err = json.Unmarshal(allValue, &allData) | ||
if err != nil { | ||
logger.Errorf("SKVS Json unmarshal error: %s", err) | ||
return err | ||
} | ||
} | ||
logger.Warningf("Calling Put State (Mid-1), decrypt succeed, allData = %s", allData) | ||
|
||
valueHex := hex.EncodeToString(value) | ||
|
||
allData[key] = valueHex | ||
logger.Warningf("Calling Put State (Mid-2), add need data key = %s, valueHex = %s, allData = %s", key, valueHex, allData) | ||
|
||
byteAllData, err := json.Marshal(allData) | ||
if err != nil { | ||
return err | ||
} | ||
logger.Warningf("Calling Put State (Mid-3), successfull marshal allData, byteAlldata = %x", byteAllData) | ||
|
||
encValue, err := s.sep.EncryptState(byteAllData) | ||
if err != nil { | ||
return err | ||
} | ||
logger.Warningf("Calling Put State (End), put encValue %x", encValue) | ||
|
||
return s.PutPublicState(SingleKey, encValue) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.