From 958a66f016711288d421c2cc2381ef04fce07d9e Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Tue, 17 Jan 2017 12:32:46 -0500 Subject: [PATCH] Orderer Signer MSP-based implementation This change-set introduces an MSP-based orderer multichain.signer implementation. At bootstrap, an orderer loads his local signing identity that is then used to sign messages by means of the multichain.Signer interface. This change-set comes in the context of https://jira.hyperledger.org/browse/FAB-1268 Also updates the orderer config path stuff to be slightly more consistent to support referencing the msp sampleconfig both from the dev env and the docker image. Change-Id: Ie4e04cb18d0f28ce801a474a3c500d4f61fa9c7f Signed-off-by: Angelo De Caro Signed-off-by: Jason Yellick --- Makefile | 1 + common/crypto/signer.go | 28 +++++++++ common/localmsp/signer.go | 75 +++++++++++++++++++++++ common/localmsp/signer_test.go | 84 ++++++++++++++++++++++++++ images/orderer/Dockerfile.in | 7 ++- orderer/localconfig/config.go | 34 +++++++---- orderer/main.go | 12 +++- orderer/mocks/multichain/multichain.go | 8 +-- orderer/multichain/chainsupport.go | 20 +++--- orderer/multichain/manager.go | 28 ++++----- orderer/multichain/manager_test.go | 6 +- protos/utils/commonutils.go | 27 +++++++++ 12 files changed, 282 insertions(+), 48 deletions(-) create mode 100644 common/crypto/signer.go create mode 100644 common/localmsp/signer.go create mode 100644 common/localmsp/signer_test.go diff --git a/Makefile b/Makefile index a61f21214ec..c83172c3b0f 100644 --- a/Makefile +++ b/Makefile @@ -187,6 +187,7 @@ build/image/peer/payload: build/docker/bin/peer \ build/msp-sampleconfig.tar.bz2 \ build/genesis-sampleconfig.tar.bz2 build/image/orderer/payload: build/docker/bin/orderer \ + build/msp-sampleconfig.tar.bz2 \ orderer/orderer.yaml build/image/testenv/payload: build/gotools.tar.bz2 build/image/runtime/payload: build/docker/busybox diff --git a/common/crypto/signer.go b/common/crypto/signer.go new file mode 100644 index 00000000000..55515eb5fcc --- /dev/null +++ b/common/crypto/signer.go @@ -0,0 +1,28 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package crypto + +import cb "github.com/hyperledger/fabric/protos/common" + +// LocalSigner is a temporary stub interface which will be implemented by the local MSP +type LocalSigner interface { + // NewSignatureHeader creates a SignatureHeader with the correct signing identity and a valid nonce + NewSignatureHeader() (*cb.SignatureHeader, error) + + // Sign a message which should embed a signature header created by NewSignatureHeader + Sign(message []byte) ([]byte, error) +} diff --git a/common/localmsp/signer.go b/common/localmsp/signer.go new file mode 100644 index 00000000000..660f978ab7c --- /dev/null +++ b/common/localmsp/signer.go @@ -0,0 +1,75 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package localmsp + +import ( + "fmt" + + "github.com/hyperledger/fabric/core/crypto/primitives" + "github.com/hyperledger/fabric/common/crypto" + cb "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/core/peer/msp" +) + +type mspSigner struct { +} + +// New returns a new instance of the msp-based LocalSigner. +// It assumes that the local msp has been already initialized. +// Look at mspmgmt.LoadLocalMsp for further information. +func NewSigner() crypto.LocalSigner { + return &mspSigner{} +} + +// NewSignatureHeader creates a SignatureHeader with the correct signing identity and a valid nonce +func (s *mspSigner) NewSignatureHeader() (*cb.SignatureHeader, error) { + signer, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() + if err != nil { + return nil, fmt.Errorf("Failed getting MSP-based signer [%s]", err) + } + + creatorIdentityRaw, err := signer.Serialize() + if err != nil { + return nil, fmt.Errorf("Failed serializing creator public identity [%s]", err) + } + + nonce, err := primitives.GetRandomNonce() + if err != nil { + return nil, fmt.Errorf("Failed creating nonce [%s]", err) + } + + sh := &cb.SignatureHeader{} + sh.Creator = creatorIdentityRaw + sh.Nonce = nonce + + return sh, nil +} + +// Sign a message which should embed a signature header created by NewSignatureHeader +func (s *mspSigner) Sign(message []byte) ([]byte, error) { + signer, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() + if err != nil { + return nil, fmt.Errorf("Failed getting MSP-based signer [%s]", err) + } + + signature, err := signer.Sign(message) + if err != nil { + return nil, fmt.Errorf("Failed generating signature [%s]", err) + } + + return signature, nil +} diff --git a/common/localmsp/signer_test.go b/common/localmsp/signer_test.go new file mode 100644 index 00000000000..2f2e8bfdef3 --- /dev/null +++ b/common/localmsp/signer_test.go @@ -0,0 +1,84 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package localmsp + +import ( + "os" + "testing" + + "github.com/hyperledger/fabric/core/crypto/primitives" + "github.com/stretchr/testify/assert" + "github.com/hyperledger/fabric/core/peer/msp" +) + +func TestMain(m *testing.M) { + // 1. Determine MSP configuration + var mspMgrConfigDir string + var alternativeCfgPath = os.Getenv("ORDERER_CFG_PATH") + if alternativeCfgPath != "" { + mspMgrConfigDir = alternativeCfgPath + "/msp/sampleconfig/" + } else if _, err := os.Stat("./msp/sampleconfig/"); err == nil { + mspMgrConfigDir = "./msp/sampleconfig/" + } else { + mspMgrConfigDir = os.Getenv("GOPATH") + "/src/github.com/hyperledger/fabric/msp/sampleconfig/" + } + + if err := mspmgmt.LoadLocalMsp(mspMgrConfigDir); err != nil { + os.Exit(-1) + } + + os.Exit(m.Run()) +} + +func TestNewSigner(t *testing.T) { + signer := NewSigner() + assert.NotNil(t, signer, "Signer must be differentr from nil.") +} + +func TestMspSigner_NewSignatureHeader(t *testing.T) { + signer := NewSigner() + + sh, err := signer.NewSignatureHeader() + if err != nil { + t.Fatalf("Failed creting signature header [%s]", err) + } + + assert.NotNil(t, sh, "SignatureHeader must be different from nil") + assert.Len(t, sh.Nonce, primitives.NonceSize, "SignatureHeader.Nonce must be of length %d", primitives.NonceSize) + + mspIdentity, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() + assert.NoError(t, err, "Failed getting default MSP Identity") + publicIdentity := mspIdentity.GetPublicVersion() + assert.NotNil(t, publicIdentity, "Failed getting default public identity. It must be different from nil.") + publicIdentityRaw, err := publicIdentity.Serialize() + assert.NoError(t, err, "Failed serializing default public identity") + assert.Equal(t, publicIdentityRaw, sh.Creator, "Creator must be local default signer identity") +} + +func TestMspSigner_Sign(t *testing.T) { + signer := NewSigner() + + msg := []byte("Hello World") + sigma, err := signer.Sign(msg) + assert.NoError(t, err, "FAiled generating signature") + + // Verify signature + mspIdentity, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() + assert.NoError(t, err, "Failed getting default MSP Identity") + err = mspIdentity.Verify(msg, sigma) + assert.NoError(t, err, "Failed verifiing signature") +} diff --git a/images/orderer/Dockerfile.in b/images/orderer/Dockerfile.in index 67fa3f7b062..37e9625565d 100644 --- a/images/orderer/Dockerfile.in +++ b/images/orderer/Dockerfile.in @@ -1,7 +1,8 @@ FROM hyperledger/fabric-runtime:_TAG_ -ENV ORDERER_CFG_PATH /etc/hyperledger/fabric -RUN mkdir -p /var/hyperledger/db /etc/hyperledger/fabric +ENV ORDERER_CFG_PATH /etc/hyperledger/fabric/orderer +RUN mkdir -p /var/hyperledger/db /etc/hyperledger/fabric/orderer COPY payload/orderer /usr/local/bin -COPY payload/orderer.yaml $ORDERER_CFG_PATH +ADD payload/msp-sampleconfig.tar.bz2 $ORDERER_CFG_PATH/../ +COPY payload/orderer.yaml $ORDERER_CFG_PATH/ EXPOSE 7050 CMD orderer diff --git a/orderer/localconfig/config.go b/orderer/localconfig/config.go index cf9ae921634..9314cc2c061 100644 --- a/orderer/localconfig/config.go +++ b/orderer/localconfig/config.go @@ -48,6 +48,7 @@ type General struct { GenesisFile string Profile Profile LogLevel string + LocalMSPDir string } // Genesis contains config which is used by the provisional bootstrapper @@ -121,7 +122,8 @@ var defaults = TopLevel{ Enabled: false, Address: "0.0.0.0:6060", }, - LogLevel: "INFO", + LogLevel: "INFO", + LocalMSPDir: "../msp/sampleconfig/", }, RAMLedger: RAMLedger{ HistorySize: 10000, @@ -180,6 +182,12 @@ func (c *TopLevel) completeInitialization() { case c.General.Profile.Enabled && (c.General.Profile.Address == ""): logger.Infof("Profiling enabled and General.Profile.Address unset, setting to %s", defaults.General.Profile.Address) c.General.Profile.Address = defaults.General.Profile.Address + case c.General.LocalMSPDir == "": + logger.Infof("General.LocalMSPDir unset, setting to %s", defaults.General.LocalMSPDir) + // Note, this is a bit of a weird one, the orderer may set the ORDERER_CFG_PATH after + // the file is initialized, so we cannot initialize this in the structure, so we + // deference the env portion here + c.General.LocalMSPDir = filepath.Join(os.Getenv("ORDERER_CFG_PATH"), defaults.General.LocalMSPDir) case c.FileLedger.Prefix == "": logger.Infof("FileLedger.Prefix unset, setting to %s", defaults.FileLedger.Prefix) c.FileLedger.Prefix = defaults.FileLedger.Prefix @@ -221,22 +229,26 @@ func Load() *TopLevel { config := viper.New() config.SetConfigName("orderer") - alternativeCfgPath := os.Getenv("ORDERER_CFG_PATH") - if alternativeCfgPath != "" { - logger.Infof("User defined config file path: %s", alternativeCfgPath) - config.AddConfigPath(alternativeCfgPath) // Path to look for the config file in - } else { - config.AddConfigPath("./") - config.AddConfigPath("../../.") - config.AddConfigPath("../orderer/") - config.AddConfigPath("../../orderer/") + cfgPath := os.Getenv("ORDERER_CFG_PATH") + if cfgPath == "" { + logger.Infof("No orderer cfg path set, assuming development environment, deriving from go path") // Path to look for the config file in based on GOPATH gopath := os.Getenv("GOPATH") for _, p := range filepath.SplitList(gopath) { ordererPath := filepath.Join(p, "src/github.com/hyperledger/fabric/orderer/") - config.AddConfigPath(ordererPath) + if _, err := os.Stat(filepath.Join(ordererPath, "orderer.yaml")); err != nil { + // The yaml file does not exist in this component of the go src + continue + } + cfgPath = ordererPath } + if cfgPath == "" { + logger.Fatalf("Could not find orderer.yaml, try setting ORDERER_CFG_PATH or GOPATH correctly") + } + logger.Infof("Setting ORDERER_CFG_PATH to: %s", cfgPath) + os.Setenv("ORDERER_CFG_PATH", cfgPath) } + config.AddConfigPath(cfgPath) // Path to look for the config file in // for environment variables config.SetEnvPrefix(Prefix) diff --git a/orderer/main.go b/orderer/main.go index 15861a8e96d..66d02789c2b 100644 --- a/orderer/main.go +++ b/orderer/main.go @@ -40,6 +40,8 @@ import ( "github.com/hyperledger/fabric/protos/utils" "github.com/Shopify/sarama" + "github.com/hyperledger/fabric/common/localmsp" + "github.com/hyperledger/fabric/core/peer/msp" logging "github.com/op/go-logging" "google.golang.org/grpc" ) @@ -47,6 +49,8 @@ import ( var logger = logging.MustGetLogger("orderer/main") func main() { + // Temporarilly set logging level until config is read + logging.SetLevel(logging.INFO, "") conf := config.Load() flogging.InitFromSpec(conf.General.LogLevel) @@ -67,6 +71,12 @@ func main() { return } + // Load local MSP + err = mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir) + if err != nil { // Handle errors reading the config file + panic(fmt.Errorf("Failed initializing crypto [%s]", err)) + } + var lf ordererledger.Factory switch conf.General.LedgerType { case "file": @@ -127,7 +137,7 @@ func main() { consenters["solo"] = solo.New() consenters["kafka"] = kafka.New(conf.Kafka.Version, conf.Kafka.Retry) - manager := multichain.NewManagerImpl(lf, consenters) + manager := multichain.NewManagerImpl(lf, consenters, localmsp.NewSigner()) server := NewServer( manager, diff --git a/orderer/mocks/multichain/multichain.go b/orderer/mocks/multichain/multichain.go index 447f2cc0aba..a04b85003c2 100644 --- a/orderer/mocks/multichain/multichain.go +++ b/orderer/mocks/multichain/multichain.go @@ -85,11 +85,11 @@ func (mcs *ConsenterSupport) ChainID() string { } // Sign returns the bytes passed in -func (mcs *ConsenterSupport) Sign(message []byte) []byte { - return message +func (mcs *ConsenterSupport) Sign(message []byte) ([]byte, error) { + return message, nil } // NewSignatureHeader returns an empty signature header -func (mcs *ConsenterSupport) NewSignatureHeader() *cb.SignatureHeader { - return &cb.SignatureHeader{} +func (mcs *ConsenterSupport) NewSignatureHeader() (*cb.SignatureHeader, error) { + return &cb.SignatureHeader{}, nil } diff --git a/orderer/multichain/chainsupport.go b/orderer/multichain/chainsupport.go index f3b0da85dc6..a8c661cf1be 100644 --- a/orderer/multichain/chainsupport.go +++ b/orderer/multichain/chainsupport.go @@ -18,6 +18,7 @@ package multichain import ( "github.com/hyperledger/fabric/common/configtx" + "github.com/hyperledger/fabric/common/crypto" "github.com/hyperledger/fabric/common/policies" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/orderer/common/blockcutter" @@ -60,7 +61,7 @@ type Chain interface { // ConsenterSupport provides the resources available to a Consenter implementation type ConsenterSupport interface { - Signer + crypto.LocalSigner BlockCutter() blockcutter.Receiver SharedConfig() sharedconfig.Manager CreateNextBlock(messages []*cb.Envelope) *cb.Block @@ -94,7 +95,7 @@ type chainSupport struct { sharedConfigManager sharedconfig.Manager ledger ordererledger.ReadWriter filters *filter.RuleSet - signer Signer + signer crypto.LocalSigner lastConfiguration uint64 lastConfigSeq uint64 } @@ -106,7 +107,7 @@ func newChainSupport( backing ordererledger.ReadWriter, sharedConfigManager sharedconfig.Manager, consenters map[string]Consenter, - signer Signer, + signer crypto.LocalSigner, ) *chainSupport { cutter := blockcutter.NewReceiverImpl(sharedConfigManager, filters) @@ -163,11 +164,11 @@ func (cs *chainSupport) start() { cs.chain.Start() } -func (cs *chainSupport) NewSignatureHeader() *cb.SignatureHeader { +func (cs *chainSupport) NewSignatureHeader() (*cb.SignatureHeader, error) { return cs.signer.NewSignatureHeader() } -func (cs *chainSupport) Sign(message []byte) []byte { +func (cs *chainSupport) Sign(message []byte) ([]byte, error) { return cs.signer.Sign(message) } @@ -210,15 +211,16 @@ func (cs *chainSupport) CreateNextBlock(messages []*cb.Envelope) *cb.Block { func (cs *chainSupport) addBlockSignature(block *cb.Block) { logger.Debugf("%+v", cs) logger.Debugf("%+v", cs.signer) + blockSignature := &cb.MetadataSignature{ - SignatureHeader: utils.MarshalOrPanic(cs.signer.NewSignatureHeader()), + SignatureHeader: utils.MarshalOrPanic(utils.NewSignatureHeaderOrPanic(cs.signer)), } // Note, this value is intentionally nil, as this metadata is only about the signature, there is no additional metadata // information required beyond the fact that the metadata item is signed. blockSignatureValue := []byte(nil) - blockSignature.Signature = cs.signer.Sign(util.ConcatenateBytes(blockSignatureValue, blockSignature.SignatureHeader, block.Header.Bytes())) + blockSignature.Signature = utils.SignOrPanic(cs.signer, util.ConcatenateBytes(blockSignatureValue, blockSignature.SignatureHeader, block.Header.Bytes())) block.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES] = utils.MarshalOrPanic(&cb.Metadata{ Value: blockSignatureValue, @@ -236,12 +238,12 @@ func (cs *chainSupport) addLastConfigSignature(block *cb.Block) { } lastConfigSignature := &cb.MetadataSignature{ - SignatureHeader: utils.MarshalOrPanic(cs.signer.NewSignatureHeader()), + SignatureHeader: utils.MarshalOrPanic(utils.NewSignatureHeaderOrPanic(cs.signer)), } lastConfigValue := utils.MarshalOrPanic(&cb.LastConfiguration{Index: cs.lastConfiguration}) - lastConfigSignature.Signature = cs.signer.Sign(util.ConcatenateBytes(lastConfigValue, lastConfigSignature.SignatureHeader, block.Header.Bytes())) + lastConfigSignature.Signature = utils.SignOrPanic(cs.signer, util.ConcatenateBytes(lastConfigValue, lastConfigSignature.SignatureHeader, block.Header.Bytes())) block.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIGURATION] = utils.MarshalOrPanic(&cb.Metadata{ Value: lastConfigValue, diff --git a/orderer/multichain/manager.go b/orderer/multichain/manager.go index cb2138ec678..73e84b0fe4f 100644 --- a/orderer/multichain/manager.go +++ b/orderer/multichain/manager.go @@ -29,6 +29,7 @@ import ( "github.com/op/go-logging" "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric/common/crypto" ) var logger = logging.MustGetLogger("orderer/multichain") @@ -41,21 +42,12 @@ func (xxx xxxCryptoHelper) VerifySignature(sd *cb.SignedData) error { return nil } -func (xxx xxxCryptoHelper) NewSignatureHeader() *cb.SignatureHeader { - return &cb.SignatureHeader{} +func (xxx xxxCryptoHelper) NewSignatureHeader() (*cb.SignatureHeader, error) { + return &cb.SignatureHeader{}, nil } -func (xxx xxxCryptoHelper) Sign(message []byte) []byte { - return message -} - -// Signer is a temporary stub interface which will be implemented by the local MSP -type Signer interface { - // NewSignatureHeader creates a SignatureHeader with the correct signing identity and a valid nonce - NewSignatureHeader() *cb.SignatureHeader - - // Sign a message which should embed a signature header created by NewSignatureHeader - Sign(message []byte) []byte +func (xxx xxxCryptoHelper) Sign(message []byte) ([]byte, error) { + return message, nil } // Manager coordinates the creation and access of chains @@ -74,6 +66,7 @@ type multiLedger struct { consenters map[string]Consenter ledgerFactory ordererledger.Factory sysChain *systemChain + signer crypto.LocalSigner } func getConfigTx(reader ordererledger.Reader) *cb.Envelope { @@ -91,11 +84,12 @@ func getConfigTx(reader ordererledger.Reader) *cb.Envelope { } // NewManagerImpl produces an instance of a Manager -func NewManagerImpl(ledgerFactory ordererledger.Factory, consenters map[string]Consenter) Manager { +func NewManagerImpl(ledgerFactory ordererledger.Factory, consenters map[string]Consenter, signer crypto.LocalSigner) Manager { ml := &multiLedger{ chains: make(map[string]*chainSupport), ledgerFactory: ledgerFactory, consenters: consenters, + signer: signer, } existingChains := ledgerFactory.ChainIDs() @@ -122,7 +116,7 @@ func NewManagerImpl(ledgerFactory ordererledger.Factory, consenters map[string]C backingLedger, sharedConfigManager, consenters, - &xxxCryptoHelper{}) + signer) ml.chains[string(chainID)] = chain ml.sysChain = newSystemChain(chain) // We delay starting this chain, as it might try to copy and replace the chains map via newChain before the map is fully built @@ -135,7 +129,7 @@ func NewManagerImpl(ledgerFactory ordererledger.Factory, consenters map[string]C backingLedger, sharedConfigManager, consenters, - &xxxCryptoHelper{}) + signer) ml.chains[string(chainID)] = chain chain.start() } @@ -238,7 +232,7 @@ func (ml *multiLedger) newChain(configtx *cb.Envelope) { newChains[key] = value } - cs := newChainSupport(createStandardFilters(configManager, policyManager, sharedConfig), configManager, policyManager, backingLedger, sharedConfig, ml.consenters, &xxxCryptoHelper{}) + cs := newChainSupport(createStandardFilters(configManager, policyManager, sharedConfig), configManager, policyManager, backingLedger, sharedConfig, ml.consenters, ml.signer) chainID := configManager.ChainID() logger.Debugf("Created and starting new chain %s", chainID) diff --git a/orderer/multichain/manager_test.go b/orderer/multichain/manager_test.go index 88811fe9f34..1269cc3b125 100644 --- a/orderer/multichain/manager_test.go +++ b/orderer/multichain/manager_test.go @@ -109,7 +109,7 @@ func TestManagerImpl(t *testing.T) { consenters := make(map[string]Consenter) consenters[conf.Genesis.OrdererType] = &mockConsenter{} - manager := NewManagerImpl(lf, consenters) + manager := NewManagerImpl(lf, consenters, &xxxCryptoHelper{}) _, ok := manager.GetChain("Fake") if ok { @@ -155,7 +155,7 @@ func TestSignatureFilter(t *testing.T) { consenters := make(map[string]Consenter) consenters[conf.Genesis.OrdererType] = &mockConsenter{} - manager := NewManagerImpl(lf, consenters) + manager := NewManagerImpl(lf, consenters, &xxxCryptoHelper{}) cs, ok := manager.GetChain(provisional.TestChainID) @@ -193,7 +193,7 @@ func TestNewChain(t *testing.T) { consenters := make(map[string]Consenter) consenters[conf.Genesis.OrdererType] = &mockConsenter{} - manager := NewManagerImpl(lf, consenters) + manager := NewManagerImpl(lf, consenters, &xxxCryptoHelper{}) generator := provisional.New(conf) items := generator.TemplateItems() diff --git a/protos/utils/commonutils.go b/protos/utils/commonutils.go index 100a1ae0fc0..f9f899445ef 100644 --- a/protos/utils/commonutils.go +++ b/protos/utils/commonutils.go @@ -23,8 +23,11 @@ import ( "github.com/hyperledger/fabric/core/crypto/primitives" cb "github.com/hyperledger/fabric/protos/common" + "errors" + "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes/timestamp" + "github.com/hyperledger/fabric/common/crypto" ) // MarshalOrPanic serializes a protobuf message and panics if this operation fails. @@ -173,3 +176,27 @@ func MakePayloadHeader(ch *cb.ChainHeader, sh *cb.SignatureHeader) *cb.Header { SignatureHeader: sh, } } + +func NewSignatureHeaderOrPanic(signer crypto.LocalSigner) *cb.SignatureHeader { + if signer == nil { + panic(errors.New("Invalid signer. Must be different from nil.")) + } + + signatureHeader, err := signer.NewSignatureHeader() + if err != nil { + panic(fmt.Errorf("Failed generating a new SignatureHeader [%s]", err)) + } + return signatureHeader +} + +func SignOrPanic(signer crypto.LocalSigner, msg []byte) []byte { + if signer == nil { + panic(errors.New("Invalid signer. Must be different from nil.")) + } + + sigma, err := signer.Sign(msg) + if err != nil { + panic(fmt.Errorf("Failed generting signature [%s]", err)) + } + return sigma +}