diff --git a/lib/PayPro.js b/lib/PayPro.js index 6d64bb8..5659ff2 100644 --- a/lib/PayPro.js +++ b/lib/PayPro.js @@ -3,6 +3,14 @@ var protobufjs = protobufjs || require('protobufjs/dist/ProtoBuf'); var Message = Message || require('./Message'); var KJUR = require('jsrsasign'); +var Trusted = require('./RootCerts'); + +// Use hash table for efficiency: +Trusted = Trusted.reduce(function(out, cert) { + cert = cert.replace(/\s+/g, ''); + trusted[cert] = true; + return trusted; +}, {}); // BIP 70 - payment protocol function PayPro() { @@ -215,6 +223,19 @@ PayPro.prototype.sign = function(key) { var pki_data = this.get('pki_data'); // contains one or more x509 certs var details = this.get('serialized_payment_details'); var type = pki_type.split('+')[1].toUpperCase(); + + pki_data = pki_data && Array.isArray(pki_data) + ? pki_data[0] + : pki_data; + + var der = pki_data.toString('hex'); + var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE'); + // var pub = KJUR.KEYUTIL.getHexFromPEM(pem, 'PUBLIC KEY') + + if (!Trusted[pem.replace(/\s+/g, '')]) { + throw new Error('Unstrusted certificate.'); + } + var signature = crypto.createSign('RSA-' + type); var buf = this.serializeForSig(); signature.update(buf); @@ -245,10 +266,11 @@ PayPro.prototype.verify = function() { var details = this.get('serialized_payment_details'); var buf = this.serializeForSig(); var type = pki_type.split('+')[1].toUpperCase(); + var verifier = crypto.createVerify('RSA-' + type); verifier.update(buf); - pki_data = pki_data && pki_data.unshift + pki_data = Array.isArray(pki_data) ? pki_data[0] : pki_data; @@ -256,6 +278,10 @@ PayPro.prototype.verify = function() { var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE'); // var pub = KJUR.KEYUTIL.getHexFromPEM(pem, 'PUBLIC KEY') + if (!Trusted[pem.replace(/\s+/g, '')]) { + throw new Error('Unstrusted certificate.'); + } + // return verifier.verify(pub, sig); return verifier.verify(pem, sig); } else if (pki_type === 'none') { diff --git a/lib/browser/PayPro.js b/lib/browser/PayPro.js index 6cfcefd..05ff008 100644 --- a/lib/browser/PayPro.js +++ b/lib/browser/PayPro.js @@ -37,6 +37,10 @@ PayPro.sign = function(key) { var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE'); // var pub = KJUR.KEYUTIL.getHexFromPEM(pem, 'PUBLIC KEY') + if (!Trusted[pem.replace(/\s+/g, '')]) { + throw new Error('Unstrusted certificate.'); + } + var jsrsaSig = new KJUR.crypto.Signature({ alg: type + 'withRSA', prov: 'cryptojs/jsrsa' @@ -84,6 +88,10 @@ PayPro.verify = function() { var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE'); // var pub = KJUR.KEYUTIL.getHexFromPEM(pem, 'PUBLIC KEY') + if (!Trusted[pem.replace(/\s+/g, '')]) { + throw new Error('Unstrusted certificate.'); + } + jsrsaSig.initVerifyByCertificatePEM(pem); jsrsaSig.updateHex(buf.toString('hex'));