Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 2fe84d2

Browse files
committed
FABJ-346 Don't verify invalid endorsements.
Change-Id: Ie021fc18ac5c0d124a46594e12d44427b5ab049b Signed-off-by: rickr <cr22rc@gmail.com>
1 parent 0b605c7 commit 2fe84d2

File tree

1 file changed

+75
-35
lines changed

1 file changed

+75
-35
lines changed

src/main/java/org/hyperledger/fabric/sdk/ProposalResponse.java

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import org.hyperledger.fabric.sdk.helper.DiagnosticFileDumper;
2828
import org.hyperledger.fabric.sdk.security.CryptoSuite;
2929

30+
import static java.lang.String.format;
31+
import static org.hyperledger.fabric.sdk.helper.Utils.toHexString;
32+
3033
public class ProposalResponse extends ChaincodeResponse {
3134

3235
private static final Log logger = LogFactory.getLog(ProposalResponse.class);
@@ -37,6 +40,7 @@ public class ProposalResponse extends ChaincodeResponse {
3740
? config.getDiagnosticFileDumper() : null;
3841

3942
private boolean isVerified = false;
43+
private boolean hasBeenVerified = false;
4044

4145
private WeakReference<ProposalResponsePayloadDeserializer> proposalResponsePayload;
4246
private FabricProposal.Proposal proposal;
@@ -95,50 +99,86 @@ public boolean isVerified() {
9599
*
96100
* @return true/false depending on result of signature verification
97101
*/
98-
public boolean verify(CryptoSuite crypto) {
102+
boolean verify(CryptoSuite crypto) {
103+
logger.trace(format("%s verifying transaction: %s endorsement.", peer, getTransactionID()));
99104

100-
if (isVerified()) { // check if this proposalResponse was already verified by client code
101-
return isVerified();
105+
if (hasBeenVerified) { // check if this proposalResponse was already verified by client code
106+
logger.trace(format("%s transaction: %s was already verified returned %b", peer, getTransactionID(), isVerified));
107+
return this.isVerified;
102108
}
103109

104-
if (isInvalid()) {
105-
this.isVerified = false;
106-
}
110+
try {
111+
if (isInvalid()) {
112+
this.isVerified = false;
113+
logger.debug(format("%s for transaction %s returned invalid. Setting verify to false", peer, getTransactionID()));
114+
return false;
115+
}
107116

108-
FabricProposalResponse.Endorsement endorsement = this.proposalResponse.getEndorsement();
109-
ByteString sig = endorsement.getSignature();
117+
FabricProposalResponse.Endorsement endorsement = this.proposalResponse.getEndorsement();
118+
ByteString sig = endorsement.getSignature();
119+
byte[] endorserCertifcate = null;
120+
byte[] signature = null;
121+
byte[] data = null;
110122

111-
try {
112-
Identities.SerializedIdentity endorser = Identities.SerializedIdentity
113-
.parseFrom(endorsement.getEndorser());
114-
ByteString plainText = proposalResponse.getPayload().concat(endorsement.getEndorser());
115-
116-
if (config.extraLogLevel(10)) {
117-
118-
if (null != diagnosticFileDumper) {
119-
StringBuilder sb = new StringBuilder(10000);
120-
sb.append("payload TransactionBuilderbytes in hex: " + DatatypeConverter.printHexBinary(proposalResponse.getPayload().toByteArray()));
121-
sb.append("\n");
122-
sb.append("endorser bytes in hex: "
123-
+ DatatypeConverter.printHexBinary(endorsement.getEndorser().toByteArray()));
124-
sb.append("\n");
125-
sb.append("plainText bytes in hex: " + DatatypeConverter.printHexBinary(plainText.toByteArray()));
126-
127-
logger.trace("payload TransactionBuilderbytes: " +
128-
diagnosticFileDumper.createDiagnosticFile(sb.toString()));
123+
try {
124+
Identities.SerializedIdentity endorser = Identities.SerializedIdentity
125+
.parseFrom(endorsement.getEndorser());
126+
ByteString plainText = proposalResponse.getPayload().concat(endorsement.getEndorser());
127+
128+
if (config.extraLogLevel(10)) {
129+
130+
if (null != diagnosticFileDumper) {
131+
StringBuilder sb = new StringBuilder(10000);
132+
sb.append("payload TransactionBuilderbytes in hex: " + DatatypeConverter.printHexBinary(proposalResponse.getPayload().toByteArray()));
133+
sb.append("\n");
134+
sb.append("endorser bytes in hex: "
135+
+ DatatypeConverter.printHexBinary(endorsement.getEndorser().toByteArray()));
136+
sb.append("\n");
137+
sb.append("plainText bytes in hex: " + DatatypeConverter.printHexBinary(plainText.toByteArray()));
138+
139+
logger.trace("payload TransactionBuilderbytes: " +
140+
diagnosticFileDumper.createDiagnosticFile(sb.toString()));
141+
}
142+
143+
}
144+
145+
if (sig == null || sig.isEmpty()) { // we shouldn't get here ...
146+
logger.warn(format("%s %s returned signature is empty verify set to false.", peer, getTransactionID()));
147+
this.isVerified = false;
148+
} else {
149+
150+
endorserCertifcate = endorser.getIdBytes().toByteArray();
151+
signature = sig.toByteArray();
152+
data = plainText.toByteArray();
153+
154+
this.isVerified = crypto.verify(endorserCertifcate, config.getSignatureAlgorithm(),
155+
signature, data);
156+
if (!this.isVerified) {
157+
logger.warn(format("%s transaction: %s verify: Failed to verify. Endorsers certificate: %s, " +
158+
"signature: %s, signing algorithm: %s, signed data: %s.",
159+
peer, getTransactionID(), toHexString(endorserCertifcate), toHexString(signature),
160+
config.getSignatureAlgorithm(), toHexString(data)
161+
));
162+
}
129163
}
130164

165+
} catch (InvalidProtocolBufferException | CryptoException e) {
166+
logger.error(format("%s transaction: %s verify: Failed to verify. Endorsers certificate: %s, " +
167+
"signature: %s, signing algorithm: %s, signed data: %s.",
168+
peer, getTransactionID(), toHexString(endorserCertifcate), toHexString(signature),
169+
config.getSignatureAlgorithm(), toHexString(data)
170+
), e);
171+
172+
logger.error(format("%s transaction: %s verify: Cannot retrieve peer identity from ProposalResponse. Error is: %s", peer, getTransactionID(), e.getMessage()), e);
173+
this.isVerified = false;
131174
}
132175

133-
this.isVerified = crypto.verify(endorser.getIdBytes().toByteArray(), config.getSignatureAlgorithm(),
134-
sig.toByteArray(), plainText.toByteArray()
135-
);
136-
} catch (InvalidProtocolBufferException | CryptoException e) {
137-
logger.error("verify: Cannot retrieve peer identity from ProposalResponse. Error is: " + e.getMessage(), e);
138-
this.isVerified = false;
139-
}
176+
logger.debug(format("%s finished verify for transaction %s returning %b", peer, getTransactionID(), this.isVerified));
140177

141-
return this.isVerified;
178+
return this.isVerified;
179+
} finally {
180+
hasBeenVerified = true;
181+
}
142182
} // verify
143183

144184
public FabricProposal.Proposal getProposal() {
@@ -150,7 +190,7 @@ public void setProposal(FabricProposal.SignedProposal signedProposal) throws Pro
150190
try {
151191
this.proposal = FabricProposal.Proposal.parseFrom(signedProposal.getProposalBytes());
152192
} catch (InvalidProtocolBufferException e) {
153-
throw new ProposalException("Proposal exception", e);
193+
throw new ProposalException(format("%s transaction: %s Proposal exception", peer, getTransactionID()), e);
154194

155195
}
156196
}

0 commit comments

Comments
 (0)