Merge branch 'feature/bip70-signing'
This commit is contained in:
commit
5cdc160dea
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
var imports = require('soop').imports();
|
||||
var protobufjs = protobufjs || require('protobufjs/dist/ProtoBuf');
|
||||
var Message = Message || require('./Message');
|
||||
|
||||
// BIP 70 - payment protocol
|
||||
function PayPro() {
|
||||
|
@ -8,8 +9,6 @@ function PayPro() {
|
|||
this.message = null;
|
||||
}
|
||||
|
||||
PayPro.constants = {};
|
||||
|
||||
PayPro.PAYMENT_REQUEST_MAX_SIZE = 50000;
|
||||
PayPro.PAYMENT_MAX_SIZE = 50000;
|
||||
PayPro.PAYMENT_ACK_MAX_SIZE = 60000;
|
||||
|
@ -149,11 +148,19 @@ PayPro.prototype.set = function(key, val) {
|
|||
PayPro.prototype.get = function(key) {
|
||||
var v = this.message.get(key);
|
||||
|
||||
if (v === null)
|
||||
return v;
|
||||
|
||||
//protobuf supports longs, javascript naturally does not
|
||||
//convert longs (see long.js, e.g. require('long')) to Numbers
|
||||
if (typeof v.low !== 'undefined' && typeof v.high !== 'undefined')
|
||||
return v.toInt();
|
||||
|
||||
if (typeof v.toBuffer !== 'undefined') {
|
||||
var maybebuf = v.toBuffer();
|
||||
return Buffer.isBuffer(maybebuf) ? maybebuf : new Buffer(new Uint8Array(maybebuf));
|
||||
}
|
||||
|
||||
return v;
|
||||
};
|
||||
|
||||
|
@ -167,6 +174,17 @@ PayPro.prototype.setObj = function(obj) {
|
|||
return this;
|
||||
};
|
||||
|
||||
PayPro.prototype.serializeForSig = function() {
|
||||
if (this.messageType !== 'PaymentRequest')
|
||||
throw new Error('serializeForSig is only for PaymentRequest');
|
||||
|
||||
var save = this.message.get('signature');
|
||||
this.message.set('signature', new Buffer([]));
|
||||
var buf = this.serialize();
|
||||
this.message.set('signature', save);
|
||||
return buf;
|
||||
};
|
||||
|
||||
PayPro.prototype.serialize = function() {
|
||||
//protobufjs returns either a Buffer or an ArrayBuffer
|
||||
//but we always want a Buffer (which browserify understands, browser or no)
|
||||
|
@ -183,4 +201,46 @@ PayPro.prototype.deserialize = function(buf, messageType) {
|
|||
return this;
|
||||
};
|
||||
|
||||
PayPro.prototype.sign = function(key) {
|
||||
if (this.messageType !== 'PaymentRequest')
|
||||
throw new Error('Signing can only be performed on a PaymentRequest');
|
||||
|
||||
var pki_type = this.get('pki_type');
|
||||
|
||||
if (pki_type === 'SIN')
|
||||
var sig = this.sinSign(key);
|
||||
else
|
||||
throw new Error('Unsupported pki_type');
|
||||
|
||||
this.set('signature', sig);
|
||||
return this;
|
||||
};
|
||||
|
||||
PayPro.prototype.verify = function() {
|
||||
if (this.messageType !== 'PaymentRequest')
|
||||
throw new Error('Verifying can only be performed on a PaymentRequest');
|
||||
|
||||
var pki_type = this.get('pki_type');
|
||||
|
||||
if (pki_type === 'SIN')
|
||||
return this.sinVerify();
|
||||
else
|
||||
throw new Error('Unsupported pki_type');
|
||||
};
|
||||
|
||||
//default signing function for prototype.sign
|
||||
PayPro.prototype.sinSign = function(key) {
|
||||
this.set('pki_data', key.public)
|
||||
var buf = this.serializeForSig();
|
||||
return Message.sign(buf, key);
|
||||
};
|
||||
|
||||
//default verify function
|
||||
PayPro.prototype.sinVerify = function() {
|
||||
var sig = this.get('signature');
|
||||
var pubkey = this.get('pki_data');
|
||||
var buf = this.serializeForSig();
|
||||
return Message.verifyWithPubKey(pubkey, buf, sig);
|
||||
};
|
||||
|
||||
module.exports = require('soop')(PayPro);
|
||||
|
|
|
@ -177,6 +177,37 @@ describe('PayPro', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('#setObj', function() {
|
||||
|
||||
it('should set properties of paymentdetails', function() {
|
||||
var pd = new PayPro.PaymentDetails();
|
||||
var paypro = new PayPro();
|
||||
paypro.messageType = "PaymentDetails";
|
||||
paypro.message = pd;
|
||||
paypro.setObj({
|
||||
time: 0
|
||||
});
|
||||
paypro.get('time').should.equal(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#serializeForSig', function() {
|
||||
|
||||
it('should serialize a PaymentRequest and not fail', function() {
|
||||
var pd = new PayPro.PaymentDetails();
|
||||
pd.set('time', 0);
|
||||
var pdbuf = pd.toBuffer();
|
||||
|
||||
var paypro = new PayPro();
|
||||
paypro.makePaymentRequest();
|
||||
paypro.set('serialized_payment_details', pdbuf);
|
||||
var buf = paypro.serializeForSig();
|
||||
buf.length.should.be.greaterThan(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#serialize', function() {
|
||||
|
||||
it('should serialize', function() {
|
||||
|
@ -209,4 +240,83 @@ describe('PayPro', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('#sign', function() {
|
||||
|
||||
it('should sign a payment request', function() {
|
||||
var pd = new PayPro.PaymentDetails();
|
||||
pd.set('time', 0);
|
||||
var pdbuf = pd.toBuffer();
|
||||
var paypro = new PayPro();
|
||||
paypro.makePaymentRequest();
|
||||
paypro.set('serialized_payment_details', pdbuf);
|
||||
paypro.set('pki_type', 'SIN');
|
||||
var key = new bitcore.Key();
|
||||
key.private = bitcore.util.sha256('test key');
|
||||
key.regenerateSync();
|
||||
paypro.sign(key);
|
||||
var sig = paypro.get('signature');
|
||||
sig.length.should.be.greaterThan(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#verify', function() {
|
||||
|
||||
it('should verify a signed payment request', function() {
|
||||
var pd = new PayPro.PaymentDetails();
|
||||
pd.set('time', 0);
|
||||
var pdbuf = pd.toBuffer();
|
||||
var paypro = new PayPro();
|
||||
paypro.makePaymentRequest();
|
||||
paypro.set('serialized_payment_details', pdbuf);
|
||||
paypro.set('pki_type', 'SIN');
|
||||
var key = new bitcore.Key();
|
||||
key.private = bitcore.util.sha256('test key');
|
||||
key.regenerateSync();
|
||||
paypro.sign(key);
|
||||
var verify = paypro.verify();
|
||||
verify.should.equal(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#sinSign', function() {
|
||||
|
||||
it('should sign assuming pki_type is SIN', function() {
|
||||
var pd = new PayPro.PaymentDetails();
|
||||
pd.set('time', 0);
|
||||
var pdbuf = pd.toBuffer();
|
||||
var paypro = new PayPro();
|
||||
paypro.makePaymentRequest();
|
||||
paypro.set('serialized_payment_details', pdbuf);
|
||||
paypro.set('pki_type', 'SIN');
|
||||
var key = new bitcore.Key();
|
||||
key.private = bitcore.util.sha256('test key');
|
||||
key.regenerateSync();
|
||||
var sig = paypro.sinSign(key);
|
||||
sig.length.should.be.greaterThan(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#sinVerify', function() {
|
||||
|
||||
it('should verify assuming pki_type is SIN', function() {
|
||||
var pd = new PayPro.PaymentDetails();
|
||||
pd.set('time', 0);
|
||||
var pdbuf = pd.toBuffer();
|
||||
var paypro = new PayPro();
|
||||
paypro.makePaymentRequest();
|
||||
paypro.set('serialized_payment_details', pdbuf);
|
||||
paypro.set('pki_type', 'SIN');
|
||||
var key = new bitcore.Key();
|
||||
key.private = bitcore.util.sha256('test key');
|
||||
key.regenerateSync();
|
||||
paypro.sign(key);
|
||||
var verify = paypro.sinVerify();
|
||||
verify.should.equal(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue