diff --git a/lib/browserid/primary.js b/lib/browserid/primary.js
index f2a8543d184da603b937f88bb4b4dfc33241723e..f9596c2234069533ab978ac3405f80f98ecb8332 100644
--- a/lib/browserid/primary.js
+++ b/lib/browserid/primary.js
@@ -42,7 +42,10 @@ const
 https = require('https'),
 logger = require('../logging.js').logger,
 urlparse = require('urlparse'),
-jwk = require('jwcrypto/jwk');
+jwk = require('jwcrypto/jwk'),
+jwcert = require("jwcrypto/jwcert"),
+vep = require("jwcrypto/vep"),
+jwt = require("jwcrypto/jwt");
 
 const WELL_KNOWN_URL = "/.well-known/vep";
 
@@ -170,4 +173,44 @@ if (process.env['SHIMMED_PRIMARIES']) {
   });
 }
 
+// verify an assertion generated to authenticate to browserid
+exports.verifyAssertion = function(assertion, cb) {
+  try {
+    var bundle = vep.unbundleCertsAndAssertion(assertion);
+  } catch(e) {
+    return process.nextTick(function() { cb("malformed assertion: " + e); });
+  }
 
+  jwcert.JWCert.verifyChain(
+    bundle.certificates,
+    new Date(), function(issuer, next) {
+      // issuer cannot be the browserid
+      if (issuer === config.get('hostname')) {
+        cb("cannot authenticate to browserid with a certificate issued by it.");
+      } else {
+        exports.checkSupport(issuer, function(err, rv) {
+          if (err) return cb(err);
+          var pubKey = g_cache[issuer].publicKey;
+          if (!pubKey) return cb("can't get public key for " + issuer);
+          next(pubKey);
+        });
+      }
+    }, function(pk, principal) {
+      try {
+        var tok = new jwt.JWT();
+        tok.parse(bundle.assertion);
+
+        // audience must be browserid itself
+        var want = urlparse(config.get('URL')).originOnly();
+        var got = urlparse(tok.audience).originOnly();
+
+        if (want.toString() !== got.toString()) {
+          return cb("can't log in with an assertion for '" + got.toString() + "'");
+        }
+        if (!tok.verify(pk)) throw "verification failure";
+        cb(null, principal.email);
+      } catch(e) {
+        cb("can't verify assertion: " + e.toString());
+      }
+    }, cb);
+};
\ No newline at end of file