diff --git a/src/script/sigencoding.cpp b/src/script/sigencoding.cpp index 22f92c9eed..55c726fd61 100644 --- a/src/script/sigencoding.cpp +++ b/src/script/sigencoding.cpp @@ -1,243 +1,239 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Copyright (c) 2017-2018 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "sigencoding.h" #include "pubkey.h" #include "script_flags.h" #include /** * A canonical signature exists of: <30> <02> <02> , where R and S are not negative (their first byte has its * highest bit not set), and not excessively padded (do not start with a 0 byte, * unless an otherwise negative number follows, in which case a single 0 byte is * necessary and even required). * * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 * * This function is consensus-critical since BIP66. */ -static bool IsValidSignatureEncoding(const valtype &sig) { +static bool +IsValidSignatureEncoding(const boost::sliced_range &sig) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] - // [sighash] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. // * R-length: 1-byte length descriptor of the R value that follows. // * R: arbitrary-length big-endian encoded R value. It must use the // shortest possible encoding for a positive integers (which means no null // bytes at the start, except a single one when the next byte has its // highest bit set). // * S-length: 1-byte length descriptor of the S value that follows. // * S: arbitrary-length big-endian encoded S value. The same rules apply. - // * sighash: 1-byte value indicating what data is hashed (not part of the - // DER signature) // Minimum and maximum size constraints. - if (sig.size() < 9 || sig.size() > 73) { + if (sig.size() < 8 || sig.size() > 72) { return false; } // // Check that the signature is a coumpound structure of proper size. // // A signature is of type 0x30 (compound). if (sig[0] != 0x30) { return false; } // Make sure the length covers the entire signature. // Remove: // * 1 byte for the coupound type. // * 1 byte for the length of the signature. - // * 1 byte for the sighash type. - if (sig[1] != sig.size() - 3) { + if (sig[1] != sig.size() - 2) { return false; } // // Check that R is an positive integer of sensible size. // // Check whether the R element is an integer. if (sig[2] != 0x02) { return false; } // Extract the length of the R element. const uint32_t lenR = sig[3]; // Zero-length integers are not allowed for R. if (lenR == 0) { return false; } // Negative numbers are not allowed for R. if (sig[4] & 0x80) { return false; } // Make sure the length of the R element is consistent with the signature // size. // Remove: // * 1 byte for the coumpound type. // * 1 byte for the length of the signature. // * 2 bytes for the integer type of R and S. // * 2 bytes for the size of R and S. // * 1 byte for S itself. - // * 1 byte for the sighash type. - if (lenR > (sig.size() - 8)) { + if (lenR > (sig.size() - 7)) { return false; } // Null bytes at the start of R are not allowed, unless R would otherwise be // interpreted as a negative number. // // /!\ This check can only be performed after we checked that lenR is // consistent with the size of the signature or we risk to access out of // bound elements. if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) { return false; } // // Check that S is an positive integer of sensible size. // // S's definition starts after R's definition: // * 1 byte for the coumpound type. // * 1 byte for the length of the signature. // * 1 byte for the size of R. // * lenR bytes for R itself. // * 1 byte to get to S. const uint32_t startS = lenR + 4; // Check whether the S element is an integer. if (sig[startS] != 0x02) { return false; } // Extract the length of the S element. const uint32_t lenS = sig[startS + 1]; // Zero-length integers are not allowed for S. if (lenS == 0) { return false; } // Negative numbers are not allowed for S. if (sig[startS + 2] & 0x80) { return false; } // Verify that the length of S is consistent with the size of the signature // including metadatas: // * 1 byte for the integer type of S. // * 1 byte for the size of S. - // * 1 byte for the sighash type. - if (size_t(startS + lenS + 3) != sig.size()) { + if (size_t(startS + lenS + 2) != sig.size()) { return false; } // Null bytes at the start of S are not allowed, unless S would otherwise be // interpreted as a negative number. // // /!\ This check can only be performed after we checked that lenR and lenS // are consistent with the size of the signature or we risk to access // out of bound elements. if (lenS > 1 && (sig[startS + 2] == 0x00) && !(sig[startS + 3] & 0x80)) { return false; } return true; } static bool IsLowDERSignature(const valtype &vchSig, ScriptError *serror) { assert(vchSig.size() > 0); if (CPubKey::CheckLowS(vchSig | boost::adaptors::sliced(0, vchSig.size() - 1))) { return true; } return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); } bool CheckSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror) { // Empty signature. Not strictly DER encoded, but allowed to provide a // compact way to provide an invalid signature for use with CHECK(MULTI)SIG if (vchSig.size() == 0) { return true; } if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && - !IsValidSignatureEncoding(vchSig)) { + !IsValidSignatureEncoding( + vchSig | boost::adaptors::sliced(0, vchSig.size() - 1))) { return set_error(serror, SCRIPT_ERR_SIG_DER); } if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { // serror is set return false; } if ((flags & SCRIPT_VERIFY_STRICTENC) != 0) { if (!GetHashType(vchSig).isDefined()) { return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); } bool usesForkId = GetHashType(vchSig).hasForkId(); bool forkIdEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID; if (!forkIdEnabled && usesForkId) { return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID); } if (forkIdEnabled && !usesForkId) { return set_error(serror, SCRIPT_ERR_MUST_USE_FORKID); } } return true; } static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { switch (vchPubKey.size()) { case 33: // Compressed public key: must start with 0x02 or 0x03. return vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03; case 65: // Non-compressed public key: must start with 0x04. return vchPubKey[0] == 0x04; default: // Non-canonical public key: invalid size. return false; } } static bool IsCompressedPubKey(const valtype &vchPubKey) { if (vchPubKey.size() != 33) { // Non-canonical public key: invalid length for compressed key return false; } if (vchPubKey[0] != 0x02 && vchPubKey[0] != 0x03) { // Non-canonical public key: invalid prefix for compressed key return false; } return true; } bool CheckPubKeyEncoding(const valtype &vchPubKey, uint32_t flags, ScriptError *serror) { if ((flags & SCRIPT_VERIFY_STRICTENC) && !IsCompressedOrUncompressedPubKey(vchPubKey)) { return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } // Only compressed keys are accepted when // SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE is enabled. if ((flags & SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE) && !IsCompressedPubKey(vchPubKey)) { return set_error(serror, SCRIPT_ERR_NONCOMPRESSED_PUBKEY); } return true; }