github.com/ewagmig/fabric@v2.1.1+incompatible/gossip/protoext/signing.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package protoext 8 9 import ( 10 "errors" 11 "fmt" 12 13 "github.com/golang/protobuf/proto" 14 "github.com/hyperledger/fabric-protos-go/gossip" 15 ) 16 17 // Signer signs a message, and returns (signature, nil) 18 // on success, and nil and an error on failure. 19 type Signer func(msg []byte) ([]byte, error) 20 21 // Verifier receives a peer identity, a signature and a message and returns nil 22 // if the signature on the message could be verified using the given identity. 23 type Verifier func(peerIdentity []byte, signature, message []byte) error 24 25 // SignSecret signs the secret payload and creates a secret envelope out of it. 26 func SignSecret(e *gossip.Envelope, signer Signer, secret *gossip.Secret) error { 27 payload, err := proto.Marshal(secret) 28 if err != nil { 29 return err 30 } 31 sig, err := signer(payload) 32 if err != nil { 33 return err 34 } 35 e.SecretEnvelope = &gossip.SecretEnvelope{ 36 Payload: payload, 37 Signature: sig, 38 } 39 return nil 40 } 41 42 // NoopSign creates a SignedGossipMessage with a nil signature 43 func NoopSign(m *gossip.GossipMessage) (*SignedGossipMessage, error) { 44 signer := func(msg []byte) ([]byte, error) { 45 return nil, nil 46 } 47 sMsg := &SignedGossipMessage{ 48 GossipMessage: m, 49 } 50 _, err := sMsg.Sign(signer) 51 return sMsg, err 52 } 53 54 // EnvelopeToGossipMessage un-marshals a given envelope and creates a 55 // SignedGossipMessage out of it. 56 // Returns an error if un-marshaling fails. 57 func EnvelopeToGossipMessage(e *gossip.Envelope) (*SignedGossipMessage, error) { 58 if e == nil { 59 return nil, errors.New("nil envelope") 60 } 61 msg := &gossip.GossipMessage{} 62 err := proto.Unmarshal(e.Payload, msg) 63 if err != nil { 64 return nil, fmt.Errorf("Failed unmarshaling GossipMessage from envelope: %v", err) 65 } 66 return &SignedGossipMessage{ 67 GossipMessage: msg, 68 Envelope: e, 69 }, nil 70 } 71 72 // InternalEndpoint returns the internal endpoint in the secret envelope, or an 73 // empty string if a failure occurs. 74 func InternalEndpoint(s *gossip.SecretEnvelope) string { 75 if s == nil { 76 return "" 77 } 78 secret := &gossip.Secret{} 79 if err := proto.Unmarshal(s.Payload, secret); err != nil { 80 return "" 81 } 82 return secret.GetInternalEndpoint() 83 } 84 85 // SignedGossipMessage contains a GossipMessage and the Envelope from which it 86 // came from 87 type SignedGossipMessage struct { 88 *gossip.Envelope 89 *gossip.GossipMessage 90 } 91 92 // Sign signs a GossipMessage with given Signer. 93 // Returns an Envelope on success, panics on failure. 94 func (m *SignedGossipMessage) Sign(signer Signer) (*gossip.Envelope, error) { 95 // If we have a secretEnvelope, don't override it. 96 // Back it up, and restore it later 97 var secretEnvelope *gossip.SecretEnvelope 98 if m.Envelope != nil { 99 secretEnvelope = m.Envelope.SecretEnvelope 100 } 101 m.Envelope = nil 102 payload, err := proto.Marshal(m.GossipMessage) 103 if err != nil { 104 return nil, err 105 } 106 sig, err := signer(payload) 107 if err != nil { 108 return nil, err 109 } 110 111 e := &gossip.Envelope{ 112 Payload: payload, 113 Signature: sig, 114 SecretEnvelope: secretEnvelope, 115 } 116 m.Envelope = e 117 return e, nil 118 } 119 120 // Verify verifies a signed GossipMessage with a given Verifier. 121 // Returns nil on success, error on failure. 122 func (m *SignedGossipMessage) Verify(peerIdentity []byte, verify Verifier) error { 123 if m.Envelope == nil { 124 return errors.New("Missing envelope") 125 } 126 if len(m.Envelope.Payload) == 0 { 127 return errors.New("Empty payload") 128 } 129 if len(m.Envelope.Signature) == 0 { 130 return errors.New("Empty signature") 131 } 132 payloadSigVerificationErr := verify(peerIdentity, m.Envelope.Signature, m.Envelope.Payload) 133 if payloadSigVerificationErr != nil { 134 return payloadSigVerificationErr 135 } 136 if m.Envelope.SecretEnvelope != nil { 137 payload := m.Envelope.SecretEnvelope.Payload 138 sig := m.Envelope.SecretEnvelope.Signature 139 if len(payload) == 0 { 140 return errors.New("Empty payload") 141 } 142 if len(sig) == 0 { 143 return errors.New("Empty signature") 144 } 145 return verify(peerIdentity, sig, payload) 146 } 147 return nil 148 } 149 150 // IsSigned returns whether the message 151 // has a signature in the envelope. 152 func (m *SignedGossipMessage) IsSigned() bool { 153 return m.Envelope != nil && m.Envelope.Payload != nil && m.Envelope.Signature != nil 154 } 155 156 // String returns a string representation 157 // of a SignedGossipMessage 158 func (m *SignedGossipMessage) String() string { 159 env := "No envelope" 160 if m.Envelope != nil { 161 var secretEnv string 162 if m.SecretEnvelope != nil { 163 pl := len(m.SecretEnvelope.Payload) 164 sl := len(m.SecretEnvelope.Signature) 165 secretEnv = fmt.Sprintf(" Secret payload: %d bytes, Secret Signature: %d bytes", pl, sl) 166 } 167 env = fmt.Sprintf("%d bytes, Signature: %d bytes%s", len(m.Envelope.Payload), len(m.Envelope.Signature), secretEnv) 168 } 169 gMsg := "No gossipMessage" 170 if m.GossipMessage != nil { 171 var isSimpleMsg bool 172 if m.GetStateResponse() != nil { 173 gMsg = fmt.Sprintf("StateResponse with %d items", len(m.GetStateResponse().Payloads)) 174 } else if IsDataMsg(m.GossipMessage) && m.GetDataMsg().Payload != nil { 175 gMsg = PayloadToString(m.GetDataMsg().Payload) 176 } else if IsDataUpdate(m.GossipMessage) { 177 update := m.GetDataUpdate() 178 gMsg = fmt.Sprintf("DataUpdate: %s", DataUpdateToString(update)) 179 } else if m.GetMemRes() != nil { 180 gMsg = MembershipResponseToString(m.GetMemRes()) 181 } else if IsStateInfoSnapshot(m.GossipMessage) { 182 gMsg = StateInfoSnapshotToString(m.GetStateSnapshot()) 183 } else if m.GetPrivateRes() != nil { 184 gMsg = RemovePvtDataResponseToString(m.GetPrivateRes()) 185 } else if m.GetAliveMsg() != nil { 186 gMsg = AliveMessageToString(m.GetAliveMsg()) 187 } else if m.GetMemReq() != nil { 188 gMsg = MembershipRequestToString(m.GetMemReq()) 189 } else if m.GetStateInfoPullReq() != nil { 190 gMsg = StateInfoPullRequestToString(m.GetStateInfoPullReq()) 191 } else if m.GetStateInfo() != nil { 192 gMsg = StateInfoToString(m.GetStateInfo()) 193 } else if m.GetDataDig() != nil { 194 gMsg = DataDigestToString(m.GetDataDig()) 195 } else if m.GetDataReq() != nil { 196 gMsg = DataRequestToString(m.GetDataReq()) 197 } else if m.GetLeadershipMsg() != nil { 198 gMsg = LeadershipMessageToString(m.GetLeadershipMsg()) 199 } else { 200 gMsg = m.GossipMessage.String() 201 isSimpleMsg = true 202 } 203 if !isSimpleMsg { 204 desc := fmt.Sprintf("Channel: %s, nonce: %d, tag: %s", string(m.Channel), m.Nonce, gossip.GossipMessage_Tag_name[int32(m.Tag)]) 205 gMsg = fmt.Sprintf("%s %s", desc, gMsg) 206 } 207 } 208 return fmt.Sprintf("GossipMessage: %v, Envelope: %s", gMsg, env) 209 }