Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,12 @@ public TransactionSignWeight getTransactionSignWeight(Transaction trx) {
tswBuilder.setPermission(permission);
if (trx.getSignatureCount() > 0) {
List<ByteString> approveList = new ArrayList<>();
// Read-only introspection: pass checkMaxSignatureSize=false so a historical tx
// committed with a sig above MAX_SIGNATURE_SIZE is still resolvable
long currentWeight = TransactionCapsule.checkWeight(permission, trx.getSignatureList(),
Sha256Hash.hash(CommonParameter.getInstance()
.isECKeyCryptoEngine(), trx.getRawData().toByteArray()), approveList);
.isECKeyCryptoEngine(), trx.getRawData().toByteArray()), approveList,
false);
tswBuilder.addAllApprovedList(approveList);
tswBuilder.setCurrentWeight(currentWeight);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,14 @@ private Sha256Hash getRawHash() {
public boolean validateSignature(DynamicPropertiesStore dynamicPropertiesStore,
AccountStore accountStore) throws ValidateSignatureException {
try {
ByteString witnessSig = block.getBlockHeader().getWitnessSignature();
if (!SignUtils.isValidLength(witnessSig.size(),
dynamicPropertiesStore.signatureMaxSizeChecked())) {
throw new ValidateSignatureException(
"Witness signature size is " + witnessSig.size());
}
Comment thread
Sunny6889 marked this conversation as resolved.
byte[] sigAddress = SignUtils.signatureToAddress(getRawHash().getBytes(),
TransactionCapsule.getBase64FromByteString(
block.getBlockHeader().getWitnessSignature()),
TransactionCapsule.getBase64FromByteString(witnessSig),
CommonParameter.getInstance().isECKeyCryptoEngine());
byte[] witnessAccountAddress = block.getBlockHeader().getRawData().getWitnessAddress()
.toByteArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.tron.common.utils.Sha256Hash;
import org.tron.core.actuator.TransactionFactory;
import org.tron.core.config.Parameter;
import org.tron.core.config.Parameter.ChainConstant;
import org.tron.core.db.TransactionContext;
import org.tron.core.db.TransactionTrace;
import org.tron.core.exception.BadItemException;
Expand Down Expand Up @@ -230,7 +231,7 @@ public static long getWeight(Permission permission, byte[] address) {
* @see ForkController#init(org.tron.core.ChainBaseManager)
*/
public static long checkWeight(Permission permission, List<ByteString> sigs, byte[] hash,
List<ByteString> approveList)
List<ByteString> approveList, boolean checkMaxSignatureSize)
throws SignatureException, PermissionException, SignatureFormatException {
long currentWeight = 0;
if (sigs.size() > permission.getKeysCount()) {
Expand All @@ -240,9 +241,8 @@ public static long checkWeight(Permission permission, List<ByteString> sigs, byt
}
HashMap addMap = new HashMap();
for (ByteString sig : sigs) {
if (sig.size() < 65) {
throw new SignatureFormatException(
"Signature size is " + sig.size());
if (!SignUtils.isValidLength(sig.size(), checkMaxSignatureSize)) {
throw new SignatureFormatException("Signature size is " + sig.size());
}
String base64 = TransactionCapsule.getBase64FromByteString(sig);
byte[] address = SignUtils
Expand Down Expand Up @@ -487,7 +487,8 @@ public static boolean validateSignature(Transaction transaction,
throw new PermissionException("permission isn't exit");
}
checkPermission(permissionId, permission, contract);
long weight = checkWeight(permission, transaction.getSignatureList(), hash, null);
long weight = checkWeight(permission, transaction.getSignatureList(), hash, null,
dynamicPropertiesStore.signatureMaxSizeChecked());
if (weight >= permission.getThreshold()) {
return true;
}
Expand Down Expand Up @@ -583,7 +584,8 @@ public void sign(byte[] privateKey) {
this.transaction = this.transaction.toBuilder().addSignature(sig).build();
}

public void addSign(byte[] privateKey, AccountStore accountStore)
public void addSign(byte[] privateKey, AccountStore accountStore,
DynamicPropertiesStore dynamicPropertiesStore)
throws PermissionException, SignatureException, SignatureFormatException {
Transaction.Contract contract = this.transaction.getRawData().getContract(0);
int permissionId = contract.getPermissionId();
Expand All @@ -604,7 +606,7 @@ public void addSign(byte[] privateKey, AccountStore accountStore)
if (this.transaction.getSignatureCount() > 0) {
checkWeight(permission, this.transaction.getSignatureList(),
this.getTransactionId().getBytes(),
approveList);
approveList, dynamicPropertiesStore.signatureMaxSizeChecked());
if (approveList.contains(ByteString.copyFrom(address))) {
throw new PermissionException(encode58Check(address) + " had signed!");
}
Expand All @@ -620,8 +622,9 @@ public void addSign(byte[] privateKey, AccountStore accountStore)
.signHash(getTransactionId().getBytes())));
this.transaction = this.transaction.toBuilder().addSignature(sig).build();
}

private static void checkPermission(int permissionId, Permission permission, Transaction.Contract contract) throws PermissionException {

private static void checkPermission(int permissionId, Permission permission,
Transaction.Contract contract) throws PermissionException {
if (permissionId != 0) {
if (permission.getType() != PermissionType.Active) {
throw new PermissionException("Permission type is error");
Expand Down Expand Up @@ -703,7 +706,7 @@ public boolean validateSignature(AccountStore accountStore,
}
}
isVerified = true;
}
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,10 @@ public void saveAllowTvmOsaka(long value) {
this.put(ALLOW_TVM_OSAKA, new BytesCapsule(ByteArray.fromLong(value)));
}

public boolean signatureMaxSizeChecked() {
return getAllowTvmOsaka() == 1L;
}

public long getAllowTvmPrague() {
return Optional.ofNullable(getUnchecked(ALLOW_TVM_PRAGUE))
.map(BytesCapsule::getData)
Expand Down
5 changes: 5 additions & 0 deletions common/src/main/java/org/tron/core/config/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public class ChainConstant {
public static final int MAX_VOTE_NUMBER = 30;
public static final int SOLIDIFIED_THRESHOLD = 70; // 70%
public static final int PRIVATE_KEY_LENGTH = 64;
public static final int MIN_SIGNATURE_SIZE = 65;
// Canonical ECDSA signature is 65 bytes (r||s||v). 68 = 65 + up to 3 trailing
// padding bytes; this window accommodates historical non-canonical encodings
// observed on chain. Long-term goal is to tighten this back to a strict 65.
public static final int MAX_SIGNATURE_SIZE = 68;
public static final int BLOCK_SIZE = 2_000_000;
public static final long CLOCK_MAX_DELAY = 3600000; // 3600 * 1000 ms
public static final int BLOCK_PRODUCE_TIMEOUT_PERCENT = 50; // 50%
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ public void onPrePrepare(PbftMessage message) {
PbftMessage paMessage = message.buildPrePareMessage(miner);
forwardMessage(paMessage);
try {
paMessage.analyzeSignature();
paMessage.analyzeSignature(
chainBaseManager.getDynamicPropertiesStore().signatureMaxSizeChecked());
} catch (SignatureException e) {
logger.error("", e);
}
Expand Down Expand Up @@ -175,7 +176,8 @@ public synchronized void onPrepare(PbftMessage message) {
doneMsg.put(message.getNo(), cmMessage);
forwardMessage(cmMessage);
try {
cmMessage.analyzeSignature();
cmMessage.analyzeSignature(
chainBaseManager.getDynamicPropertiesStore().signatureMaxSizeChecked());
} catch (SignatureException e) {
logger.error("", e);
}
Expand Down Expand Up @@ -316,4 +318,4 @@ public void run() {
}
}, 10, 1000);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package org.tron.consensus.pbft.message;

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.IOException;
import java.security.SignatureException;
import java.util.stream.Collectors;
import org.bouncycastle.util.encoders.Hex;
import org.tron.common.crypto.ECKey;
import org.tron.common.crypto.SignUtils;
import org.tron.common.overlay.message.Message;
import org.tron.common.utils.ByteUtil;
import org.tron.common.utils.Sha256Hash;
import org.tron.common.utils.StringUtil;
import org.tron.core.capsule.TransactionCapsule;
import org.tron.core.exception.P2pException;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.protos.Protocol.PBFTMessage;
import org.tron.protos.Protocol.PBFTMessage.DataType;
import org.tron.protos.Protocol.SRL;
Expand Down Expand Up @@ -94,10 +97,15 @@ public DataType getDataType() {

public abstract String getNo();

public void analyzeSignature() throws SignatureException {
public void analyzeSignature(boolean checkMaxSignatureSize)
throws SignatureException {
ByteString signature = getPbftMessage().getSignature();
if (!SignUtils.isValidLength(signature.size(), checkMaxSignatureSize)) {
throw new SignatureException("PBFT signature size is " + signature.size());
}
byte[] hash = Sha256Hash.hash(true, getPbftMessage().getRawData().toByteArray());
publicKey = ECKey.signatureToAddress(hash, TransactionCapsule
.getBase64FromByteString(getPbftMessage().getSignature()));
.getBase64FromByteString(signature));
}

@Override
Expand Down
6 changes: 6 additions & 0 deletions crypto/src/main/java/org/tron/common/crypto/SignUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
import org.tron.common.crypto.ECKey.ECDSASignature;
import org.tron.common.crypto.sm2.SM2;
import org.tron.common.crypto.sm2.SM2.SM2Signature;
import org.tron.core.config.Parameter.ChainConstant;

public class SignUtils {

public static boolean isValidLength(int size, boolean checkMaxSignatureSize) {
return size >= ChainConstant.MIN_SIGNATURE_SIZE
&& (!checkMaxSignatureSize || size <= ChainConstant.MAX_SIGNATURE_SIZE);
}

public static SignInterface getGeneratedRandomSign(
SecureRandom secureRandom, boolean isECKeyCryptoEngine) {
if (isECKeyCryptoEngine) {
Expand Down
3 changes: 2 additions & 1 deletion framework/src/main/java/org/tron/core/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,8 @@ public TransactionApprovedList getTransactionApprovedList(Transaction trx) {
byte[] hash = Sha256Hash.hash(CommonParameter
.getInstance().isECKeyCryptoEngine(), trx.getRawData().toByteArray());
for (ByteString sig : trx.getSignatureList()) {
if (sig.size() < 65) {
// Read-only path: skip the upper bound so historical txs stay resolvable.
if (!SignUtils.isValidLength(sig.size(), false)) {
throw new SignatureFormatException(
"Signature size is " + sig.size());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.tron.common.crypto.ECKey;
import org.tron.common.crypto.SignUtils;
import org.tron.common.es.ExecutorServiceManager;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.Sha256Hash;
Expand Down Expand Up @@ -173,6 +174,11 @@ private class ValidPbftSignTask implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
try {
if (!SignUtils.isValidLength(sign.size(),
chainBaseManager.getDynamicPropertiesStore().signatureMaxSizeChecked())) {
logger.error("viewN {} pbft signature size {} is invalid", viewN, sign.size());
return false;
}
byte[] srAddress = ECKey.signatureToAddress(dataHash,
TransactionCapsule.getBase64FromByteString(sign));
if (!srSet.contains(ByteString.copyFrom(srAddress))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.tron.consensus.pbft.PbftManager;
import org.tron.consensus.pbft.message.PbftBaseMessage;
import org.tron.consensus.pbft.message.PbftMessage;
import org.tron.core.ChainBaseManager;
import org.tron.core.config.args.Args;
import org.tron.core.exception.P2pException;
import org.tron.core.net.TronNetDelegate;
Expand All @@ -32,6 +33,9 @@ public class PbftMsgHandler {
@Autowired
private TronNetDelegate tronNetDelegate;

@Autowired
private ChainBaseManager chainBaseManager;

public void processMessage(PeerConnection peer, PbftMessage msg) throws Exception {
if (!tronNetDelegate.allowPBFT()) {
return;
Expand All @@ -50,7 +54,7 @@ public void processMessage(PeerConnection peer, PbftMessage msg) throws Exceptio
&& currentEpoch - msg.getEpoch() > expireEpoch) {
return;
}
msg.analyzeSignature();
msg.analyzeSignature(chainBaseManager.getDynamicPropertiesStore().signatureMaxSizeChecked());
String key = buildKey(msg);
Lock lock = striped.get(key);
try {
Expand Down Expand Up @@ -79,4 +83,4 @@ private String buildKey(PbftBaseMessage msg) {
return msg.getKey() + msg.getPbftMessage().getRawData().getMsgType().toString();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,17 @@ public boolean checkHelloMessage(HelloMessage message, Channel channel) {

boolean flag;
try {
ByteString signature = msg.getSignature();
if (!SignUtils.isValidLength(signature.size(),
chainBaseManager.getDynamicPropertiesStore().signatureMaxSizeChecked())) {
logger.warn("HelloMessage from {}, signature size {} is invalid.",
channel.getInetAddress(), signature.size());
return false;
}
Sha256Hash hash = Sha256Hash.of(CommonParameter
.getInstance().isECKeyCryptoEngine(), ByteArray.fromLong(msg.getTimestamp()));
String sig =
TransactionCapsule.getBase64FromByteString(msg.getSignature());
TransactionCapsule.getBase64FromByteString(signature);
byte[] sigAddress = SignUtils.signatureToAddress(hash.getBytes(), sig,
Args.getInstance().isECKeyCryptoEngine());
if (manager.getDynamicPropertiesStore().getAllowMultiSign() != 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.tron.core.exception.SignatureFormatException;
import org.tron.core.services.http.JsonFormat;
import org.tron.core.store.AccountStore;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.protos.Protocol.Transaction;
import org.tron.protos.Protocol.Transaction.Contract;
import org.tron.protos.contract.AccountContract.AccountCreateContract;
Expand Down Expand Up @@ -193,11 +194,12 @@ public static String getTransactionSign(String transaction, String priKey,
}

public static TransactionCapsule addTransactionSign(Transaction transaction, String priKey,
AccountStore accountStore)
AccountStore accountStore,
DynamicPropertiesStore dynamicPropertiesStore)
throws PermissionException, SignatureException, SignatureFormatException {
byte[] privateKey = ByteArray.fromHexString(priKey);
TransactionCapsule trx = new TransactionCapsule(transaction);
trx.addSign(privateKey, accountStore);
trx.addSign(privateKey, accountStore, dynamicPropertiesStore);
return trx;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ public void publicAddressToShieldedAddressSuccess() {

//Add public address sign
transactionCap = TransactionUtils.addTransactionSign(transactionCap.getInstance(),
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore());
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore(),
dbManager.getDynamicPropertiesStore());

Assert.assertTrue(dbManager.pushTransaction(transactionCap));
} catch (Exception e) {
Expand Down Expand Up @@ -235,7 +236,8 @@ public void publicAddressToPublicAddressAndZereValueOutputSuccess() {

//Add public address sign
transactionCap = TransactionUtils.addTransactionSign(transactionCap.getInstance(),
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore());
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore(),
dbManager.getDynamicPropertiesStore());

Assert.assertTrue(dbManager.pushTransaction(transactionCap));
} catch (Exception e) {
Expand All @@ -255,7 +257,7 @@ public void publicAddressToShieldedAddressInvalidSign() {

//Add public address sign
TransactionUtils.addTransactionSign(transactionCap.getInstance(), ADDRESS_TWO_PRIVATE_KEY,
dbManager.getAccountStore());
dbManager.getAccountStore(), dbManager.getDynamicPropertiesStore());
Assert.assertTrue(false);
} catch (PermissionException e) {
Assert.assertTrue(e instanceof PermissionException);
Expand Down Expand Up @@ -395,7 +397,8 @@ public void publicAddressToShieldedAddressNotConsumeBandwidth() {
TransactionCapsule transactionCap = getPublicToShieldedTransaction();
//Add public address sign
transactionCap = TransactionUtils.addTransactionSign(transactionCap.getInstance(),
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore());
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore(),
dbManager.getDynamicPropertiesStore());

AccountCapsule accountCapsule =
dbManager.getAccountStore().get(ByteArray.fromHexString(PUBLIC_ADDRESS_ONE));
Expand Down Expand Up @@ -983,7 +986,8 @@ public void publicToShieldAddressAndShieldToPublicAddressWithZoreValueSuccess()

//Add public address sign
transactionCapOne = TransactionUtils.addTransactionSign(transactionCapOne.getInstance(),
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore());
ADDRESS_ONE_PRIVATE_KEY, dbManager.getAccountStore(),
dbManager.getDynamicPropertiesStore());

Assert.assertTrue(dbManager.pushTransaction(transactionCapOne));
AccountCapsule accountCapsuleOne =
Expand Down Expand Up @@ -1403,4 +1407,3 @@ public void shieldedTransferValidationWorksWhenApiDisabled() {
}
}
}

Loading
Loading