14

I am trying to make a request with a p12 file or a pfx, but I can't get it to work. If I use PEM and KEY the code works fine. But Azure Keyvault does not support PEM and KEY. Is there an alternative that works with KEY/PEM certificates?

This is how I generated a p12/pfx file if that is the problem.

openssl pkcs12 -export -out certificate.pfx -inkey 1231181189.key -in 1231181189.pem -certfile CA.pem

Here is an example code, if I comment out cert and key the system does not work,

Error: read ECONNRESET

But if I comment out pfx and passphrase and use pem and key the connection work.

var request = require('request');
var fs = require('fs');
var path = require('path');
var certFile = __dirname + '/certs/1231181189.pem';
var keyFile = __dirname + '/certs/1231181189.key';

var options = {
  method: 'POST',
  url: 'https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests',
  headers: { 'Content-Type': 'application/json' },
  agentOptions: {
    cert: fs.readFileSync(certFile),
    key: fs.readFileSync(keyFile),
    pfx: fs.readFileSync(__dirname + '/certs/certificate.pfx'),
    passphrase: 'swish'
  },
  body: {
    payeePaymentReference: '0123456789',
    callbackUrl: 'https://example.com/api/swishcb/paymentrequests',
    payerAlias: '4671234768',
    payeeAlias: '1231181189',
    amount: '100',
    currency: 'SEK',
    message: 'Kingston USB Flash Drive 8 GB'
  },
  json: true
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(response.headers);
  console.log(body);
});
Krister Johansson
  • 691
  • 2
  • 10
  • 34
  • What error message do you get? – antzshrek Nov 27 '18 at 22:32
  • @antzshrek No code error, just connection fail ”ECONNREST” Its in my question – Krister Johansson Nov 27 '18 at 23:15
  • Your code seems ok. A pem file can contain several certificates, including the certificacion chain. Since you are not using `CA.pem` in the `agentOptions`, could you check that the entire certification chain is really included in `CA.pem` or is only present in `1231181189.pem`? – pedrofb Dec 10 '18 at 12:48
  • @pedrofb my "Swish TLS Root CA.pem" does only have one CERTIFICATE and my "1231181189.pem" have multiple. I'm I mixing them up? Tried to add **ca:CA.pem** to my code but got the same error. – Krister Johansson Dec 10 '18 at 13:22
  • 1
    The PFX file should contain the entire certificate chain, from the final certificate to root CA. It could be the error cause (i do not know if `-in 1231181189.pem` includes only the final certificate, but I suspect that it does). Try to copy the certificate chain of `1231181189.pem` into `CA.pem`. PEM is a text file containing certificates with a header and a footer. Alternatively, I think you can also try exporting the P12 using openssl command `-certfile 1231181189.pem` – pedrofb Dec 10 '18 at 13:40
  • If you have doubts about the exact content of p12, you can see that the certification chain is really present using the graphical tool keystore explorer or using `openssl pkcs12 -info -in certs/certificate.pfx` – pedrofb Dec 10 '18 at 13:41
  • @pedrofb It looks right to me, but first time working with certificates like this. If you have time, you can check the test cert from Swish here. https://developer.getswish.se/content/uploads/2018/10/Merchants_Test.zip – Krister Johansson Dec 10 '18 at 13:51
  • Wireshark is very useful in debugging such cases. Try to run this code from a computer that you have admin rights and do a dump while the code executes. Try to filter out this dialog and look for any issues in the handshake. – szogoon Dec 17 '18 at 08:20

2 Answers2

1

ECONNRESET means the far end -- in your case the endpoint on swish.net -- unceremoniously disconnected from the https client in your nodejs program. It's hard to know precisely why it did so. It's likely due to some sort of security failure. Robust servers don't explain security failures; after all why help cybercreeps? It's possible looking at a log on that server will tell you more.

In the meantime, it's possible the npm request package you use to wrap node's https agent function doesn't know anything about .pfx files or passwords, and therefore attempts to connect without any client certificates.

The pemutils package may allow you to extract the information you need from your .pfx file and use it. Something like this may work (not debugged).

var request = require('request');
var pemutils = require('pemutils');
var fs = require('fs');
var path = require('path');
const pfxFile =  __dirname + '/certs/certificate.pfx';

pemutils.fromPfx({
    path: pfxFile,
    password: 'myPass'
}, function(err, pfxresults) {
    if(err) throw err;
    var options = {
      method: 'POST',
      url: 'https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests',
      headers: { 'Content-Type': 'application/json' },
      agentOptions: {
        cert: pfxresults.certificate,
        key:  pfxresults.key,
      },
      body: {
           ...
      },
      json: true
    };
    ...

Notice the .fromPfx method is asynchronous.

O. Jones
  • 103,626
  • 17
  • 118
  • 172
0

I have the same issue with Azure APIM and I also need basic auth for the request.

I send request with axios like below:

const fs = require("fs");
const axios = require("axios");
const https = require("https");

(async function () {
    try {
        const response = await axios.request({
            url: "url",
            method: "get",
            headers: {
                accept: "application/json",
            },
            auth: {
                username: "name",
                password: "pw",
            },
            httpsAgent: new https.Agent({
                pfx: fs.readFileSync(
                    __dirname + "/mycert.pfx"
                ),
            }),
        });

        console.log(JSON.stringify(response.data));
    } catch (error) {
        console.log(error);
    }
})();
ikhvjs
  • 5,316
  • 2
  • 13
  • 36