Skip to content

Commit

Permalink
[FAB-2411] PKI-ID computation restructuring
Browse files Browse the repository at this point in the history
This change-set does the following:

1. It addresses FAB-2411 (https://jira.hyperledger.org/browse/FAB-2411)
by computing the PKI-ID of a peer identity as the hash of the
concatenation of the corresponding serialized identity's fields.

Tests have been updated to reflect the changes.

Change-Id: If78ffca85bdf7811744c3b11043ef007db542186
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro authored and yacovm committed Apr 9, 2017
1 parent af23d64 commit ae18085
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 15 deletions.
14 changes: 14 additions & 0 deletions msp/mgmt/deserializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ limitations under the License.
package mgmt

import (
"fmt"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/msp"
mspproto "github.com/hyperledger/fabric/protos/msp"
)

// DeserializersManager is a support interface to
// access the local and channel deserializers
type DeserializersManager interface {
Deserialize(raw []byte) (*mspproto.SerializedIdentity, error)

// GetLocalMSPIdentifier returns the local MSP identifier
GetLocalMSPIdentifier() string
Expand All @@ -41,6 +46,15 @@ func NewDeserializersManager() DeserializersManager {

type mspDeserializersManager struct{}

func (m *mspDeserializersManager) Deserialize(raw []byte) (*mspproto.SerializedIdentity, error) {
sId := &mspproto.SerializedIdentity{}
err := proto.Unmarshal(raw, sId)
if err != nil {
return nil, fmt.Errorf("Could not deserialize a SerializedIdentity, err %s", err)
}
return sId, nil
}

func (m *mspDeserializersManager) GetLocalMSPIdentifier() string {
id, _ := GetLocalMSP().GetIdentifier()
return id
Expand Down
39 changes: 30 additions & 9 deletions msp/mspimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,17 @@ func (msp *bccspmsp) getIdentityFromConf(idBytes []byte) (Identity, bccsp.Key, e
return nil, nil, fmt.Errorf("getIdentityFromBytes error: failed to import certitifacate's public key [%s]", err)
}

return newIdentity(&IdentityIdentifier{
// Use the hash of the identity's certificate as id in the IdentityIdentifier
digest, err := factory.GetDefault().Hash(cert.Raw, &bccsp.SHA256Opts{})
if err != nil {
return nil, nil, fmt.Errorf("getIdentityFromConf failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: "IDENTITY"}, /* FIXME: not clear where we would get the identifier for this identity */
cert, certPubK, msp), certPubK, nil
Id: hex.EncodeToString(digest)}

return newIdentity(id, cert, certPubK, msp), certPubK, nil
}

func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo) (SigningIdentity, error) {
Expand Down Expand Up @@ -141,10 +148,17 @@ func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo)
return nil, fmt.Errorf("getIdentityFromBytes error: Failed initializing CryptoSigner, err %s", err)
}

return newSigningIdentity(&IdentityIdentifier{
// Use the hash of the identity's certificate as id in the IdentityIdentifier
digest, err := factory.GetDefault().Hash(idPub.(*identity).cert.Raw, &bccsp.SHA256Opts{})
if err != nil {
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: "DEFAULT"}, /* FIXME: not clear where we would get the identifier for this identity */
idPub.(*identity).cert, idPub.(*identity).pk, peerSigner, msp), nil
Id: hex.EncodeToString(digest)}

return newSigningIdentity(id, idPub.(*identity).cert, idPub.(*identity).pk, peerSigner, msp), nil
}

/*
Expand Down Expand Up @@ -512,12 +526,19 @@ func (msp *bccspmsp) deserializeIdentityInternal(serializedIdentity []byte) (Ide
// We can't do it yet because there is no standardized way
// (yet) to encode the MSP ID into the x.509 body of a cert

id := &IdentityIdentifier{Mspid: msp.name,
Id: "DEFAULT"} // TODO: where should this identifier be obtained from?
// Use the hash of the identity's certificate as id in the IdentityIdentifier
digest, err := factory.GetDefault().Hash(cert.Raw, &bccsp.SHA256Opts{})
if err != nil {
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: hex.EncodeToString(digest)}

pub, err := msp.bccsp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true})
if err != nil {
return nil, fmt.Errorf("Failed to import certitifacateś public key [%s]", err)
return nil, fmt.Errorf("Failed to import certitifacate's public key [%s]", err)
}

return newIdentity(id, cert, pub, msp), nil
Expand Down
16 changes: 15 additions & 1 deletion peer/gossip/mcs/mcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,22 @@ func (s *mspMessageCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityTy
return nil
}

sid, err := s.deserializer.Deserialize(peerIdentity)
if err != nil {
logger.Errorf("Failed getting validated identity from peer identity [% x]: [%s]", peerIdentity, err)

return nil
}

// concatenate msp-id and idbytes
// idbytes is the low-level representation of an identity.
// it is supposed to be already in its minimal representation

mspIdRaw := []byte(sid.Mspid)
raw := append(mspIdRaw, sid.IdBytes...)

// Hash
digest, err := factory.GetDefault().Hash(peerIdentity, &bccsp.SHA256Opts{})
digest, err := factory.GetDefault().Hash(raw, &bccsp.SHA256Opts{})
if err != nil {
logger.Errorf("Failed computing digest of serialized identity [% x]: [%s]", peerIdentity, err)

Expand Down
26 changes: 21 additions & 5 deletions peer/gossip/mcs/mcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"fmt"
"testing"

"reflect"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/bccsp/factory"
Expand All @@ -38,17 +40,31 @@ import (
)

func TestPKIidOfCert(t *testing.T) {
msgCryptoService := New(&MockChannelPolicyManagerGetter{}, localmsp.NewSigner(), mgmt.NewDeserializersManager())
deserializersManager := &mockDeserializersManager{
localDeserializer: &mockIdentityDeserializer{[]byte("Alice"), []byte("msg1")},
}
msgCryptoService := New(&mockChannelPolicyManagerGetter2{},
&mockscrypto.LocalSigner{Identity: []byte("Alice")},
deserializersManager,
)

peerIdentity := []byte("Alice")
pkid := msgCryptoService.GetPKIidOfCert(peerIdentity)

// Check pkid is not nil
assert.NotNil(t, pkid, "PKID must be different from nil")
// Check that pkid is the SHA2-256 of ithe peerIdentity
digest, err := factory.GetDefault().Hash(peerIdentity, &bccsp.SHA256Opts{})
// Check that pkid is correctly computed
id, err := deserializersManager.Deserialize(peerIdentity)
assert.NoError(t, err, "Failed getting validated identity from [% x]", []byte(peerIdentity))
idRaw := append([]byte(id.Mspid), id.IdBytes...)
assert.NoError(t, err, "Failed marshalling identity identifier [% x]: [%s]", peerIdentity, err)
digest, err := factory.GetDefault().Hash(idRaw, &bccsp.SHA256Opts{})
assert.NoError(t, err, "Failed computing digest of serialized identity [% x]", []byte(peerIdentity))
assert.Equal(t, digest, []byte(pkid), "PKID must be the SHA2-256 of peerIdentity")

// The PKI-ID is calculated by concatenating the MspId with IdBytes. Ensure that additional fields haven't been introduced in the code
v := reflect.Indirect(reflect.ValueOf(id))
assert.Equal(t, 2, v.NumField())
}

func TestPKIidOfNil(t *testing.T) {
Expand Down Expand Up @@ -87,7 +103,7 @@ func TestVerify(t *testing.T) {
channelDeserializers: map[string]msp.IdentityDeserializer{
"A": &mockIdentityDeserializer{[]byte("Bob"), []byte("msg2")},
"B": &mockIdentityDeserializer{[]byte("Charlie"), []byte("msg3")},
"C": &mockIdentityDeserializer{[]byte("Yacov"), []byte("msg4")},
"C": &mockIdentityDeserializer{[]byte("Dave"), []byte("msg4")},
},
},
)
Expand All @@ -107,7 +123,7 @@ func TestVerify(t *testing.T) {

sigma, err = msgCryptoService.Sign(msg)
assert.NoError(t, err)
err = msgCryptoService.Verify(api.PeerIdentityType("Yacov"), sigma, msg)
err = msgCryptoService.Verify(api.PeerIdentityType("Dave"), sigma, msg)
assert.Error(t, err)
assert.Contains(t, fmt.Sprintf("%v", err), "Could not acquire policy manager")
}
Expand Down
4 changes: 4 additions & 0 deletions peer/gossip/mcs/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ type mockDeserializersManager struct {
channelDeserializers map[string]msp.IdentityDeserializer
}

func (m *mockDeserializersManager) Deserialize(raw []byte) (*mspproto.SerializedIdentity, error) {
return &mspproto.SerializedIdentity{Mspid: "mock", IdBytes: raw}, nil
}

func (m *mockDeserializersManager) GetLocalMSPIdentifier() string {
return "mock"
}
Expand Down

0 comments on commit ae18085

Please sign in to comment.