From d9c8628d303f367b53eea561765b45dd61da446b Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel <lloyd@hilaiel.com> Date: Mon, 16 Jul 2012 16:44:04 -0600 Subject: [PATCH] Allow assertions issued by person to be used to authenticate. This makes it possible for "proxy idps" to work without the implementation details leaking out into others verifier implementations. --- lib/primary.js | 18 ++++++++++---- tests/lib/primary.js | 12 +++++----- tests/proxy-idp-test.js | 53 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/lib/primary.js b/lib/primary.js index f89ba0111..4cccbe295 100644 --- a/lib/primary.js +++ b/lib/primary.js @@ -12,7 +12,8 @@ http = require('http'), logger = require('./logging.js').logger, urlparse = require('urlparse'), jwcrypto = require("jwcrypto"), -config = require("./configuration.js"); +config = require("./configuration.js"), +secrets = require("./secrets.js"); // alg require("jwcrypto/lib/algs/rs"); @@ -27,6 +28,14 @@ const HOSTNAME = urlparse(config.get('public_url')).host; var g_shim_cache = {}; +try { + const PUBLIC_KEY = secrets.loadPublicKey(); + if (typeof PUBLIC_KEY !== 'object') throw "secrets.loadPublicKey() returns non-object, load failure"; +} catch(e){ + logger.error("can't read public key, exiting: " + e); + setTimeout(function() { process.exit(1); }, 0); +} + // This becomes async function parseWellKnownBody(body, domain, delegates, cb) { try { @@ -274,9 +283,10 @@ exports.verifyAssertion = function(assertion, cb) { } var getRoot = function(issuer, next) { - // issuer cannot be the browserid + // allow assertions rooted in certs issued by us. this occurs in the proxy_idp case + // where we sign assertions for other domains. if (issuer === HOSTNAME) { - next("cannot authenticate to browserid with a certificate issued by it."); + next(null, PUBLIC_KEY); } else { exports.getPublicKey(issuer, function(err, pubKey) { if (err) return next(err); @@ -293,7 +303,7 @@ exports.verifyAssertion = function(assertion, cb) { // for now, to be extra safe, we don't allow cert chains if (certParamsArray.length > 1) return cb("certificate chaining is not yet allowed"); - + // audience must be browserid itself var want = urlparse(config.get('public_url')).originOnly(); var got = urlparse(assertionParams.audience).originOnly(); diff --git a/tests/lib/primary.js b/tests/lib/primary.js index 1ff1b4d77..40d3a5200 100644 --- a/tests/lib/primary.js +++ b/tests/lib/primary.js @@ -24,18 +24,18 @@ User.prototype.setup = function(cb) { // upon allocation of a user, we'll gen a keypair and get a signed cert jwcrypto.generateKeypair({algorithm:"DS", keysize:256}, function(err, kp) { if (err) return cb(err); - + self._keyPair = kp; - + var expiration = new Date(); expiration.setTime(new Date().valueOf() + 60 * 60 * 1000); - + jwcrypto.cert.sign(self._keyPair.publicKey, {email: self.options.email}, {expiresAt: expiration, issuer: self.options.domain, issuedAt: new Date()}, - {}, g_privKey, function(err, signedCert) { + {}, self.options.privKey || g_privKey, function(err, signedCert) { if (err) return cb(err); self._cert = signedCert; - + cb(null); }); }); @@ -52,4 +52,4 @@ User.prototype.getAssertion = function(origin, cb) { }); }; -module.exports = User; \ No newline at end of file +module.exports = User; diff --git a/tests/proxy-idp-test.js b/tests/proxy-idp-test.js index f8d4685f6..1321c5c6e 100755 --- a/tests/proxy-idp-test.js +++ b/tests/proxy-idp-test.js @@ -12,7 +12,12 @@ vows = require('vows'), path = require('path'), start_stop = require('./lib/start-stop.js'), wsapi = require('./lib/wsapi.js'), -util = require('util'); +primary = require('./lib/primary.js'), +util = require('util'), +jwcrypto = require('jwcrypto'); + +require("jwcrypto/lib/algs/rs"); +require("jwcrypto/lib/algs/ds"); var suite = vows.describe('delegated-primary'); @@ -76,6 +81,52 @@ suite.addBatch({ } }); +// and now let's verify a primary +var primaryUser = new primary({ + email: "bartholomew@yahoo.com", + domain: "127.0.0.1", + privKey: jwcrypto.loadSecretKey( + require('fs').readFileSync( + path.join(__dirname, '..', 'var', 'root.secretkey'))) +}); + +suite.addBatch({ + "set things up": { + topic: function() { + primaryUser.setup(this.callback); + }, + "works": function() { + // nothing to do here + } + } +}); + +// now let's generate an assertion using this user +suite.addBatch({ + "generating an assertion": { + topic: function() { + primaryUser.getAssertion('http://127.0.0.1:10002', this.callback); + }, + "succeeds": function(err, r) { + assert.isString(r); + }, + "and logging in with the assertion succeeds": { + topic: function(err, assertion) { + wsapi.post('/wsapi/auth_with_assertion', { + assertion: assertion, + ephemeral: true + }).call(this); + }, + "works": function(err, r) { + var resp = JSON.parse(r.body); + console.log(resp); + assert.isObject(resp); + assert.isTrue(resp.success); + } + } + } +}); + start_stop.addShutdownBatches(suite); // run or export the suite. -- GitLab