-
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.
- initial go sdk extension for FPC that hides the FPC transaction flow from the user - integrate with test-network Signed-off-by: bur <[email protected]>
- Loading branch information
1 parent
fdccf21
commit e2dd849
Showing
9 changed files
with
561 additions
and
2 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,20 @@ | ||
package attestation | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/hyperledger-labs/fabric-private-chaincode/internal/protos" | ||
) | ||
|
||
func ToEvidence(credentials *protos.Credentials) (*protos.Credentials, error) { | ||
|
||
// do something | ||
log.Printf("Perform attestation to evidence transformation\n") | ||
|
||
// TODO call brunos attestation_to_evidence.sh | ||
// call $FPC_PATH/common/crypto/attestation-api/conversion/attestation_to_evidence.sh | ||
|
||
credentials.Evidence = credentials.Attestation | ||
|
||
return credentials, nil | ||
} |
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,154 @@ | ||
/* | ||
Copyright 2020 IBM All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package fpc | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/json" | ||
"log" | ||
|
||
"github.com/hyperledger-labs/fabric-private-chaincode/internal/utils" | ||
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" | ||
"github.com/hyperledger/fabric-sdk-go/pkg/gateway" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
type ContractInterface interface { | ||
ManagementInterface | ||
Name() string | ||
EvaluateTransaction(name string, args ...string) ([]byte, error) | ||
SubmitTransaction(name string, args ...string) ([]byte, error) | ||
//CreateTransaction(name string, opts ...gateway.TransactionOption) (*gateway.Transaction, error) | ||
RegisterEvent(eventFilter string) (fab.Registration, <-chan *fab.CCEvent, error) | ||
Unregister(registration fab.Registration) | ||
} | ||
|
||
func GetContract(network *gateway.Network, chaincodeId string) ContractInterface { | ||
contract := network.GetContract(chaincodeId) | ||
ercc := network.GetContract("ercc") | ||
return &Contract{contract, ercc, nil} | ||
} | ||
|
||
type Contract struct { | ||
contract *gateway.Contract | ||
ercc *gateway.Contract | ||
cachedChaincodeEncryptionKey []byte | ||
} | ||
|
||
func (c *Contract) Name() string { | ||
return c.contract.Name() | ||
} | ||
|
||
func (c *Contract) getChaincodeEncryptionKey() ([]byte, error) { | ||
if c.cachedChaincodeEncryptionKey == nil { | ||
ccKeyBytes, err := c.ercc.EvaluateTransaction("queryChaincodeEncryptionKey", c.Name()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
c.cachedChaincodeEncryptionKey = ccKeyBytes | ||
} | ||
return c.cachedChaincodeEncryptionKey, nil | ||
} | ||
|
||
func (c *Contract) prepareChaincodeInvocation(name string, args []string, resultEncryptionKey []byte) (string, error) { | ||
p := &utils.ChaincodeParams{ | ||
Function: name, | ||
Args: args, | ||
ResultEncryptionKey: resultEncryptionKey, | ||
} | ||
|
||
pBytes, err := json.Marshal(p) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
log.Printf("prepping chaincode params: %s\n", p) | ||
|
||
k, err := c.getChaincodeEncryptionKey() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
encryptedParams, err := Encrypt(pBytes, k) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return base64.StdEncoding.EncodeToString(encryptedParams), nil | ||
} | ||
|
||
func (c *Contract) EvaluateTransaction(name string, args ...string) ([]byte, error) { | ||
|
||
// pick response encryption key | ||
resultEncryptionKey, err := KeyGen() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
encryptedParamsBase64, err := c.prepareChaincodeInvocation(name, args, resultEncryptionKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Printf("calling __invoke!\n") | ||
responseBytes, err := c.contract.EvaluateTransaction("__invoke", encryptedParamsBase64) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
response, err := utils.UnmarshalResponse(responseBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// decrypt result | ||
return Decrypt(response.ResponseData, resultEncryptionKey) | ||
} | ||
|
||
func (c *Contract) SubmitTransaction(name string, args ...string) ([]byte, error) { | ||
|
||
// pick response encryption key | ||
resultEncryptionKey, err := KeyGen() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
encryptedParamsBase64, err := c.prepareChaincodeInvocation(name, args, resultEncryptionKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Printf("calling __invoke!\n") | ||
|
||
// first invoke (query) fpc chaincode | ||
responseBytes, err := c.contract.EvaluateTransaction("__invoke", encryptedParamsBase64) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "evaluation transaction failed") | ||
} | ||
|
||
log.Printf("calling __endorse!\n") | ||
// next invoke chaincode endorsement | ||
_, err = c.contract.SubmitTransaction("__endorse", base64.StdEncoding.EncodeToString(responseBytes)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
response, err := utils.UnmarshalResponse(responseBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return Decrypt(response.ResponseData, resultEncryptionKey) | ||
} | ||
|
||
func (c *Contract) RegisterEvent(eventFilter string) (fab.Registration, <-chan *fab.CCEvent, error) { | ||
return c.contract.RegisterEvent(eventFilter) | ||
} | ||
|
||
func (c *Contract) Unregister(registration fab.Registration) { | ||
c.contract.Unregister(registration) | ||
} |
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,13 @@ | ||
package fpc | ||
|
||
func Encrypt(input []byte, encryptionKey []byte) ([]byte, error) { | ||
return input, nil | ||
} | ||
|
||
func KeyGen() ([]byte, error) { | ||
return []byte("fake key"), nil | ||
} | ||
|
||
func Decrypt(encryptedResponse []byte, resultEncryptionKey []byte) ([]byte, error) { | ||
return encryptedResponse, nil | ||
} |
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,61 @@ | ||
package fpc | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hyperledger-labs/fabric-private-chaincode/internal/utils" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger-labs/fabric-private-chaincode/client_sdk/go/fpc/attestation" | ||
"github.com/hyperledger-labs/fabric-private-chaincode/internal/protos" | ||
"github.com/hyperledger/fabric-sdk-go/pkg/gateway" | ||
"github.com/hyperledger/fabric/protoutil" | ||
) | ||
|
||
type ManagementInterface interface { | ||
CreateEnclave(attestationParams ...string) error | ||
} | ||
|
||
type ManagementAPI struct { | ||
network *gateway.Network | ||
} | ||
|
||
func (c *Contract) CreateEnclave(attestationParams ...string) error { | ||
|
||
p, err := json.Marshal(&utils.AttestationParams{Params: attestationParams}) | ||
attestationParamsBase64 := base64.StdEncoding.EncodeToString(p) | ||
|
||
log.Printf("Prep attestation params: %s\n", attestationParamsBase64) | ||
|
||
credentialsBytes, err := c.contract.EvaluateTransaction("__initEnclave", attestationParamsBase64) | ||
if err != nil { | ||
return fmt.Errorf("evaluation error: %s", err) | ||
} | ||
|
||
credentials := &protos.Credentials{} | ||
err = proto.Unmarshal(credentialsBytes, credentials) | ||
if err != nil { | ||
return fmt.Errorf("cannot unmarshal credentials: %s", err) | ||
} | ||
log.Printf("Received credentials from enclave: %s\n", credentials) | ||
|
||
// perform attestation evidence transformation | ||
credentials, err = attestation.ToEvidence(credentials) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
credentialsBytes = protoutil.MarshalOrPanic(credentials) | ||
credentialsBase64 := base64.StdEncoding.EncodeToString(credentialsBytes) | ||
|
||
log.Printf("Call registerEnclave at ERCC: %s\n", attestationParamsBase64) | ||
_, err = c.ercc.SubmitTransaction("registerEnclave", credentialsBase64) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
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,20 @@ | ||
# Copyright 2019 Intel Corporation | ||
# Copyright IBM Corp. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
TOP = ../../.. | ||
include $(TOP)/build.mk | ||
|
||
build: | ||
$(GO) build | ||
|
||
test: | ||
$(GO) test $(GOTAGS) -v ./... | ||
|
||
clean: | ||
$(GO) clean | ||
rm -rf keystore wallet | ||
|
||
run: | ||
$(GO) run . |
Oops, something went wrong.