created module. yay.
This commit is contained in:
parent
ef342cd105
commit
5ea73e38ad
|
@ -0,0 +1,2 @@
|
||||||
|
Forrest L Norvell <forrest@newrelic.com>
|
||||||
|
AJ ONeal <coolaj86@gmail.com> (http://coolaj86.com)
|
|
@ -0,0 +1,139 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Explained here: https://groups.google.com/d/msg/nodejs/AjkHSYmiGYs/1LfNHbMhd48J
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, path = require('path')
|
||||||
|
, request = require('request')
|
||||||
|
, CERTDB_URL = 'https://mxr.mozilla.org/nss/source/lib/ckfw/builtins/certdata.txt?raw=1'
|
||||||
|
, OUTFILE = path.join(__dirname, './ssl-root-cas-latest.js')
|
||||||
|
, HEADER
|
||||||
|
;
|
||||||
|
|
||||||
|
HEADER =
|
||||||
|
"/**\n" +
|
||||||
|
" * Mozilla's root CA store\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * generated from " + CERTDB_URL + "\n" +
|
||||||
|
" */\n\n";
|
||||||
|
|
||||||
|
function Certificate() {
|
||||||
|
this.name = null;
|
||||||
|
this.body = '';
|
||||||
|
this.trusted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Certificate.prototype.quasiPEM = function quasiPEM() {
|
||||||
|
var bytes = this.body.split('\\')
|
||||||
|
, offset = 0
|
||||||
|
, converted
|
||||||
|
;
|
||||||
|
|
||||||
|
bytes.shift();
|
||||||
|
converted = new Buffer(bytes.length);
|
||||||
|
while(bytes.length > 0) {
|
||||||
|
converted.writeUInt8(parseInt(bytes.shift(), 8), offset++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ' // ' + this.name + '\n' +
|
||||||
|
' "-----BEGIN CERTIFICATE-----\\n" +\n' +
|
||||||
|
converted.toString('base64').replace(/(.{1,76})/g, ' "$1\\n" +\n') +
|
||||||
|
' "-----END CERTIFICATE-----\\n"';
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseBody(current, lines) {
|
||||||
|
var line
|
||||||
|
;
|
||||||
|
|
||||||
|
while (lines.length > 0) {
|
||||||
|
line = lines.shift();
|
||||||
|
if (line.match(/^END/)) { break; }
|
||||||
|
current.body += line;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (lines.length > 0) {
|
||||||
|
line = lines.shift();
|
||||||
|
if (line.match(/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/)) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
while (lines.length > 0) {
|
||||||
|
line = lines.shift();
|
||||||
|
if (line.match(/^#|^\s*$/)) { break; }
|
||||||
|
if (line.match(/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/) ||
|
||||||
|
line.match(/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUST_UNKNOWN$/)) {
|
||||||
|
current.trusted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current.trusted) return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCertData(lines) {
|
||||||
|
var certs = []
|
||||||
|
, line
|
||||||
|
, current
|
||||||
|
, skipped = 0
|
||||||
|
, match
|
||||||
|
, finished
|
||||||
|
;
|
||||||
|
|
||||||
|
while (lines.length > 0) {
|
||||||
|
line = lines.shift();
|
||||||
|
|
||||||
|
// nuke whitespace and comments
|
||||||
|
if (line.match(/^#|^\s*$/)) continue;
|
||||||
|
|
||||||
|
if (line.match(/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/)) {
|
||||||
|
current = new Certificate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current) {
|
||||||
|
match = line.match(/^CKA_LABEL UTF8 \"(.*)\"/);
|
||||||
|
if (match) {
|
||||||
|
current.name = match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.match(/^CKA_VALUE MULTILINE_OCTAL/)) {
|
||||||
|
finished = parseBody(current, lines);
|
||||||
|
if (finished) {
|
||||||
|
certs.push(finished);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skipped++;
|
||||||
|
}
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info("Skipped %s untrusted certificates.", skipped);
|
||||||
|
console.info("Processed %s certificates.", certs.length);
|
||||||
|
|
||||||
|
return certs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dumpCerts(certs) {
|
||||||
|
fs.writeFileSync(
|
||||||
|
OUTFILE,
|
||||||
|
HEADER +
|
||||||
|
'module.exports = [\n' +
|
||||||
|
certs.map(function (cert) { return cert.quasiPEM(); }).join(',\n\n') +
|
||||||
|
'\n];\n'
|
||||||
|
);
|
||||||
|
console.info("Wrote '" + OUTFILE.replace(/'/g, "\\'") + "'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
request(CERTDB_URL, function (error, response, body) {
|
||||||
|
if (error) {
|
||||||
|
console.error(error.stacktrace);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
console.error("Fetching failed with status code %s", response.statusCode);
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = body.split("\n");
|
||||||
|
dumpCerts(parseCertData(lines));
|
||||||
|
});
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"name": "ssl-root-cas",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "The module you need to solve node's SSL woes when including a custom certificate.",
|
||||||
|
"main": "ssl-root-cas",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node ca-store-generator.js",
|
||||||
|
"prepublish": "node ca-store-generator.js; mv ssl-root-cas-latest.js ssl-root-cas.js",
|
||||||
|
"postinstall": "node ca-store-generator.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/coolaj86/node-ssl-root-cas.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"SSL",
|
||||||
|
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
||||||
|
"CERT_UNTRUSTED",
|
||||||
|
"CAS",
|
||||||
|
"CA",
|
||||||
|
"ROOT",
|
||||||
|
"intermediate",
|
||||||
|
"leaf",
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"license": "Apache2",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/coolaj86/node-ssl-root-cas/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/coolaj86/node-ssl-root-cas",
|
||||||
|
"dependencies": {
|
||||||
|
"request": "~2.34.0"
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue