Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js - HTTPS PFX Error: Unable to load BIO

I'm trying to make a HTTPS request-promise. I already know that the PFX is good and that is not the issue (I have a similar sample app working).

I am doing the following:

var request = require('request-promise');

...

options.pfx = fs.readFileSync('myfile.pfx');
options.passphrase = 'passphrase';

I am passing my options into an request.

request.post(options);

I then try to build the request I get the following error:

_tls_common.js:130
  c.context.loadPKCS12(pfx, passphrase);
            ^

Error: Unable to load BIO
at Error (native)
at Object.createSecureContext (_tls_common.js:130:17)
at Object.exports.connect (_tls_wrap.js:955:21)
at Agent.createConnection (https.js:73:22)
at Agent.createSocket (_http_agent.js:174:16)
at Agent.addRequest (_http_agent.js:143:23)
at new ClientRequest (_http_client.js:133:16)
at Object.exports.request (http.js:31:10)
at Object.exports.request (https.js:163:15)
at Request.start (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:747:30)
at Request.write (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:1369:10)
at end (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:561:16)
at Immediate._onImmediate (/Users/filomeno/workspace/sla-crawler/node_modules/request/request.js:589:7)
at processImmediate [as _immediateCallback] (timers.js:374:17)

I have a sample app where the same code works. I've tried to convert to .p12 without success.

Does anyone have an idea what this error might refer to?

Edit: I'm using lodash to do a merge of 2 objects with dinamic properties and static properties

_.merge(options, _this.requestOptions);

And that was causing the problem

like image 275
fasantos Avatar asked Mar 01 '16 17:03

fasantos


1 Answers

Looking at the nodejs source code (specifically this file https://github.com/nodejs/node/blob/master/src/node_crypto.cc)

the error is thrown by this function

// Takes .pfx or .p12 and password in string or buffer format
void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
   Environment* env = Environment::GetCurrent(args);
   ...

In line 964

in = LoadBIO(env, args[0]);
if (in == nullptr) {
   return env->ThrowError("Unable to load BIO");
}

Where the LoadBIO returns null

// Takes a string or buffer and loads it into a BIO.
// Caller responsible for BIO_free_all-ing the returned object.
static BIO* LoadBIO(Environment* env, Local<Value> v) {
  HandleScope scope(env->isolate());

  if (v->IsString()) {
    const node::Utf8Value s(env->isolate(), v);
    return NodeBIO::NewFixed(*s, s.length());
  }

  if (Buffer::HasInstance(v)) {
    return NodeBIO::NewFixed(Buffer::Data(v), Buffer::Length(v));
  }

  return nullptr;
}

Perhaps the buffer is somehow not readable? Also it seems that the function is expecting an utf-8 encoded string.

Some ideas:

Are you sure the path to the file is correct?

Maybe encoding issue? Did you try to set fs.readFileSync() encoding explicitly?

Try with fs.readFile(<filename>, <encoding>, function(error, data){}) to see if it throws an error?

like image 180
nardeas Avatar answered Nov 04 '22 03:11

nardeas