var ursa = require("ursa"),
exec = require("child_process").exec,
+ forge = require("node-forge"),
spawn = require("child_process").spawn,
async = require("async"),
path = require("path"),
console.log("oauth2client error ", arguments);
res.send({isError: true, error: err});
},
- convertToP12 = function (publicKey, privateKey) {
- var filenamePrefix = path.join("/tmp/temp_" + id),
- publicKeyFilename = filenamePrefix + "_public_key.pem",
- csrFilename = filenamePrefix + "_csr.pem",
- certFilename = filenamePrefix + "_cert.pem",
- privateKeyFilename = filenamePrefix + "_private_key.pem",
- p12Filename = filenamePrefix + ".p12",
- attachmentFilename = publicKey.substring(0, publicKey.indexOf("-----END")) + ".p12",
- csrExec = "openssl req -new -key %@ -out %@".f(privateKeyFilename, csrFilename),
- p12contents;
-
- async.series([
- function (callback) { fs.writeFile(publicKeyFilename, publicKey, callback); },
- function (callback) { fs.writeFile(privateKeyFilename, privateKey, callback); },
- function (callback) {
- var child = exec(csrExec, callback);
- // blow through command-line questions
- child.stdin.setEncoding = 'utf-8';
- child.stdin.write("\n\n\n\n\n\n\n\n\n");
- //child.stdin.write("US\nVirginia\nNorfolk\nxTuple\n\n\n\n\n");
- child.stdin.end();
- },
- function (callback) {
- var certSpawn = spawn("openssl",
- ["x509", "-req", "-in", csrFilename, "-signkey", privateKeyFilename, "-out", certFilename]);
- certSpawn.on('close', function (code) {
- callback(null, code);
- });
- },
- function (callback) {
- var child = spawn("openssl",
- ["pkcs12", "-export", "-in", certFilename, "-inkey", privateKeyFilename, "-out", p12Filename, "-password", "pass:notasecret"]);
-
- child.on('close', function (code) {
- callback(null, code);
- });
- },
- function (callback) {
- fs.readFile(p12Filename, function (err, contents) {
- p12contents = contents;
- callback(err, contents);
- });
- },
- function (callback) { fs.unlink(publicKeyFilename, callback); },
- function (callback) { fs.unlink(privateKeyFilename, callback); },
- function (callback) { fs.unlink(csrFilename, callback); },
- function (callback) { fs.unlink(certFilename, callback); },
- function (callback) { fs.unlink(p12Filename, callback); }
- ],
- function (err, results) {
+ genKey = function (model, result) {
+ /**
+ * This is REALLY slow in pure javascript. ursa is much faster.
+ * @See: https://github.com/digitalbazaar/forge/issues/125
+ forge.pki.rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) {
if (err) {
- res.send({isError: true, message: "Error generating p12 key: " + err.message, error: err});
+ res.send({isError: true, message: "Error generating keypair: " + err.message, error: err});
return;
}
- res.attachment(attachmentFilename);
- res.send(new Buffer(p12contents));
+
+ console.log("1.2: ", new Date().getTime());
+ fetchSuccess(model, result, keypair);
});
+ */
+
+ // Use ursa for the key gen and then convert to forge's format.
+ var keypair = ursa.generatePrivateKey();
+ var keys = {
+ privateKey: forge.pki.privateKeyFromPem(keypair.toPrivatePem().toString()),
+ publicKey: forge.pki.publicKeyFromPem(keypair.toPublicPem().toString())
+ };
+
+ fetchSuccess(model, result, keys);
+ },
+ sendP12 = function (keys) {
+ // It's possible and much easier to generate the p12 file without a
+ // cert. This example shows how to generate a cert if we actually need
+ // to, but OAuth is working without.
+ // @see: https://github.com/digitalbazaar/forge/blob/master/tests/nodejs-create-pkcs12.js#L11
+ //var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey, [cert], 'notasecret'),
+ var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey, null, 'notasecret'),
+ p12Der = forge.asn1.toDer(p12Asn1).getBytes(),
+ buffer = new Buffer(p12Der, 'binary');
+
+ res.attachment(clientModel.get('clientName') + '.p12');
+ res.send(new Buffer(buffer, 'base64'));
},
- fetchSuccess = function (model, result) {
- var keypair = ursa.generatePrivateKey(),
- privateKey = keypair.toPrivatePem().toString(),
- publicKey = keypair.toPublicPem().toString(),
+ fetchSuccess = function (model, result, keys) {
+ var publicKey = forge.pki.publicKeyToPem(keys.publicKey),
saveSuccess = function (model, result) {
- convertToP12(publicKey, privateKey);
+ sendP12(keys);
};
// Cursory validation: this should be a jwt bearer and the
username: req.session.passport.user.username,
database: req.session.passport.user.organization,
error: error,
- success: fetchSuccess
+ success: genKey
});
};