extractSigs - verify pubKey & pubKeyHash purported public keys, plus a round of comments
This commit is contained in:
parent
c215f350fc
commit
b09cf89f97
@ -185,12 +185,19 @@ InSigner.prototype.extractStandard = function (solution, chunks, sigVersion) {
|
||||
if (solution.type === bscript.types.P2PK) {
|
||||
if (bscript.pubKey.input.check(chunks)) {
|
||||
decoded = bscript.pubKey.input.decode(chunks)
|
||||
if (!decoded.pubKey.equals(solution.solvedBy)) {
|
||||
throw new Error('Key in scriptSig does not match output script key')
|
||||
}
|
||||
|
||||
signatures[0] = decoded.signature
|
||||
publicKeys[0] = solution.solvedBy
|
||||
}
|
||||
} else if (solution.type === bscript.types.P2PKH) {
|
||||
if (bscript.pubKeyHash.input.check(chunks)) {
|
||||
decoded = bscript.pubKeyHash.input.decode(chunks)
|
||||
if (!bcrypto.hash160(decoded.pubKey).equals(solution.solvedBy)) {
|
||||
throw new Error('Key in scriptSig does not match output script key-hash')
|
||||
}
|
||||
signatures[0] = decoded.signature
|
||||
publicKeys[0] = decoded.pubKey
|
||||
}
|
||||
@ -216,67 +223,75 @@ InSigner.prototype.extractStandard = function (solution, chunks, sigVersion) {
|
||||
}
|
||||
|
||||
InSigner.prototype.solve = function (opts) {
|
||||
// Determine scriptPubKey is solvable
|
||||
var scriptPubKey = solveScript(opts.scriptPubKey)
|
||||
if (scriptPubKey.type !== bscript.types.P2SH && ALLOWED_P2SH_SCRIPTS.indexOf(scriptPubKey.type) === -1) {
|
||||
throw new Error('txOut script is non-standard')
|
||||
}
|
||||
|
||||
var solution = scriptPubKey
|
||||
var redeemScript
|
||||
var witnessScript
|
||||
var value = 0
|
||||
var sigVersion = Transaction.SIG_V0
|
||||
var solution = scriptPubKey
|
||||
var value = 0
|
||||
|
||||
if (solution.type === bscript.types.P2SH) {
|
||||
var scriptHash = solution.solvedBy
|
||||
// Redeem script must be provided by opts
|
||||
if (!(opts.redeemScript instanceof Buffer)) {
|
||||
throw new Error('Redeem script required to solve utxo')
|
||||
}
|
||||
|
||||
// Check redeemScript against script-hash
|
||||
if (!scriptHash.equals(bcrypto.hash160(opts.redeemScript))) {
|
||||
throw new Error('Redeem script does not match txOut script hash')
|
||||
}
|
||||
|
||||
// Determine redeemScript is solvable
|
||||
solution = solveScript(opts.redeemScript)
|
||||
if (ALLOWED_P2SH_SCRIPTS.indexOf(solution.type)) {
|
||||
redeemScript = solution
|
||||
} else {
|
||||
if (!ALLOWED_P2SH_SCRIPTS.indexOf(solution.type)) {
|
||||
throw new Error('Unsupported P2SH script')
|
||||
}
|
||||
redeemScript = solution
|
||||
}
|
||||
|
||||
if (solution.type === bscript.types.P2WPKH) {
|
||||
// txOutValue is required here
|
||||
if (!types.Satoshi(opts.value)) {
|
||||
throw new Error('Value is required for witness-key-hash')
|
||||
}
|
||||
|
||||
// We set solution to this to avoid work later, since P2WPKH is a special case of P2PKH
|
||||
solution = solveScript(bscript.pubKeyHash.output.encode(solution.solvedBy))
|
||||
value = opts.value
|
||||
sigVersion = Transaction.SIG_V1
|
||||
value = opts.value
|
||||
} else if (solution.type === bscript.types.P2WSH) {
|
||||
var witnessScriptHash = solution.solvedBy
|
||||
// Witness script must be provided by opts
|
||||
if (!(opts.witnessScript instanceof Buffer)) {
|
||||
throw new Error('P2WSH script required to solve utxo')
|
||||
}
|
||||
// txOutValue is required here
|
||||
if (!types.Satoshi(opts.value)) {
|
||||
throw new Error('Value is required for witness-script-hash')
|
||||
}
|
||||
if (!bufferEquals(bcrypto.sha256(opts.witnessScript), witnessScriptHash)) {
|
||||
// Check witnessScript against script hash
|
||||
if (!bcrypto.sha256(opts.witnessScript).equals(witnessScriptHash)) {
|
||||
throw new Error('Witness script does not match txOut script hash')
|
||||
}
|
||||
solution = witnessScript = solveScript(opts.witnessScript)
|
||||
value = opts.value
|
||||
sigVersion = Transaction.SIG_V1
|
||||
if (SIGNABLE_SCRIPTS.indexOf(witnessScript.type) === -1) {
|
||||
solution = solveScript(opts.witnessScript)
|
||||
// Determine if witnessScript is solvable
|
||||
if (SIGNABLE_SCRIPTS.indexOf(solution.type) === -1) {
|
||||
throw new Error('witness script is not supported')
|
||||
}
|
||||
witnessScript = solution
|
||||
sigVersion = Transaction.SIG_V1
|
||||
value = opts.value
|
||||
}
|
||||
|
||||
this.signScript = solution
|
||||
this.scriptPubKey = scriptPubKey
|
||||
this.value = value
|
||||
this.sigVersion = sigVersion
|
||||
this.redeemScript = redeemScript
|
||||
this.witnessScript = witnessScript
|
||||
this.sigVersion = sigVersion
|
||||
this.value = value
|
||||
}
|
||||
|
||||
InSigner.prototype.extractSig = function () {
|
||||
@ -284,20 +299,20 @@ InSigner.prototype.extractSig = function () {
|
||||
var input = this.tx.ins[this.nIn]
|
||||
var solution = this.scriptPubKey
|
||||
var extractChunks = []
|
||||
var sigVersion = 0
|
||||
if (solution.canSign) {
|
||||
extractChunks = evalPushOnly(input.script)
|
||||
}
|
||||
|
||||
if (solution.type === bscript.types.P2SH) {
|
||||
if (bscript.scriptHash.input.check(input.script)) {
|
||||
// If we go to extract a P2SH scriptSig, verify the provided redeemScript
|
||||
var p2sh = bscript.scriptHash.input.decode(input.script)
|
||||
if (!p2sh.redeemScript.equals(this.redeemScript.script)) {
|
||||
throw new Error('Redeem script from scriptSig does not match')
|
||||
}
|
||||
|
||||
solution = this.redeemScript
|
||||
if (solution.canSign) {
|
||||
// We only bother if canSign, otherwise we waste time
|
||||
extractChunks = evalPushOnly(p2sh.redeemScriptSig)
|
||||
}
|
||||
}
|
||||
@ -310,7 +325,6 @@ InSigner.prototype.extractSig = function () {
|
||||
throw new Error('Public key does not match key-hash')
|
||||
}
|
||||
|
||||
sigVersion = 1
|
||||
extractChunks = input.witness
|
||||
}
|
||||
} else if (solution.type === bscript.types.P2WSH) {
|
||||
@ -318,14 +332,13 @@ InSigner.prototype.extractSig = function () {
|
||||
if (!this.witnessScript.equals(input.witness[ input.witness.length - 1 ])) {
|
||||
throw new Error('Witness script does not match')
|
||||
}
|
||||
sigVersion = 1
|
||||
solution = input.witnessScript
|
||||
extractChunks = input.witness.slice(0, -1)
|
||||
}
|
||||
}
|
||||
|
||||
if (extractChunks.length > 0) {
|
||||
[this.signatures, this.publicKeys] = this.extractStandard(solution, extractChunks, sigVersion)
|
||||
[this.signatures, this.publicKeys] = this.extractStandard(solution, extractChunks, this.sigVersion)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user