parsing of x509 certificates and keys in javascript (via emscripten)
npm install x509.js
<pre>
Cert <input type="file" id="ui_fcert">
Key <input type="file" id="ui_fkey">
</pre>
<script>
// Tests passed on Chrome 43 with a Blob.prototype.arrayBuffer() patch
// Recommend to use Worker to avoid the global vars be messed up
var w = new Worker(URL.createObjectURL(new Blob([`
// patch some nodejs enviroment
var __dirname = '${location.href.replace(/\/[^\/]*$/, '')}';
var module = {};
function require(e){
if(e == './em-x509') return t;
console.error('required module', e, 'not exists!');
}
// import modules
importScripts(__dirname + '/em-x509.js'); // this must be first
importScripts(__dirname + '/index.js'); // imported cppMapToObject and cppVectorToArray
onmessage = function(e){ // required an ArrayBuffer to call t.parseCert and t.parseKey
e.data.return = t[e.data.fn].apply(this, e.data.args);
if(e.data.fn == 'parseCert'){ // re-implemented part of parseCert because there's can't invoke "new Buffer(str, 'utf8').toString('binary')"
var out = e.data.return;
out.altNames = cppVectorToArray(out.altNames);
out.ocspList = cppVectorToArray(out.ocspList);
out.subject = cppMapToObject(out.subject);
out.issuer = cppMapToObject(out.issuer);
}
postMessage(e.data);
}
`], { type: 'text/javascript' })));
ui_fcert.onchange = function(){ // when open a cert file (.cer; .crt; .pem)
this.files[0].arrayBuffer().then(function(e){
w.postMessage({ fn: 'parseCert', args: [e] });
});
};
ui_fkey.onchange = function(){ // when open a private key file
this.files[0].arrayBuffer().then(function(e){
w.postMessage({ fn: 'parseKey', args: [e] });
});
};
w.onmessage = function(e){ // when parsed data
console.log(e.data.return);
}
</script>
var fs = require('fs');
var x509 = require('x509.js');
var parsedData = x509.parseCert(fs.readFileSync('domain.crt')); // use fs.readFile in actual code
/* parsedData looks like
{ publicModulus: 'B27DB7A94351A4E542245917C579C7DFC8A703CEDE18D5CC0A40DB41B2B17B79AFF559F9B952824B78D8D41475060D5D7E44D47E360AD03083C8222EAC3AD9A1241CB4376855CC99C324B4253EFFFBE6DDC303E5284A44AC7163D6B3950D406085172492602BBF68D6F4C2A7AD80A10691E5D11CCA7EA3911EECDF98F9946FAB35193D56D7129ED8AA1545FA1DCA2422F1DF7E997A616B406D98A07E6EB0EEC125B7B6E00FE8E5879DE617DBF61296D068BB1529A31A1CB95B81E1B83B0C3E0305A7A5F5260451E29364F7444F785B1AA49540980CDB2F34B4D0C1ADF874323425B508D44C4B0BB968D3E7C98029CB7F75376AFB146EEA3EF2799254B85DCE47',
publicExponent: '010001',
subject:
{ commonName: 'www.acaline.com',
organizationalUnitName: 'Domain Control Validated' },
issuer:
{ commonName: 'Go Daddy Secure Certification Authority',
countryName: 'US',
localityName: 'Scottsdale',
organizationName: 'GoDaddy.com, Inc.',
organizationalUnitName: 'http://certificates.godaddy.com/repository',
serialNumber: '07969287',
stateOrProvinceName: 'Arizona' },
serial: '27ACAE30B9F323',
notBefore: 'Apr 26 14:51:17 2013 GMT',
notAfter: 'Apr 26 14:51:17 2014 GMT',
altNames: [ 'www.acaline.com', 'acaline.com' ],
ocspList: [ 'http://ocsp.godaddy.com/' ] });
}
*/
var parsedKey = x509.parseKey(fs.readFileSync('domain.key')); // use fs.readFile in actual code
/* parsedKey looks like
{
publicExponent: '010001',
publicModulus: 'E6C5BC84CF79CC6EDB1A1F7ED0CE39EFA413395C055886605AB66E2DE1C0B31C8D1C12F436FD222C167DDE44928F72F72DFE9E5420FD0595836D47A163CC59A1C444AEE8C0E9CE3B8A53D2FCD569A4ADA38D537E3542C81F887538E6B6A953D82ADC6150B88B09E961E451D721895002A0628A4F7387E3D99ED78E05AC94F5640698D833BC518CEF5A2192B2F58FB79BD6F1F499FA603C9A3DB4AD8EF6EAB4071D25CBC2A41F9CC8BA1D47B9135AAE53ED479B00F09C40B4607274FEA4585E61D541DB297336F373DF1DB569AD41D17D1A04EFAED7A9938F651C71AA99C0C4D4BFB6347CCE90469B12A23F04BDD32DB4066DB22E757D57272BAD6485A9F61D1D',
}
*/