Skip to content

Commit

Permalink
Goosip MessageCryptoService and SecurityAdvisor Impl
Browse files Browse the repository at this point in the history
This change-set implements the gossip MessageCryptoService and
SecurityAdvisor. This implementation will be used by
a peer to initialiaze the gossip layer.

What remains to do is to integrate the channel read
policies once they are in place.

This change-set comes in the context of JIRA item:
https://jira.hyperledger.org/browse/FAB-1394
Notice that before starting using the implementation
provided by this change-set, the implementation of
identity.GetOrganizationUnits() and the enforcement
that DeserializeIdentity fails when the mspIDs do not match
must be in place.

Change-Id: I8b9cbe90044de14a68ba78ce5f7391f9e5da2cd0
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro committed Jan 29, 2017
1 parent bb41bbc commit bb3b20b
Show file tree
Hide file tree
Showing 18 changed files with 511 additions and 26 deletions.
9 changes: 4 additions & 5 deletions gossip/api/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ import (
// that provides security and identity related capabilities
type SecurityAdvisor interface {
// OrgByPeerIdentity returns the OrgIdentityType
// of a given peer identity
// of a given peer identity.
// If any error occurs, nil is returned.
// This method does not validate peerIdentity.
// This validation is supposed to be done appropriately during the execution flow.
OrgByPeerIdentity(PeerIdentityType) OrgIdentityType

// Verify verifies a JoinChannelMessage, returns nil on success,
// and an error on failure
Verify(JoinChannelMessage) error
}

// ChannelNotifier is implemented by the gossip component and is used for the peer
Expand Down
9 changes: 6 additions & 3 deletions gossip/api/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,28 @@ import "github.com/hyperledger/fabric/gossip/common"
type MessageCryptoService interface {

// GetPKIidOfCert returns the PKI-ID of a peer's identity
// If any error occurs, the method return nil
// This method does not validate peerIdentity.
// This validation is supposed to be done appropriately during the execution flow.
GetPKIidOfCert(peerIdentity PeerIdentityType) common.PKIidType

// VerifyBlock returns nil if the block is properly signed,
// else returns error
VerifyBlock(signedBlock SignedBlock) error
VerifyBlock(chainID common.ChainID, signedBlock SignedBlock) error

// Sign signs msg with this peer's signing key and outputs
// the signature if no error occurred.
Sign(msg []byte) ([]byte, error)

// Verify checks that signature is a valid signature of message under a peer's verification key.
// If the verification succeeded, Verify returns nil meaning no error occurred.
// If peerIdentity is nil, then the signature is verified against this peer's verification key.
// If peerIdentity is nil, then the verification fails.
Verify(peerIdentity PeerIdentityType, signature, message []byte) error

// VerifyByChannel checks that signature is a valid signature of message
// under a peer's verification key, but also in the context of a specific channel.
// If the verification succeeded, Verify returns nil meaning no error occurred.
// If peerIdentity is nil, then the signature is verified against this peer's verification key.
// If peerIdentity is nil, then the verification fails.
VerifyByChannel(chainID common.ChainID, peerIdentity PeerIdentityType, signature, message []byte) error

// ValidateIdentity validates the identity of a remote peer.
Expand Down
2 changes: 1 addition & 1 deletion gossip/comm/comm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (*naiveSecProvider) GetPKIidOfCert(peerIdentity api.PeerIdentityType) commo

// VerifyBlock returns nil if the block is properly signed,
// else returns error
func (*naiveSecProvider) VerifyBlock(signedBlock api.SignedBlock) error {
func (*naiveSecProvider) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion gossip/gossip/channel/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ func (gc *gossipChannel) verifyBlock(msg *proto.GossipMessage, sender common.PKI
gc.logger.Warning("Received empty payload from", sender)
return false
}
err := gc.mcs.VerifyBlock(msg.GetDataMsg().Payload)
err := gc.mcs.VerifyBlock(msg.Channel, msg.GetDataMsg().Payload)
if err != nil {
gc.logger.Warning("Received fabricated block from", sender, "in DataUpdate:", err)
return false
Expand Down
2 changes: 1 addition & 1 deletion gossip/gossip/channel/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (cs *cryptoService) VerifyByChannel(_ common.ChainID, _ api.PeerIdentityTyp
panic("Should not be called in this test")
}

func (cs *cryptoService) VerifyBlock(signedBlock api.SignedBlock) error {
func (cs *cryptoService) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
args := cs.Called(signedBlock)
if args.Get(0) == nil {
return nil
Expand Down
7 changes: 2 additions & 5 deletions gossip/gossip/gossip_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ func (g *gossipServiceImpl) toDie() bool {
}

func (g *gossipServiceImpl) JoinChan(joinMsg api.JoinChannelMessage, chainID common.ChainID) {
if err := g.secAdvisor.Verify(joinMsg); err != nil {
g.logger.Error("Failed verifying join channel message", joinMsg, "error:", err)
return
}
// joinMsg is supposed to have been already verified
g.chanState.joinChannel(joinMsg, chainID)

selfPkiID := g.mcs.GetPKIidOfCert(g.selfIdentity)
Expand Down Expand Up @@ -343,7 +340,7 @@ func (g *gossipServiceImpl) validateMsg(msg comm.ReceivedMessage) bool {
return true
}

if err := g.mcs.VerifyBlock(blockMsg); err != nil {
if err := g.mcs.VerifyBlock(msg.GetGossipMessage().Channel, blockMsg); err != nil {
g.logger.Warning("Could not verify block", blockMsg.Payload.SeqNum, ":", err)
return false
}
Expand Down
2 changes: 1 addition & 1 deletion gossip/gossip/gossip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) com

// VerifyBlock returns nil if the block is properly signed,
// else returns error
func (*naiveCryptoService) VerifyBlock(signedBlock api.SignedBlock) error {
func (*naiveCryptoService) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
return nil
}

Expand Down
11 changes: 6 additions & 5 deletions gossip/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ package identity

import (
"bytes"
"fmt"
"sync"

"errors"

"github.com/hyperledger/fabric/gossip/api"
"github.com/hyperledger/fabric/gossip/common"
)
Expand Down Expand Up @@ -66,10 +67,10 @@ func NewIdentityMapper(mcs api.MessageCryptoService) Mapper {
// in case the given pkiID doesn't match the identity
func (is *identityMapperImpl) Put(pkiID common.PKIidType, identity api.PeerIdentityType) error {
if pkiID == nil {
return fmt.Errorf("pkiID is nil")
return errors.New("PkiID is nil")
}
if identity == nil {
return fmt.Errorf("identity is nil")
return errors.New("Identity is nil")
}

if err := is.mcs.ValidateIdentity(identity); err != nil {
Expand All @@ -78,7 +79,7 @@ func (is *identityMapperImpl) Put(pkiID common.PKIidType, identity api.PeerIdent

id := is.mcs.GetPKIidOfCert(identity)
if !bytes.Equal(pkiID, id) {
return fmt.Errorf("Identity doesn't match the computed pkiID")
return errors.New("Identity doesn't match the computed pkiID")
}

is.Lock()
Expand All @@ -94,7 +95,7 @@ func (is *identityMapperImpl) Get(pkiID common.PKIidType) (api.PeerIdentityType,
defer is.RUnlock()
identity, exists := is.pkiID2Cert[string(pkiID)]
if !exists {
return nil, fmt.Errorf("pkiID wasn't found")
return nil, errors.New("PkiID wasn't found")
}
return identity, nil
}
Expand Down
2 changes: 1 addition & 1 deletion gossip/identity/identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) com

// VerifyBlock returns nil if the block is properly signed,
// else returns error
func (*naiveCryptoService) VerifyBlock(signedBlock api.SignedBlock) error {
func (*naiveCryptoService) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion gossip/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) com

// VerifyBlock returns nil if the block is properly signed,
// else returns error
func (*naiveCryptoService) VerifyBlock(signedBlock api.SignedBlock) error {
func (*naiveCryptoService) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion gossip/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) com

// VerifyBlock returns nil if the block is properly signed,
// else returns error
func (*naiveCryptoService) VerifyBlock(signedBlock api.SignedBlock) error {
func (*naiveCryptoService) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
return nil
}

Expand Down
33 changes: 33 additions & 0 deletions msp/mgmt/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ func GetManagerForChain(ChainID string) msp.MSPManager {
return mspMgr
}

// GetManagers returns all the managers registered
func GetManagers() map[string]msp.MSPManager {
m.Lock()
defer m.Unlock()

clone := make(map[string]msp.MSPManager)

for key, mspManager := range mspMap {
clone[key] = mspManager
}

return clone
}

// GetManagerForChainIfExists returns the MSPManager associated to ChainID
// it it exists
func GetManagerForChainIfExists(ChainID string) msp.MSPManager {
m.Lock()
defer m.Unlock()

return mspMap[ChainID]
}

// GetLocalMSP returns the local msp (and creates it if it doesn't exist)
func GetLocalMSP() msp.MSP {
var lclMsp msp.MSP
Expand Down Expand Up @@ -96,3 +119,13 @@ func GetMSPCommon(chainID string) msp.Common {

return GetManagerForChain(chainID)
}

// GetLocalSigningIdentityOrPanic returns the local signing identity or panic in case
// or error
func GetLocalSigningIdentityOrPanic() msp.SigningIdentity {
id, err := GetLocalMSP().GetDefaultSigningIdentity()
if err != nil {
peerLogger.Panic("Failed getting local signing identity [%s]", err)
}
return id
}
5 changes: 4 additions & 1 deletion msp/msp.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import (

//Common is implemented by both MSPManger and MSP
type Common interface {
// DeserializeIdentity deserializes an identity
// DeserializeIdentity deserializes an identity.
// Deserialization will fail if the identity is associated to
// an msp that is different from this one that is performing
// the deserialization.
DeserializeIdentity(serializedIdentity []byte) (Identity, error)
}

Expand Down
2 changes: 2 additions & 0 deletions msp/mspimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ func (msp *bccspmsp) DeserializeIdentity(serializedID []byte) (Identity, error)
return nil, fmt.Errorf("Could not deserialize a SerializedIdentity, err %s", err)
}

// TODO: check that sId.Mspid is equal to this msp'id as per contract of the interface.

// This MSP will always deserialize certs this way
bl, _ := pem.Decode(sId.IdBytes)
if bl == nil {
Expand Down
Loading

0 comments on commit bb3b20b

Please sign in to comment.