diff --git a/lib/verifier/certassertion.js b/lib/verifier/certassertion.js
index 4e54eb943f5300be3e5c9dabaa74d1914f651b07..ac94d2ee659cfdf8879e125e9f70e7714563f242 100644
--- a/lib/verifier/certassertion.js
+++ b/lib/verifier/certassertion.js
@@ -145,36 +145,52 @@ function retrieveHostPublicKey(host, successCB, errorCB) {
 //   *got* is what was provided by the RP, so depending on their implementation
 //   it might be strangely formed.
 function compareAudiences(want, got) {
+  function normalizeParsedURL(u) {
+    if (!u.port) u.port = u.protocol === 'https:' ? 443 : 80;
+    return u;
+  }
+
   try {
-    var checkHostOnly = false;
-
-    // issue #82 - for a limited time, let's allow got to be sloppy and omit scheme
-    // in which case we guess a scheme based on port
-    if (!/^https?:\/\//.test(got)) {
-      var x = got.split(':');
-      var scheme = "http";
-      if (x.length === 2 && x[1] === '443') scheme = "https";
-      got = scheme + "://" + got;
-      checkHostOnly = true;
+    var got_scheme, got_domain, got_port;
+
+    // We allow the RP to provide audience in multiple forms (see issue #82).
+    // The RP SHOULD provide full origin, but we allow these alternate forms for
+    // some dude named Postel doesn't go postal.
+    // 1. full origin 'http://rp.tld'
+    // 1a. full origin with port 'http://rp.tld:8080'
+    // 2. domain and port 'rp.tld:8080'
+    // 3. domain only 'rp.tld'
+
+    // case 1 & 1a
+    if (/^https?:\/\//.test(got)) {
+      var gu = normalizeParsedURL(url.parse(got));
+      got_scheme = gu.protocol;
+      got_domain = gu.hostname;
+      got_port = gu.port;
     }
-
-    // now parse and compare
-    function normalizeParsedURL(u) {
-      if (!u.port) u.port = u.protocol === 'https:' ? 443 : 80;
-      return u;
+    // case 2
+    else if (got.indexOf(':') != -1) {
+      var p = got.split(':');
+      if (p.length !== 2) throw "malformed domain";
+      got_domain = p[0];
+      got_port = p[1];
+    }
+    // case 3
+    else {
+      got_domain = got;
     }
 
+    // now parse "want" url
     want = normalizeParsedURL(url.parse(want));
 
-    got = normalizeParsedURL(url.parse(got));
-
-    if (checkHostOnly) return want.hostname === got.hostname;
+    // compare the parts explicitly provided by the client
+    if (got_scheme && got_scheme != want.protocol) throw "scheme mismatch"
+    if (got_port && got_port != want.port) throw "port mismatch"
+    if (got_domain && got_domain != want.hostname) throw "domain mismatch"
 
-    return (want.protocol === got.protocol &&
-            want.hostname === got.hostname &&
-            want.port == got.port);
+    return undefined;
   } catch(e) {
-    return false;
+    return e.toString();
   }
 }
 
@@ -211,10 +227,11 @@ function verify(assertion, audience, successCB, errorCB, pkRetriever) {
       tok.parse(bundle.assertion);
 
       // audience must match!
-      if (!compareAudiences(tok.audience, audience)) {
+      var err = compareAudiences(tok.audience, audience)
+      if (err) {
         logger.debug("verification failure, audience mismatch: '"
-                     + tok.audience + "' != '" + audience + "'");
-        return errorCB("audience mismatch");
+                     + tok.audience + "' != '" + audience + "': " + err);
+        return errorCB("audience mismatch: " + err);
       }
 
       if (tok.verify(pk)) {
diff --git a/tests/verifier-test.js b/tests/verifier-test.js
index 4854fc11851df6be08570b7badee3cca765c5dd2..5943e3a3471ab21531da4729ab66bda854d5fb2d 100755
--- a/tests/verifier-test.js
+++ b/tests/verifier-test.js
@@ -198,7 +198,7 @@ suite.addBatch({
       "fails with a nice error": function(r, err) {
         var resp = JSON.parse(r.body);
         assert.strictEqual(resp.status, 'failure');
-        assert.strictEqual(resp.reason, 'audience mismatch');
+        assert.strictEqual(resp.reason, 'audience mismatch: domain mismatch');
       }
     },
     "but specifying the wrong port": {
@@ -211,7 +211,7 @@ suite.addBatch({
       "fails with a nice error": function(r, err) {
         var resp = JSON.parse(r.body);
         assert.strictEqual(resp.status, 'failure');
-        assert.strictEqual(resp.reason, 'audience mismatch');
+        assert.strictEqual(resp.reason, 'audience mismatch: port mismatch');
       }
     },
     "but specifying the wrong scheme": {
@@ -224,7 +224,7 @@ suite.addBatch({
       "fails with a nice error": function(r, err) {
         var resp = JSON.parse(r.body);
         assert.strictEqual(resp.status, 'failure');
-        assert.strictEqual(resp.reason, 'audience mismatch');
+        assert.strictEqual(resp.reason, 'audience mismatch: scheme mismatch');
       }
     },
     "and providing just a domain and port": {
@@ -256,7 +256,7 @@ suite.addBatch({
       "fails as you would expect": function(r, err) {
         var resp = JSON.parse(r.body);
         assert.strictEqual(resp.status, 'failure');
-        assert.strictEqual(resp.reason, 'audience mismatch');
+        assert.strictEqual(resp.reason, 'audience mismatch: port mismatch');
       }
     },
     "leaving off the audience": {