1 /*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, strict:true, trailing:true, white:true */
3 /*global X:true, _:true, SYS:true */
5 // https://localhost/dev/oauth/generate-key?id=7
10 var ursa = require("ursa"),
11 exec = require("child_process").exec,
12 spawn = require("child_process").spawn,
13 async = require("async"),
14 path = require("path"),
18 Fetch the requested oauth2client model, validate the request,
19 generate a keypair whose public key will be saved with the
20 model and whose private key is returned to the browser.
22 exports.generateKey = function (req, res) {
23 var clientModel = new SYS.Oauth2client(),
25 // generic error function for both the fetch and the save
26 error = function (model, err) {
27 console.log("oauth2client error ", arguments);
28 res.send({isError: true, error: err});
30 convertToP12 = function (publicKey, privateKey) {
31 var filenamePrefix = path.join(process.cwd(), "lib/private/temp_" + id),
32 publicKeyFilename = filenamePrefix + "_public_key.pem",
33 csrFilename = filenamePrefix + "_csr.pem",
34 certFilename = filenamePrefix + "_cert.pem",
35 privateKeyFilename = filenamePrefix + "_private_key.pem",
36 p12Filename = filenamePrefix + ".p12",
37 attachmentFilename = publicKey.substring(0, publicKey.indexOf("-----END")) + ".p12",
38 csrExec = "openssl req -new -key %@ -out %@".f(privateKeyFilename, csrFilename),
42 function (callback) { fs.writeFile(publicKeyFilename, publicKey, callback); },
43 function (callback) { fs.writeFile(privateKeyFilename, privateKey, callback); },
45 var child = exec(csrExec, callback);
46 // blow through command-line questions
47 child.stdin.setEncoding = 'utf-8';
48 child.stdin.write("\n\n\n\n\n\n\n\n\n");
49 //child.stdin.write("US\nVirginia\nNorfolk\nxTuple\n\n\n\n\n");
53 var certSpawn = spawn("openssl",
54 ["x509", "-req", "-in", csrFilename, "-signkey", privateKeyFilename, "-out", certFilename]);
55 certSpawn.on('close', function (code) {
60 var child = spawn("openssl",
61 ["pkcs12", "-export", "-in", certFilename, "-inkey", privateKeyFilename, "-out", p12Filename, "-password", "pass:notasecret"]);
63 child.on('close', function (code) {
68 fs.readFile(p12Filename, function (err, contents) {
69 p12contents = contents;
70 callback(err, contents);
73 function (callback) { fs.unlink(publicKeyFilename, callback); },
74 function (callback) { fs.unlink(privateKeyFilename, callback); },
75 function (callback) { fs.unlink(csrFilename, callback); },
76 function (callback) { fs.unlink(certFilename, callback); },
77 function (callback) { fs.unlink(p12Filename, callback); }
79 function (err, results) {
81 res.send({isError: true, message: "Error generating p12 key: " + err.message, error: err});
84 res.attachment(attachmentFilename);
85 res.send(new Buffer(p12contents));
88 fetchSuccess = function (model, result) {
89 var keypair = ursa.generatePrivateKey(),
90 privateKey = keypair.toPrivatePem().toString(),
91 publicKey = keypair.toPublicPem().toString(),
92 saveSuccess = function (model, result) {
93 convertToP12(publicKey, privateKey);
96 // Cursory validation: this should be a jwt bearer and the
97 // public key field should not have already been set.
98 if (clientModel.get("clientType" !== "jwt bearer") ||
99 clientModel.get("clientX509PubCert")) {
100 res.send({isError: true, message: "Invalid request"});
104 clientModel.set("clientX509PubCert", publicKey);
105 clientModel.save(null, {
107 username: req.session.passport.user.username,
108 database: req.session.passport.user.organization,
115 username: req.session.passport.user.username,
116 database: req.session.passport.user.organization,
118 success: fetchSuccess