bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.7k stars 2.11k forks source link

redeemScript error with ERR_OSSL_EVP_UNSUPPORTED #1811

Closed miguilimzero closed 2 years ago

miguilimzero commented 2 years ago

I'm currently trying to add an P2SH input with the following code:

psbt.addInput({
    "hash": "e07b8d7a1df04db0e57fbb68653ea0ca92bff20f40a2ba6630428a96c0741e98",
    "index": 0,
    "nonWitnessUtxo": Buffer.from("01000000000101ea693827c0e58f14f8c8a1199f9532068046a2a1c66e6d9b9ab637b7f07b88bc01000000232200207ddd32a32f4cb8b977668c1ce69d3f2e3a553fec7b6fa902c0fb5e08f3f1c875ffffffff0242807a050000000017a9143b38b4696f97b92a9c6e704583b3027fd019aeae8704374f600200000017a91498afdc14853023c29756f2a2da749314d00342a287040047304402205c0724d4fb33afe436192461929c2d295a9355ec1f0ebcb2a7f50a4986512fbd02204764e4a7f3eace94541786f3dad8904d601a44370c4a213c5188011fba9e319f0147304402200db40c6ea98ac01925640e282e4fe7815e62f7c5adb28060d61e0eded212512d02205b7e86afea335ec742c9adb5dfcf932119fa9c7ffbc2b31696154a1b84a4c08f0147522102c972d537e84439b579d36c21ef3cb105bbd3cedab39b772fe89329cfcb7da0ee21036626cc7e50b67d52e74c9f78129c2e3800992c3cbb87ec6c083ded4fbdfbd80952ae00000000", "hex")
})

This step do not thrown any error, but when I try to sign all inputs, I get the following errors:

Error: No inputs were signed

Error: scriptPubkey is P2SH but redeemScript missing

So, I assumed I need to pass a redeemScript value on the input, but when I try with any value, I get the following error when signing:

Error: error:0308010C:digital envelope routines::unsupporte

at ripemd160 (bitcoinjs-lib/src/crypto.js:11:12)
    at Object.hash160 (bitcoinjs-lib/src/crypto.js:30:10)
    at checkRedeem (bitcoinjs-lib/src/payments/p2sh.js:148:31)
    at p2sh (bitcoinjs-lib/src/payments/p2sh.js:183:7)
    at bitcoinjs-lib/src/psbt.js:837:32
    at getMeaningfulScript (bitcoinjs-lib/src/psbt.js:1379:5)
    at getHashForSig (bitcoinjs-lib/src/psbt.js:972:38)
    at getHashAndSighashType (bitcoinjs-lib/src/psbt.js:925:41)

opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

After a little research, I found that this problem is related to Node v17, however I'm using the Node v16. So after a deeper research, I found this bug also occur at v16.14.0 (which is my version).

All solutions says: "downgrade your node version" (or add a openssl-legacy param that didn't worked). Is there a solution without changing the node version, or fixable by the lib?

junderw commented 2 years ago

nonWitnessUtxo needs to be a Buffer, not a string.

redeemScript also needs to be a Buffer. Are you using a Buffer? (you said "any value" but it can't be any value, it needs to be a Buffer)

miguilimzero commented 2 years ago

@junderw Sorry for the bad code example (Just edited it). Yes I'm using Buffer. Currently getting the data and converting using:

Buffer.from('.....', 'hex')

This problem is only happening for P2SH inputs (when I need to set the redeemScript).

About the "any value". I mean, I tried the public key value, private key value, hash and the raw transaction hex (Everything as buffer).

But this problem seems to be related to some kind of OpenSSL issue with newer Node.js versions (That's what I found by searching the internet).

junderw commented 2 years ago

I just installed v16.14.0 and tried unit and integration tests (which definitely uses redeemScript with Psbt) and all tests are passing...

Which OS are you using?

junderw commented 2 years ago

Also, what kind of output are you spending?

P2SH(P2WSH(xxx)) or P2SH(P2WPKH) or P2SH(xxx) ?

junderw commented 2 years ago

it looks like the input of the tx inside nonWitnessUtxo is P2SH(P2WSH(P2MS:2-of-2)) and the 2nd output is the same script.

Is the one you're trying to spend also the same type of script?

miguilimzero commented 2 years ago

@junderw I'm currently using Fedora 36. Node v16.14.0. NPM v8.11.0.

I'm spending from P2SH(P2WPKH()) address. Trying to send to any kind of address leaves me to this error.

I had forgotten to run the library tests on my machine. And in the tests it is also giving the same error:

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at createHash (node:crypto:130:10)
    at ripemd160 (bitcoinjs-lib/src/crypto.js:2:565)
    at Object.hash160 (bitcoinjs-lib/src/crypto.js:2:1083)
    at Object.p2pkh (bitcoinjs-lib/src/payments/p2pkh.js:5:2067)
    at p2pkhPub (bitcoinjs-lib/test/psbt.spec.js:469:51)
    at getInputTypeTest (bitcoinjs-lib/test/psbt.spec.js:487:41)
    at Array.forEach (<anonymous>)
    at Suite.<anonymous> (bitcoinjs-lib/test/psbt.spec.js:547:11)
    at Object.create (bitcoinjs-lib/node_modules/mocha/lib/interfaces/common.js:140:19)
    at context.describe.context.context (bitcoinjs-lib/node_modules/mocha/lib/interfaces/bdd.js:42:27)
    at Suite.<anonymous> (bitcoinjs-lib/test/psbt.spec.js:463:26)
    at Object.create (bitcoinjs-lib/node_modules/mocha/lib/interfaces/common.js:140:19)
    at context.describe.context.context (bitcoinjs-lib/node_modules/mocha/lib/interfaces/bdd.js:42:27)
    at Object.<anonymous> (bitcoinjs-lib/test/psbt.spec.js:57:22)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Module.replacementCompile (bitcoinjs-lib/node_modules/append-transform/index.js:60:13)
    at Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
    at Object.<anonymous> (bitcoinjs-lib/node_modules/append-transform/index.js:64:4)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at requireOrImport (bitcoinjs-lib/node_modules/mocha/lib/esm-utils.js:15:12)
    at Object.exports.loadFilesAsync (bitcoinjs-lib/node_modules/mocha/lib/esm-utils.js:28:26)
    at async singleRun (bitcoinjs-lib/node_modules/mocha/lib/cli/run-helpers.js:107:3)
    at async exports.runMocha (bitcoinjs-lib/node_modules/mocha/lib/cli/run-helpers.js:144:5)
    at async Object.exports.handler (bitcoinjs-lib/node_modules/mocha/lib/cli/run.js:306:5)
junderw commented 2 years ago

I started a fresh Fedora 36 in docker, ran yum update. Installed nvm. Installed the exact node version you had. Installed git. Cloned this repo, ran npm ci to install deps. ran npm run nobuild:unit, and it passed.

The only difference I can think of: My host is running Manjaro.

These commands are run in my Fedora 36 fully updated container:

$ uname -r 5.15.41-1-MANJARO $ node -v v16.14.0 $ npm -v 8.3.1 $ yum list installed | grep openssl openssl-libs.x86_64 1:3.0.3-1.fc36 @ updates

Can you compare?

landabaso commented 2 years ago

Yeah, that happens with new versions of nodejs.

I'm on macos Monterey, node v17.9.0, npm 8.11.0 and I was getting the same issue.

You can workaround this problem launching node like this:

node --openssl-legacy-provider YOURSCRIPT.js

If you are using npx or whatever tool that uses node internally:

NODE_OPTIONS="--openssl-legacy-provider" npx YOURCOMMAND

(I read that this did not work for the OP but this worked for me for the same prob).

EDIT: Apparently RIPEMD160 belongs to legacy now ?!

miguilimzero commented 2 years ago

@junderw My OpenSSL version is the same: openssl.x86_64 1:3.0.3-1.fc36.

The only thing I can find different is the NPM version. Mine is 8.11.0 and yours is 8.3.1.

@landabaso I tried using this first solution, but I get this error:

node: bad option: --openssl-legacy-provider

Trying the second solution, I get this other error:

node: --openssl-legacy-provider is not allowed in NODE_OPTIONS
miguilimzero commented 2 years ago

@junderw Downgraded my NPM to 8.3.1 and followed the same steps as you.

Cloned the repo, npm ci and npm run nobuild:unit. I keep getting the same error.

junderw commented 2 years ago

what is the output for uname -r?

miguilimzero commented 2 years ago

@junderw uname -r : 5.17.12-300.fc36.x86_64

junderw commented 2 years ago

Can you try the commit on the pull request to see if it works for you?

  1. Pull the new commit
  2. run npm ci to install all the dependencies from package-lock
  3. run npm run nobuild:unit and tell me if it errors out for you?
miguilimzero commented 2 years ago

@junderw Now the tests pass for most of things. Its throwing an error since the package https://github.com/bitcoinjs/bip32 uses the ripemd160 too:

14) Psbt
       outputHasHDKey
         should return true if HD key is present:
     Error: error:0308010C:digital envelope routines::unsupported
      at new Hash (node:internal/crypto/hash:67:19)
      at createHash (node:crypto:130:10)
      at Object.hash160 (node_modules/bip32/src/crypto.js:15:16)
      at BIP32.get identifier [as identifier] (node_modules/bip32/src/bip32.js:67:27)
      at BIP32.get fingerprint [as fingerprint] (node_modules/bip32/src/bip32.js:70:25)
      at Context.<anonymous> (test/psbt.spec.ts:819:39)
      at processImmediate (node:internal/timers:466:21)
miguilimzero commented 2 years ago

Seems to be related to: https://github.com/bitcoinjs/bip32/issues/59. However I'm using node v16.14.0.

landabaso commented 2 years ago

Seems to be related to: https://github.com/bitcoinjs/bip32/issues/59. However I'm using node v16.14.0.

The "--openssl-legacy-provider" flag was introduced in v17.