Skip to content

Commit

Permalink
proposal response checks the validity of the
Browse files Browse the repository at this point in the history
endorsement signature agains a verifier provider

Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro committed Oct 21, 2024
1 parent 907cc24 commit 9b09a4c
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 83 deletions.
56 changes: 28 additions & 28 deletions platform/fabric/core/generic/committer/committer.go
Original file line number Diff line number Diff line change
Expand Up @@ -736,36 +736,36 @@ func (c *Committer) commit(ctx context.Context, txID string, block uint64, index
c.logger.Errorf("[%s] failed to unmarshal envelope [%s]", txID, err)
return err
}
//if headerType == int32(common.HeaderType_ENDORSER_TRANSACTION) {
if !c.Vault.RWSExists(txID) && c.EnvelopeService.Exists(txID) {
// Then match rwsets
span.AddEvent("extract_stored_env_to_vault")
if err := c.extractStoredEnvelopeToVault(txID); err != nil {
return errors.WithMessagef(err, "failed to load stored enveloper into the vault")
}
span.AddEvent("match_rwset")
if err := c.Vault.Match(txID, pt.Results()); err != nil {
c.logger.Errorf("[%s] rwsets do not match [%s]", txID, err)
return errors2.Wrapf(ErrDiscardTX, "[%s] rwsets do not match [%s]", txID, err)
}
} else {
// Store it
envelopeRaw, err := proto.Marshal(envelope)
if err != nil {
return errors.WithMessagef(err, "failed to store unknown envelope for [%s]", txID)
}
span.AddEvent("store_env")
if err := c.EnvelopeService.StoreEnvelope(txID, envelopeRaw); err != nil {
return errors.WithMessagef(err, "failed to store unknown envelope for [%s]", txID)
}
span.AddEvent("get_rwset_from_evn")
rws, _, err := c.RWSetLoaderService.GetRWSetFromEvn(txID)
if err != nil {
return errors.WithMessagef(err, "failed to get rws from envelope [%s]", txID)
if headerType == int32(common.HeaderType_ENDORSER_TRANSACTION) {
if !c.Vault.RWSExists(txID) && c.EnvelopeService.Exists(txID) {
// Then match rwsets
span.AddEvent("extract_stored_env_to_vault")
if err := c.extractStoredEnvelopeToVault(txID); err != nil {
return errors.WithMessagef(err, "failed to load stored enveloper into the vault")
}
span.AddEvent("match_rwset")
if err := c.Vault.Match(txID, pt.Results()); err != nil {
c.logger.Errorf("[%s] rwsets do not match [%s]", txID, err)
return errors2.Wrapf(ErrDiscardTX, "[%s] rwsets do not match [%s]", txID, err)
}
} else {
// Store it
envelopeRaw, err := proto.Marshal(envelope)
if err != nil {
return errors.WithMessagef(err, "failed to store unknown envelope for [%s]", txID)
}
span.AddEvent("store_env")
if err := c.EnvelopeService.StoreEnvelope(txID, envelopeRaw); err != nil {
return errors.WithMessagef(err, "failed to store unknown envelope for [%s]", txID)
}
span.AddEvent("get_rwset_from_evn")
rws, _, err := c.RWSetLoaderService.GetRWSetFromEvn(txID)
if err != nil {
return errors.WithMessagef(err, "failed to get rws from envelope [%s]", txID)
}
rws.Done()
}
rws.Done()
}
//}
}

// Post-Processes
Expand Down
11 changes: 11 additions & 0 deletions platform/fabric/core/generic/transaction/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ package transaction

import (
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
Expand Down Expand Up @@ -83,3 +85,12 @@ func (p *ProposalResponse) Bytes() ([]byte, error) {
}
return raw, nil
}

func (p *ProposalResponse) VerifyEndorsement(provider driver.VerifierProvider) error {
endorser := view.Identity(p.pr.Endorsement.Endorser)
v, err := provider.GetVerifier(endorser)
if err != nil {
return errors.Wrapf(err, "failed getting verifier for [%s]", endorser)
}
return v.Verify(append(p.Payload(), endorser...), p.EndorserSignature())
}
6 changes: 6 additions & 0 deletions platform/fabric/driver/sig.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import (
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
)

// VerifierProvider returns a Verifier for the passed identity
type VerifierProvider interface {
// GetVerifier returns a Verifier for the passed identity
GetVerifier(identity view.Identity) (Verifier, error)
}

type SigningIdentity interface {
Serialize() ([]byte, error)
Sign(msg []byte) ([]byte, error)
Expand Down
1 change: 1 addition & 0 deletions platform/fabric/driver/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type ProposalResponse interface {
ResponseStatus() int32
ResponseMessage() string
Bytes() ([]byte, error)
VerifyEndorsement(provider VerifierProvider) error
}

type Proposal interface {
Expand Down
5 changes: 1 addition & 4 deletions platform/fabric/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,7 @@ func (s *LocalMembership) Refresh() error {
}

// Verifier is an interface which wraps the Verify method.
type Verifier interface {
// Verify verifies the signature over the passed message.
Verify(message, sigma []byte) error
}
type Verifier = driver.Verifier

type MSPManager struct {
ch driver.ChannelMembership
Expand Down
90 changes: 45 additions & 45 deletions platform/fabric/services/endorser/endorsement.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package endorser

import (
"bytes"
"encoding/json"
"time"

Expand All @@ -21,28 +22,28 @@ type collectEndorsementsView struct {
tx *Transaction
parties []view.Identity
deleteTransient bool
verifierProviders []VerifierProvider
verifierProviders []fabric.VerifierProvider
}

func (c *collectEndorsementsView) Call(context view.Context) (interface{}, error) {
span := trace.SpanFromContext(context.Context())
// Prepare verifiers
//ch, err := c.tx.FabricNetworkService().Channel(c.tx.Channel())
//if err != nil {
// return nil, errors.Wrapf(err, "failed getting channel [%s:%s]", c.tx.Network(), c.tx.Channel())
//}
////mspManager := ch.MSPManager()
ch, err := c.tx.FabricNetworkService().Channel(c.tx.Channel())
if err != nil {
return nil, errors.Wrapf(err, "failed getting channel [%s:%s]", c.tx.Network(), c.tx.Channel())
}
mspManager := ch.MSPManager()

//var vProviders []VerifierProvider
//vProviders = append(vProviders, c.verifierProviders...)
//vProviders = append(vProviders, c.tx.verifierProviders...)
//vProviders = append(vProviders, &verifierProviderWrapper{m: mspManager})
var vProviders []fabric.VerifierProvider
vProviders = append(vProviders, c.verifierProviders...)
vProviders = append(vProviders, c.tx.verifierProviders...)
vProviders = append(vProviders, &verifierProviderWrapper{m: mspManager})

// Get results to send
//res, err := c.tx.Results()
//if err != nil {
// return nil, errors.Wrapf(err, "failed getting tx results")
//}
res, err := c.tx.Results()
if err != nil {
return nil, errors.Wrapf(err, "failed getting tx results")
}

// Contact sequantially all parties.
logger.Debugf("Collect Endorsements from [%d] parties [%v]", len(c.parties), c.parties)
Expand Down Expand Up @@ -125,34 +126,33 @@ func (c *collectEndorsementsView) Call(context view.Context) (interface{}, error
return nil, errors.Wrap(err, "failed unmarshalling received proposal response")
}

// the signature check should be done by the proposal response to make sure that
// platform dependant operation can be performed.
endorser := view.Identity(proposalResponse.Endorser())

//// Check the validity of the response
// Check the validity of the response
if view2.GetEndpointService(context).IsBoundTo(endorser, party) {
found = true
}
//
//// TODO: check the verifier providers, if any
//verified := false
//for _, provider := range vProviders {
// span.AddEvent("verify_endorsement")
// if v, err := provider.GetVerifier(endorser); err == nil {
// if err := v.Verify(append(proposalResponse.Payload(), endorser...), proposalResponse.EndorserSignature()); err == nil {
// verified = true
// break
// }
// }
//}
//if !verified {
// return nil, errors.Errorf("failed to verify signature for party [%s][%s]", endorser.String(), string(endorser))
//}
//// Check the content of the response
//// Now results can be equal to what this node has proposed or different
//if !bytes.Equal(res, proposalResponse.Results()) {
// return nil, errors.Errorf("received different results")
//}

// TODO: check the verifier providers, if any
verified := false
for _, provider := range vProviders {
span.AddEvent("verify_endorsement")
err := proposalResponse.VerifyEndorsement(provider)
if err == nil {
logger.Debugf("endorsement [%s] is valid", endorser)
verified = true
break
}
logger.Debugf("endorsement [%s] is invalid, reason [%s]", endorser, err)
}
if !verified {
return nil, errors.Errorf("failed to verify signature for party [%s][%s]", endorser.String(), string(endorser))
}
// Check the content of the response
// Now results can be equal to what this node has proposed or different
if !bytes.Equal(res, proposalResponse.Results()) {
return nil, errors.Errorf("received different results")
}

logger.Debugf("append response from party [%s]", party)
err = c.tx.AppendProposalResponse(proposalResponse)
Expand All @@ -168,7 +168,7 @@ func (c *collectEndorsementsView) Call(context view.Context) (interface{}, error
return c.tx, nil
}

func (c *collectEndorsementsView) SetVerifierProviders(p []VerifierProvider) *collectEndorsementsView {
func (c *collectEndorsementsView) SetVerifierProviders(p []fabric.VerifierProvider) *collectEndorsementsView {
c.verifierProviders = p
return c
}
Expand Down Expand Up @@ -248,10 +248,10 @@ func NewAcceptView(tx *Transaction, ids ...view.Identity) *endorseView {
return &endorseView{tx: tx, identities: ids}
}

//type verifierProviderWrapper struct {
// m *fabric.MSPManager
//}
//
//func (v *verifierProviderWrapper) GetVerifier(identity view.Identity) (view2.Verifier, error) {
// return v.m.GetVerifier(identity)
//}
type verifierProviderWrapper struct {
m *fabric.MSPManager
}

func (v *verifierProviderWrapper) GetVerifier(identity view.Identity) (fabric.Verifier, error) {
return v.m.GetVerifier(identity)
}
8 changes: 2 additions & 6 deletions platform/fabric/services/endorser/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@ import (
"github.com/pkg/errors"
)

type VerifierProvider interface {
GetVerifier(identity view.Identity) (view2.Verifier, error)
}

type Transaction struct {
view2.ServiceProvider

Transaction *fabric.Transaction
verifierProviders []VerifierProvider
verifierProviders []fabric.VerifierProvider
}

func (t *Transaction) ID() string {
Expand Down Expand Up @@ -218,7 +214,7 @@ func (t *Transaction) FabricNetworkService() *fabric.NetworkService {
return t.Transaction.FabricNetworkService()
}

func (t *Transaction) AppendVerifierProvider(vp VerifierProvider) {
func (t *Transaction) AppendVerifierProvider(vp fabric.VerifierProvider) {
t.verifierProviders = append(t.verifierProviders, vp)
}

Expand Down
6 changes: 6 additions & 0 deletions platform/fabric/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
)

type VerifierProvider = driver.VerifierProvider

type TransactionType = driver.TransactionType

const (
Expand Down Expand Up @@ -126,6 +128,10 @@ func (r *ProposalResponse) Bytes() ([]byte, error) {
return r.pr.Bytes()
}

func (r *ProposalResponse) VerifyEndorsement(provider VerifierProvider) error {
return r.pr.VerifyEndorsement(provider)
}

type Proposal struct {
p driver.Proposal
}
Expand Down

0 comments on commit 9b09a4c

Please sign in to comment.