From 5085880bd054286d3894f80e7a2e94f89b274a78 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 22 Aug 2014 00:31:20 -0700 Subject: [PATCH] paypro: use fedor's asn1.js to deal with DER certificates. --- lib/PayPro.js | 82 +++++++++++++++++++++++++++++++++++++++++---------- package.json | 3 +- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/lib/PayPro.js b/lib/PayPro.js index 61d4893..f2965d0 100644 --- a/lib/PayPro.js +++ b/lib/PayPro.js @@ -8,6 +8,10 @@ var PayPro = require('./common/PayPro'); var KJUR = require('jsrsasign'); +var asn1 = require('asn1.js'); +var rfc3280 = require('asn1.js/rfc/3280'); +var Certificate = rfc3280.Certificate; + PayPro.prototype.x509Sign = function(key) { var self = this; var crypto = require('crypto'); @@ -91,25 +95,71 @@ PayPro.prototype.x509Verify = function() { var nder = ncert.toString('hex'); var npem = self._DERtoPEM(nder, 'CERTIFICATE'); - // get sig from current cert - BAD - var sig = new Buffer(der.slice(-(blen * 2)), 'hex'); - - // Should work but doesn't: - // get sig from current cert - // var o = new KJUR.asn1.cms.SignerInfo(); - // o.setSignerIdentifier(pem); - // var sig = o.getEncodedHex(); - - // get public key from next cert - var js = new KJUR.crypto.Signature({ - alg: type + 'withRSA', - prov: 'cryptojs/jsrsa' - }); - js.initVerifyByCertificatePEM(npem); - var npubKey = KJUR.KEYUTIL.getPEM(js.pubKey); + /* + https://www.ietf.org/rfc/rfc2459 + https://en.wikipedia.org/wiki/X509 + https://github.com/indutny/asn1.js + https://github.com/indutny/asn1.js/blob/master/rfc/3280/index.js + ~/work/node_modules/bitcore/node_modules/asn1.js/rfc/3280/index.js + Error: Failed to match tag: "objid" at: + ["tbsCertificate"]["issuerUniqueID"]["subjectUniqueID"]["extensions"]["extnID"] + PR: https://github.com/indutny/asn1.js/pull/22 + */ + + // Get public key from next certificate. + var data = new Buffer(nder, 'hex'); + var nc = Certificate.decode(data, 'der'); + var npubKey = nc.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data; + // Need to convert this to PEM: + // Doesn't work because KJUR is terrible: + // npubKey = KJUR.KEYUTIL.getPEM(npubKey.toString('hex')); + npubKey = self._DERtoPEM(npubKey, 'RSA PUBLIC KEY'); + + // Get signature from current certificate. + var data = new Buffer(der, 'hex'); + //var c = Certificate.decode(data, 'der', { partial: true }); + var c = Certificate.decode(data, 'der'); + var sig = c.signature.data; var verifier = crypto.createVerify('RSA-' + type); + var t = c.tbsCertificate; + + // Messy work: + // Fails on Issuer: + /* + var cur = Certificate.encode({ + tbsCertificate: { + version: t.version, + serialNumber: t.serialNumber, + signature: t.signature, + // Fails on issuer: + //issuer: t.issuer, + //issuer: t.issuer.value, + //issuer: t.issuer.value.map(function(obj) { + // return obj.value; + //}), + //issuer: t.issuer.type, + //issuer: 'rdh', + //issuer: rfc3280.Name.decode(t.issuer, 'der'), + validity: t.validity, + subject: t.subject, + subjectPublicKeyInfo: t.subjectPublicKeyInfo, + extensions: t.extensions + }, + signatureAlgorithm: '', + signature: '' + }, 'der'); + */ + + var cur = Certificate.encode({ + tbsCertificate: c.tbsCertificate, + signatureAlgorithm: '', + signature: '' + }, 'der'); + + // console.log(cur); + // NOTE: We need to slice off the signatureAlgorithm and signatureValue. // consult the x509 spec: // https://www.ietf.org/rfc/rfc2459 diff --git a/package.json b/package.json index e3e6d59..6392c43 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,8 @@ "event-stream": "~3.1.5", "gulp-concat": "~2.2.0", "gulp": "~3.8.2", - "preconditions": "^1.0.7" + "preconditions": "^1.0.7", + "asn1.js": "git://github.com/chjj/asn1.js.git" }, "testling": { "harness": "mocha-bdd",