| 3380 | } |
| 3381 | |
| 3382 | bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) |
| 3383 | { |
| 3384 | static const CScriptWitness emptyWitness; |
| 3385 | if (witness == nullptr) { |
| 3386 | witness = &emptyWitness; |
| 3387 | } |
| 3388 | bool hadWitness = false; |
| 3389 | |
| 3390 | set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); |
| 3391 | |
| 3392 | if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { |
| 3393 | return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); |
| 3394 | } |
| 3395 | |
| 3396 | // scriptSig and scriptPubKey must be evaluated sequentially on the same stack |
| 3397 | // rather than being simply concatenated (see CVE-2010-5141) |
| 3398 | std::vector<std::vector<unsigned char> > stack, stackCopy; |
| 3399 | if (!EvalScript(stack, scriptSig, flags, checker, SigVersion::BASE, serror)) |
| 3400 | // serror is set |
| 3401 | return false; |
| 3402 | if (flags & SCRIPT_VERIFY_P2SH) |
| 3403 | stackCopy = stack; |
| 3404 | if (!EvalScript(stack, scriptPubKey, flags, checker, SigVersion::BASE, serror)) |
| 3405 | // serror is set |
| 3406 | return false; |
| 3407 | if (stack.empty()) |
| 3408 | return set_error(serror, SCRIPT_ERR_EVAL_FALSE); |
| 3409 | if (CastToBool(stack.back()) == false) |
| 3410 | return set_error(serror, SCRIPT_ERR_EVAL_FALSE); |
| 3411 | |
| 3412 | // Bare witness programs |
| 3413 | int witnessversion; |
| 3414 | std::vector<unsigned char> witnessprogram; |
| 3415 | if (flags & SCRIPT_VERIFY_WITNESS) { |
| 3416 | if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { |
| 3417 | hadWitness = true; |
| 3418 | if (scriptSig.size() != 0) { |
| 3419 | // The scriptSig must be _exactly_ CScript(), otherwise we reintroduce malleability. |
| 3420 | return set_error(serror, SCRIPT_ERR_WITNESS_MALLEATED); |
| 3421 | } |
| 3422 | if (!VerifyWitnessProgram(*witness, witnessversion, witnessprogram, flags, checker, serror, /* is_p2sh */ false)) { |
| 3423 | return false; |
| 3424 | } |
| 3425 | // Bypass the cleanstack check at the end. The actual stack is obviously not clean |
| 3426 | // for witness programs. |
| 3427 | stack.resize(1); |
| 3428 | } |
| 3429 | } |
| 3430 | |
| 3431 | // Additional validation for spend-to-script-hash transactions: |
| 3432 | if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) |
| 3433 | { |
| 3434 | // scriptSig must be literals-only or validation fails |
| 3435 | if (!scriptSig.IsPushOnly()) |
| 3436 | return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); |
| 3437 | |
| 3438 | // Restore stack. |
| 3439 | swap(stack, stackCopy); |