From e0c6e7a4c72a9494004ecb6aeffb718e7472cd48 Mon Sep 17 00:00:00 2001 From: Ben Adida <ben@adida.net> Date: Mon, 2 Jul 2012 12:17:22 -0700 Subject: [PATCH] disable cert chaining for now as the spec is changing. --- lib/primary.js | 4 +++ lib/verifier/certassertion.js | 4 +++ tests/auth-with-assertion-test.js | 60 +++++++++++++++++++++++++++++-- tests/verifier-test.js | 53 +++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 2 deletions(-) diff --git a/lib/primary.js b/lib/primary.js index ad422cbf1..37c3fc809 100644 --- a/lib/primary.js +++ b/lib/primary.js @@ -275,6 +275,10 @@ exports.verifyAssertion = function(assertion, cb) { jwcrypto.cert.verifyBundle(assertion, now, getRoot, function(err, certParamsArray, payload, assertionParams) { if (err) return cb(err); + // 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/lib/verifier/certassertion.js b/lib/verifier/certassertion.js index a8342f316..1222df636 100644 --- a/lib/verifier/certassertion.js +++ b/lib/verifier/certassertion.js @@ -119,6 +119,10 @@ function verify(assertion, audience, successCB, errorCB) { }, function(err, certParamsArray, payload, assertionParams) { if (err) return errorCB(err); + // for now, to be extra safe, we don't allow cert chains + if (certParamsArray.length > 1) + return errorCB("certificate chaining is not yet allowed"); + // audience must match! var err = compareAudiences(assertionParams.audience, audience) if (err) { diff --git a/tests/auth-with-assertion-test.js b/tests/auth-with-assertion-test.js index 94a0e9ff1..d82156e74 100755 --- a/tests/auth-with-assertion-test.js +++ b/tests/auth-with-assertion-test.js @@ -15,7 +15,8 @@ db = require('../lib/db.js'), config = require('../lib/configuration.js'), http = require('http'), querystring = require('querystring'), -primary = require('./lib/primary.js'); +primary = require('./lib/primary.js'), +jwcrypto = require('jwcrypto'); var suite = vows.describe('auth-with-assertion'); @@ -26,7 +27,9 @@ start_stop.addStartupBatches(suite); const TEST_DOMAIN = 'example.domain', TEST_EMAIL = 'testuser@' + TEST_DOMAIN, - TEST_ORIGIN = 'http://127.0.0.1:10002'; + TEST_ORIGIN = 'http://127.0.0.1:10002', + OTHER_EMAIL = 'otheruser@' + TEST_DOMAIN; + // here we go! let's authenticate with an assertion from // a primary. @@ -72,6 +75,59 @@ suite.addBatch({ } }); +// now let's generate an assertion using this user +suite.addBatch({ + "generating a new intermediate keypair and then an assertion": { + topic: function() { + var expirationDate = new Date(new Date().getTime() + (2 * 60 * 1000)); + var self = this; + + jwcrypto.generateKeypair( + {algorithm: "DS", keysize: 256}, + function(err, innerKeypair) { + + // sign this innerkeypair with the key from g_cert (g_keypair) + jwcrypto.cert.sign( + innerKeypair.publicKey, {email: OTHER_EMAIL}, + {issuedAt: new Date(), expiresAt: expirationDate}, + {}, primaryUser._keyPair.secretKey, + function(err, innerCert) { + + jwcrypto.assertion.sign( + {}, + {audience: TEST_ORIGIN, expiresAt: expirationDate}, + innerKeypair.secretKey, function(err, signedObject) { + if (err) return cb(err); + + var fullAssertion = jwcrypto.cert.bundle( + [primaryUser._cert, innerCert], signedObject); + + self.callback(null, fullAssertion); + }); + + }); + }); + }, + "succeeds": function(err, assertion) { + assert.isString(assertion); + }, + "and logging in with the assertion fails": { + topic: function(err, assertion) { + wsapi.post('/wsapi/auth_with_assertion', { + assertion: assertion, + ephemeral: true + }).call(this); + }, + "fails": function(err, r) { + var resp = JSON.parse(r.body); + assert.isObject(resp); + assert.isFalse(resp.success); + assert.equal(resp.reason, "certificate chaining is not yet allowed"); + } + } + } +}); + start_stop.addShutdownBatches(suite); // run or export the suite. diff --git a/tests/verifier-test.js b/tests/verifier-test.js index c3f708acc..f6225c048 100755 --- a/tests/verifier-test.js +++ b/tests/verifier-test.js @@ -966,6 +966,59 @@ suite.addBatch({ } }); +const OTHER_EMAIL = 'otheremail@example.com'; + +// check that chained certs do not work +suite.addBatch({ + "generating an assertion with chained certs": { + topic: function() { + // primaryCert generated + // newClientKeypair generated + var expirationDate = new Date(new Date().getTime() + (2 * 60 * 1000)); + var self = this; + + jwcrypto.generateKeypair( + {algorithm: "DS", keysize: 256}, + function(err, innerKeypair) { + + // sign this innerkeypair with the key from g_cert (g_keypair) + jwcrypto.cert.sign( + innerKeypair.publicKey, {email: OTHER_EMAIL}, + {issuedAt: new Date(), expiresAt: expirationDate}, + {}, g_keypair.secretKey, + function(err, innerCert) { + jwcrypto.assertion.sign({}, {audience: TEST_ORIGIN, expiresAt: expirationDate}, + innerKeypair.secretKey, function(err, assertion) { + if (err) return self.callback(err); + + var b = jwcrypto.cert.bundle([g_cert, innerCert], + assertion); + self.callback(null, b); + }); + }); + + }); + }, + "yields a good looking assertion": function (err, assertion) { + assert.isString(assertion); + assert.equal(assertion.length > 0, true); + }, + "will cause the verifier": { + topic: function(err, assertion) { + wsapi.post('/verify', { + audience: TEST_ORIGIN, + assertion: assertion + }).call(this); + }, + "to fail": function (err, r) { + var resp = JSON.parse(r.body); + assert.strictEqual(resp.status, 'failure'); + assert.strictEqual(resp.reason, "certificate chaining is not yet allowed"); + } + } + } +}); + start_stop.addShutdownBatches(suite); // run or export the suite. -- GitLab