rasha-fork/bin/rasha.js

74 lines
2.3 KiB
JavaScript
Executable File

#!/usr/bin/env node
'use strict';
var fs = require('fs');
var infile = process.argv[2];
var pem = fs.readFileSync(infile, 'ascii');
var b64 = pem.split(/\n/).filter(function (line) {
// TODO test if RSA key
if (/^---/.test(line)) {
return false;
}
return true;
}).join('');
var buf = Buffer.from(b64, 'base64');
function ASN1(buf, depth) {
console.log();
if (!depth) { depth = 0; }
if (depth >= 15) {
throw new Error("We got stuck in a loop (or this is actually more than 15 layers deep, which we never expected)");
}
var asn1 = {
index: 2 // start after type (0) and lengthSize (1)
, type: buf[0]
, length: buf[1]
, lengthSize: 0
, value: null
, children: []
};
console.log(depth, buf.byteLength, buf);
var child;
var i = 0;
if (0x80 & asn1.length) {
asn1.lengthSize = 0x7f & asn1.length;
// I think that buf->hex->int solves the problem of Endianness... not sure
console.log('lenlen:', buf.slice(asn1.index, asn1.index + asn1.lengthSize).toString('hex'));
asn1.length = parseInt(buf.slice(asn1.index, asn1.index + asn1.lengthSize).toString('hex'), 16);
// add back the original byte indicating lengthSize
//asn1.lengthSize += 1;
//asn1.index += asn1.lengthSize;
asn1.index += 1;
}
console.log('asn1', 'type', Buffer.from([asn1.type]).toString('hex')
, 'ls', Buffer.from([asn1.lengthSize]).toString('hex'), 'len', asn1.length
, 'ch', asn1.children.length, 'vlen', asn1.value && asn1.value.length || null);
// this is a primitive value type
if (asn1.type <= 0x06) {
i += 1;
asn1.value = buf.slice(asn1.index, asn1.index + asn1.length);
return asn1;
}
while (i < 12 && asn1.index < buf.byteLength) {
var childbuf = buf.slice(asn1.index);
child = ASN1(childbuf, depth += 1);
console.log('child', 'type', Buffer.from([child.type]).toString('hex')
, 'ls', Buffer.from([child.lengthSize]).toString('hex'), 'len', child.length
, 'ch', child.children.length, 'vlen', child.value && child.value.length || null);
asn1.index += 2 /*child.type.length*/ + child.lengthSize + child.length;
asn1.children.push(child);
}
if (i >= 12) {
throw new Error("malformed ASN1: got stuck in a read loop (or there were actually 100+ elements in a sequence, which we never expected)");
}
return asn1;
}
console.log(ASN1(buf));