bug 1278605 - ensure that nsICertOverrideService can be implemented in JS r?Cykesiopka draft
authorDavid Keeler <dkeeler@mozilla.com>
Tue, 07 Jun 2016 11:27:33 -0700
changeset 376387 144fa7ded6d69447f17b28dfe59ad8f2153cda47
parent 375744 d98f20c25feeac4dd7ebbd1c022957df1ef58af4
child 523138 c30a4b56314ee39f51168e7b50577445b33246c4
push id20562
push userdkeeler@mozilla.com
push dateTue, 07 Jun 2016 21:05:50 +0000
reviewersCykesiopka
bugs1278605
milestone49.0a1
bug 1278605 - ensure that nsICertOverrideService can be implemented in JS r?Cykesiopka MozReview-Commit-ID: KSVeraWuRPZ
security/manager/ssl/nsNSSCallbacks.cpp
security/manager/ssl/tests/unit/test_js_cert_override_service.js
security/manager/ssl/tests/unit/xpcshell.ini
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsNSSCallbacks.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Casting.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
+#include "mozilla/unused.h"
 #include "nsContentUtils.h"
 #include "nsICertOverrideService.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIPrompt.h"
 #include "nsISupportsPriority.h"
 #include "nsITokenDialogs.h"
 #include "nsIUploadChannel.h"
 #include "nsIWebProgressListener.h"
@@ -1227,35 +1228,27 @@ void HandshakeCallback(PRFileDesc* fd, v
   } else {
     UniqueCERTCertificate serverCert(SSL_PeerCertificate(fd));
     RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(serverCert.get()));
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
            ("HandshakeCallback using NEW cert %p\n", nssc.get()));
     status->SetServerCert(nssc, nsNSSCertificate::ev_status_unknown);
   }
 
-  nsCOMPtr<nsICertOverrideService> overrideService =
-      do_GetService(NS_CERTOVERRIDE_CONTRACTID);
-
-  if (overrideService) {
-    bool haveOverride;
-    uint32_t overrideBits = 0; // Unused.
-    bool isTemporaryOverride; // Unused.
-    const nsACString& hostString(infoObject->GetHostName());
-    const int32_t port(infoObject->GetPort());
-    nsCOMPtr<nsIX509Cert> cert;
-    status->GetServerCert(getter_AddRefs(cert));
-    nsresult nsrv = overrideService->HasMatchingOverride(hostString, port,
-                                                         cert,
-                                                         &overrideBits,
-                                                         &isTemporaryOverride,
-                                                         &haveOverride);
-    if (NS_SUCCEEDED(nsrv) && haveOverride) {
-      state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
-    }
+  bool domainMismatch;
+  bool untrusted;
+  bool notValidAtThisTime;
+  // These all return NS_OK, so don't even bother checking the return values.
+  Unused << status->GetIsDomainMismatch(&domainMismatch);
+  Unused << status->GetIsUntrusted(&untrusted);
+  Unused << status->GetIsNotValidAtThisTime(&notValidAtThisTime);
+  // If we're here, the TLS handshake has succeeded. Thus if any of these
+  // booleans are true, the user has added an override for a certificate error.
+  if (domainMismatch || untrusted || notValidAtThisTime) {
+    state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
   }
 
   infoObject->SetSecurityState(state);
 
   // XXX Bug 883674: We shouldn't be formatting messages here in PSM; instead,
   // we should set a flag on the channel that higher (UI) level code can check
   // to log the warning. In particular, these warnings should go to the web
   // console instead of to the error console. Also, the warning is not
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_js_cert_override_service.js
@@ -0,0 +1,56 @@
+/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// This test ensures that nsICertOverrideService can be implemented in JS.
+// It does so by creating and registering a mock implementation that indicates
+// a specific host ("expired.example.com") has a matching override (ERROR_TIME).
+// Connections to that host should succeed.
+
+// Mock implementation of nsICertOverrideService
+const gCertOverrideService = {
+  rememberValidityOverride() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  rememberTemporaryValidityOverrideUsingFingerprint() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  hasMatchingOverride(hostname, port, cert, overrideBits, isTemporary) {
+    Assert.equal(hostname, "expired.example.com",
+                 "hasMatchingOverride: hostname should be expired.example.com");
+    overrideBits.value = Ci.nsICertOverrideService.ERROR_TIME;
+    isTemporary.value = false;
+    return true;
+  },
+
+  getValidityOverride() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  clearValidityOverride() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  isCertUsedForOverrides() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsICertOverrideService])
+};
+
+function run_test() {
+  do_get_profile();
+  let certOverrideServiceCID =
+    MockRegistrar.register("@mozilla.org/security/certoverride;1",
+                           gCertOverrideService);
+  do_register_cleanup(() => {
+    MockRegistrar.unregister(certOverrideServiceCID);
+  });
+  add_tls_server_setup("BadCertServer", "bad_certs");
+  add_connection_test("expired.example.com", PRErrorCodeSuccess);
+  run_next_test();
+}
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -63,16 +63,18 @@ skip-if = os != 'win' # tests a Windows-
 run-sequentially = hardcoded ports
 [test_getchain.js]
 [test_hash_algorithms.js]
 [test_hash_algorithms_wrap.js]
 # bug 1124289 - run_test_in_child violates the sandbox on b2g and android
 skip-if = toolkit == 'android' || toolkit == 'gonk'
 [test_hmac.js]
 [test_intermediate_basic_usage_constraints.js]
+[test_js_cert_override_service.js]
+run-sequentially = hardcoded ports
 [test_keysize.js]
 [test_keysize_ev.js]
 # OCSP requests in this test time out on slow B2G Emulator debug builds.
 # See Bug 1147726.
 skip-if = toolkit == 'gonk' && debug
 run-sequentially = hardcoded ports
 [test_local_cert.js]
 [test_logoutAndTeardown.js]