Skip to content

Commit

Permalink
fix paypro sig validation
Browse files Browse the repository at this point in the history
  • Loading branch information
kajoseph committed Aug 29, 2024
1 parent aa1b63b commit a1b8cf6
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 23 deletions.
33 changes: 18 additions & 15 deletions packages/bitcore-wallet-client/src/lib/paypro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,30 +100,33 @@ export class PayPro {
);
}

var hashbuf = Buffer.from(hash, 'hex');
let sigbuf = Buffer.from(signature, 'hex');
try {
const hashbuf = Buffer.from(hash, 'hex');
const sigbuf = Buffer.from(signature, 'hex');

let s_r = Buffer.alloc(32);
let s_s = Buffer.alloc(32);
const s_r = Buffer.alloc(32);
const s_s = Buffer.alloc(32);

sigbuf.copy(s_r, 0, 0);
sigbuf.copy(s_s, 0, 32);
sigbuf.copy(s_r, 0, 0);
sigbuf.copy(s_s, 0, 32);

let s_rBN = Bitcore.crypto.BN.fromBuffer(s_r);
let s_sBN = Bitcore.crypto.BN.fromBuffer(s_s);
const s_rBN = Bitcore.crypto.BN.fromBuffer(s_r);
const s_sBN = Bitcore.crypto.BN.fromBuffer(s_s);

let pub = Bitcore.PublicKey.fromString(keyData.publicKey);
const pub = Bitcore.PublicKey.fromString(keyData.publicKey);

let sig = new Bitcore.crypto.Signature();
sig.set({ r: s_rBN, s: s_sBN });
const sig = new Bitcore.crypto.Signature();
sig.set({ r: s_rBN, s: s_sBN });

let valid = Bitcore.crypto.ECDSA.verify(hashbuf, sig, pub);
const valid = Bitcore.crypto.ECDSA.verify(hashbuf, sig, pub);
if (!valid) {
throw new Error('Invalid signature');
}

if (!valid) {
return callback(null, keyData.owner);
} catch (err) {
return callback(new Error('Response signature invalid'));
}

return callback(null, keyData.owner);
}

static runRequest(opts, cb) {
Expand Down
58 changes: 50 additions & 8 deletions packages/bitcore-wallet-client/test/paypro.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use strict';

var _ = require('lodash');
var chai = chai || require('chai');
var sinon = sinon || require('sinon');
var should = chai.should();
var {PayPro: payPro} = require('../ts_build/lib/paypro');
var TestData = require('./testdata');
const chai = require('chai');
const sinon = require('sinon');
const crypto = require('crypto');
const should = chai.should();
const { PayPro: payPro } = require('../ts_build/lib/paypro');
const TestData = require('./testdata');

function mockRequest(bodyBuf, headers) {
bodyBuf = _.isArray(bodyBuf) ? bodyBuf : [bodyBuf];
bodyBuf = Array.isArray(bodyBuf) ? bodyBuf : [bodyBuf];
payPro.r = {
'get': (_url) => {
return {
Expand Down Expand Up @@ -110,7 +110,49 @@ describe('paypro', function () {
});

it('Should detect a tampered PP request (bad signature)', function (done) {
let h = _.clone(TestData.payProJson.bch.headers);
let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers));
h.signature = crypto.randomBytes(64).toString('hex');
mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h);
payPro.get({
url: 'https://test.bitpay.com/paypro',
network: 'testnet',
coin: 'bch',
}, function (err, res) {
err.toString().should.contain('signature invalid');
done();
});
});

it('Should detect a tampered PP request (short signature)', function (done) {
let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers));
h.signature = h.signature.slice(0, -1);
mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h);
payPro.get({
url: 'https://test.bitpay.com/paypro',
network: 'testnet',
coin: 'bch',
}, function (err, res) {
err.toString().should.contain('signature invalid');
done();
});
});

it('Should detect a tampered PP request (non-hex signature)', function (done) {
let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers));
h.signature = crypto.randomBytes(64).toString('base64');
mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h);
payPro.get({
url: 'https://test.bitpay.com/paypro',
network: 'testnet',
coin: 'bch',
}, function (err, res) {
err.toString().should.contain('signature invalid');
done();
});
});

it('Should detect a tampered PP request (bogus signature)', function (done) {
let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers));
h.signature = 'xx';
mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h);
payPro.get({
Expand Down

0 comments on commit a1b8cf6

Please sign in to comment.