Merge #12460: Assert CPubKey::ValidLength to the pubkey's header-relevant size

f8c249ab91 Assert CPubKey::ValidLength to the pubkey's header-relevent size (Ben Woosley)

Pull request description:

  A pubkey's length is specific to its type which is indicated by its header value. GetLen returns the header-indicated length, so this change ensures that a key matches its header-indicated length.

  And replace some magic values with their constant equivalents.

Tree-SHA512: b727b39a631babe0932326396fc4d796ade8ec1e37454ff0c709ae9b78ecbd0cfdf59d84089ba8415e6efa7bc180e3cd39a14ddaf0871cbac54b96851e1b7b44
This commit is contained in:
MarcoFalke 2018-04-04 17:50:14 -04:00
commit bfaed1ab2e
No known key found for this signature in database
GPG key ID: D2EA4850E7528B25
4 changed files with 12 additions and 7 deletions

View file

@ -127,7 +127,7 @@ static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
CScript::const_iterator pc = dest.begin(); CScript::const_iterator pc = dest.begin();
opcodetype opcode; opcodetype opcode;
std::vector<unsigned char> vch; std::vector<unsigned char> vch;
if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65) if (!dest.GetOp(pc, opcode, vch) || !CPubKey::ValidSize(vch))
return false; return false;
pubKeyOut = CPubKey(vch); pubKeyOut = CPubKey(vch);
if (!pubKeyOut.IsFullyValid()) if (!pubKeyOut.IsFullyValid())

View file

@ -70,6 +70,11 @@ private:
} }
public: public:
bool static ValidSize(const std::vector<unsigned char> &vch) {
return vch.size() > 0 && GetLen(vch[0]) == vch.size();
}
//! Construct an invalid public key. //! Construct an invalid public key.
CPubKey() CPubKey()
{ {

View file

@ -61,17 +61,17 @@ static inline void popstack(std::vector<valtype>& stack)
} }
bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
if (vchPubKey.size() < 33) { if (vchPubKey.size() < CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) {
// Non-canonical public key: too short // Non-canonical public key: too short
return false; return false;
} }
if (vchPubKey[0] == 0x04) { if (vchPubKey[0] == 0x04) {
if (vchPubKey.size() != 65) { if (vchPubKey.size() != CPubKey::PUBLIC_KEY_SIZE) {
// Non-canonical public key: invalid length for uncompressed key // Non-canonical public key: invalid length for uncompressed key
return false; return false;
} }
} else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
if (vchPubKey.size() != 33) { if (vchPubKey.size() != CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) {
// Non-canonical public key: invalid length for compressed key // Non-canonical public key: invalid length for compressed key
return false; return false;
} }
@ -83,7 +83,7 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
} }
bool static IsCompressedPubKey(const valtype &vchPubKey) { bool static IsCompressedPubKey(const valtype &vchPubKey) {
if (vchPubKey.size() != 33) { if (vchPubKey.size() != CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) {
// Non-canonical public key: invalid length for compressed key // Non-canonical public key: invalid length for compressed key
return false; return false;
} }

View file

@ -132,7 +132,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
// Template matching opcodes: // Template matching opcodes:
if (opcode2 == OP_PUBKEYS) if (opcode2 == OP_PUBKEYS)
{ {
while (vch1.size() >= 33 && vch1.size() <= 65) while (CPubKey::ValidSize(vch1))
{ {
vSolutionsRet.push_back(vch1); vSolutionsRet.push_back(vch1);
if (!script1.GetOp(pc1, opcode1, vch1)) if (!script1.GetOp(pc1, opcode1, vch1))
@ -146,7 +146,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
if (opcode2 == OP_PUBKEY) if (opcode2 == OP_PUBKEY)
{ {
if (vch1.size() < 33 || vch1.size() > 65) if (!CPubKey::ValidSize(vch1))
break; break;
vSolutionsRet.push_back(vch1); vSolutionsRet.push_back(vch1);
} }