summaryrefslogtreecommitdiffstats
path: root/mobile/android/modules/SSLExceptions.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/modules/SSLExceptions.jsm')
-rw-r--r--mobile/android/modules/SSLExceptions.jsm118
1 files changed, 118 insertions, 0 deletions
diff --git a/mobile/android/modules/SSLExceptions.jsm b/mobile/android/modules/SSLExceptions.jsm
new file mode 100644
index 000000000..48dfe8d92
--- /dev/null
+++ b/mobile/android/modules/SSLExceptions.jsm
@@ -0,0 +1,118 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict"
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+this.EXPORTED_SYMBOLS = ["SSLExceptions"];
+
+/**
+ A class to add exceptions to override SSL certificate problems. The functionality
+ itself is borrowed from exceptionDialog.js.
+*/
+function SSLExceptions() {
+ this._overrideService = Cc["@mozilla.org/security/certoverride;1"]
+ .getService(Ci.nsICertOverrideService);
+}
+
+
+SSLExceptions.prototype = {
+ _overrideService: null,
+ _sslStatus: null,
+
+ getInterface: function SSLE_getInterface(aIID) {
+ return this.QueryInterface(aIID);
+ },
+ QueryInterface: function SSLE_QueryInterface(aIID) {
+ if (aIID.equals(Ci.nsIBadCertListener2) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ /**
+ To collect the SSL status we intercept the certificate error here
+ and store the status for later use.
+ */
+ notifyCertProblem: function SSLE_notifyCertProblem(socketInfo, sslStatus, targetHost) {
+ this._sslStatus = sslStatus.QueryInterface(Ci.nsISSLStatus);
+ return true; // suppress error UI
+ },
+
+ /**
+ Attempt to download the certificate for the location specified to get the SSLState
+ for the certificate and the errors.
+ */
+ _checkCert: function SSLE_checkCert(aURI) {
+ this._sslStatus = null;
+
+ let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
+ try {
+ if (aURI) {
+ req.open("GET", aURI.prePath, false);
+ req.channel.notificationCallbacks = this;
+ req.send(null);
+ }
+ } catch (e) {
+ // We *expect* exceptions if there are problems with the certificate
+ // presented by the site. Log it, just in case, but we can proceed here,
+ // with appropriate sanity checks
+ Components.utils.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " +
+ "This results in a (mostly harmless) exception being thrown. " +
+ "Logged for information purposes only: " + e);
+ }
+
+ return this._sslStatus;
+ },
+
+ /**
+ Internal method to create an override.
+ */
+ _addOverride: function SSLE_addOverride(aURI, aWindow, aTemporary) {
+ let SSLStatus = this._checkCert(aURI);
+ let certificate = SSLStatus.serverCert;
+
+ let flags = 0;
+
+ // in private browsing do not store exceptions permanently ever
+ if (PrivateBrowsingUtils.isWindowPrivate(aWindow)) {
+ aTemporary = true;
+ }
+
+ if (SSLStatus.isUntrusted)
+ flags |= this._overrideService.ERROR_UNTRUSTED;
+ if (SSLStatus.isDomainMismatch)
+ flags |= this._overrideService.ERROR_MISMATCH;
+ if (SSLStatus.isNotValidAtThisTime)
+ flags |= this._overrideService.ERROR_TIME;
+
+ this._overrideService.rememberValidityOverride(
+ aURI.asciiHost,
+ aURI.port,
+ certificate,
+ flags,
+ aTemporary);
+ },
+
+ /**
+ Creates a permanent exception to override all overridable errors for
+ the given URL.
+ */
+ addPermanentException: function SSLE_addPermanentException(aURI, aWindow) {
+ this._addOverride(aURI, aWindow, false);
+ },
+
+ /**
+ Creates a temporary exception to override all overridable errors for
+ the given URL.
+ */
+ addTemporaryException: function SSLE_addTemporaryException(aURI, aWindow) {
+ this._addOverride(aURI, aWindow, true);
+ }
+};