Skip to content

Commit d64668d

Browse files
authored
Merge pull request #233 from darosior/finalizer_check_sig
Explicitly error on non-standard sighash types
2 parents f550b9b + b8432e1 commit d64668d

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed

src/interpreter/error.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
1313
//
1414

15-
use bitcoin::hashes::hash160;
15+
use bitcoin::hashes::{hash160, hex::ToHex};
1616
use bitcoin::{self, secp256k1};
1717
use std::{error, fmt};
1818

@@ -39,6 +39,8 @@ pub enum Error {
3939
InsufficientSignaturesMultiSig,
4040
/// Signature failed to verify
4141
InvalidSignature(bitcoin::PublicKey),
42+
/// Last byte of this signature isn't a standard sighash type
43+
NonStandardSigHash(Vec<u8>),
4244
/// Miniscript error
4345
Miniscript(::Error),
4446
/// MultiSig requires 1 extra zero element apart from the `k` signatures
@@ -128,6 +130,13 @@ impl fmt::Display for Error {
128130
Error::IncorrectWScriptHash => f.write_str("witness script did not match scriptpubkey"),
129131
Error::InsufficientSignaturesMultiSig => f.write_str("Insufficient signatures for CMS"),
130132
Error::InvalidSignature(pk) => write!(f, "bad signature with pk {}", pk),
133+
Error::NonStandardSigHash(ref sig) => {
134+
write!(
135+
f,
136+
"Non standard sighash type for signature '{}'",
137+
sig.to_hex()
138+
)
139+
}
131140
Error::NonEmptyWitness => f.write_str("legacy spend had nonempty witness"),
132141
Error::NonEmptyScriptSig => f.write_str("segwit spend had nonempty scriptsig"),
133142
Error::Miniscript(ref e) => write!(f, "parse error: {}", e),

src/interpreter/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,8 @@ where
757757
F: FnOnce(&bitcoin::PublicKey, BitcoinSig) -> bool,
758758
{
759759
if let Some((sighash_byte, sig)) = sigser.split_last() {
760-
let sighashtype = bitcoin::SigHashType::from_u32(*sighash_byte as u32);
760+
let sighashtype = bitcoin::SigHashType::from_u32_standard(*sighash_byte as u32)
761+
.map_err(|_| Error::NonStandardSigHash([sig, &[*sighash_byte]].concat().to_vec()))?;
761762
let sig = secp256k1::Signature::from_der(sig)?;
762763
if verify_sig(pk, (sig, sighashtype)) {
763764
Ok(sig)

src/miniscript/satisfy.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use miniscript::limits::{
3030
HEIGHT_TIME_THRESHOLD, SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_TYPE_FLAG,
3131
};
3232
use util::witness_size;
33-
use Error;
3433
use Miniscript;
3534
use ScriptContext;
3635
use Terminal;
@@ -43,9 +42,10 @@ pub type Preimage32 = [u8; 32];
4342
/// Helper function to create BitcoinSig from Rawsig
4443
/// Useful for downstream when implementing Satisfier.
4544
/// Returns underlying secp if the Signature is not of correct format
46-
pub fn bitcoinsig_from_rawsig(rawsig: &[u8]) -> Result<BitcoinSig, Error> {
45+
pub fn bitcoinsig_from_rawsig(rawsig: &[u8]) -> Result<BitcoinSig, ::interpreter::Error> {
4746
let (flag, sig) = rawsig.split_last().unwrap();
48-
let flag = bitcoin::SigHashType::from_u32(*flag as u32);
47+
let flag = bitcoin::SigHashType::from_u32_standard(*flag as u32)
48+
.map_err(|_| ::interpreter::Error::NonStandardSigHash([sig, &[*flag]].concat().to_vec()))?;
4949
let sig = secp256k1::Signature::from_der(sig)?;
5050
Ok((sig, flag))
5151
}

src/psbt/finalizer.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,14 @@ pub fn finalize<C: secp256k1::Verification>(
262262
));
263263
}
264264
let (flag, sig) = rawsig.split_last().unwrap();
265-
let flag = bitcoin::SigHashType::from_u32(*flag as u32);
265+
let flag = bitcoin::SigHashType::from_u32_standard(*flag as u32).map_err(|_| {
266+
super::Error::InputError(
267+
InputError::Interpreter(interpreter::Error::NonStandardSigHash(
268+
[sig, &[*flag]].concat().to_vec(),
269+
)),
270+
n,
271+
)
272+
})?;
266273
if target != flag {
267274
return Err(Error::InputError(
268275
InputError::WrongSigHashFlag {

0 commit comments

Comments
 (0)