From d41bd36feb2c0a4bd6e317ae4d630d8b4d1e814f Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 22 Nov 2018 01:46:20 -0700 Subject: [PATCH] testing working pkcs1 --- lib/asn1.js | 21 ++++++++++++ lib/encoding.js | 11 ++++++ lib/rasha.js | 90 +++++++++++++++++++++++++++++++------------------ 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/lib/asn1.js b/lib/asn1.js index 504dafc..78e8666 100644 --- a/lib/asn1.js +++ b/lib/asn1.js @@ -51,4 +51,25 @@ ASN1.parse = function parseAsn1(buf, depth) { return asn1; }; +/* +ASN1._stringify = function(asn1) { + //console.log(JSON.stringify(asn1, null, 2)); + //console.log(asn1); + var ws = ''; + + function write(asn1) { + console.log(ws, 'ch', Buffer.from([asn1.type]).toString('hex'), asn1.length); + if (!asn1.children) { + return; + } + asn1.children.forEach(function (a) { + ws += '\t'; + write(a); + ws = ws.slice(1); + }); + } + write(asn1); +}; +*/ + module.exports = ASN1; diff --git a/lib/encoding.js b/lib/encoding.js index 753afaa..48de237 100644 --- a/lib/encoding.js +++ b/lib/encoding.js @@ -15,6 +15,17 @@ Enc.bufToHex = function toHex(u8) { return hex.join('').toLowerCase(); }; +Enc.bufToBase64 = function toHex(u8) { + // we want to maintain api compatability with browser APIs, + // so we assume that this could be a Uint8Array + return Buffer.from(u8).toString('base64'); +}; + +Enc.bufToUrlBase64 = function toHex(u8) { + return Enc.bufToBase64(u8) + .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); +}; + /* Enc.strToBin = function strToBin(str) { var escstr = encodeURIComponent(str); diff --git a/lib/rasha.js b/lib/rasha.js index d630ca8..639aa44 100644 --- a/lib/rasha.js +++ b/lib/rasha.js @@ -5,8 +5,37 @@ var ASN1 = require('./asn1.js'); //var Enc = require('./encoding.js'); var PEM = require('./pem.js'); var SSH = require('./ssh.js'); +var Enc = require('./encoding.js'); +/*global Promise*/ +RSA.parse = function parseRsa(opts) { + return Promise.resolve().then(function () { + if (!opts || !opts.pem || 'string' !== typeof opts.pem) { + throw new Error("must pass { pem: pem } as a string"); + } + if (0 === opts.pem.indexOf('ssh-rsa ')) { + return SSH.parse(opts.pem); + } + var pem = opts.pem; + var block = PEM.parseBlock(pem); + var asn1 = ASN1.parse(block.der); + //var hex = toHex(u8); + var jwk = { kty: 'RSA' }; + + console.log(asn1); + var len = asn1.children.length; + if (2 === len || 9 === len) { + jwk = RSA.parsePkcs1(block.der, asn1, jwk); + } else { + jwk = RSA.parsePkcs8(block.der, asn1, jwk); + } + + return jwk; + }); +}; +RSA.toJwk = RSA.import = RSA.parse; + /* RSAPrivateKey ::= SEQUENCE { version Version, @@ -22,38 +51,35 @@ RSAPrivateKey ::= SEQUENCE { } */ -/*global Promise*/ -RSA.parse = function parseEc(opts) { - return Promise.resolve().then(function () { - if (!opts || !opts.pem || 'string' !== typeof opts.pem) { - throw new Error("must pass { pem: pem } as a string"); - } - if (0 === opts.pem.indexOf('ssh-rsa ')) { - return SSH.parse(opts.pem); - } - var pem = opts.pem; - var block = PEM.parseBlock(pem); - //var hex = toHex(u8); - //var jwk = { kty: 'RSA' }; +RSA.parsePkcs1 = function parseRsaPkcs1(buf, asn1, jwk) { + if (!asn1.children.every(function(el) { + return 0x02 === el.type; + })) { + throw new Error("not an RSA PKCS#1 public or private key (not all ints)"); + } - var asn1 = ASN1.parse(block.der); - var ws = ''; - function write(asn1) { - console.log(ws, 'ch', Buffer.from([asn1.type]).toString('hex'), asn1.length); - if (!asn1.children) { - return; - } - asn1.children.forEach(function (a) { - ws += '\t'; - write(a); - ws = ws.slice(1); - }); - } - //console.log(JSON.stringify(asn1, null, 2)); - console.log(asn1); - write(asn1); + if (2 === asn1.children.length) { - return { kty: 'RSA' }; - }); + jwk.n = Enc.bufToUrlBase64(asn1.children[0].value); + jwk.e = Enc.bufToUrlBase64(asn1.children[1].value); + return jwk; + + } else if (asn1.children.length >= 9) { + // the standard allows for "otherPrimeInfos", hence at least 9 + + jwk.n = Enc.bufToUrlBase64(asn1.children[1].value); + jwk.e = Enc.bufToUrlBase64(asn1.children[2].value); + jwk.d = Enc.bufToUrlBase64(asn1.children[3].value); + jwk.p = Enc.bufToUrlBase64(asn1.children[4].value); + jwk.q = Enc.bufToUrlBase64(asn1.children[5].value); + jwk.dp = Enc.bufToUrlBase64(asn1.children[6].value); + jwk.dq = Enc.bufToUrlBase64(asn1.children[7].value); + jwk.qi = Enc.bufToUrlBase64(asn1.children[8].value); + + return jwk; + } else { + throw new Error("not an RSA PKCS#1 public or private key (wrong number of ints)"); + } +}; +RSA.parsePkcs8 = function parseRsaPkcs8(buf, asn1, jwk) { }; -RSA.toJwk = RSA.import = RSA.parse;