mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-11 17:55:53 +00:00
DefaultRiskAnalysis.isStandard checks for signatures to use canonical DER encoding. Adds a test.
This commit is contained in:
parent
121d2fcb63
commit
2fa5ba30e2
@ -18,12 +18,15 @@
|
|||||||
package org.bitcoinj.wallet;
|
package org.bitcoinj.wallet;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.ECKey;
|
||||||
|
import org.bitcoinj.core.ECKey.ECDSASignature;
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
import org.bitcoinj.core.NetworkParameters;
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
import org.bitcoinj.core.TransactionConfidence;
|
||||||
import org.bitcoinj.core.TransactionInput;
|
import org.bitcoinj.core.TransactionInput;
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
import org.bitcoinj.core.TransactionOutput;
|
||||||
import org.bitcoinj.core.Wallet;
|
import org.bitcoinj.core.Wallet;
|
||||||
|
import org.bitcoinj.crypto.TransactionSignature;
|
||||||
import org.bitcoinj.script.ScriptChunk;
|
import org.bitcoinj.script.ScriptChunk;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -111,7 +114,8 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
|
|||||||
VERSION,
|
VERSION,
|
||||||
DUST,
|
DUST,
|
||||||
SHORTEST_POSSIBLE_PUSHDATA,
|
SHORTEST_POSSIBLE_PUSHDATA,
|
||||||
NONEMPTY_STACK // Not yet implemented (for post 0.12)
|
NONEMPTY_STACK, // Not yet implemented (for post 0.12)
|
||||||
|
SIGNATURE_CANONICAL_ENCODING
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,6 +172,19 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
|
|||||||
for (ScriptChunk chunk : input.getScriptSig().getChunks()) {
|
for (ScriptChunk chunk : input.getScriptSig().getChunks()) {
|
||||||
if (chunk.data != null && !chunk.isShortestPossiblePushData())
|
if (chunk.data != null && !chunk.isShortestPossiblePushData())
|
||||||
return RuleViolation.SHORTEST_POSSIBLE_PUSHDATA;
|
return RuleViolation.SHORTEST_POSSIBLE_PUSHDATA;
|
||||||
|
if (chunk.isPushData()) {
|
||||||
|
ECDSASignature signature;
|
||||||
|
try {
|
||||||
|
signature = ECKey.ECDSASignature.decodeFromDER(chunk.data);
|
||||||
|
} catch (RuntimeException x) {
|
||||||
|
// Doesn't look like a signature.
|
||||||
|
signature = null;
|
||||||
|
}
|
||||||
|
if (signature != null) {
|
||||||
|
if (!TransactionSignature.isEncodingCanonical(chunk.data))
|
||||||
|
return RuleViolation.SIGNATURE_CANONICAL_ENCODING;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return RuleViolation.NONE;
|
return RuleViolation.NONE;
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,17 @@
|
|||||||
|
|
||||||
package org.bitcoinj.wallet;
|
package org.bitcoinj.wallet;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import java.util.Arrays;
|
||||||
import org.bitcoinj.core.*;
|
import org.bitcoinj.core.*;
|
||||||
|
import org.bitcoinj.crypto.TransactionSignature;
|
||||||
import org.bitcoinj.params.MainNetParams;
|
import org.bitcoinj.params.MainNetParams;
|
||||||
|
import org.bitcoinj.script.Script;
|
||||||
import org.bitcoinj.script.ScriptBuilder;
|
import org.bitcoinj.script.ScriptBuilder;
|
||||||
import org.bitcoinj.script.ScriptChunk;
|
import org.bitcoinj.script.ScriptChunk;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.bitcoinj.wallet.DefaultRiskAnalysis;
|
import org.bitcoinj.wallet.DefaultRiskAnalysis;
|
||||||
import org.bitcoinj.wallet.RiskAnalysis;
|
import org.bitcoinj.wallet.RiskAnalysis;
|
||||||
|
import org.bitcoinj.wallet.DefaultRiskAnalysis.RuleViolation;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -162,6 +165,22 @@ public class DefaultRiskAnalysisTest {
|
|||||||
assertEquals(DefaultRiskAnalysis.RuleViolation.SHORTEST_POSSIBLE_PUSHDATA, DefaultRiskAnalysis.isStandard(tx));
|
assertEquals(DefaultRiskAnalysis.RuleViolation.SHORTEST_POSSIBLE_PUSHDATA, DefaultRiskAnalysis.isStandard(tx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canonicalSignature() {
|
||||||
|
TransactionSignature sig = TransactionSignature.dummy();
|
||||||
|
Script scriptOk = ScriptBuilder.createInputScript(sig);
|
||||||
|
assertEquals(RuleViolation.NONE,
|
||||||
|
DefaultRiskAnalysis.isInputStandard(new TransactionInput(params, null, scriptOk.getProgram())));
|
||||||
|
|
||||||
|
byte[] sigBytes = sig.encodeToBitcoin();
|
||||||
|
// Appending a zero byte makes the signature uncanonical without violating DER encoding.
|
||||||
|
Script scriptUncanonicalEncoding = new ScriptBuilder().data(Arrays.copyOf(sigBytes, sigBytes.length + 1))
|
||||||
|
.build();
|
||||||
|
assertEquals(RuleViolation.SIGNATURE_CANONICAL_ENCODING,
|
||||||
|
DefaultRiskAnalysis.isInputStandard(new TransactionInput(params, null, scriptUncanonicalEncoding
|
||||||
|
.getProgram())));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void standardOutputs() throws Exception {
|
public void standardOutputs() throws Exception {
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user