Bug 1468222 Consolidate nsISSLStatus info nsITransportSecurityInfo r=Gijs,snorp,jcj,mcmanus,sfraser,keeler,baku,ato
authorDipen Patel <bugzilla@pansara.org>
Tue, 11 Sep 2018 00:07:30 +0000
changeset 435582 5cfda4227c6a2301c05900ee40d710b2324fb4a9
parent 435581 771b94d5ab5c7a5b0a42233bc2cc3b1b11553672
child 435583 c661bb000e34e56ab7780ff6053e0dd628dfc0e2
push id34615
push usercsabou@mozilla.com
push dateTue, 11 Sep 2018 10:05:56 +0000
treeherdermozilla-central@cb28a4b17303 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, snorp, jcj, mcmanus, sfraser, keeler, baku, ato
bugs1468222
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1468222 Consolidate nsISSLStatus info nsITransportSecurityInfo r=Gijs,snorp,jcj,mcmanus,sfraser,keeler,baku,ato Move all fields of nsISSLStatus to nsITransportSecurityProvider Remove nsISSLStatus interface and definition Update all code and test references to nsISSLStatus Maintain ability to read in older version of serialized nsISSLStatus. This is verified with psm_DeserializeCert gtest. Differential Revision: https://phabricator.services.mozilla.com/D3704
browser/base/content/browser-siteIdentity.js
browser/base/content/browser.js
browser/base/content/pageinfo/security.js
devtools/shared/security/auth.js
devtools/shared/security/socket.js
devtools/shared/webconsole/network-helper.js
devtools/shared/webconsole/test/unit/test_security-info-parser.js
devtools/shared/webconsole/test/unit/test_security-info-state.js
devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
dom/push/test/xpcshell/head-http2.js
mobile/android/chrome/content/browser.js
mobile/android/chrome/content/content.js
mobile/android/modules/SSLExceptions.jsm
mobile/android/modules/geckoview/GeckoViewProgress.jsm
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpNTLMAuth.cpp
netwerk/socket/nsITransportSecurityInfo.idl
netwerk/test/unit/test_http2.js
security/manager/pki/resources/content/exceptionDialog.js
security/manager/ssl/SSLServerCertVerification.cpp
security/manager/ssl/TransportSecurityInfo.cpp
security/manager/ssl/TransportSecurityInfo.h
security/manager/ssl/moz.build
security/manager/ssl/nsIBadCertListener2.idl
security/manager/ssl/nsISSLStatus.idl
security/manager/ssl/nsISiteSecurityService.idl
security/manager/ssl/nsNSSCallbacks.cpp
security/manager/ssl/nsNSSIOLayer.cpp
security/manager/ssl/nsNSSIOLayer.h
security/manager/ssl/nsNSSModule.cpp
security/manager/ssl/nsSSLStatus.cpp
security/manager/ssl/nsSSLStatus.h
security/manager/ssl/nsSecureBrowserUIImpl.cpp
security/manager/ssl/nsSiteSecurityService.cpp
security/manager/ssl/nsSiteSecurityService.h
security/manager/ssl/tests/gtest/DeserializeCertTest.cpp
security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
security/manager/ssl/tests/unit/head_psm.js
security/manager/ssl/tests/unit/test_cert_overrides_read_only.js
security/manager/ssl/tests/unit/test_ct.js
security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js
security/manager/ssl/tests/unit/test_ocsp_must_staple.js
security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js
security/manager/ssl/tests/unit/test_pinning_header_parsing.js
security/manager/ssl/tests/unit/test_session_resumption.js
security/manager/ssl/tests/unit/test_ssl_status.js
security/manager/ssl/tests/unit/test_sss_enumerate.js
security/manager/ssl/tests/unit/test_sss_eviction.js
security/manager/ssl/tests/unit/test_sss_originAttributes.js
security/manager/ssl/tests/unit/test_sss_savestate.js
security/manager/ssl/tests/unit/test_sts_fqdn.js
security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js
security/manager/ssl/tests/unit/test_sts_parser.js
security/manager/ssl/tests/unit/test_sts_preload_dynamic.js
security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js
services/common/rest.js
taskcluster/docker/periodic-updates/scripts/getHSTSPreloadList.js
testing/marionette/puppeteer/firefox/firefox_puppeteer/api/security.py
toolkit/components/extensions/webrequest/ChannelWrapper.cpp
toolkit/modules/CertUtils.jsm
toolkit/modules/addons/SecurityInfo.jsm
toolkit/modules/tests/chrome/test_bug544442_checkCert.xul
toolkit/mozapps/extensions/test/browser/head.js
toolkit/mozapps/update/nsUpdateService.js
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -30,20 +30,20 @@ var gIdentityHandler = {
    * Whether this._uri refers to an internally implemented browser page.
    *
    * Note that this is set for some "about:" pages, but general "chrome:" URIs
    * are not included in this category by default.
    */
   _isSecureInternalUI: false,
 
   /**
-   * nsISSLStatus metadata provided by gBrowser.securityUI the last time the
-   * identity UI was updated, or null if the connection is not secure.
+   * nsITransportSecurityInfo metadata provided by gBrowser.securityUI the last
+   * time the identity UI was updated, or null if the connection is not secure.
    */
-  _sslStatus: null,
+  _secInfo: null,
 
   /**
    * Bitmask provided by nsIWebProgressListener.onSecurityChange.
    */
   _state: 0,
 
   /**
    * RegExp used to decide if an about url should be shown as being part of
@@ -292,22 +292,22 @@ var gIdentityHandler = {
     let host = this._uri.host;
     let port = this._uri.port > 0 ? this._uri.port : 443;
     this._overrideService.clearValidityOverride(host, port);
     BrowserReloadSkipCache();
     PanelMultiView.hidePopup(this._identityPopup);
   },
 
   /**
-   * Helper to parse out the important parts of _sslStatus (of the SSL cert in
+   * Helper to parse out the important parts of _secInfo (of the SSL cert in
    * particular) for use in constructing identity UI strings
   */
   getIdentityData() {
     var result = {};
-    var cert = this._sslStatus.serverCert;
+    var cert = this._secInfo.serverCert;
 
     // Human readable name of Subject
     result.subjectOrg = cert.organization;
 
     // SubjectName fields, broken up for individual access
     if (cert.subjectName) {
       result.subjectNameFields = {};
       cert.subjectName.split(",").forEach(function(v) {
@@ -342,18 +342,17 @@ var gIdentityHandler = {
    */
   updateIdentity(state, uri) {
     let shouldHidePopup = this._uri && (this._uri.spec != uri.spec);
     this._state = state;
 
     // Firstly, populate the state properties required to display the UI. See
     // the documentation of the individual properties for details.
     this.setURI(uri);
-    this._sslStatus = gBrowser.securityUI.secInfo &&
-                      gBrowser.securityUI.secInfo.SSLStatus;
+    this._secInfo = gBrowser.securityUI.secInfo;
 
     // Then, update the user interface with the available data.
     this.refreshIdentityBlock();
     // Handle a location change while the Control Center is focused
     // by closing the popup (bug 1207542)
     if (shouldHidePopup) {
       PanelMultiView.hidePopup(this._identityPopup);
     }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2959,43 +2959,41 @@ var BrowserOnClick = {
         goBackFromErrorPage();
       break;
     }
   },
 
   onCertError(browser, elementId, isTopFrame, location, securityInfoAsString, frameId) {
     let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
     let securityInfo;
-    let sslStatus;
 
     switch (elementId) {
       case "exceptionDialogButton":
         if (isTopFrame) {
           secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION);
         }
 
         securityInfo = getSecurityInfo(securityInfoAsString);
-        sslStatus = securityInfo.SSLStatus;
         let params = { exceptionAdded: false,
-                       sslStatus };
+                       securityInfo };
         if (Services.prefs.getBoolPref("browser.security.newcerterrorpage.enabled", false)) {
           let overrideService = Cc["@mozilla.org/security/certoverride;1"]
                                   .getService(Ci.nsICertOverrideService);
           let flags = 0;
-          if (sslStatus.isUntrusted) {
+          if (securityInfo.isUntrusted) {
             flags |= overrideService.ERROR_UNTRUSTED;
           }
-          if (sslStatus.isDomainMismatch) {
+          if (securityInfo.isDomainMismatch) {
             flags |= overrideService.ERROR_MISMATCH;
           }
-          if (sslStatus.isNotValidAtThisTime) {
+          if (securityInfo.isNotValidAtThisTime) {
             flags |= overrideService.ERROR_TIME;
           }
           let uri = Services.uriFixup.createFixupURI(location, 0);
-          let cert = sslStatus.serverCert;
+          let cert = securityInfo.serverCert;
           overrideService.rememberValidityOverride(
             uri.asciiHost, uri.port,
             cert,
             flags,
             true);
           browser.reload();
           return;
         }
@@ -3033,35 +3031,34 @@ var BrowserOnClick = {
 
       case "advancedButton":
       case "moreInformationButton":
         if (isTopFrame) {
           secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS);
         }
 
         securityInfo = getSecurityInfo(securityInfoAsString);
-        sslStatus = securityInfo.SSLStatus;
         let errorInfo = getDetailedCertErrorInfo(location,
                                                  securityInfo);
         let validityInfo = {
-          notAfter: sslStatus.serverCert.validity.notAfter,
-          notBefore: sslStatus.serverCert.validity.notBefore,
-          notAfterLocalTime: sslStatus.serverCert.validity.notAfterLocalTime,
-          notBeforeLocalTime: sslStatus.serverCert.validity.notBeforeLocalTime,
+          notAfter: securityInfo.serverCert.validity.notAfter,
+          notBefore: securityInfo.serverCert.validity.notBefore,
+          notAfterLocalTime: securityInfo.serverCert.validity.notAfterLocalTime,
+          notBeforeLocalTime: securityInfo.serverCert.validity.notBeforeLocalTime,
         };
         browser.messageManager.sendAsyncMessage("CertErrorDetails", {
             code: securityInfo.errorCode,
             info: errorInfo,
             codeString: securityInfo.errorCodeString,
-            certIsUntrusted: sslStatus.isUntrusted,
-            certSubjectAltNames: sslStatus.serverCert.subjectAltNames,
+            certIsUntrusted: securityInfo.isUntrusted,
+            certSubjectAltNames: securityInfo.serverCert.subjectAltNames,
             validity: validityInfo,
             url: location,
-            isDomainMismatch: sslStatus.isDomainMismatch,
-            isNotValidAtThisTime: sslStatus.isNotValidAtThisTime,
+            isDomainMismatch: securityInfo.isDomainMismatch,
+            isNotValidAtThisTime: securityInfo.isNotValidAtThisTime,
             frameId,
         });
         break;
 
       case "copyToClipboard":
         const gClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"]
                                     .getService(Ci.nsIClipboardHelper);
         securityInfo = getSecurityInfo(securityInfoAsString);
--- a/browser/base/content/pageinfo/security.js
+++ b/browser/base/content/pageinfo/security.js
@@ -22,18 +22,16 @@ var security = {
 
   // Display the server certificate (static)
   viewCert() {
     var cert = security._cert;
     viewCertHelper(window, cert);
   },
 
   _getSecurityInfo() {
-    const nsISSLStatus = Ci.nsISSLStatus;
-
     // We don't have separate info for a frame, return null until further notice
     // (see bug 138479)
     if (!this.windowInfo.isTopWindow)
       return null;
 
     var hostName = this.windowInfo.hostName;
 
     var ui = security._getSecurityUI();
@@ -44,20 +42,20 @@ var security = {
       (ui.state & Ci.nsIWebProgressListener.STATE_IS_BROKEN);
     var isMixed =
       (ui.state & (Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT |
                    Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT));
     var isInsecure =
       (ui.state & Ci.nsIWebProgressListener.STATE_IS_INSECURE);
     var isEV =
       (ui.state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL);
-    var status = ui.secInfo && ui.secInfo.SSLStatus;
+    var secInfo = ui.secInfo;
 
-    if (!isInsecure && status) {
-      var cert = status.serverCert;
+    if (!isInsecure && secInfo) {
+      var cert = secInfo.serverCert;
       var issuerName = cert.issuerOrganization || cert.issuerName;
 
       var retval = {
         hostName,
         cAName: issuerName,
         encryptionAlgorithm: undefined,
         encryptionStrength: undefined,
         version: undefined,
@@ -65,51 +63,55 @@ var security = {
         isMixed,
         isEV,
         cert,
         certificateTransparency: undefined,
       };
 
       var version;
       try {
-        retval.encryptionAlgorithm = status.cipherName;
-        retval.encryptionStrength = status.secretKeyLength;
-        version = status.protocolVersion;
+        retval.encryptionAlgorithm = secInfo.cipherName;
+        retval.encryptionStrength = secInfo.secretKeyLength;
+        version = secInfo.protocolVersion;
       } catch (e) {
       }
 
       switch (version) {
-        case nsISSLStatus.SSL_VERSION_3:
+        case Ci.nsITransportSecurityInfo.SSL_VERSION_3:
           retval.version = "SSL 3";
           break;
-        case nsISSLStatus.TLS_VERSION_1:
+        case Ci.nsITransportSecurityInfo.TLS_VERSION_1:
           retval.version = "TLS 1.0";
           break;
-        case nsISSLStatus.TLS_VERSION_1_1:
+        case Ci.nsITransportSecurityInfo.TLS_VERSION_1_1:
           retval.version = "TLS 1.1";
           break;
-        case nsISSLStatus.TLS_VERSION_1_2:
+        case Ci.nsITransportSecurityInfo.TLS_VERSION_1_2:
           retval.version = "TLS 1.2";
           break;
-        case nsISSLStatus.TLS_VERSION_1_3:
+        case Ci.nsITransportSecurityInfo.TLS_VERSION_1_3:
           retval.version = "TLS 1.3";
           break;
       }
 
       // Select the status text to display for Certificate Transparency.
       // Since we do not yet enforce the CT Policy on secure connections,
       // we must not complain on policy discompliance (it might be viewed
       // as a security issue by the user).
-      switch (status.certificateTransparencyStatus) {
-        case nsISSLStatus.CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE:
-        case nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS:
-        case nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS:
+      switch (secInfo.certificateTransparencyStatus) {
+        case Ci.nsITransportSecurityInfo.
+                CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE:
+        case Ci.nsITransportSecurityInfo.
+                CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS:
+        case Ci.nsITransportSecurityInfo.
+                CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS:
           retval.certificateTransparency = null;
           break;
-        case nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT:
+        case Ci.nsITransportSecurityInfo.
+                CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT:
           retval.certificateTransparency = "Compliant";
           break;
       }
 
       return retval;
     }
     return {
       hostName,
--- a/devtools/shared/security/auth.js
+++ b/devtools/shared/security/auth.js
@@ -295,18 +295,19 @@ OOBCert.Client.prototype = {
    *         Whether the connection is valid.
    */
   // eslint-disable-next-line no-shadow
   validateConnection({ cert, socket }) {
     // Step B.7
     // Client verifies that Server's cert matches hash(ServerCert) from the
     // advertisement
     dumpv("Validate server cert hash");
-    const serverCert = socket.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
-                           .SSLStatus.serverCert;
+    const serverCert = socket.securityInfo
+                             .QueryInterface(Ci.nsITransportSecurityInfo)
+                             .serverCert;
     const advertisedCert = cert;
     if (serverCert.sha256Fingerprint != advertisedCert.sha256) {
       dumpn("Server cert hash doesn't match advertisement");
       return false;
     }
     return true;
   },
 
--- a/devtools/shared/security/socket.js
+++ b/devtools/shared/security/socket.js
@@ -349,17 +349,17 @@ function _isInputAlive(input) {
 /**
  * To allow the connection to proceed with self-signed cert, we store a cert
  * override.  This implies that we take on the burden of authentication for
  * these connections.
  */
 function _storeCertOverride(s, host, port) {
   // eslint-disable-next-line no-shadow
   const cert = s.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
-              .SSLStatus.serverCert;
+                             .serverCert;
   const overrideBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED |
                      Ci.nsICertOverrideService.ERROR_MISMATCH;
   certOverrideService.rememberValidityOverride(host, port, cert, overrideBits,
                                                true /* temporary */);
 }
 
 /**
  * Creates a new socket listener for remote connections to the DebuggerServer.
--- a/devtools/shared/webconsole/network-helper.js
+++ b/devtools/shared/webconsole/network-helper.js
@@ -583,17 +583,16 @@ var NetworkHelper = {
      *      => state === "weak"
      */
 
     securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
 
     const wpl = Ci.nsIWebProgressListener;
     const NSSErrorsService = Cc["@mozilla.org/nss_errors_service;1"]
                                .getService(Ci.nsINSSErrorsService);
-    const SSLStatus = securityInfo.SSLStatus;
     if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
       const state = securityInfo.securityState;
 
       let uri = null;
       if (httpActivity.channel && httpActivity.channel.URI) {
         uri = httpActivity.channel.URI;
       }
       if (uri && !uri.schemeIs("https") && !uri.schemeIs("wss")) {
@@ -616,33 +615,33 @@ var NetworkHelper = {
         return info;
       } else {
         DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo",
           "Security state " + state + " has no known STATE_IS_* flags.");
         return info;
       }
 
       // Cipher suite.
-      info.cipherSuite = SSLStatus.cipherName;
+      info.cipherSuite = securityInfo.cipherName;
 
       // Key exchange group name.
-      info.keaGroupName = SSLStatus.keaGroupName;
+      info.keaGroupName = securityInfo.keaGroupName;
 
       // Certificate signature scheme.
-      info.signatureSchemeName = SSLStatus.signatureSchemeName;
+      info.signatureSchemeName = securityInfo.signatureSchemeName;
 
       // Protocol version.
       info.protocolVersion =
-        this.formatSecurityProtocol(SSLStatus.protocolVersion);
+        this.formatSecurityProtocol(securityInfo.protocolVersion);
 
       // Certificate.
-      info.cert = this.parseCertificateInfo(SSLStatus.serverCert);
+      info.cert = this.parseCertificateInfo(securityInfo.serverCert);
 
       // Certificate transparency status.
-      info.certificateTransparency = SSLStatus.certificateTransparencyStatus;
+      info.certificateTransparency = securityInfo.certificateTransparencyStatus;
 
       // HSTS and HPKP if available.
       if (httpActivity.hostname) {
         const sss = Cc["@mozilla.org/ssservice;1"]
                       .getService(Ci.nsISiteSecurityService);
 
         // SiteSecurityService uses different storage if the channel is
         // private. Thus we must give isSecureURI correct flags or we
@@ -715,34 +714,34 @@ var NetworkHelper = {
       DevToolsUtils.reportException("NetworkHelper.parseCertificateInfo",
         "Secure connection established without certificate.");
     }
 
     return info;
   },
 
   /**
-   * Takes protocolVersion of SSLStatus object and returns human readable
-   * description.
+   * Takes protocolVersion of TransportSecurityInfo object and returns
+   * human readable description.
    *
    * @param Number version
-   *        One of nsISSLStatus version constants.
+   *        One of nsITransportSecurityInfo version constants.
    * @return string
    *         One of TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 if @param version
    *         is valid, Unknown otherwise.
    */
   formatSecurityProtocol: function(version) {
     switch (version) {
-      case Ci.nsISSLStatus.TLS_VERSION_1:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1:
         return "TLSv1";
-      case Ci.nsISSLStatus.TLS_VERSION_1_1:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1_1:
         return "TLSv1.1";
-      case Ci.nsISSLStatus.TLS_VERSION_1_2:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1_2:
         return "TLSv1.2";
-      case Ci.nsISSLStatus.TLS_VERSION_1_3:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1_3:
         return "TLSv1.3";
       default:
         DevToolsUtils.reportException("NetworkHelper.formatSecurityProtocol",
           "protocolVersion " + version + " is unknown.");
         return "Unknown";
     }
   },
 
--- a/devtools/shared/webconsole/test/unit/test_security-info-parser.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-parser.js
@@ -31,30 +31,28 @@ const MockCertificate = {
     notAfterLocalDay: "tomorrow",
   }
 };
 
 const MockSecurityInfo = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsITransportSecurityInfo]),
   securityState: wpl.STATE_IS_SECURE,
   errorCode: 0,
-  SSLStatus: {
-    cipherSuite: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
-    // TLS_VERSION_1_2
-    protocolVersion: 3,
-    serverCert: MockCertificate,
-  }
+  cipherName: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
+  // TLS_VERSION_1_2
+  protocolVersion: 3,
+  serverCert: MockCertificate,
 };
 
 function run_test() {
   const result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
 
   equal(result.state, "secure", "State is correct.");
 
-  equal(result.cipherSuite, MockSecurityInfo.cipherSuite,
+  equal(result.cipherSuite, MockSecurityInfo.cipherName,
     "Cipher suite is correct.");
 
   equal(result.protocolVersion, "TLSv1.2", "Protocol version is correct.");
 
   deepEqual(result.cert, NetworkHelper.parseCertificateInfo(MockCertificate),
     "Certificate information is correct.");
 
   equal(result.hpkp, false, "HPKP is false when URI is not available.");
--- a/devtools/shared/webconsole/test/unit/test_security-info-state.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-state.js
@@ -17,21 +17,19 @@ Object.defineProperty(this, "NetworkHelp
   enumerable: true
 });
 
 const wpl = Ci.nsIWebProgressListener;
 const MockSecurityInfo = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsITransportSecurityInfo]),
   securityState: wpl.STATE_IS_BROKEN,
   errorCode: 0,
-  SSLStatus: {
-    // nsISSLStatus.TLS_VERSION_1_2
-    protocolVersion: 3,
-    cipherSuite: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
-  }
+  // nsISSLStatus.TLS_VERSION_1_2
+  protocolVersion: 3,
+  cipherName: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
 };
 
 function run_test() {
   test_nullSecurityInfo();
   test_insecureSecurityInfoWithNSSError();
   test_insecureSecurityInfoWithoutNSSError();
   test_brokenSecurityInfo();
   test_secureSecurityInfo();
--- a/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
+++ b/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js
@@ -18,23 +18,21 @@ Object.defineProperty(this, "NetworkHelp
 });
 
 const wpl = Ci.nsIWebProgressListener;
 
 const MockSecurityInfo = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsITransportSecurityInfo]),
   securityState: wpl.STATE_IS_SECURE,
   errorCode: 0,
-  SSLStatus: {
-    cipherSuite: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
-    // TLS_VERSION_1_2
-    protocolVersion: 3,
-    serverCert: {
-      validity: {}
-    },
+  cipherName: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
+  // TLS_VERSION_1_2
+  protocolVersion: 3,
+  serverCert: {
+    validity: {}
   }
 };
 
 const MockHttpInfo = {
   hostname: "include-subdomains.pinning.example.com",
   private: false,
 };
 
--- a/dom/push/test/xpcshell/head-http2.js
+++ b/dom/push/test/xpcshell/head-http2.js
@@ -28,18 +28,18 @@ CertOverrideListener.prototype = {
   QueryInterface: function(aIID) {
     if (aIID.equals(Ci.nsIBadCertListener2) ||
         aIID.equals(Ci.nsIInterfaceRequestor) ||
         aIID.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 
-  notifyCertProblem: function(socketInfo, sslStatus, targetHost) {
-    var cert = sslStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
+  notifyCertProblem: function(socketInfo, secInfo, targetHost) {
+    var cert = secInfo.serverCert;
     var cos = Cc["@mozilla.org/security/certoverride;1"].
               getService(Ci.nsICertOverrideService);
     cos.rememberValidityOverride(this.host, this.port, cert, this.bits, false);
     dump("Certificate Override in place\n");
     return true;
   },
 };
 
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -5563,28 +5563,28 @@ var IdentityHandler = {
   TRACKING_MODE_UNKNOWN: "unknown",
 
   // Blocked active tracking content. Shield icon is shown, with a popup option to load content.
   TRACKING_MODE_CONTENT_BLOCKED: "tracking_content_blocked",
 
   // Loaded active tracking content. Yellow triangle icon is shown.
   TRACKING_MODE_CONTENT_LOADED: "tracking_content_loaded",
 
-  // Cache the most recent SSLStatus and Location seen in getIdentityStrings
-  _lastStatus : null,
+  // Cache the most recent TransportSecurityInfo and Location seen in
+  // getIdentityStrings
+  _lastSecInfo : null,
   _lastLocation : null,
 
   /**
-   * Helper to parse out the important parts of _lastStatus (of the SSL cert in
+   * Helper to parse out the important parts of _lastSecInfo (of the SSL cert in
    * particular) for use in constructing identity UI strings
   */
   getIdentityData : function() {
     let result = {};
-    let status = this._lastStatus.QueryInterface(Ci.nsISSLStatus);
-    let cert = status.serverCert;
+    let cert = this._lastSecInfo.serverCert;
 
     // Human readable name of Subject
     result.subjectOrg = cert.organization;
 
     // SubjectName fields, broken up for individual access
     if (cert.subjectName) {
       result.subjectNameFields = {};
       cert.subjectName.split(",").forEach(function(v) {
@@ -5678,18 +5678,17 @@ var IdentityHandler = {
     Telemetry.addData("TRACKING_PROTECTION_SHIELD", value);
   },
 
   /**
    * Determine the identity of the page being displayed by examining its SSL cert
    * (if available). Return the data needed to update the UI.
    */
   checkIdentity: function checkIdentity(aState, aBrowser) {
-    this._lastStatus = aBrowser.securityUI.secInfo &&
-                       aBrowser.securityUI.secInfo.SSLStatus;
+    this._lastSecInfo = aBrowser.securityUI.secInfo;
 
     // Don't pass in the actual location object, since it can cause us to
     // hold on to the window object too long.  Just pass in the fields we
     // care about. (bug 424829)
     let locationObj = {};
     try {
       let location = aBrowser.contentWindow.location;
       locationObj.host = location.host;
--- a/mobile/android/chrome/content/content.js
+++ b/mobile/android/chrome/content/content.js
@@ -176,22 +176,22 @@ var AboutCertErrorListener = {
   init(chromeGlobal) {
     addEventListener("AboutCertErrorLoad", this, false, true);
   },
 
   get isCertErrorSite() {
     return content.document.documentURI.startsWith("about:certerror");
   },
 
-  _setTechDetailsMsgPart1(hostString, sslStatus, securityInfo, technicalInfo, doc) {
+  _setTechDetailsMsgPart1(hostString, securityInfo, technicalInfo, doc) {
     let msg = gPipNSSBundle.formatStringFromName("certErrorIntro",
                                                  [hostString], 1);
     msg += "\n\n";
 
-    if (sslStatus.isUntrusted && !sslStatus.serverCert.isSelfSigned) {
+    if (securityInfo.isUntrusted && !securityInfo.serverCert.isSelfSigned) {
       switch (securityInfo.errorCode) {
         case SEC_ERROR_UNKNOWN_ISSUER:
           msg += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer") + "\n";
           msg += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer2") + "\n";
           msg += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer3") + "\n";
           break;
         case SEC_ERROR_CA_CERT_INVALID:
           msg += gPipNSSBundle.GetStringFromName("certErrorTrust_CaInvalid") + "\n";
@@ -210,28 +210,28 @@ var AboutCertErrorListener = {
         case MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
           msg += gPipNSSBundle.formatStringFromName("certErrorTrust_Symantec", [hostString], 1) + "\n";
           break;
         case SEC_ERROR_UNTRUSTED_CERT:
         default:
           msg += gPipNSSBundle.GetStringFromName("certErrorTrust_Untrusted") + "\n";
       }
     }
-    if (sslStatus.isUntrusted && sslStatus.serverCert.isSelfSigned) {
+    if (securityInfo.isUntrusted && securityInfo.serverCert.isSelfSigned) {
       msg += gPipNSSBundle.GetStringFromName("certErrorTrust_SelfSigned") + "\n";
     }
 
     technicalInfo.appendChild(doc.createTextNode(msg));
   },
 
-  _setTechDetails(sslStatus, securityInfo, location) {
-    if (!securityInfo || !sslStatus || !location) {
+  _setTechDetails(securityInfo, location) {
+    if (!securityInfo || !location) {
       return;
     }
-    let validity = sslStatus.serverCert.validity;
+    let validity = securityInfo.serverCert.validity;
 
     let doc = content.document;
     // CSS class and error code are set from nsDocShell.
     let searchParams = new URLSearchParams(doc.documentURI.split("?")[1]);
     let cssClass = searchParams.get("s");
     let error = searchParams.get("e");
     let technicalInfo = doc.getElementById("technicalContentText");
 
@@ -253,20 +253,20 @@ var AboutCertErrorListener = {
         "certErrorSymantecDistrustDescription", [hostString], 1);
       introContent.append(description);
 
       // The regular "what should I do" message does not make sense in this case.
       doc.getElementById("whatShouldIDoContentText").textContent =
         gPipNSSBundle.GetStringFromName("certErrorSymantecDistrustAdministrator");
     }
 
-    this._setTechDetailsMsgPart1(hostString, sslStatus, securityInfo, technicalInfo, doc);
+    this._setTechDetailsMsgPart1(hostString, securityInfo, technicalInfo, doc);
 
-    if (sslStatus.isDomainMismatch) {
-      let subjectAltNamesList = sslStatus.serverCert.subjectAltNames;
+    if (securityInfo.isDomainMismatch) {
+      let subjectAltNamesList = securityInfo.serverCert.subjectAltNames;
       let subjectAltNames = subjectAltNamesList.split(",");
       let numSubjectAltNames = subjectAltNames.length;
       let msgPrefix = "";
       if (numSubjectAltNames != 0) {
         if (numSubjectAltNames == 1) {
           msgPrefix = gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix");
 
           // Let's check if we want to make this a link.
@@ -338,17 +338,17 @@ var AboutCertErrorListener = {
         }
       } else {
         let msg = gPipNSSBundle.formatStringFromName("certErrorMismatch",
                                                     [hostString], 1);
         technicalInfo.append(msg + "\n");
       }
     }
 
-    if (sslStatus.isNotValidAtThisTime) {
+    if (securityInfo.isNotValidAtThisTime) {
       let nowTime = new Date().getTime() * 1000;
       let dateOptions = { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric" };
       let now = new Services.intl.DateTimeFormat(undefined, dateOptions).format(new Date());
       let msg = "";
       if (validity.notBefore) {
         if (nowTime > validity.notAfter) {
           msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow",
                                                    [validity.notAfterLocalTime, now], 2) + "\n";
@@ -379,18 +379,17 @@ var AboutCertErrorListener = {
     if (aEvent.type != "AboutCertErrorLoad") {
       return;
     }
 
     let ownerDoc = aEvent.originalTarget.ownerGlobal;
     let securityInfo = docShell.failedChannel && docShell.failedChannel.securityInfo;
     securityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
                 .QueryInterface(Ci.nsISerializable);
-    let sslStatus = securityInfo.SSLStatus;
-    this._setTechDetails(sslStatus, securityInfo, ownerDoc.location.href);
+    this._setTechDetails(securityInfo, ownerDoc.location.href);
   },
 };
 AboutCertErrorListener.init();
 
 // This is copied from desktop's tab-content.js. See bug 1153485 about sharing this code somehow.
 var AboutReaderListener = {
 
   _articlePromise: null,
--- a/mobile/android/modules/SSLExceptions.jsm
+++ b/mobile/android/modules/SSLExceptions.jsm
@@ -17,38 +17,40 @@ var EXPORTED_SYMBOLS = ["SSLExceptions"]
 function SSLExceptions() {
   this._overrideService = Cc["@mozilla.org/security/certoverride;1"]
                           .getService(Ci.nsICertOverrideService);
 }
 
 
 SSLExceptions.prototype = {
   _overrideService: null,
-  _sslStatus: null,
+  _secInfo: null,
 
   getInterface: function SSLE_getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
   QueryInterface: ChromeUtils.generateQI(["nsIBadCertListener2"]),
 
   /**
     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);
+  notifyCertProblem: function SSLE_notifyCertProblem(socketInfo,
+                                                     secInfo,
+                                                     targetHost) {
+    this._secInfo = secInfo;
     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;
+    this._secInfo = null;
 
     let req = new XMLHttpRequest();
     try {
       if (aURI) {
         req.open("GET", aURI.prePath, false);
         req.channel.notificationCallbacks = this;
         req.send(null);
       }
@@ -56,38 +58,38 @@ SSLExceptions.prototype = {
       // 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
       Cu.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;
+    return this._secInfo;
   },
 
   /**
     Internal method to create an override.
   */
   _addOverride: function SSLE_addOverride(aURI, aWindow, aTemporary) {
-    let SSLStatus = this._checkCert(aURI);
-    let certificate = SSLStatus.serverCert;
+    let secInfo = this._checkCert(aURI);
+    let certificate = secInfo.serverCert;
 
     let flags = 0;
 
     // in private browsing do not store exceptions permanently ever
     if (PrivateBrowsingUtils.isWindowPrivate(aWindow)) {
       aTemporary = true;
     }
 
-    if (SSLStatus.isUntrusted)
+    if (secInfo.isUntrusted)
       flags |= this._overrideService.ERROR_UNTRUSTED;
-    if (SSLStatus.isDomainMismatch)
+    if (secInfo.isDomainMismatch)
       flags |= this._overrideService.ERROR_MISMATCH;
-    if (SSLStatus.isNotValidAtThisTime)
+    if (secInfo.isNotValidAtThisTime)
       flags |= this._overrideService.ERROR_TIME;
 
     this._overrideService.rememberValidityOverride(
       aURI.asciiHost,
       aURI.port,
       certificate,
       flags,
       aTemporary);
--- a/mobile/android/modules/geckoview/GeckoViewProgress.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewProgress.jsm
@@ -154,18 +154,17 @@ var IdentityHandler = {
     } catch (e) {}
 
     try {
       result.host = IDNService.convertToDisplayIDN(uri.host, {});
     } catch (e) {
       result.host = uri.host;
     }
 
-    let status = aBrowser.securityUI.secInfo.SSLStatus;
-    let cert = status.serverCert;
+    let cert = aBrowser.securityUI.secInfo.serverCert;
 
     result.organization = cert.organization;
     result.subjectName = cert.subjectName;
     result.issuerOrganization = cert.issuerOrganization;
     result.issuerCommonName = cert.issuerCommonName;
 
     try {
       result.securityException = OverrideService.hasMatchingOverride(
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -66,17 +66,16 @@
 #include "sslt.h"
 #include "nsContentUtils.h"
 #include "nsContentSecurityManager.h"
 #include "nsIClassOfService.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsISSLStatus.h"
 #include "nsITransportSecurityInfo.h"
 #include "nsIWebProgressListener.h"
 #include "LoadContextInfo.h"
 #include "netCore.h"
 #include "nsHttpTransaction.h"
 #include "nsICacheEntryDescriptor.h"
 #include "nsICancelable.h"
 #include "nsIHttpChannelAuthProvider.h"
@@ -1920,17 +1919,17 @@ GetPKPConsoleErrorTag(uint32_t failureRe
     }
 }
 
 /**
  * Process a single security header. Only two types are supported: HSTS and HPKP.
  */
 nsresult
 nsHttpChannel::ProcessSingleSecurityHeader(uint32_t aType,
-                                           nsISSLStatus *aSSLStatus,
+                                           nsITransportSecurityInfo* aSecInfo,
                                            uint32_t aFlags)
 {
     nsHttpAtom atom;
     switch (aType) {
         case nsISiteSecurityService::HEADER_HSTS:
             atom = nsHttp::ResolveAtom("Strict-Transport-Security");
             break;
         case nsISiteSecurityService::HEADER_HPKP:
@@ -1947,17 +1946,17 @@ nsHttpChannel::ProcessSingleSecurityHead
         nsISiteSecurityService* sss = gHttpHandler->GetSSService();
         NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
         // Process header will now discard the headers itself if the channel
         // wasn't secure (whereas before it had to be checked manually)
         OriginAttributes originAttributes;
         NS_GetOriginAttributes(this, originAttributes);
         uint32_t failureResult;
         uint32_t headerSource = nsISiteSecurityService::SOURCE_ORGANIC_REQUEST;
-        rv = sss->ProcessHeader(aType, mURI, securityHeader, aSSLStatus,
+        rv = sss->ProcessHeader(aType, mURI, securityHeader, aSecInfo,
                                 aFlags, headerSource, originAttributes,
                                 nullptr, nullptr, &failureResult);
         if (NS_FAILED(rv)) {
             nsAutoString consoleErrorCategory;
             nsAutoString consoleErrorTag;
             switch (aType) {
                 case nsISiteSecurityService::HEADER_HSTS:
                     GetSTSConsoleErrorTag(failureResult, consoleErrorTag);
@@ -2022,27 +2021,23 @@ nsHttpChannel::ProcessSecurityHeaders()
     NS_ENSURE_TRUE(mSecurityInfo, NS_OK);
 
     uint32_t flags =
       NS_UsePrivateBrowsing(this) ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
 
     // Get the TransportSecurityInfo
     nsCOMPtr<nsITransportSecurityInfo> transSecInfo = do_QueryInterface(mSecurityInfo);
     NS_ENSURE_TRUE(transSecInfo, NS_ERROR_FAILURE);
-    nsCOMPtr<nsISSLStatus> sslStatus;
-    rv = transSecInfo->GetSSLStatus(getter_AddRefs(sslStatus));
-    NS_ENSURE_SUCCESS(rv, rv);
-    NS_ENSURE_TRUE(sslStatus, NS_ERROR_FAILURE);
 
     rv = ProcessSingleSecurityHeader(nsISiteSecurityService::HEADER_HSTS,
-                                     sslStatus, flags);
+                                     transSecInfo, flags);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = ProcessSingleSecurityHeader(nsISiteSecurityService::HEADER_HPKP,
-                                     sslStatus, flags);
+                                     transSecInfo, flags);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
 nsresult
 nsHttpChannel::ProcessContentSignatureHeader(nsHttpResponseHead *aResponseHead)
 {
@@ -2158,36 +2153,32 @@ nsHttpChannel::ProcessSSLInformation()
     if (mCanceled || NS_FAILED(mStatus) || !mSecurityInfo ||
         !IsHTTPS() || mPrivateBrowsing)
         return;
 
     nsCOMPtr<nsITransportSecurityInfo> securityInfo =
         do_QueryInterface(mSecurityInfo);
     if (!securityInfo)
         return;
-    nsCOMPtr<nsISSLStatus> sslstat;
-    securityInfo->GetSSLStatus(getter_AddRefs(sslstat));
-    if (!sslstat)
-        return;
 
     uint32_t state;
     if (securityInfo &&
         NS_SUCCEEDED(securityInfo->GetSecurityState(&state)) &&
         (state & nsIWebProgressListener::STATE_IS_BROKEN)) {
         // Send weak crypto warnings to the web console
         if (state & nsIWebProgressListener::STATE_USES_WEAK_CRYPTO) {
             nsString consoleErrorTag = NS_LITERAL_STRING("WeakCipherSuiteWarning");
             nsString consoleErrorCategory = NS_LITERAL_STRING("SSL");
             Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
         }
     }
 
     // Send (SHA-1) signature algorithm errors to the web console
     nsCOMPtr<nsIX509Cert> cert;
-    sslstat->GetServerCert(getter_AddRefs(cert));
+    securityInfo->GetServerCert(getter_AddRefs(cert));
     if (cert) {
         UniqueCERTCertificate nssCert(cert->GetCert());
         if (nssCert) {
             SECOidTag tag = SECOID_GetAlgorithmTag(&nssCert->signature);
             LOG(("Checking certificate signature: The OID tag is %i [this=%p]\n", tag, this));
             // Check to see if the signature is sha-1 based.
             // Not including checks for SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE
             // from http://tools.ietf.org/html/rfc2437#section-8 since I
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -33,17 +33,17 @@
 #include "mozilla/extensions/PStreamFilterParent.h"
 #include "mozilla/Mutex.h"
 #include "nsITabParent.h"
 
 class nsDNSPrefetch;
 class nsICancelable;
 class nsIHttpChannelAuthProvider;
 class nsInputStreamPump;
-class nsISSLStatus;
+class nsITransportSecurityInfo;
 
 namespace mozilla { namespace net {
 
 class nsChannelClassifier;
 class Http2PushedStream;
 
 class HttpChannelSecurityWarningReporter : public nsISupports
 {
@@ -434,18 +434,18 @@ private:
     void ProcessSecurityReport(nsresult status);
 
     /**
      * A function to process a single security header (STS or PKP), assumes
      * some basic sanity checks have been applied to the channel. Called
      * from ProcessSecurityHeaders.
      */
     MOZ_MUST_USE nsresult ProcessSingleSecurityHeader(uint32_t aType,
-                                                      nsISSLStatus *aSSLStatus,
-                                                      uint32_t aFlags);
+      nsITransportSecurityInfo* aSecInfo,
+      uint32_t aFlags);
 
     void InvalidateCacheEntryForLocation(const char *location);
     void AssembleCacheKey(const char *spec, uint32_t postID, nsACString &key);
     MOZ_MUST_USE nsresult CreateNewURI(const char *loc, nsIURI **newURI);
     void DoInvalidateCacheEntry(nsIURI* aURI);
 
     // Ref RFC2616 13.10: "invalidation... MUST only be performed if
     // the host part is the same as in the Request-URI"
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -18,17 +18,16 @@
 
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsIURI.h"
 #ifdef XP_WIN
 #include "nsIChannel.h"
 #include "nsIX509Cert.h"
-#include "nsISSLStatus.h"
 #include "nsITransportSecurityInfo.h"
 #endif
 #include "mozilla/Attributes.h"
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Tokenizer.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
@@ -334,23 +333,18 @@ nsHttpNTLMAuth::GenerateCredentials(nsIH
         rv = channel->GetSecurityInfo(getter_AddRefs(security));
         if (NS_FAILED(rv))
             return rv;
 
         nsCOMPtr<nsITransportSecurityInfo> secInfo =
             do_QueryInterface(security);
 
         if (mUseNative && secInfo) {
-            nsCOMPtr<nsISSLStatus> status;
-            rv = secInfo->GetSSLStatus(getter_AddRefs(status));
-            if (NS_FAILED(rv))
-                return rv;
-
             nsCOMPtr<nsIX509Cert> cert;
-            rv = status->GetServerCert(getter_AddRefs(cert));
+            rv = secInfo->GetServerCert(getter_AddRefs(cert));
             if (NS_FAILED(rv))
                 return rv;
 
             uint32_t length;
             uint8_t* certArray;
             rv = cert->GetRawDER(&length, &certArray);
             if (NS_FAILED(rv))
                 return rv;
--- a/netwerk/socket/nsITransportSecurityInfo.idl
+++ b/netwerk/socket/nsITransportSecurityInfo.idl
@@ -1,28 +1,75 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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/. */
 
 #include "nsISupports.idl"
 
-interface nsISSLStatus;
+interface nsIX509Cert;
 interface nsIX509CertList;
 
-[builtinclass, scriptable, uuid(216112d3-28bc-4671-b057-f98cc09ba1ea)]
+[scriptable, uuid(216112d3-28bc-4671-b057-f98cc09ba1ea)]
 interface nsITransportSecurityInfo : nsISupports {
     readonly attribute unsigned long securityState;
-    [infallible] readonly attribute long errorCode; // PRErrorCode
+    readonly attribute long errorCode; // PRErrorCode
     // errorCode as string (e.g. "SEC_ERROR_UNKNOWN_ISSUER")
     readonly attribute AString errorCodeString;
 
     /**
+     * The following parameters are only valid after the TLS handshake
+     * has completed.  Check securityState first.
+     */
+
+    /**
      * If certificate verification failed, this will be the peer certificate
      * chain provided in the handshake, so it can be used for error reporting.
      * If verification succeeded, this will be null.
      */
     readonly attribute nsIX509CertList failedCertChain;
 
-    readonly attribute nsISSLStatus SSLStatus;
+    readonly attribute nsIX509Cert serverCert;
+    readonly attribute nsIX509CertList succeededCertChain;
+
+    [must_use]
+    readonly attribute ACString cipherName;
+    [must_use]
+    readonly attribute unsigned long keyLength;
+    [must_use]
+    readonly attribute unsigned long secretKeyLength;
+    [must_use]
+    readonly attribute ACString keaGroupName;
+    [must_use]
+    readonly attribute ACString signatureSchemeName;
+
+    const short SSL_VERSION_3   = 0;
+    const short TLS_VERSION_1   = 1;
+    const short TLS_VERSION_1_1 = 2;
+    const short TLS_VERSION_1_2 = 3;
+    const short TLS_VERSION_1_3 = 4;
+    [must_use]
+    readonly attribute unsigned short protocolVersion;
+
+    const short CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE          = 0;
+    const short CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT        = 5;
+    const short CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS  = 6;
+    const short CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS = 7;
+    [must_use]
+    readonly attribute unsigned short certificateTransparencyStatus;
+
+    [must_use]
+    readonly attribute boolean isDomainMismatch;
+    [must_use]
+    readonly attribute boolean isNotValidAtThisTime;
+
+    [must_use]
+    readonly attribute boolean isUntrusted;
+
+    /**
+     * True only if (and after) serverCert was successfully validated as
+     * Extended Validation (EV).
+     */
+    [must_use]
+    readonly attribute boolean isExtendedValidation;
 };
 
--- a/netwerk/test/unit/test_http2.js
+++ b/netwerk/test/unit/test_http2.js
@@ -1203,18 +1203,18 @@ CertOverrideListener.prototype = {
   QueryInterface: function(aIID) {
     if (aIID.equals(Ci.nsIBadCertListener2) ||
         aIID.equals(Ci.nsIInterfaceRequestor) ||
         aIID.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 
-  notifyCertProblem: function(socketInfo, sslStatus, targetHost) {
-    var cert = sslStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
+  notifyCertProblem: function(socketInfo, secInfo, targetHost) {
+    var cert = secInfo.serverCert;
     var cos = Cc["@mozilla.org/security/certoverride;1"].
               getService(Ci.nsICertOverrideService);
     cos.rememberValidityOverride(this.host, this.port, cert, this.bits, false);
     dump("Certificate Override in place\n");
     return true;
   },
 };
 
--- a/security/manager/pki/resources/content/exceptionDialog.js
+++ b/security/manager/pki/resources/content/exceptionDialog.js
@@ -2,17 +2,17 @@
  * 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/. */
 /* import-globals-from pippki.js */
 "use strict";
 
 var gDialog;
 var gBundleBrand;
 var gPKIBundle;
-var gSSLStatus;
+var gSecInfo;
 var gCert;
 var gChecking;
 var gBroken;
 var gNeedReset;
 var gSecHistogram;
 var gNsISecTel;
 
 ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
@@ -33,19 +33,19 @@ function initExceptionDialog() {
 
   var args = window.arguments;
   if (args && args[0]) {
     if (args[0].location) {
       // We were pre-seeded with a location.
       document.getElementById("locationTextBox").value = args[0].location;
       document.getElementById("checkCertButton").disabled = false;
 
-      if (args[0].sslStatus) {
-        gSSLStatus = args[0].sslStatus;
-        gCert = gSSLStatus.serverCert;
+      if (args[0].securityInfo) {
+        gSecInfo = args[0].securityInfo;
+        gCert = gSecInfo.serverCert;
         gBroken = true;
         updateCertStatus();
       } else if (args[0].prefetchCert) {
         // We can optionally pre-fetch the certificate too.  Don't do this
         // synchronously, since it would prevent the window from appearing
         // until the fetch is completed, which could be multiple seconds.
         // Instead, let's use a timer to spawn the actual fetch, but update
         // the dialog to "checking..." state right away, so that the UI
@@ -61,43 +61,42 @@ function initExceptionDialog() {
     // Set out parameter to false by default
     args[0].exceptionAdded = false;
   }
   window.sizeToContent();
 }
 
 /**
  * Helper function for checkCert. Set as the onerror/onload callbacks for an
- * XMLHttpRequest. Sets gSSLStatus, gCert, gBroken, and gChecking according to
+ * XMLHttpRequest. Sets gSecInfo, gCert, gBroken, and gChecking according to
  * the load information from the request. Probably should not be used directly.
  *
  * @param {XMLHttpRequest} req
  *        The XMLHttpRequest created and sent by checkCert.
  * @param {Event} evt
  *        The load or error event.
  */
 function grabCert(req, evt) {
   if (req.channel && req.channel.securityInfo) {
-    gSSLStatus = req.channel.securityInfo
-                    .QueryInterface(Ci.nsITransportSecurityInfo).SSLStatus;
-    gCert = gSSLStatus ? gSSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert
-                       : null;
+    gSecInfo = req.channel.securityInfo
+                  .QueryInterface(Ci.nsITransportSecurityInfo);
+    gCert = gSecInfo ? gSecInfo.serverCert : null;
   }
   gBroken = evt.type == "error";
   gChecking = false;
   updateCertStatus();
 }
 
 /**
  * Attempt to download the certificate for the location specified, and populate
  * the Certificate Status section with the result.
  */
 function checkCert() {
   gCert = null;
-  gSSLStatus = null;
+  gSecInfo = null;
   gChecking = true;
   gBroken = false;
   updateCertStatus();
 
   let uri = getURI();
 
   if (uri) {
     let req = new XMLHttpRequest();
@@ -180,35 +179,35 @@ function updateCertStatus() {
     if (gBroken) {
       var mms = "addExceptionDomainMismatchShort";
       var mml = "addExceptionDomainMismatchLong2";
       var exs = "addExceptionExpiredShort";
       var exl = "addExceptionExpiredLong2";
       var uts = "addExceptionUnverifiedOrBadSignatureShort";
       var utl = "addExceptionUnverifiedOrBadSignatureLong2";
       var use1 = false;
-      if (gSSLStatus.isDomainMismatch) {
+      if (gSecInfo.isDomainMismatch) {
         bucketId += gNsISecTel.WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_DOMAIN;
         use1 = true;
         shortDesc = mms;
         longDesc  = mml;
       }
-      if (gSSLStatus.isNotValidAtThisTime) {
+      if (gSecInfo.isNotValidAtThisTime) {
         bucketId += gNsISecTel.WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_TIME;
         if (!use1) {
           use1 = true;
           shortDesc = exs;
           longDesc  = exl;
         } else {
           use2 = true;
           shortDesc2 = exs;
           longDesc2  = exl;
         }
       }
-      if (gSSLStatus.isUntrusted) {
+      if (gSecInfo.isUntrusted) {
         bucketId +=
           gNsISecTel.WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_UNTRUSTED;
         if (!use1) {
           use1 = true;
           shortDesc = uts;
           longDesc  = utl;
         } else if (!use2) {
           use2 = true;
@@ -294,36 +293,36 @@ function viewCertButtonClick() {
     viewCertHelper(this, gCert);
   }
 }
 
 /**
  * Handle user request to add an exception for the specified cert
  */
 function addException() {
-  if (!gCert || !gSSLStatus) {
+  if (!gCert || !gSecInfo) {
     return;
   }
 
   var overrideService = Cc["@mozilla.org/security/certoverride;1"]
                           .getService(Ci.nsICertOverrideService);
   var flags = 0;
   let confirmBucketId =
         gNsISecTel.WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_BASE;
-  if (gSSLStatus.isUntrusted) {
+  if (gSecInfo.isUntrusted) {
     flags |= overrideService.ERROR_UNTRUSTED;
     confirmBucketId +=
         gNsISecTel.WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_UNTRUSTED;
   }
-  if (gSSLStatus.isDomainMismatch) {
+  if (gSecInfo.isDomainMismatch) {
     flags |= overrideService.ERROR_MISMATCH;
     confirmBucketId +=
            gNsISecTel.WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_DOMAIN;
   }
-  if (gSSLStatus.isNotValidAtThisTime) {
+  if (gSecInfo.isNotValidAtThisTime) {
     flags |= overrideService.ERROR_TIME;
     confirmBucketId +=
            gNsISecTel.WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_TIME;
   }
 
   var permanentCheckbox = document.getElementById("permanent");
   var shouldStorePermanently = permanentCheckbox.checked &&
                                !inPrivateBrowsingMode();
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -121,17 +121,16 @@
 #include "nsICertOverrideService.h"
 #include "nsISiteSecurityService.h"
 #include "nsISocketProvider.h"
 #include "nsIThreadPool.h"
 #include "nsNetUtil.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsNSSIOLayer.h"
-#include "nsSSLStatus.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsURLHelper.h"
 #include "nsXPCOMCIDInternal.h"
 #include "pkix/pkix.h"
 #include "pkix/pkixnss.h"
 #include "secerr.h"
 #include "secoidt.h"
@@ -613,17 +612,17 @@ CertErrorRunnable::CheckCertOverrides()
     nsCOMPtr<nsIInterfaceRequestor> cb;
     sslSocketControl->GetNotificationCallbacks(getter_AddRefs(cb));
     if (cb) {
       nsCOMPtr<nsIBadCertListener2> bcl = do_GetInterface(cb);
       if (bcl) {
         nsIInterfaceRequestor* csi
           = static_cast<nsIInterfaceRequestor*>(mInfoObject);
         bool suppressMessage = false; // obsolete, ignored
-        Unused << bcl->NotifyCertProblem(csi, mInfoObject->SSLStatus(),
+        Unused << bcl->NotifyCertProblem(csi, mInfoObject,
                                          hostWithPortString, &suppressMessage);
       }
     }
   }
 
   // pick the error code to report by priority
   PRErrorCode errorCodeToReport = mErrorCodeTrust    ? mErrorCodeTrust
                                 : mErrorCodeMismatch ? mErrorCodeMismatch
@@ -823,27 +822,26 @@ SSLServerCertVerificationJob::SSLServerC
 static SECStatus
 BlockServerCertChangeForSpdy(nsNSSSocketInfo* infoObject,
                              const UniqueCERTCertificate& serverCert)
 {
   // Get the existing cert. If there isn't one, then there is
   // no cert change to worry about.
   nsCOMPtr<nsIX509Cert> cert;
 
-  RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
-  if (!status) {
-    // If we didn't have a status, then this is the
+  if (!infoObject->IsHandshakeCompleted()) {
     // first handshake on this connection, not a
     // renegotiation.
     return SECSuccess;
   }
 
-  status->GetServerCert(getter_AddRefs(cert));
+  infoObject->GetServerCert(getter_AddRefs(cert));
   if (!cert) {
-    MOZ_ASSERT_UNREACHABLE("nsSSLStatus must have a cert implementing nsIX509Cert");
+    MOZ_ASSERT_UNREACHABLE(
+             "TransportSecurityInfo must have a cert implementing nsIX509Cert");
     PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
     return SECFailure;
   }
 
   // Filter out sockets that did not neogtiate SPDY via NPN
   nsAutoCString negotiatedNPN;
   nsresult rv = infoObject->GetNegotiatedNPN(negotiatedNPN);
   MOZ_ASSERT(NS_SUCCEEDED(rv), "GetNegotiatedNPN() failed during renegotiation");
@@ -1436,47 +1434,37 @@ AuthCertificate(CertVerifier& certVerifi
     Telemetry::Accumulate(pinningTelemetryInfo.certPinningResultHistogram.value(),
                           pinningTelemetryInfo.certPinningResultBucket);
   }
 
   if (rv == Success) {
     // Certificate verification succeeded. Delete any potential record of
     // certificate error bits.
     RememberCertErrorsTable::GetInstance().RememberCertHasError(infoObject,
-                                                                nullptr,
                                                                 SECSuccess);
     GatherSuccessfulValidationTelemetry(builtCertChain);
     GatherCertificateTransparencyTelemetry(builtCertChain,
                                   /*isEV*/ evOidPolicy != SEC_OID_UNKNOWN,
                                            certificateTransparencyInfo);
 
-    // The connection may get terminated, for example, if the server requires
-    // a client cert. Let's provide a minimal SSLStatus
-    // to the caller that contains at least the cert and its status.
-    RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
-    if (!status) {
-      status = new nsSSLStatus();
-      infoObject->SetSSLStatus(status);
-    }
-
     EVStatus evStatus;
     if (evOidPolicy == SEC_OID_UNKNOWN) {
       evStatus = EVStatus::NotEV;
     } else {
       evStatus = EVStatus::EV;
     }
 
     RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(cert.get());
-    status->SetServerCert(nsc, evStatus);
+    infoObject->SetServerCert(nsc, evStatus);
 
-    status->SetSucceededCertChain(std::move(builtCertChain));
+    infoObject->SetSucceededCertChain(std::move(builtCertChain));
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
             ("AuthCertificate setting NEW cert %p", nsc.get()));
 
-    status->SetCertificateTransparencyInfo(certificateTransparencyInfo);
+    infoObject->SetCertificateTransparencyInfo(certificateTransparencyInfo);
   }
 
   if (rv != Success) {
     // Certificate validation failed; store the peer certificate chain on
     // infoObject so it can be used for error reporting.
     infoObject->SetFailedCertChain(std::move(peerCertChain));
     PR_SetError(MapResultToPRErrorCode(rv), 0);
   }
--- a/security/manager/ssl/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/TransportSecurityInfo.cpp
@@ -34,17 +34,30 @@
                        //read/write buffer to a log.
                        //Uses PR_LOG except on Mac where
                        //we always write out to our own
                        //file.
 
 namespace mozilla { namespace psm {
 
 TransportSecurityInfo::TransportSecurityInfo()
-  : mMutex("TransportSecurityInfo::mMutex")
+  : mCipherSuite(0)
+  , mProtocolVersion(0)
+  , mCertificateTransparencyStatus(nsITransportSecurityInfo::
+      CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE)
+  , mKeaGroup()
+  , mSignatureSchemeName()
+  , mIsDomainMismatch(false)
+  , mIsNotValidAtThisTime(false)
+  , mIsUntrusted(false)
+  , mIsEV(false)
+  , mHasIsEVStatus(false)
+  , mHaveCipherSuiteAndProtocol(false)
+  , mHaveCertErrorBits(false)
+  , mMutex("TransportSecurityInfo::mMutex")
   , mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE)
   , mSubRequestsBrokenSecurity(0)
   , mSubRequestsNoSecurity(0)
   , mErrorCode(0)
   , mPort(0)
 {
 }
 
@@ -178,135 +191,329 @@ TransportSecurityInfo::GetInterface(cons
 // of the previous value. This is so when older versions attempt to
 // read a newer serialized TransportSecurityInfo, they will actually
 // fail and return NS_ERROR_FAILURE instead of silently failing.
 #define TRANSPORTSECURITYINFOMAGIC { 0xa9863a23, 0x1faa, 0x4169, \
   { 0xb0, 0xd2, 0x81, 0x29, 0xec, 0x7c, 0xb1, 0xde } }
 static NS_DEFINE_CID(kTransportSecurityInfoMagic, TRANSPORTSECURITYINFOMAGIC);
 
 NS_IMETHODIMP
-TransportSecurityInfo::Write(nsIObjectOutputStream* stream)
+TransportSecurityInfo::Write(nsIObjectOutputStream* aStream)
 {
-  nsresult rv = stream->WriteID(kTransportSecurityInfoMagic);
+  nsresult rv = aStream->WriteID(kTransportSecurityInfoMagic);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   MutexAutoLock lock(mMutex);
 
-  rv = stream->Write32(mSecurityState);
+  rv = aStream->Write32(mSecurityState);
   if (NS_FAILED(rv)) {
     return rv;
   }
-  rv = stream->Write32(mSubRequestsBrokenSecurity);
+  rv = aStream->Write32(mSubRequestsBrokenSecurity);
   if (NS_FAILED(rv)) {
     return rv;
   }
-  rv = stream->Write32(mSubRequestsNoSecurity);
+  rv = aStream->Write32(mSubRequestsNoSecurity);
   if (NS_FAILED(rv)) {
     return rv;
   }
-  rv = stream->Write32(static_cast<uint32_t>(mErrorCode));
+  rv = aStream->Write32(static_cast<uint32_t>(mErrorCode));
   if (NS_FAILED(rv)) {
     return rv;
   }
-  // Write empty string where mErrorMessageCached lived before.
-  rv = stream->WriteWStringZ(NS_ConvertUTF8toUTF16("").get());
+
+  // Re-purpose mErrorMessageCached to represent serialization version
+  // If string doesn't match exact version it will be treated as older
+  // serialization.
+  rv = aStream->WriteWStringZ(NS_ConvertUTF8toUTF16("1").get());
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  // For successful connections and for connections with overridable errors,
-  // mSSLStatus will be non-null. However, for connections with non-overridable
-  // errors, it will be null.
-  nsCOMPtr<nsISerializable> serializable(mSSLStatus);
-  rv = NS_WriteOptionalCompoundObject(stream,
-                                      serializable,
-                                      NS_GET_IID(nsISSLStatus),
+  // moved from nsISSLStatus
+  rv = NS_WriteOptionalCompoundObject(aStream, mServerCert,
+                                      NS_GET_IID(nsIX509Cert),
                                       true);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->Write16(mCipherSuite);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->Write16(mProtocolVersion);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->WriteBoolean(mIsDomainMismatch);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->WriteBoolean(mIsNotValidAtThisTime);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->WriteBoolean(mIsUntrusted);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->WriteBoolean(mIsEV);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = NS_WriteOptionalCompoundObject(stream,
+  rv = aStream->WriteBoolean(mHasIsEVStatus);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->WriteBoolean(mHaveCipherSuiteAndProtocol);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->WriteBoolean(mHaveCertErrorBits);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->Write16(mCertificateTransparencyStatus);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->WriteStringZ(mKeaGroup.get());
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->WriteStringZ(mSignatureSchemeName.get());
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = NS_WriteOptionalCompoundObject(aStream,
+                                      mSucceededCertChain,
+                                      NS_GET_IID(nsIX509CertList),
+                                       true);
+   if (NS_FAILED(rv)) {
+     return rv;
+   }
+  // END moved from nsISSLStatus
+
+  rv = NS_WriteOptionalCompoundObject(aStream,
                                       mFailedCertChain,
                                       NS_GET_IID(nsIX509CertList),
                                       true);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   return NS_OK;
 }
 
+// This is for backward compatability to be able to read nsISSLStatus
+// serialized object.
+nsresult TransportSecurityInfo::ReadSSLStatus(nsIObjectInputStream* aStream)
+{
+  bool nsISSLStatusPresent;
+  nsresult rv = aStream->ReadBoolean(&nsISSLStatusPresent);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!nsISSLStatusPresent) {
+    return NS_OK;
+  }
+  // nsISSLStatus present.  Prepare to read elements.
+  // Throw away cid, validate iid
+  nsCID cid;
+  nsIID iid;
+  rv = aStream->ReadID(&cid);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->ReadID(&iid);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  static const nsIID nsSSLStatusIID = {
+    0xfa9ba95b, 0xca3b, 0x498a,
+    { 0xb8, 0x89, 0x7c, 0x79, 0xcf, 0x28, 0xfe, 0xe8 }
+  };
+  if (!iid.Equals(nsSSLStatusIID)) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsCOMPtr<nsISupports> cert;
+  rv = aStream->ReadObject(true, getter_AddRefs(cert));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (cert) {
+    mServerCert = do_QueryInterface(cert);
+    if (!mServerCert) {
+      return NS_NOINTERFACE;
+    }
+  }
+
+  rv = aStream->Read16(&mCipherSuite);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // The code below is a workaround to allow serializing new fields
+  // while preserving binary compatibility with older streams. For more details
+  // on the binary compatibility requirement, refer to bug 1248628.
+  // Here, we take advantage of the fact that mProtocolVersion was originally
+  // stored as a 16 bits integer, but the highest 8 bits were never used.
+  // These bits are now used for stream versioning.
+  uint16_t protocolVersionAndStreamFormatVersion;
+  rv = aStream->Read16(&protocolVersionAndStreamFormatVersion);
+  NS_ENSURE_SUCCESS(rv, rv);
+  mProtocolVersion = protocolVersionAndStreamFormatVersion & 0xFF;
+  const uint8_t streamFormatVersion =
+  (protocolVersionAndStreamFormatVersion >> 8) & 0xFF;
+
+  rv = aStream->ReadBoolean(&mIsDomainMismatch);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->ReadBoolean(&mIsNotValidAtThisTime);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->ReadBoolean(&mIsUntrusted);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->ReadBoolean(&mIsEV);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = aStream->ReadBoolean(&mHasIsEVStatus);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->ReadBoolean(&mHaveCipherSuiteAndProtocol);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = aStream->ReadBoolean(&mHaveCertErrorBits);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Added in version 1 (see bug 1305289).
+  if (streamFormatVersion >= 1) {
+    rv = aStream->Read16(&mCertificateTransparencyStatus);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  // Added in version 2 (see bug 1304923).
+  if (streamFormatVersion >= 2) {
+    rv = aStream->ReadCString(mKeaGroup);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->ReadCString(mSignatureSchemeName);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  // Added in version 3 (see bug 1406856).
+  if (streamFormatVersion >= 3) {
+    nsCOMPtr<nsISupports> succeededCertChainSupports;
+    rv = NS_ReadOptionalObject(aStream, true,
+                               getter_AddRefs(succeededCertChainSupports));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    mSucceededCertChain = do_QueryInterface(succeededCertChainSupports);
+
+    // Read only to consume bytes from the stream.
+    nsCOMPtr<nsISupports> failedCertChainSupports;
+    rv = NS_ReadOptionalObject(aStream, true,
+                               getter_AddRefs(failedCertChainSupports));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+  }
+  return rv;
+}
+
 NS_IMETHODIMP
-TransportSecurityInfo::Read(nsIObjectInputStream* stream)
+TransportSecurityInfo::Read(nsIObjectInputStream* aStream)
 {
   nsID id;
-  nsresult rv = stream->ReadID(&id);
+  nsresult rv = aStream->ReadID(&id);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (!id.Equals(kTransportSecurityInfoMagic)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   MutexAutoLock lock(mMutex);
 
-  rv = stream->Read32(&mSecurityState);
+  rv = aStream->Read32(&mSecurityState);
   if (NS_FAILED(rv)) {
     return rv;
   }
   uint32_t subRequestsBrokenSecurity;
-  rv = stream->Read32(&subRequestsBrokenSecurity);
+  rv = aStream->Read32(&subRequestsBrokenSecurity);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (subRequestsBrokenSecurity >
       static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
     return NS_ERROR_UNEXPECTED;
   }
   mSubRequestsBrokenSecurity = subRequestsBrokenSecurity;
   uint32_t subRequestsNoSecurity;
-  rv = stream->Read32(&subRequestsNoSecurity);
+  rv = aStream->Read32(&subRequestsNoSecurity);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (subRequestsNoSecurity >
-      static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
+        static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
     return NS_ERROR_UNEXPECTED;
   }
   mSubRequestsNoSecurity = subRequestsNoSecurity;
   uint32_t errorCode;
-  rv = stream->Read32(&errorCode);
+  rv = aStream->Read32(&errorCode);
   if (NS_FAILED(rv)) {
     return rv;
   }
   // PRErrorCode will be a negative value
   mErrorCode = static_cast<PRErrorCode>(errorCode);
 
-  // We don't do error messages here anymore.
-  nsString unused;
-  rv = stream->ReadString(unused);
+  // Re-purpose mErrorMessageCached to represent serialization version
+  // If string doesn't match exact version it will be treated as older
+  // serialization.
+  nsAutoString serVersion;
+  rv = aStream->ReadString(serVersion);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  // For successful connections and for connections with overridable errors,
-  // mSSLStatus will be non-null. For connections with non-overridable errors,
-  // it will be null.
-  nsCOMPtr<nsISupports> supports;
-  rv = NS_ReadOptionalObject(stream, true, getter_AddRefs(supports));
-  if (NS_FAILED(rv)) {
-    return rv;
+  // moved from nsISSLStatus
+  if (!serVersion.EqualsASCII("1")) {
+    // nsISSLStatus may be present
+    rv = ReadSSLStatus(aStream);
+    NS_ENSURE_SUCCESS(rv, rv);
+  } else {
+    nsCOMPtr<nsISupports> cert;
+    rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(cert));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (cert != nullptr) {
+      mServerCert = do_QueryInterface(cert);
+      if (!mServerCert) {
+        return NS_NOINTERFACE;
+      }
+    }
+
+    rv = aStream->Read16(&mCipherSuite);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->Read16(&mProtocolVersion);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->ReadBoolean(&mIsDomainMismatch);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = aStream->ReadBoolean(&mIsNotValidAtThisTime);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = aStream->ReadBoolean(&mIsUntrusted);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = aStream->ReadBoolean(&mIsEV);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->ReadBoolean(&mHasIsEVStatus);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = aStream->ReadBoolean(&mHaveCipherSuiteAndProtocol);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = aStream->ReadBoolean(&mHaveCertErrorBits);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->Read16(&mCertificateTransparencyStatus);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->ReadCString(mKeaGroup);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aStream->ReadCString(mSignatureSchemeName);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsISupports> succeededCertChainSupports;
+    rv = NS_ReadOptionalObject(aStream, true,
+                               getter_AddRefs(succeededCertChainSupports));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    mSucceededCertChain = do_QueryInterface(succeededCertChainSupports);
   }
-  mSSLStatus = BitwiseCast<nsSSLStatus*, nsISupports*>(supports.get());
+  // END moved from nsISSLStatus
 
   nsCOMPtr<nsISupports> failedCertChainSupports;
-  rv = NS_ReadOptionalObject(stream, true, getter_AddRefs(failedCertChainSupports));
+  rv = NS_ReadOptionalObject(aStream, true,
+                             getter_AddRefs(failedCertChainSupports));
   if (NS_FAILED(rv)) {
     return rv;
   }
   mFailedCertChain = do_QueryInterface(failedCertChainSupports);
 
   return NS_OK;
 }
 
@@ -357,33 +564,16 @@ static NS_DEFINE_CID(kNSSSocketInfoCID, 
 
 NS_IMETHODIMP
 TransportSecurityInfo::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
 {
   *aClassIDNoAlloc = kNSSSocketInfoCID;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-TransportSecurityInfo::GetSSLStatus(nsISSLStatus** _result)
-{
-  NS_ENSURE_ARG_POINTER(_result);
-
-  *_result = mSSLStatus;
-  NS_IF_ADDREF(*_result);
-
-  return NS_OK;
-}
-
-void
-TransportSecurityInfo::SetSSLStatus(nsSSLStatus *aSSLStatus)
-{
-  mSSLStatus = aSSLStatus;
-}
-
 // RememberCertErrorsTable
 
 /*static*/ RememberCertErrorsTable*
 RememberCertErrorsTable::sInstance = nullptr;
 
 RememberCertErrorsTable::RememberCertErrorsTable()
   : mErrorHosts()
   , mMutex("RememberCertErrorsTable::mMutex")
@@ -402,101 +592,96 @@ GetHostPortKey(TransportSecurityInfo* in
   result.Append(':');
   result.AppendInt(infoObject->GetPort());
 
   return NS_OK;
 }
 
 void
 RememberCertErrorsTable::RememberCertHasError(TransportSecurityInfo* infoObject,
-                                              nsSSLStatus* status,
                                               SECStatus certVerificationResult)
 {
   nsresult rv;
 
   nsAutoCString hostPortKey;
   rv = GetHostPortKey(infoObject, hostPortKey);
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
     return;
+  }
 
   if (certVerificationResult != SECSuccess) {
-    MOZ_ASSERT(status, "Must have nsSSLStatus object when remembering flags");
-
-    if (!status)
+    MOZ_ASSERT(infoObject->mHaveCertErrorBits, "Must have error bits when remembering flags");
+    if (!infoObject->mHaveCertErrorBits) {
       return;
+    }
 
     CertStateBits bits;
-    bits.mIsDomainMismatch = status->mIsDomainMismatch;
-    bits.mIsNotValidAtThisTime = status->mIsNotValidAtThisTime;
-    bits.mIsUntrusted = status->mIsUntrusted;
+    bits.mIsDomainMismatch = infoObject->mIsDomainMismatch;
+    bits.mIsNotValidAtThisTime = infoObject->mIsNotValidAtThisTime;
+    bits.mIsUntrusted = infoObject->mIsUntrusted;
 
     MutexAutoLock lock(mMutex);
     mErrorHosts.Put(hostPortKey, bits);
-  }
-  else {
+  } else {
     MutexAutoLock lock(mMutex);
     mErrorHosts.Remove(hostPortKey);
   }
 }
 
 void
-RememberCertErrorsTable::LookupCertErrorBits(TransportSecurityInfo* infoObject,
-                                             nsSSLStatus* status)
+RememberCertErrorsTable::LookupCertErrorBits(TransportSecurityInfo* infoObject)
 {
   // Get remembered error bits from our cache, because of SSL session caching
   // the NSS library potentially hasn't notified us for this socket.
-  if (status->mHaveCertErrorBits)
+  if (infoObject->mHaveCertErrorBits) {
     // Rather do not modify bits if already set earlier
     return;
+  }
 
   nsresult rv;
 
   nsAutoCString hostPortKey;
   rv = GetHostPortKey(infoObject, hostPortKey);
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
     return;
+  }
 
   CertStateBits bits;
   {
     MutexAutoLock lock(mMutex);
-    if (!mErrorHosts.Get(hostPortKey, &bits))
+    if (!mErrorHosts.Get(hostPortKey, &bits)) {
       // No record was found, this host had no cert errors
       return;
+    }
   }
 
   // This host had cert errors, update the bits correctly
-  status->mHaveCertErrorBits = true;
-  status->mIsDomainMismatch = bits.mIsDomainMismatch;
-  status->mIsNotValidAtThisTime = bits.mIsNotValidAtThisTime;
-  status->mIsUntrusted = bits.mIsUntrusted;
+  infoObject->mHaveCertErrorBits = true;
+  infoObject->mIsDomainMismatch = bits.mIsDomainMismatch;
+  infoObject->mIsNotValidAtThisTime = bits.mIsNotValidAtThisTime;
+  infoObject->mIsUntrusted = bits.mIsUntrusted;
 }
 
 void
 TransportSecurityInfo::SetStatusErrorBits(nsNSSCertificate* cert,
                                           uint32_t collected_errors)
 {
   MutexAutoLock lock(mMutex);
 
-  if (!mSSLStatus) {
-    mSSLStatus = new nsSSLStatus();
-  }
-
-  mSSLStatus->SetServerCert(cert, EVStatus::NotEV);
-  mSSLStatus->SetFailedCertChain(mFailedCertChain);
+  SetServerCert(cert, EVStatus::NotEV);
 
-  mSSLStatus->mHaveCertErrorBits = true;
-  mSSLStatus->mIsDomainMismatch =
+  mHaveCertErrorBits = true;
+  mIsDomainMismatch =
     collected_errors & nsICertOverrideService::ERROR_MISMATCH;
-  mSSLStatus->mIsNotValidAtThisTime =
+  mIsNotValidAtThisTime =
     collected_errors & nsICertOverrideService::ERROR_TIME;
-  mSSLStatus->mIsUntrusted =
+  mIsUntrusted =
     collected_errors & nsICertOverrideService::ERROR_UNTRUSTED;
 
   RememberCertErrorsTable::GetInstance().RememberCertHasError(this,
-                                                              mSSLStatus,
                                                               SECFailure);
 }
 
 NS_IMETHODIMP
 TransportSecurityInfo::GetFailedCertChain(nsIX509CertList** _result)
 {
   MOZ_ASSERT(_result);
 
@@ -510,9 +695,228 @@ nsresult
 TransportSecurityInfo::SetFailedCertChain(UniqueCERTCertList certList)
 {
   // nsNSSCertList takes ownership of certList
   mFailedCertChain = new nsNSSCertList(std::move(certList));
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+TransportSecurityInfo::GetServerCert(nsIX509Cert** aServerCert)
+{
+  NS_ENSURE_ARG_POINTER(aServerCert);
+
+  nsCOMPtr<nsIX509Cert> cert = mServerCert;
+  cert.forget(aServerCert);
+  return NS_OK;
+}
+
+void
+TransportSecurityInfo::SetServerCert(nsNSSCertificate* aServerCert,
+                                     EVStatus aEVStatus)
+{
+  MOZ_ASSERT(aServerCert);
+
+  mServerCert = aServerCert;
+  mIsEV = (aEVStatus == EVStatus::EV);
+  mHasIsEVStatus = true;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetSucceededCertChain(nsIX509CertList** _result)
+{
+  NS_ENSURE_ARG_POINTER(_result);
+
+  nsCOMPtr<nsIX509CertList> tmpList = mSucceededCertChain;
+  tmpList.forget(_result);
+
+  return NS_OK;
+}
+
+nsresult
+TransportSecurityInfo::SetSucceededCertChain(UniqueCERTCertList aCertList)
+{
+  // nsNSSCertList takes ownership of certList
+  mSucceededCertChain = new nsNSSCertList(std::move(aCertList));
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetCipherName(nsACString& aCipherName)
+{
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  SSLCipherSuiteInfo cipherInfo;
+  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
+                             sizeof(cipherInfo)) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
+
+  aCipherName.Assign(cipherInfo.cipherSuiteName);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetKeyLength(uint32_t* aKeyLength)
+{
+  NS_ENSURE_ARG_POINTER(aKeyLength);
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  SSLCipherSuiteInfo cipherInfo;
+  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
+                             sizeof(cipherInfo)) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
+
+  *aKeyLength = cipherInfo.symKeyBits;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetSecretKeyLength(uint32_t* aSecretKeyLength)
+{
+  NS_ENSURE_ARG_POINTER(aSecretKeyLength);
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  SSLCipherSuiteInfo cipherInfo;
+  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
+                             sizeof(cipherInfo)) != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
+
+  *aSecretKeyLength = cipherInfo.effectiveKeyBits;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetKeaGroupName(nsACString& aKeaGroup)
+{
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  aKeaGroup.Assign(mKeaGroup);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetSignatureSchemeName(nsACString& aSignatureScheme)
+{
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  aSignatureScheme.Assign(mSignatureSchemeName);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetProtocolVersion(uint16_t* aProtocolVersion)
+{
+  NS_ENSURE_ARG_POINTER(aProtocolVersion);
+  if (!mHaveCipherSuiteAndProtocol) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  *aProtocolVersion = mProtocolVersion;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetCertificateTransparencyStatus(
+  uint16_t* aCertificateTransparencyStatus)
+{
+  NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus);
+
+  *aCertificateTransparencyStatus = mCertificateTransparencyStatus;
+  return NS_OK;
+}
+
+void
+TransportSecurityInfo::SetCertificateTransparencyInfo(
+  const mozilla::psm::CertificateTransparencyInfo& info)
+{
+  using mozilla::ct::CTPolicyCompliance;
+
+  mCertificateTransparencyStatus =
+    nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
+
+  if (!info.enabled) {
+    // CT disabled.
+    return;
+  }
+
+  switch (info.policyCompliance) {
+    case CTPolicyCompliance::Compliant:
+      mCertificateTransparencyStatus =
+        nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT;
+      break;
+    case CTPolicyCompliance::NotEnoughScts:
+      mCertificateTransparencyStatus =
+        nsITransportSecurityInfo
+          ::CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS;
+      break;
+    case CTPolicyCompliance::NotDiverseScts:
+      mCertificateTransparencyStatus =
+        nsITransportSecurityInfo
+          ::CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS;
+      break;
+    case CTPolicyCompliance::Unknown:
+    default:
+      MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
+  }
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetIsDomainMismatch(bool* aIsDomainMismatch)
+{
+  NS_ENSURE_ARG_POINTER(aIsDomainMismatch);
+
+  *aIsDomainMismatch = mHaveCertErrorBits && mIsDomainMismatch;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetIsNotValidAtThisTime(bool* aIsNotValidAtThisTime)
+{
+  NS_ENSURE_ARG_POINTER(aIsNotValidAtThisTime);
+
+  *aIsNotValidAtThisTime = mHaveCertErrorBits && mIsNotValidAtThisTime;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetIsUntrusted(bool* aIsUntrusted)
+{
+  NS_ENSURE_ARG_POINTER(aIsUntrusted);
+
+  *aIsUntrusted = mHaveCertErrorBits && mIsUntrusted;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TransportSecurityInfo::GetIsExtendedValidation(bool* aIsEV)
+{
+  NS_ENSURE_ARG_POINTER(aIsEV);
+  *aIsEV = false;
+
+  // Never allow bad certs for EV, regardless of overrides.
+  if (mHaveCertErrorBits) {
+    return NS_OK;
+  }
+
+  if (mHasIsEVStatus) {
+    *aIsEV = mIsEV;
+    return NS_OK;
+  }
+
+  return NS_ERROR_NOT_AVAILABLE;
+}
+
 } } // namespace mozilla::psm
--- a/security/manager/ssl/TransportSecurityInfo.h
+++ b/security/manager/ssl/TransportSecurityInfo.h
@@ -2,32 +2,39 @@
  *
  * 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/. */
 
 #ifndef TransportSecurityInfo_h
 #define TransportSecurityInfo_h
 
+#include "CertVerifier.h" // For CertificateTransparencyInfo
 #include "ScopedNSSTypes.h"
 #include "certt.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/RefPtr.h"
 #include "nsDataHashtable.h"
 #include "nsIAssociatedContentSecurity.h"
+#include "nsIClassInfo.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsITransportSecurityInfo.h"
-#include "nsSSLStatus.h"
+#include "nsNSSCertificate.h"
 #include "nsString.h"
 #include "pkix/pkixtypes.h"
 
 namespace mozilla { namespace psm {
 
+enum class EVStatus {
+  NotEV = 0,
+  EV = 1,
+};
+
 class TransportSecurityInfo : public nsITransportSecurityInfo
                             , public nsIInterfaceRequestor
                             , public nsIAssociatedContentSecurity
                             , public nsISerializable
                             , public nsIClassInfo
 {
 protected:
   virtual ~TransportSecurityInfo() {}
@@ -38,37 +45,71 @@ public:
   NS_DECL_NSITRANSPORTSECURITYINFO
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIASSOCIATEDCONTENTSECURITY
   NS_DECL_NSISERIALIZABLE
   NS_DECL_NSICLASSINFO
 
   void SetSecurityState(uint32_t aState);
 
+  inline int32_t GetErrorCode()
+  {
+    int32_t result;
+    mozilla::DebugOnly<nsresult> rv = GetErrorCode(&result);
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
+    return result;
+  }
+
   const nsACString & GetHostName() const { return mHostName; }
 
   void SetHostName(const char* host);
 
   int32_t GetPort() const { return mPort; }
   void SetPort(int32_t aPort);
 
   const OriginAttributes& GetOriginAttributes() const {
     return mOriginAttributes;
   }
   void SetOriginAttributes(const OriginAttributes& aOriginAttributes);
 
   void SetCanceled(PRErrorCode errorCode);
 
-  /* Set SSL Status values */
-  void SetSSLStatus(nsSSLStatus* aSSLStatus);
-  nsSSLStatus* SSLStatus() { return mSSLStatus; }
   void SetStatusErrorBits(nsNSSCertificate* cert, uint32_t collected_errors);
 
   nsresult SetFailedCertChain(UniqueCERTCertList certList);
 
+  void SetServerCert(nsNSSCertificate* aServerCert, EVStatus aEVStatus);
+
+  nsresult SetSucceededCertChain(mozilla::UniqueCERTCertList certList);
+
+  bool HasServerCert() {
+    return mServerCert != nullptr;
+  }
+
+  void SetCertificateTransparencyInfo(
+    const mozilla::psm::CertificateTransparencyInfo& info);
+
+  uint16_t mCipherSuite;
+  uint16_t mProtocolVersion;
+  uint16_t mCertificateTransparencyStatus;
+  nsCString mKeaGroup;
+  nsCString mSignatureSchemeName;
+
+  bool mIsDomainMismatch;
+  bool mIsNotValidAtThisTime;
+  bool mIsUntrusted;
+  bool mIsEV;
+
+  bool mHasIsEVStatus;
+  bool mHaveCipherSuiteAndProtocol;
+
+  /* mHaveCertErrrorBits is relied on to determine whether or not a SPDY
+     connection is eligible for joining in nsNSSSocketInfo::JoinConnection() */
+  bool mHaveCertErrorBits;
+
 private:
   mutable ::mozilla::Mutex mMutex;
 
 protected:
   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
 
 private:
   uint32_t mSecurityState;
@@ -76,42 +117,42 @@ private:
   int32_t mSubRequestsNoSecurity;
 
   PRErrorCode mErrorCode;
 
   int32_t mPort;
   nsCString mHostName;
   OriginAttributes mOriginAttributes;
 
-  /* SSL Status */
-  RefPtr<nsSSLStatus> mSSLStatus;
+  nsCOMPtr<nsIX509Cert> mServerCert;
+  nsCOMPtr<nsIX509CertList> mSucceededCertChain;
 
   /* Peer cert chain for failed connections (for error reporting) */
   nsCOMPtr<nsIX509CertList> mFailedCertChain;
+
+  nsresult ReadSSLStatus(nsIObjectInputStream* aStream);
 };
 
 class RememberCertErrorsTable
 {
 private:
   RememberCertErrorsTable();
 
   struct CertStateBits
   {
     bool mIsDomainMismatch;
     bool mIsNotValidAtThisTime;
     bool mIsUntrusted;
   };
   nsDataHashtable<nsCStringHashKey, CertStateBits> mErrorHosts;
 
 public:
-  void RememberCertHasError(TransportSecurityInfo * infoobject,
-                            nsSSLStatus * status,
+  void RememberCertHasError(TransportSecurityInfo* infoObject,
                             SECStatus certVerificationResult);
-  void LookupCertErrorBits(TransportSecurityInfo * infoObject,
-                           nsSSLStatus* status);
+  void LookupCertErrorBits(TransportSecurityInfo* infoObject);
 
   static void Init()
   {
     sInstance = new RememberCertErrorsTable();
   }
 
   static RememberCertErrorsTable & GetInstance()
   {
--- a/security/manager/ssl/moz.build
+++ b/security/manager/ssl/moz.build
@@ -31,17 +31,16 @@ XPIDL_SOURCES += [
     'nsIPK11TokenDB.idl',
     'nsIPKCS11Module.idl',
     'nsIPKCS11ModuleDB.idl',
     'nsIPKCS11Slot.idl',
     'nsIProtectedAuthThread.idl',
     'nsISecretDecoderRing.idl',
     'nsISecurityUITelemetry.idl',
     'nsISiteSecurityService.idl',
-    'nsISSLStatus.idl',
     'nsITokenDialogs.idl',
     'nsITokenPasswordDialogs.idl',
     'nsIX509Cert.idl',
     'nsIX509CertDB.idl',
     'nsIX509CertList.idl',
     'nsIX509CertValidity.idl',
 ]
 
@@ -121,17 +120,16 @@ UNIFIED_SOURCES += [
     'nsProtectedAuthThread.cpp',
     'nsRandomGenerator.cpp',
     'nsSecureBrowserUIImpl.cpp',
     'nsSecurityHeaderParser.cpp',
     'NSSErrorsService.cpp',
     'nsSiteSecurityService.cpp',
     'NSSKeyStore.cpp',
     'nsSSLSocketProvider.cpp',
-    'nsSSLStatus.cpp',
     'nsTLSSocketProvider.cpp',
     'OSKeyStore.cpp',
     'PKCS11ModuleDB.cpp',
     'PSMContentListener.cpp',
     'PSMRunnable.cpp',
     'PublicKeyPinningService.cpp',
     'RootCertificateTelemetryUtils.cpp',
     'SecretDecoderRing.cpp',
--- a/security/manager/ssl/nsIBadCertListener2.idl
+++ b/security/manager/ssl/nsIBadCertListener2.idl
@@ -1,32 +1,32 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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/. */
 
 #include "nsISupports.idl"
 
-interface nsISSLStatus;
 interface nsIInterfaceRequestor;
+interface nsITransportSecurityInfo;
 
 /**
  * A mechanism to report a broken SSL status. The recipient should NOT block.
  * Can be used to obtain the SSL handshake status of a connection
  * that will be canceled because of improper cert status.
  */
 [scriptable, uuid(2c3d268c-ad82-49f3-99aa-e9ffddd7a0dc)]
 interface nsIBadCertListener2 : nsISupports {
 
   /**
    *  @param socketInfo A network communication context that can be used to obtain more information
    *                    about the active connection.
-   *  @param status The SSL status object that describes the problem(s).
+   *  @param secInfo The TransportSecurityinfo object that describes the problem(s).
    *  @param targetSite The Site name that was used to open the current connection.
    *
    *  @return The consumer shall return true if it wants to suppress the error message
    *          related to the bad cert (the connection will still get canceled).
    */
   boolean notifyCertProblem(in nsIInterfaceRequestor socketInfo, 
-                            in nsISSLStatus status,
+                            in nsITransportSecurityInfo secInfo,
                             in AUTF8String targetSite);
 };
deleted file mode 100644
--- a/security/manager/ssl/nsISSLStatus.idl
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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/. */
-
-#include "nsISupports.idl"
-
-interface nsIX509Cert;
-interface nsIX509CertList;
-
-[scriptable, uuid(fa9ba95b-ca3b-498a-b889-7c79cf28fee8)]
-interface nsISSLStatus : nsISupports {
-  readonly attribute nsIX509Cert serverCert;
-  readonly attribute nsIX509CertList failedCertChain;
-  readonly attribute nsIX509CertList succeededCertChain;
-
-  [must_use]
-  readonly attribute ACString cipherName;
-  [must_use]
-  readonly attribute unsigned long keyLength;
-  [must_use]
-  readonly attribute unsigned long secretKeyLength;
-  [must_use]
-  readonly attribute ACString keaGroupName;
-  [must_use]
-  readonly attribute ACString signatureSchemeName;
-
-  const short SSL_VERSION_3   = 0;
-  const short TLS_VERSION_1   = 1;
-  const short TLS_VERSION_1_1 = 2;
-  const short TLS_VERSION_1_2 = 3;
-  const short TLS_VERSION_1_3 = 4;
-  [must_use]
-  readonly attribute unsigned short protocolVersion;
-
-  const short CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE          = 0;
-  const short CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT        = 5;
-  const short CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS  = 6;
-  const short CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS = 7;
-  [must_use]
-  readonly attribute unsigned short certificateTransparencyStatus;
-
-  [must_use]
-  readonly attribute boolean isDomainMismatch;
-  [must_use]
-  readonly attribute boolean isNotValidAtThisTime;
-
-  /* Note: To distinguish between
-   *         "unstrusted because missing or untrusted issuer"
-   *       and
-   *         "untrusted because self signed"
-   *       query nsIX509Cert::isSelfSigned
-   */
-  [must_use]
-  readonly attribute boolean isUntrusted;
-
-  /**
-   * True only if (and after) serverCert was successfully validated as
-   * Extended Validation (EV).
-   */
-  [must_use]
-  readonly attribute boolean isExtendedValidation;
-};
--- a/security/manager/ssl/nsISiteSecurityService.idl
+++ b/security/manager/ssl/nsISiteSecurityService.idl
@@ -2,17 +2,17 @@
  * 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/. */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
 interface nsIObserver;
 interface nsIHttpChannel;
-interface nsISSLStatus;
+interface nsITransportSecurityInfo;
 interface nsISimpleEnumerator;
 
 %{C++
 #include "nsStringFwd.h"
 #include "nsTArrayForwardDeclare.h"
 namespace mozilla
 {
   namespace pkix
@@ -110,17 +110,17 @@ interface nsISiteSecurityService : nsISu
      * The format of the HPKP header is defined by the HPKP specification:
      * https://tools.ietf.org/html/rfc7469
      * and allows a host to specify a subset of trusted anchors to be used
      * in future HTTPS connections.
      *
      * @param aType the type of security header in question.
      * @param aSourceURI the URI of the resource with the HTTP header.
      * @param aHeader the HTTP response header specifying security data.
-     * @param aSSLStatus the SSLStatus of the current channel.
+     * @param aSecInfo the TransportSecurityInfo of the current channel.
      * @param aFlags  options for this request as defined in nsISocketProvider:
      *                  NO_PERMANENT_STORAGE
      * @param aOriginAttributes the origin attributes that isolate this origin,
      *                          (note that this implementation does not isolate
      *                          by userContextId because of the risk of man-in-
      *                          the-middle attacks before trust-on-second-use
      *                          happens).
      * @param aSource the source of the header, whether it was from the preload
@@ -133,30 +133,30 @@ interface nsISiteSecurityService : nsISu
      *         NS_ERROR_FAILURE if it can't be parsed
      *         NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
      *                          if there are unrecognized tokens in the header.
      */
     [binaryname(ProcessHeader), noscript, must_use]
     void processHeaderNative(in uint32_t aType,
                              in nsIURI aSourceURI,
                              in ACString aHeader,
-                             in nsISSLStatus aSSLStatus,
+                             in nsITransportSecurityInfo aSecInfo,
                              in uint32_t aFlags,
                              in uint32_t aSource,
                              in const_OriginAttributesRef aOriginAttributes,
                              [optional] out unsigned long long aMaxAge,
                              [optional] out boolean aIncludeSubdomains,
                              [optional] out uint32_t aFailureResult);
 
     [binaryname(ProcessHeaderScriptable), implicit_jscontext, optional_argc,
      must_use]
     void processHeader(in uint32_t aType,
                        in nsIURI aSourceURI,
                        in ACString aHeader,
-                       in nsISSLStatus aSSLStatus,
+                       in nsITransportSecurityInfo aSecInfo,
                        in uint32_t aFlags,
                        in uint32_t aSource,
                        [optional] in jsval aOriginAttributes,
                        [optional] out unsigned long long aMaxAge,
                        [optional] out boolean aIncludeSubdomains,
                        [optional] out uint32_t aFailureResult);
 
     /**
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -732,28 +732,22 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
   SSLChannelInfo channelInfo;
   if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
     infoObject->SetSSLVersionUsed(channelInfo.protocolVersion);
     infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted);
 
     SSLCipherSuiteInfo cipherInfo;
     if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
                                sizeof cipherInfo) == SECSuccess) {
-      /* Set the SSL Status information */
-      RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
-      if (!status) {
-        status = new nsSSLStatus();
-        infoObject->SetSSLStatus(status);
-      }
-
-      status->mHaveCipherSuiteAndProtocol = true;
-      status->mCipherSuite = channelInfo.cipherSuite;
-      status->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
-      status->mKeaGroup.Assign(getKeaGroupName(channelInfo.keaGroup));
-      status->mSignatureSchemeName.Assign(
+      /* Set the Status information */
+      infoObject->mHaveCipherSuiteAndProtocol = true;
+      infoObject->mCipherSuite = channelInfo.cipherSuite;
+      infoObject->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
+      infoObject->mKeaGroup.Assign(getKeaGroupName(channelInfo.keaGroup));
+      infoObject->mSignatureSchemeName.Assign(
         getSignatureName(channelInfo.signatureScheme));
       infoObject->SetKEAUsed(channelInfo.keaType);
       infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
       infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
     }
   }
 
   // Don't update NPN details on renegotiation.
@@ -957,25 +951,23 @@ AccumulateCipherSuite(Telemetry::Histogr
 // case, we unfortunately don't know what the verified certificate chain was, if
 // the peer's server certificate verified as extended validation, or what its CT
 // status is (if enabled). To address this, we attempt to build a certificate
 // chain here using as much of the original context as possible (e.g. stapled
 // OCSP responses, SCTs, the hostname, the first party domain, etc.). Note that
 // because we are on the socket thread, this must not cause any network
 // requests, hence the use of FLAG_LOCAL_ONLY.
 static void
-RebuildVerifiedCertificateInformation(RefPtr<nsSSLStatus> sslStatus,
-                                      PRFileDesc* fd,
+RebuildVerifiedCertificateInformation(PRFileDesc* fd,
                                       nsNSSSocketInfo* infoObject)
 {
-  MOZ_ASSERT(sslStatus);
   MOZ_ASSERT(fd);
   MOZ_ASSERT(infoObject);
 
-  if (!sslStatus || !fd || !infoObject) {
+  if (!fd || !infoObject) {
     return;
   }
 
   UniqueCERTCertificate cert(SSL_PeerCertificate(fd));
   MOZ_ASSERT(cert, "SSL_PeerCertificate failed in TLS handshake callback?");
   if (!cert) {
     return;
   }
@@ -1032,29 +1024,29 @@ RebuildVerifiedCertificateInformation(Re
 
   if (rv != Success) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
             ("HandshakeCallback: couldn't rebuild verified certificate info"));
   }
 
   RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get()));
   if (rv == Success && evOidPolicy != SEC_OID_UNKNOWN) {
-    sslStatus->SetCertificateTransparencyInfo(certificateTransparencyInfo);
+    infoObject->SetCertificateTransparencyInfo(certificateTransparencyInfo);
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
             ("HandshakeCallback using NEW cert %p (is EV)", nssc.get()));
-    sslStatus->SetServerCert(nssc, EVStatus::EV);
+    infoObject->SetServerCert(nssc, EVStatus::EV);
   } else {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
             ("HandshakeCallback using NEW cert %p (is not EV)", nssc.get()));
-    sslStatus->SetServerCert(nssc, EVStatus::NotEV);
+    infoObject->SetServerCert(nssc, EVStatus::NotEV);
   }
 
   if (rv == Success) {
-    sslStatus->SetCertificateTransparencyInfo(certificateTransparencyInfo);
-    sslStatus->SetSucceededCertChain(std::move(builtChain));
+    infoObject->SetCertificateTransparencyInfo(certificateTransparencyInfo);
+    infoObject->SetSucceededCertChain(std::move(builtChain));
   }
 }
 
 static nsresult
 IsCertificateDistrustImminent(nsIX509CertList* aCertList,
                               /* out */ bool& isDistrusted) {
   if (!aCertList) {
     return NS_ERROR_INVALID_POINTER;
@@ -1219,67 +1211,60 @@ void HandshakeCallback(PRFileDesc* fd, v
   } else {
     // TLS 1.3 dropped support for renegotiation.
     siteSupportsSafeRenego = true;
   }
   bool renegotiationUnsafe = !siteSupportsSafeRenego &&
                              ioLayerHelpers.treatUnsafeNegotiationAsBroken();
 
 
-  /* Set the SSL Status information */
-  RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
-  if (!status) {
-    status = new nsSSLStatus();
-    infoObject->SetSSLStatus(status);
-  }
-
-  RememberCertErrorsTable::GetInstance().LookupCertErrorBits(infoObject,
-                                                             status);
+  RememberCertErrorsTable::GetInstance().LookupCertErrorBits(infoObject);
 
   uint32_t state;
   if (renegotiationUnsafe) {
     state = nsIWebProgressListener::STATE_IS_BROKEN;
   } else {
     state = nsIWebProgressListener::STATE_IS_SECURE |
             nsIWebProgressListener::STATE_SECURE_HIGH;
     SSLVersionRange defVersion;
     rv = SSL_VersionRangeGetDefault(ssl_variant_stream, &defVersion);
     if (rv == SECSuccess && versions.max >= defVersion.max) {
       // we know this site no longer requires a version fallback
       ioLayerHelpers.removeInsecureFallbackSite(infoObject->GetHostName(),
                                                 infoObject->GetPort());
     }
   }
 
-  if (status->HasServerCert()) {
+  if (infoObject->HasServerCert()) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
            ("HandshakeCallback KEEPING existing cert\n"));
   } else {
-    RebuildVerifiedCertificateInformation(status, fd, infoObject);
+    RebuildVerifiedCertificateInformation(fd, infoObject);
   }
 
   nsCOMPtr<nsIX509CertList> succeededCertChain;
   // This always returns NS_OK, but the list could be empty. This is a
   // best-effort check for now. Bug 731478 will reduce the incidence of empty
   // succeeded cert chains through better caching.
-  Unused << status->GetSucceededCertChain(getter_AddRefs(succeededCertChain));
+  Unused << infoObject->GetSucceededCertChain(
+                          getter_AddRefs(succeededCertChain));
   bool distrustImminent;
   nsresult srv = IsCertificateDistrustImminent(succeededCertChain,
                                                distrustImminent);
   if (NS_SUCCEEDED(srv) && distrustImminent) {
     state |= nsIWebProgressListener::STATE_CERT_DISTRUST_IMMINENT;
   }
 
   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);
+  Unused << infoObject->GetIsDomainMismatch(&domainMismatch);
+  Unused << infoObject->GetIsUntrusted(&untrusted);
+  Unused << infoObject->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);
 
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -455,39 +455,40 @@ nsNSSSocketInfo::IsAcceptableForHost(con
   // need to be considered. They are joinable.
   if (hostname.Equals(GetHostName())) {
     *_retval = true;
     return NS_OK;
   }
 
   // Before checking the server certificate we need to make sure the
   // handshake has completed.
-  if (!mHandshakeCompleted || !SSLStatus() || !SSLStatus()->HasServerCert()) {
+  if (!mHandshakeCompleted || !HasServerCert()) {
     return NS_OK;
   }
 
   // If the cert has error bits (e.g. it is untrusted) then do not join.
   // The value of mHaveCertErrorBits is only reliable because we know that
   // the handshake completed.
-  if (SSLStatus()->mHaveCertErrorBits)
+  if (mHaveCertErrorBits) {
     return NS_OK;
+  }
 
   // If the connection is using client certificates then do not join
   // because the user decides on whether to send client certs to hosts on a
   // per-domain basis.
   if (mSentClientCert)
     return NS_OK;
 
   // Ensure that the server certificate covers the hostname that would
   // like to join this connection
 
   UniqueCERTCertificate nssCert;
 
   nsCOMPtr<nsIX509Cert> cert;
-  if (NS_FAILED(SSLStatus()->GetServerCert(getter_AddRefs(cert)))) {
+  if (NS_FAILED(GetServerCert(getter_AddRefs(cert)))) {
     return NS_OK;
   }
   if (cert) {
     nssCert.reset(cert->GetCert());
   }
 
   if (!nssCert) {
     return NS_OK;
--- a/security/manager/ssl/nsNSSIOLayer.h
+++ b/security/manager/ssl/nsNSSIOLayer.h
@@ -56,16 +56,17 @@ public:
   SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; };
 
   PRStatus CloseSocketAndDestroy();
 
   void SetNegotiatedNPN(const char* value, uint32_t length);
   void SetEarlyDataAccepted(bool aAccepted);
 
   void SetHandshakeCompleted();
+  bool IsHandshakeCompleted() const { return mHandshakeCompleted; }
   void NoteTimeUntilReady();
 
 
   void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; }
   void SetFalseStarted() { mFalseStarted = true; }
 
   // Note that this is only valid *during* a handshake; at the end of the handshake,
   // it gets reset back to false.
--- a/security/manager/ssl/nsNSSModule.cpp
+++ b/security/manager/ssl/nsNSSModule.cpp
@@ -24,17 +24,16 @@
 #include "nsNSSComponent.h"
 #include "nsNSSVersion.h"
 #include "nsNTLMAuthModule.h"
 #include "nsNetCID.h"
 #include "nsPK11TokenDB.h"
 #include "nsPKCS11Slot.h"
 #include "nsRandomGenerator.h"
 #include "nsSSLSocketProvider.h"
-#include "nsSSLStatus.h"
 #include "nsSecureBrowserUIImpl.h"
 #include "nsSiteSecurityService.h"
 #include "nsTLSSocketProvider.h"
 #include "nsXULAppAPI.h"
 #include "OSKeyStore.h"
 
 #ifdef MOZ_XUL
 #include "nsCertTree.h"
@@ -149,17 +148,16 @@ NS_DEFINE_NAMED_CID(NS_CERTTREE_CID);
 NS_DEFINE_NAMED_CID(NS_CRYPTO_HASH_CID);
 NS_DEFINE_NAMED_CID(NS_CRYPTO_HMAC_CID);
 NS_DEFINE_NAMED_CID(NS_NTLMAUTHMODULE_CID);
 NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECT_CID);
 NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_CONTENTSIGNATUREVERIFIER_CID);
 NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID);
 NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID);
-NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID);
 NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
 NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NSSVERSION_CID);
 NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID);
 NS_DEFINE_NAMED_CID(NS_SITE_SECURITY_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CERT_BLOCKLIST_CID);
 NS_DEFINE_NAMED_CID(NS_OSKEYSTORE_CID);
 
@@ -200,18 +198,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_CONTENTSIGNATUREVERIFIER_CID, false, nullptr,
     Constructor<ContentSignatureVerifier> },
   { &kNS_CERTOVERRIDE_CID, false, nullptr,
     Constructor<nsCertOverrideService, &nsCertOverrideService::Init,
                 ProcessRestriction::ParentProcessOnly,
                 ThreadRestriction::MainThreadOnly> },
   { &kNS_RANDOMGENERATOR_CID, false, nullptr,
     Constructor<nsRandomGenerator, nullptr, ProcessRestriction::AnyProcess> },
-  { &kNS_SSLSTATUS_CID, false, nullptr,
-    Constructor<nsSSLStatus, nullptr, ProcessRestriction::AnyProcess> },
   { &kTRANSPORTSECURITYINFO_CID, false, nullptr,
     Constructor<TransportSecurityInfo, nullptr,
                 ProcessRestriction::AnyProcess> },
   { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor },
   { &kNS_NSSVERSION_CID, false, nullptr, nsNSSVersionConstructor },
   { &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor },
   { &kNS_SITE_SECURITY_SERVICE_CID, false, nullptr,
     Constructor<nsSiteSecurityService, &nsSiteSecurityService::Init,
deleted file mode 100644
--- a/security/manager/ssl/nsSSLStatus.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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/. */
-
-#include "CTVerifyResult.h"
-#include "mozilla/Casting.h"
-#include "nsSSLStatus.h"
-#include "nsIClassInfoImpl.h"
-#include "nsIObjectOutputStream.h"
-#include "nsIObjectInputStream.h"
-#include "nsNSSCertificate.h"
-#include "ssl.h"
-
-NS_IMETHODIMP
-nsSSLStatus::GetServerCert(nsIX509Cert** aServerCert)
-{
-  NS_ENSURE_ARG_POINTER(aServerCert);
-
-  nsCOMPtr<nsIX509Cert> cert = mServerCert;
-  cert.forget(aServerCert);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetKeyLength(uint32_t* aKeyLength)
-{
-  NS_ENSURE_ARG_POINTER(aKeyLength);
-  if (!mHaveCipherSuiteAndProtocol) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  SSLCipherSuiteInfo cipherInfo;
-  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
-                             sizeof(cipherInfo)) != SECSuccess) {
-    return NS_ERROR_FAILURE;
-  }
-
-  *aKeyLength = cipherInfo.symKeyBits;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetSecretKeyLength(uint32_t* aSecretKeyLength)
-{
-  NS_ENSURE_ARG_POINTER(aSecretKeyLength);
-  if (!mHaveCipherSuiteAndProtocol) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  SSLCipherSuiteInfo cipherInfo;
-  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
-                             sizeof(cipherInfo)) != SECSuccess) {
-    return NS_ERROR_FAILURE;
-  }
-
-  *aSecretKeyLength = cipherInfo.effectiveKeyBits;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetCipherName(nsACString& aCipherName)
-{
-  if (!mHaveCipherSuiteAndProtocol) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  SSLCipherSuiteInfo cipherInfo;
-  if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo,
-                             sizeof(cipherInfo)) != SECSuccess) {
-    return NS_ERROR_FAILURE;
-  }
-
-  aCipherName.Assign(cipherInfo.cipherSuiteName);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetKeaGroupName(nsACString& aKeaGroup)
-{
-  if (!mHaveCipherSuiteAndProtocol) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  aKeaGroup.Assign(mKeaGroup);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetSignatureSchemeName(nsACString& aSignatureScheme)
-{
-  if (!mHaveCipherSuiteAndProtocol) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  aSignatureScheme.Assign(mSignatureSchemeName);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetProtocolVersion(uint16_t* aProtocolVersion)
-{
-  NS_ENSURE_ARG_POINTER(aProtocolVersion);
-  if (!mHaveCipherSuiteAndProtocol) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  *aProtocolVersion = mProtocolVersion;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetCertificateTransparencyStatus(
-  uint16_t* aCertificateTransparencyStatus)
-{
-  NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus);
-
-  *aCertificateTransparencyStatus = mCertificateTransparencyStatus;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetIsDomainMismatch(bool* aIsDomainMismatch)
-{
-  NS_ENSURE_ARG_POINTER(aIsDomainMismatch);
-
-  *aIsDomainMismatch = mHaveCertErrorBits && mIsDomainMismatch;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetIsNotValidAtThisTime(bool* aIsNotValidAtThisTime)
-{
-  NS_ENSURE_ARG_POINTER(aIsNotValidAtThisTime);
-
-  *aIsNotValidAtThisTime = mHaveCertErrorBits && mIsNotValidAtThisTime;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetIsUntrusted(bool* aIsUntrusted)
-{
-  NS_ENSURE_ARG_POINTER(aIsUntrusted);
-
-  *aIsUntrusted = mHaveCertErrorBits && mIsUntrusted;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetIsExtendedValidation(bool* aIsEV)
-{
-  NS_ENSURE_ARG_POINTER(aIsEV);
-  *aIsEV = false;
-
-  // Never allow bad certs for EV, regardless of overrides.
-  if (mHaveCertErrorBits) {
-    return NS_OK;
-  }
-
-  if (mHasIsEVStatus) {
-    *aIsEV = mIsEV;
-    return NS_OK;
-  }
-
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::Read(nsIObjectInputStream* aStream)
-{
-  nsCOMPtr<nsISupports> cert;
-  nsresult rv = aStream->ReadObject(true, getter_AddRefs(cert));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mServerCert = do_QueryInterface(cert);
-  if (!mServerCert) {
-    return NS_NOINTERFACE;
-  }
-
-  rv = aStream->Read16(&mCipherSuite);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // The code below is a workaround to allow serializing new fields
-  // while preserving binary compatibility with older streams. For more details
-  // on the binary compatibility requirement, refer to bug 1248628.
-  // Here, we take advantage of the fact that mProtocolVersion was originally
-  // stored as a 16 bits integer, but the highest 8 bits were never used.
-  // These bits are now used for stream versioning.
-  uint16_t protocolVersionAndStreamFormatVersion;
-  rv = aStream->Read16(&protocolVersionAndStreamFormatVersion);
-  NS_ENSURE_SUCCESS(rv, rv);
-  mProtocolVersion = protocolVersionAndStreamFormatVersion & 0xFF;
-  const uint8_t streamFormatVersion =
-    (protocolVersionAndStreamFormatVersion >> 8) & 0xFF;
-
-  rv = aStream->ReadBoolean(&mIsDomainMismatch);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->ReadBoolean(&mIsNotValidAtThisTime);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->ReadBoolean(&mIsUntrusted);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->ReadBoolean(&mIsEV);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = aStream->ReadBoolean(&mHasIsEVStatus);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->ReadBoolean(&mHaveCipherSuiteAndProtocol);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->ReadBoolean(&mHaveCertErrorBits);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Added in version 1 (see bug 1305289).
-  if (streamFormatVersion >= 1) {
-    rv = aStream->Read16(&mCertificateTransparencyStatus);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Added in version 2 (see bug 1304923).
-  if (streamFormatVersion >= 2) {
-    rv = aStream->ReadCString(mKeaGroup);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = aStream->ReadCString(mSignatureSchemeName);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Added in version 3 (see bug 1406856).
-  if (streamFormatVersion >= 3) {
-    nsCOMPtr<nsISupports> succeededCertChainSupports;
-    rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(succeededCertChainSupports));
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    mSucceededCertChain = do_QueryInterface(succeededCertChainSupports);
-
-    nsCOMPtr<nsISupports> failedCertChainSupports;
-    rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(failedCertChainSupports));
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    mFailedCertChain = do_QueryInterface(failedCertChainSupports);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::Write(nsIObjectOutputStream* aStream)
-{
-  // The current version of the binary stream format.
-  const uint8_t STREAM_FORMAT_VERSION = 3;
-
-  nsresult rv = aStream->WriteCompoundObject(mServerCert,
-                                             NS_GET_IID(nsIX509Cert),
-                                             true);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = aStream->Write16(mCipherSuite);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  uint16_t protocolVersionAndStreamFormatVersion =
-    mozilla::AssertedCast<uint8_t>(mProtocolVersion) |
-    (STREAM_FORMAT_VERSION << 8);
-  rv = aStream->Write16(protocolVersionAndStreamFormatVersion);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = aStream->WriteBoolean(mIsDomainMismatch);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->WriteBoolean(mIsNotValidAtThisTime);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->WriteBoolean(mIsUntrusted);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->WriteBoolean(mIsEV);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = aStream->WriteBoolean(mHasIsEVStatus);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->WriteBoolean(mHaveCipherSuiteAndProtocol);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aStream->WriteBoolean(mHaveCertErrorBits);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Added in version 1.
-  rv = aStream->Write16(mCertificateTransparencyStatus);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Added in version 2.
-  rv = aStream->WriteStringZ(mKeaGroup.get());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = aStream->WriteStringZ(mSignatureSchemeName.get());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Added in version 3.
-  rv = NS_WriteOptionalCompoundObject(aStream,
-                                      mSucceededCertChain,
-                                      NS_GET_IID(nsIX509CertList),
-                                      true);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  rv = NS_WriteOptionalCompoundObject(aStream,
-                                      mFailedCertChain,
-                                      NS_GET_IID(nsIX509CertList),
-                                      true);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetInterfaces(uint32_t* aCount, nsIID*** aArray)
-{
-  *aCount = 0;
-  *aArray = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetScriptableHelper(nsIXPCScriptable** aHelper)
-{
-  *aHelper = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetContractID(nsACString& aContractID)
-{
-  aContractID.SetIsVoid(true);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetClassDescription(nsACString& aClassDescription)
-{
-  aClassDescription.SetIsVoid(true);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetClassID(nsCID** aClassID)
-{
-  *aClassID = (nsCID*) moz_xmalloc(sizeof(nsCID));
-  return GetClassIDNoAlloc(*aClassID);
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetFlags(uint32_t* aFlags)
-{
-  *aFlags = 0;
-  return NS_OK;
-}
-
-static NS_DEFINE_CID(kSSLStatusCID, NS_SSLSTATUS_CID);
-
-NS_IMETHODIMP
-nsSSLStatus::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
-{
-  *aClassIDNoAlloc = kSSLStatusCID;
-  return NS_OK;
-}
-
-nsSSLStatus::nsSSLStatus()
-: mCipherSuite(0)
-, mProtocolVersion(0)
-, mCertificateTransparencyStatus(nsISSLStatus::
-    CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE)
-, mKeaGroup()
-, mSignatureSchemeName()
-, mIsDomainMismatch(false)
-, mIsNotValidAtThisTime(false)
-, mIsUntrusted(false)
-, mIsEV(false)
-, mHasIsEVStatus(false)
-, mHaveCipherSuiteAndProtocol(false)
-, mHaveCertErrorBits(false)
-{
-}
-
-NS_IMPL_ISUPPORTS(nsSSLStatus, nsISSLStatus, nsISerializable, nsIClassInfo)
-
-void
-nsSSLStatus::SetServerCert(nsNSSCertificate* aServerCert, EVStatus aEVStatus)
-{
-  MOZ_ASSERT(aServerCert);
-
-  mServerCert = aServerCert;
-  mIsEV = (aEVStatus == EVStatus::EV);
-  mHasIsEVStatus = true;
-}
-
-nsresult
-nsSSLStatus::SetSucceededCertChain(UniqueCERTCertList aCertList)
-{
-  // nsNSSCertList takes ownership of certList
-  mSucceededCertChain = new nsNSSCertList(std::move(aCertList));
-
-  return NS_OK;
-}
-
-void
-nsSSLStatus::SetFailedCertChain(nsIX509CertList* aX509CertList)
-{
-  mFailedCertChain = aX509CertList;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetSucceededCertChain(nsIX509CertList** _result)
-{
-  NS_ENSURE_ARG_POINTER(_result);
-
-  nsCOMPtr<nsIX509CertList> tmpList = mSucceededCertChain;
-  tmpList.forget(_result);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSSLStatus::GetFailedCertChain(nsIX509CertList** _result)
-{
-  NS_ENSURE_ARG_POINTER(_result);
-
-  nsCOMPtr<nsIX509CertList> tmpList = mFailedCertChain;
-  tmpList.forget(_result);
-
-  return NS_OK;
-}
-
-void
-nsSSLStatus::SetCertificateTransparencyInfo(
-  const mozilla::psm::CertificateTransparencyInfo& info)
-{
-  using mozilla::ct::CTPolicyCompliance;
-
-  mCertificateTransparencyStatus =
-    nsISSLStatus::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
-
-  if (!info.enabled) {
-    // CT disabled.
-    return;
-  }
-
-  switch (info.policyCompliance) {
-    case CTPolicyCompliance::Compliant:
-      mCertificateTransparencyStatus =
-        nsISSLStatus::CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT;
-      break;
-    case CTPolicyCompliance::NotEnoughScts:
-      mCertificateTransparencyStatus =
-        nsISSLStatus::CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS;
-      break;
-    case CTPolicyCompliance::NotDiverseScts:
-      mCertificateTransparencyStatus =
-        nsISSLStatus::CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS;
-      break;
-    case CTPolicyCompliance::Unknown:
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
-  }
-}
deleted file mode 100644
--- a/security/manager/ssl/nsSSLStatus.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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/. */
-
-#ifndef _NSSSLSTATUS_H
-#define _NSSSLSTATUS_H
-
-#include "CertVerifier.h" // For CertificateTransparencyInfo
-#include "nsISSLStatus.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsIX509Cert.h"
-#include "nsIX509CertList.h"
-#include "nsISerializable.h"
-#include "nsIClassInfo.h"
-#include "nsNSSCertificate.h"
-#include "ScopedNSSTypes.h"
-
-class nsNSSCertificate;
-
-enum class EVStatus {
-  NotEV = 0,
-  EV = 1,
-};
-
-class nsSSLStatus final
-  : public nsISSLStatus
-  , public nsISerializable
-  , public nsIClassInfo
-{
-protected:
-  virtual ~nsSSLStatus() {}
-public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSISSLSTATUS
-  NS_DECL_NSISERIALIZABLE
-  NS_DECL_NSICLASSINFO
-
-  nsSSLStatus();
-
-  void SetServerCert(nsNSSCertificate* aServerCert, EVStatus aEVStatus);
-
-  nsresult SetSucceededCertChain(mozilla::UniqueCERTCertList certList);
-  void SetFailedCertChain(nsIX509CertList* x509CertList);
-
-  bool HasServerCert() {
-    return mServerCert != nullptr;
-  }
-
-  void SetCertificateTransparencyInfo(
-    const mozilla::psm::CertificateTransparencyInfo& info);
-
-  /* public for initilization in this file */
-  uint16_t mCipherSuite;
-  uint16_t mProtocolVersion;
-  uint16_t mCertificateTransparencyStatus;
-  nsCString mKeaGroup;
-  nsCString mSignatureSchemeName;
-
-  bool mIsDomainMismatch;
-  bool mIsNotValidAtThisTime;
-  bool mIsUntrusted;
-  bool mIsEV;
-
-  bool mHasIsEVStatus;
-  bool mHaveCipherSuiteAndProtocol;
-
-  /* mHaveCertErrrorBits is relied on to determine whether or not a SPDY
-     connection is eligible for joining in nsNSSSocketInfo::JoinConnection() */
-  bool mHaveCertErrorBits;
-
-private:
-  nsCOMPtr<nsIX509Cert> mServerCert;
-  nsCOMPtr<nsIX509CertList> mSucceededCertChain;
-  nsCOMPtr<nsIX509CertList> mFailedCertChain;
-};
-
-#define NS_SSLSTATUS_CID \
-{ 0xe2f14826, 0x9e70, 0x4647, \
-  { 0xb2, 0x3f, 0x10, 0x10, 0xf5, 0x12, 0x46, 0x28 } }
-
-#endif
--- a/security/manager/ssl/nsSecureBrowserUIImpl.cpp
+++ b/security/manager/ssl/nsSecureBrowserUIImpl.cpp
@@ -7,17 +7,16 @@
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Unused.h"
 #include "nsIChannel.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsISSLStatus.h"
 #include "nsISecurityEventSink.h"
 #include "nsITransportSecurityInfo.h"
 #include "nsIWebProgress.h"
 
 using namespace mozilla;
 
 LazyLogModule gSecureBrowserUILog("nsSecureBrowserUI");
 
@@ -219,38 +218,24 @@ nsSecureBrowserUIImpl::UpdateStateAndSec
             ("  we have a security info %p", securityInfo.get()));
     mTopLevelSecurityInfo = securityInfo;
     MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
             ("  set mTopLevelSecurityInfo"));
     nsresult rv = mTopLevelSecurityInfo->GetSecurityState(&mState);
     if (NS_FAILED(rv)) {
       return rv;
     }
-    nsCOMPtr<nsISSLStatus> sslStatus;
-    rv = mTopLevelSecurityInfo->GetSSLStatus(getter_AddRefs(sslStatus));
+    bool isEV;
+    rv = mTopLevelSecurityInfo->GetIsExtendedValidation(&isEV);
     if (NS_FAILED(rv)) {
       return rv;
     }
-    if (!sslStatus) {
-      MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
-              ("  no sslStatus -> setting state to not secure"));
-      mState = STATE_IS_INSECURE;
-      mTopLevelSecurityInfo = nullptr;
-    } else {
-      MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
-              ("  have sslStatus %p", sslStatus.get()));
-      bool isEV;
-      rv = sslStatus->GetIsExtendedValidation(&isEV);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      if (isEV) {
-        MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, ("  is EV"));
-        mState |= STATE_IDENTITY_EV_TOPLEVEL;
-      }
+    if (isEV) {
+      MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, ("  is EV"));
+      mState |= STATE_IDENTITY_EV_TOPLEVEL;
     }
   } else {
     mState = STATE_IS_INSECURE;
     mTopLevelSecurityInfo = nullptr;
   }
   return NS_OK;
 }
 
--- a/security/manager/ssl/nsSiteSecurityService.cpp
+++ b/security/manager/ssl/nsSiteSecurityService.cpp
@@ -14,19 +14,19 @@
 #include "mozilla/LinkedList.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Tokenizer.h"
 #include "mozilla/dom/PContent.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsArrayEnumerator.h"
 #include "nsCOMArray.h"
-#include "nsISSLStatus.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISocketProvider.h"
+#include "nsITransportSecurityInfo.h"
 #include "nsIURI.h"
 #include "nsIX509Cert.h"
 #include "nsNSSComponent.h"
 #include "nsNetUtil.h"
 #include "nsPromiseFlatString.h"
 #include "nsReadableUtils.h"
 #include "nsSecurityHeaderParser.h"
 #include "nsThreadUtils.h"
@@ -769,43 +769,43 @@ HostIsIPAddress(const nsCString& hostnam
   return (prv == PR_SUCCESS);
 }
 
 NS_IMETHODIMP
 nsSiteSecurityService::ProcessHeaderScriptable(
   uint32_t aType,
   nsIURI* aSourceURI,
   const nsACString& aHeader,
-  nsISSLStatus* aSSLStatus,
+  nsITransportSecurityInfo* aSecInfo,
   uint32_t aFlags,
   uint32_t aSource,
   JS::HandleValue aOriginAttributes,
   uint64_t* aMaxAge,
   bool* aIncludeSubdomains,
   uint32_t* aFailureResult,
   JSContext* aCx,
   uint8_t aArgc)
 {
   OriginAttributes originAttributes;
   if (aArgc > 0) {
     if (!aOriginAttributes.isObject() ||
         !originAttributes.Init(aCx, aOriginAttributes)) {
       return NS_ERROR_INVALID_ARG;
     }
   }
-  return ProcessHeader(aType, aSourceURI, aHeader, aSSLStatus, aFlags,
+  return ProcessHeader(aType, aSourceURI, aHeader, aSecInfo, aFlags,
                        aSource, originAttributes, aMaxAge, aIncludeSubdomains,
                        aFailureResult);
 }
 
 NS_IMETHODIMP
 nsSiteSecurityService::ProcessHeader(uint32_t aType,
                                      nsIURI* aSourceURI,
                                      const nsACString& aHeader,
-                                     nsISSLStatus* aSSLStatus,
+                                     nsITransportSecurityInfo* aSecInfo,
                                      uint32_t aFlags,
                                      uint32_t aHeaderSource,
                                      const OriginAttributes& aOriginAttributes,
                                      uint64_t* aMaxAge,
                                      bool* aIncludeSubdomains,
                                      uint32_t* aFailureResult)
 {
   // Child processes are not allowed direct access to this.
@@ -825,28 +825,28 @@ nsSiteSecurityService::ProcessHeader(uin
     case SourceUnknown:
     case SourcePreload:
     case SourceOrganic:
       break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
-  NS_ENSURE_ARG(aSSLStatus);
+  NS_ENSURE_ARG(aSecInfo);
   return ProcessHeaderInternal(aType, aSourceURI, PromiseFlatCString(aHeader),
-                               aSSLStatus, aFlags, source, aOriginAttributes,
+                               aSecInfo, aFlags, source, aOriginAttributes,
                                aMaxAge, aIncludeSubdomains, aFailureResult);
 }
 
 nsresult
 nsSiteSecurityService::ProcessHeaderInternal(
   uint32_t aType,
   nsIURI* aSourceURI,
   const nsCString& aHeader,
-  nsISSLStatus* aSSLStatus,
+  nsITransportSecurityInfo* aSecInfo,
   uint32_t aFlags,
   SecurityPropertySource aSource,
   const OriginAttributes& aOriginAttributes,
   uint64_t* aMaxAge,
   bool* aIncludeSubdomains,
   uint32_t* aFailureResult)
 {
   if (aFailureResult) {
@@ -860,29 +860,29 @@ nsSiteSecurityService::ProcessHeaderInte
   if (aMaxAge != nullptr) {
     *aMaxAge = 0;
   }
 
   if (aIncludeSubdomains != nullptr) {
     *aIncludeSubdomains = false;
   }
 
-  if (aSSLStatus) {
+  if (aSecInfo) {
     bool tlsIsBroken = false;
     bool trustcheck;
     nsresult rv;
-    rv = aSSLStatus->GetIsDomainMismatch(&trustcheck);
+    rv = aSecInfo->GetIsDomainMismatch(&trustcheck);
     NS_ENSURE_SUCCESS(rv, rv);
     tlsIsBroken = tlsIsBroken || trustcheck;
 
-    rv = aSSLStatus->GetIsNotValidAtThisTime(&trustcheck);
+    rv = aSecInfo->GetIsNotValidAtThisTime(&trustcheck);
     NS_ENSURE_SUCCESS(rv, rv);
     tlsIsBroken = tlsIsBroken || trustcheck;
 
-    rv = aSSLStatus->GetIsUntrusted(&trustcheck);
+    rv = aSecInfo->GetIsUntrusted(&trustcheck);
     NS_ENSURE_SUCCESS(rv, rv);
     tlsIsBroken = tlsIsBroken || trustcheck;
     if (tlsIsBroken) {
        SSSLOG(("SSS: discarding header from untrustworthy connection"));
        if (aFailureResult) {
          *aFailureResult = nsISiteSecurityService::ERROR_UNTRUSTWORTHY_CONNECTION;
        }
       return NS_ERROR_FAILURE;
@@ -899,17 +899,17 @@ nsSiteSecurityService::ProcessHeaderInte
 
   switch (aType) {
     case nsISiteSecurityService::HEADER_HSTS:
       rv = ProcessSTSHeader(aSourceURI, aHeader, aFlags, aSource,
                             aOriginAttributes, aMaxAge, aIncludeSubdomains,
                             aFailureResult);
       break;
     case nsISiteSecurityService::HEADER_HPKP:
-      rv = ProcessPKPHeader(aSourceURI, aHeader, aSSLStatus, aFlags,
+      rv = ProcessPKPHeader(aSourceURI, aHeader, aSecInfo, aFlags,
                             aOriginAttributes, aMaxAge, aIncludeSubdomains,
                             aFailureResult);
       break;
     default:
       MOZ_CRASH("unexpected header type");
   }
   return rv;
 }
@@ -1051,28 +1051,28 @@ ParseSSSHeaders(uint32_t aType,
   }
   return nsISiteSecurityService::Success;
 }
 
 nsresult
 nsSiteSecurityService::ProcessPKPHeader(
   nsIURI* aSourceURI,
   const nsCString& aHeader,
-  nsISSLStatus* aSSLStatus,
+  nsITransportSecurityInfo* aSecInfo,
   uint32_t aFlags,
   const OriginAttributes& aOriginAttributes,
   uint64_t* aMaxAge,
   bool* aIncludeSubdomains,
   uint32_t* aFailureResult)
 {
   if (aFailureResult) {
     *aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
   }
   SSSLOG(("SSS: processing HPKP header '%s'", aHeader.get()));
-  NS_ENSURE_ARG(aSSLStatus);
+  NS_ENSURE_ARG(aSecInfo);
 
   const uint32_t aType = nsISiteSecurityService::HEADER_HPKP;
   bool foundMaxAge = false;
   bool foundIncludeSubdomains = false;
   bool foundUnrecognizedDirective = false;
   uint64_t maxAge = 0;
   nsTArray<nsCString> sha256keys;
   uint32_t sssrv = ParseSSSHeaders(aType, aHeader, foundIncludeSubdomains,
@@ -1098,17 +1098,17 @@ nsSiteSecurityService::ProcessPKPHeader(
   // before we add the pin we need to ensure it will not break the site as
   // currently visited so:
   // 1. recompute a valid chain (no external ocsp)
   // 2. use this chain to check if things would have broken!
   nsAutoCString host;
   nsresult rv = GetHost(aSourceURI, host);
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIX509Cert> cert;
-  rv = aSSLStatus->GetServerCert(getter_AddRefs(cert));
+  rv = aSecInfo->GetServerCert(getter_AddRefs(cert));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(cert, NS_ERROR_FAILURE);
   UniqueCERTCertificate nssCert(cert->GetCert());
   NS_ENSURE_TRUE(nssCert, NS_ERROR_FAILURE);
 
   // This use of VerifySSLServerCert should be able to be removed in Bug #1406854
   mozilla::pkix::Time now(mozilla::pkix::Now());
   UniqueCERTCertList certList;
--- a/security/manager/ssl/nsSiteSecurityService.h
+++ b/security/manager/ssl/nsSiteSecurityService.h
@@ -13,17 +13,17 @@
 #include "nsIObserver.h"
 #include "nsISiteSecurityService.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "pkix/pkixtypes.h"
 #include "prtime.h"
 
 class nsIURI;
-class nsISSLStatus;
+class nsITransportSecurityInfo;
 
 using mozilla::OriginAttributes;
 
 // {16955eee-6c48-4152-9309-c42a465138a1}
 #define NS_SITE_SECURITY_SERVICE_CID \
   {0x16955eee, 0x6c48, 0x4152, \
     {0x93, 0x09, 0xc4, 0x2a, 0x46, 0x51, 0x38, 0xa1} }
 
@@ -173,30 +173,30 @@ private:
   nsresult GetHost(nsIURI *aURI, nsACString &aResult);
   nsresult SetHSTSState(uint32_t aType, const char* aHost, int64_t maxage,
                         bool includeSubdomains, uint32_t flags,
                         SecurityPropertyState aHSTSState,
                         SecurityPropertySource aSource,
                         const OriginAttributes& aOriginAttributes);
   nsresult ProcessHeaderInternal(uint32_t aType, nsIURI* aSourceURI,
                                  const nsCString& aHeader,
-                                 nsISSLStatus* aSSLStatus,
+                                 nsITransportSecurityInfo* aSecInfo,
                                  uint32_t aFlags,
                                  SecurityPropertySource aSource,
                                  const OriginAttributes& aOriginAttributes,
                                  uint64_t* aMaxAge, bool* aIncludeSubdomains,
                                  uint32_t* aFailureResult);
   nsresult ProcessSTSHeader(nsIURI* aSourceURI, const nsCString& aHeader,
                             uint32_t flags,
                             SecurityPropertySource aSource,
                             const OriginAttributes& aOriginAttributes,
                             uint64_t* aMaxAge, bool* aIncludeSubdomains,
                             uint32_t* aFailureResult);
   nsresult ProcessPKPHeader(nsIURI* aSourceURI, const nsCString& aHeader,
-                            nsISSLStatus* aSSLStatus, uint32_t flags,
+                            nsITransportSecurityInfo* aSecInfo, uint32_t flags,
                             const OriginAttributes& aOriginAttributes,
                             uint64_t* aMaxAge, bool* aIncludeSubdomains,
                             uint32_t* aFailureResult);
   nsresult SetHPKPState(const char* aHost, SiteHPKPState& entry, uint32_t flags,
                         bool aIsPreload,
                         const OriginAttributes& aOriginAttributes);
   nsresult RemoveStateInternal(uint32_t aType, nsIURI* aURI, uint32_t aFlags,
                                const OriginAttributes& aOriginAttributes);
--- a/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp
+++ b/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp
@@ -1,32 +1,64 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "gtest/gtest.h"
 #include "nsCOMPtr.h"
-#include "nsString.h"
+#include "nsITransportSecurityInfo.h"
+#include "nsIX509Cert.h"
+#include "nsIX509CertList.h"
 #include "nsSerializationHelper.h"
+#include "nsString.h"
 
+// nsITransportSecurityInfo de-serializatin tests
+//
 // These tests verify that we can still deserialize old binary strings
 // generated for security info.  This is necessary because service workers
 // stores these strings on disk.
 //
 // If you make a change and start breaking these tests, you will need to
 // add a compat fix for loading the old versions.  For things that affect
 // the UUID, but do not break the rest of the format you can simply add
 // another hack condition in nsBinaryInputStream::ReadObject().  If you
 // change the overall format of the serialization then we will need more
 // complex handling in the security info concrete classes.
 //
 // We would like to move away from this binary compatibility requirement
 // in service workers.  See bug 1248628.
+void
+deserializeAndVerify(const nsCString &serializedSecInfo,
+                     bool hasFailedCertChain)
+{
+  nsCOMPtr<nsISupports> secInfo;
+  nsresult rv = NS_DeserializeObject(serializedSecInfo, getter_AddRefs(secInfo));
+  ASSERT_EQ(NS_OK, rv);
+  ASSERT_TRUE(secInfo);
+
+  nsCOMPtr<nsITransportSecurityInfo> securityInfo = do_QueryInterface(secInfo);
+  ASSERT_TRUE(securityInfo);
+
+  nsCOMPtr<nsIX509Cert> cert;
+  rv = securityInfo->GetServerCert(getter_AddRefs(cert));
+  ASSERT_EQ(NS_OK, rv);
+  ASSERT_TRUE(cert);
+
+  nsCOMPtr<nsIX509CertList> failedChain;
+  rv = securityInfo->GetFailedCertChain(getter_AddRefs(failedChain));
+  ASSERT_EQ(NS_OK, rv);
+ 
+  if (hasFailedCertChain) { 
+    ASSERT_TRUE(failedChain);
+  } else {
+    ASSERT_FALSE(failedChain);
+  }
+}
 
 TEST(psm_DeserializeCert, gecko33)
 {
   // Gecko 33+ vintage Security info serialized with UUIDs:
   //  - nsISupports  00000000-0000-0000-c000-000000000046
   //  - nsISSLStatus fa9ba95b-ca3b-498a-b889-7c79cf28fee8
   //  - nsIX509Cert  f8ed8364-ced9-4c6e-86ba-48af53c393e6
   nsCString base64Serialization(
@@ -48,20 +80,17 @@ TEST(psm_DeserializeCert, gecko33)
   "9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggrBgEFBQc"
   "wAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUN"
   "lcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAc4dbVmuKvyI7"
   "KZ4Txk+ZqcAYToJGKUIVaPL94e5SZGweUisjaCbplAOihnf6Mxt8n6vnuH2IsCaz2NRHqhdcosjT3CwAiJpJNkXPKWVL/txgdSTV"
   "2cqB1GG4esFOalvI52dzn+J4fTIYZvNF+AtGyHSLm2XRXYZCw455laUKf6Sk9RDShDgUvzhOKL4GXfTwKXv12MyMknJybH8UCpjC"
   "HZmFBVHMcUN/87HsQo20PdOekeEvkjrrMIxW+gxw22Yb67yF/qKgwrWr+43bLN709iyw+LWiU7sQcHL2xk9SYiWQDj2tYz2soObV"
   "QYTJm0VUZMEVFhtALq46cx92Zu4vFwC8AAwAAAAABAQAA");
 
-  nsCOMPtr<nsISupports> cert;
-  nsresult rv = NS_DeserializeObject(base64Serialization, getter_AddRefs(cert));
-  ASSERT_EQ(NS_OK, rv);
-  ASSERT_TRUE(cert);
+  deserializeAndVerify(base64Serialization, false);
 }
 
 TEST(psm_DeserializeCert, gecko46)
 {
   // Gecko 46+ vintage Security info serialized with UUIDs:
   //  - nsISupports  00000000-0000-0000-c000-000000000046
   //  - nsISSLStatus fa9ba95b-ca3b-498a-b889-7c79cf28fee8
   //  - nsIX509Cert  bdc3979a-5422-4cd5-8589-696b6e96ea83
@@ -84,13 +113,124 @@ TEST(psm_DeserializeCert, gecko46)
   "9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHU"
   "wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQ"
   "uY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQE"
   "ATxbRdPg+o49+96/P+rbdp4ie+CGtfCgUubT/Z9C54k+BfQO0nbxVgCSM5WZQuLgo2Q+0lcxisod8zxZeU0j5wviQINwOln/iN89"
   "Bx3VmDRynTe4CqhsAwOoO1ERmCAmsAJBwY/rNr4mK22p8erBrqMW0nYXYU5NFynI+pNTjojhKD4II8PNV8G2yMWwYOb/u4+WPzUA"
   "HC9DpZdrWTEH/W69Cr/KxRqGsWPwpgMv2Wqav8jaT35JxqTXjOlhQqzo6fNn3eYOeCf4PkCxZKwckWjy10qDaRbjhwAMHAGj2TPr"
   "idlvOj/7QyyX5m8up/1US8z1fRW4yoCSOt6V2bwuH6cAvAAMAAAAAAQEAAA==");
 
-  nsCOMPtr<nsISupports> cert;
-  nsresult rv = NS_DeserializeObject(base64Serialization, getter_AddRefs(cert));
-  ASSERT_EQ(NS_OK, rv);
-  ASSERT_TRUE(cert);
+  deserializeAndVerify(base64Serialization, false);
+}
+
+TEST(psm_DeserializeCert, preSSLStatusConsolidation)
+{
+  // Generated using serialized output of test "good.include-subdomains.pinning.example.com"
+  // in security/manager/ssl/tests/unit/test_cert_chains.js
+  nsCString base64Serialization(
+  "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAgAAgAAAAAAAAAAAAAAAAAAAAAB4vFIJp5w"
+  "RkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAONMIIDiTCCAnGg"
+  "AwIBAgIUWbWLTwLBvfwcoiU7I8lDz9snfUgwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE2MTEyNzAw"
+  "MDAwMFoYDzIwMTkwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw"
+  "ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV"
+  "JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o"
+  "N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd"
+  "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0"
+  "gg0qLmV4YW1wbGUuY29tghUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs"
+  "ZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAB"
+  "hhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQBE+6IPJK5OeonoQPC4CCWMd69SjhwS7X6TNgxDJzW7"
+  "qpVm4SFyYZ2xqzr2zib5LsYek6/jok5LPSpJVeFuSeiesvGMxk0O4ZEihPxSM4uR4xpCnPzz7LoFIzMELJv5i+cgLw4+6cINPkLj"
+  "oCUdb+AXSTur7THJaO75B44I2JjJfMfzgW1FwoWgXL/PQWRw+VY6OY1glqZOXzP+vfSja1SoggpiCzdPx7h1/SEEZov7zhCZXv1C"
+  "enx1njlpcj9wWEJMsyZczMNtiz5GkRrLaqCz9F8ah3NvkvPAZ0oOqtxuQgMXK/c0OXJVKi0SCJsWqZDoZhCrS/dE9guxlseZqhSI"
+  "wC8DAwAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+xZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgA"
+  "AAACZgoyJpFcT/u7IImFpjLfBb3Dl5pUIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFFm1i08Cwb38HKIlOyPJQ8/b"
+  "J31IMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNjExMjcwMDAwMDBaGA8yMDE5MDIwNTAwMDAwMFow"
+  "GjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2"
+  "ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC"
+  "a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk"
+  "zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+"
+  "SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbYIVKi5waW5u"
+  "aW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZG9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9t"
+  "YWlucy5waW5uaW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4"
+  "LzANBgkqhkiG9w0BAQsFAAOCAQEARPuiDySuTnqJ6EDwuAgljHevUo4cEu1+kzYMQyc1u6qVZuEhcmGdsas69s4m+S7GHpOv46JO"
+  "Sz0qSVXhbknonrLxjMZNDuGRIoT8UjOLkeMaQpz88+y6BSMzBCyb+YvnIC8OPunCDT5C46AlHW/gF0k7q+0xyWju+QeOCNiYyXzH"
+  "84FtRcKFoFy/z0FkcPlWOjmNYJamTl8z/r30o2tUqIIKYgs3T8e4df0hBGaL+84QmV79Qnp8dZ45aXI/cFhCTLMmXMzDbYs+RpEa"
+  "y2qgs/RfGodzb5LzwGdKDqrcbkIDFyv3NDlyVSotEgibFqmQ6GYQq0v3RPYLsZbHmaoUiGYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM"
+  "1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYD"
+  "VQQDDAdUZXN0IENBMCIYDzIwMTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0G"
+  "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr"
+  "4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk"
+  "fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo"
+  "4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQF"
+  "MAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK"
+  "9cZFVtzRWYEYkIlicAyTiPw34bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK9"
+  "22MsOsnrLjNlpRDmuH0VFhb5uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZB"
+  "bEw7P6+V9zz5cAzaaq7EB0mCE+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBCAAA=");
+
+  deserializeAndVerify(base64Serialization, false);
 }
+
+TEST(psm_DeserializeCert, preSSLStatusConsolidationFailedCertChain)
+{
+  // Generated using serialized output of test "expired.example.com"
+  // in security/manager/ssl/tests/unit/test_cert_chains.js
+  nsCString base64Serialization(
+  "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAAAAAAAAAAA///gCwAAAAAB4vFIJp5w"
+  "RkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAMgMIIDHDCCAgSg"
+  "AwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAw"
+  "MDAwMFoYDzIwMTQwMTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEB"
+  "BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6"
+  "pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9"
+  "0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK"
+  "lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJl"
+  "ZC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcN"
+  "AQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7"
+  "IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l"
+  "297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6"
+  "laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7IAAAMAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vY"
+  "kTvlMZeudM2lzS9HP5b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwggMcMIICBKAD"
+  "AgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAw"
+  "MDAwWhgPMjAxNDAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEF"
+  "AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql"
+  "WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S"
+  "O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV"
+  "YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVk"
+  "LmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0B"
+  "AQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF0DjclopP2B8yxuc/WqIjbN6XdT4Xsg"
+  "Aw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrKf/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb"
+  "3tlpKXSdsp99vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag7gO5iubzT+npsw7qV"
+  "oHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAA"
+  "AAAAAtcwggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENB"
+  "MCIYDzIwMTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA"
+  "A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa"
+  "p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7"
+  "xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh"
+  "He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0P"
+  "BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK9cZFVtzRWYEYkIli"
+  "cAyTiPw34bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK922MsOsnrLjNlpRDm"
+  "uH0VFhb5uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZBbEw7P6+V9zz5cAza"
+  "aq7EB0mCE+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBCAZWfsWVlF0h/q5vYkTvlMZeu"
+  "dM2lzS9HP5b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwggMcMIICBKADAgECAhRj"
+  "0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgP"
+  "MjAxNDAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A"
+  "MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc"
+  "1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf"
+  "qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl"
+  "nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1w"
+  "bGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOC"
+  "AQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvk"
+  "VV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrKf/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSd"
+  "sp99vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag7gO5iubzT+npsw7qVoHRS/lbq"
+  "5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcw"
+  "ggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIw"
+  "MTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw"
+  "ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV"
+  "JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o"
+  "N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd"
+  "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEG"
+  "MA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK9cZFVtzRWYEYkIlicAyTiPw3"
+  "4bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK922MsOsnrLjNlpRDmuH0VFhb5"
+  "uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZBbEw7P6+V9zz5cAzaaq7EB0mC"
+  "E+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBC");
+
+  deserializeAndVerify(base64Serialization, true);
+}
+
--- a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
@@ -1,28 +1,28 @@
 /* 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 FakeSSLStatus = function() {
+var FakeTransportSecurityInfo = function() {
 };
 
-FakeSSLStatus.prototype = {
+FakeTransportSecurityInfo.prototype = {
   serverCert: null,
   cipherName: null,
   keyLength: 2048,
   isDomainMismatch: false,
   isNotValidAtThisTime: false,
   isUntrusted: false,
   isExtendedValidation: false,
   getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
-  QueryInterface: ChromeUtils.generateQI(["nsISSLStatus"]),
+  QueryInterface: ChromeUtils.generateQI(["nsITransportSecurityInfo"]),
 };
 
 function whenNewWindowLoaded(aOptions, aCallback) {
   let win = OpenBrowserWindow(aOptions);
   win.addEventListener("load", function() {
     aCallback(win);
   }, {once: true});
 }
@@ -39,20 +39,20 @@ function test() {
                    getService(Ci.nsISiteSecurityService);
 
   function privacyFlags(aIsPrivateMode) {
     return aIsPrivateMode ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
   }
 
   function doTest(aIsPrivateMode, aWindow, aCallback) {
     BrowserTestUtils.browserLoaded(aWindow.gBrowser.selectedBrowser).then(() => {
-      let sslStatus = new FakeSSLStatus();
+      let secInfo = new FakeTransportSecurityInfo();
       uri = aWindow.Services.io.newURI("https://localhost/img.png");
       gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                               "max-age=1000", sslStatus, privacyFlags(aIsPrivateMode),
+                               "max-age=1000", secInfo, privacyFlags(aIsPrivateMode),
                                Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
       ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                                 privacyFlags(aIsPrivateMode)),
                                 "checking sts host");
 
       aCallback();
     });
 
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -691,90 +691,87 @@ function startOCSPResponder(serverPort, 
 // resolves when the responder has successfully stopped.
 function stopOCSPResponder(responder) {
   return new Promise((resolve, reject) => {
     responder.stop(resolve);
   });
 }
 
 
-// A prototype for a fake, error-free sslstatus
-var FakeSSLStatus = function(certificate) {
+// A prototype for a fake, error-free secInfo
+var FakeTransportSecurityInfo = function(certificate) {
   this.serverCert = certificate;
 };
 
-FakeSSLStatus.prototype = {
+FakeTransportSecurityInfo.prototype = {
   serverCert: null,
   cipherName: null,
   keyLength: 2048,
   isDomainMismatch: false,
   isNotValidAtThisTime: false,
   isUntrusted: false,
   isExtendedValidation: false,
   getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
-  QueryInterface: ChromeUtils.generateQI(["nsISSLStatus"]),
+  QueryInterface: ChromeUtils.generateQI(["nsITransportSecurityInfo"]),
 };
 
 // Utility functions for adding tests relating to certificate error overrides
 
 // Helper function for add_cert_override_test. Probably doesn't need to be
 // called directly.
 function add_cert_override(aHost, aExpectedBits, aSecurityInfo) {
-  let sslstatus = aSecurityInfo.SSLStatus;
   let bits =
-    (sslstatus.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
-    (sslstatus.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
-    (sslstatus.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
+    (aSecurityInfo.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
+    (aSecurityInfo.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
+    (aSecurityInfo.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
 
   Assert.equal(bits, aExpectedBits,
                "Actual and expected override bits should match");
-  let cert = sslstatus.serverCert;
+  let cert = aSecurityInfo.serverCert;
   let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
                               .getService(Ci.nsICertOverrideService);
   certOverrideService.rememberValidityOverride(aHost, 8443, cert, aExpectedBits,
                                                true);
 }
 
 // Given a host, expected error bits (see nsICertOverrideService.idl), and an
 // expected error code, tests that an initial connection to the host fails
 // with the expected errors and that adding an override results in a subsequent
 // connection succeeding.
 function add_cert_override_test(aHost, aExpectedBits, aExpectedError,
-                                aExpectedSSLStatus = undefined) {
+                                aExpectedSecInfo = undefined) {
   add_connection_test(aHost, aExpectedError, null,
                       add_cert_override.bind(this, aHost, aExpectedBits));
   add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => {
     Assert.ok(aSecurityInfo.securityState &
               Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN,
               "Cert override flag should be set on the security state");
-    if (aExpectedSSLStatus) {
-      let sslstatus = aSecurityInfo.SSLStatus;
-      if (aExpectedSSLStatus.failedCertChain) {
-        ok(aExpectedSSLStatus.failedCertChain.equals(sslstatus.failedCertChain));
+    if (aExpectedSecInfo) {
+      if (aExpectedSecInfo.failedCertChain) {
+        ok(aExpectedSecInfo.failedCertChain.equals(aSecurityInfo.failedCertChain));
       }
     }
   });
 }
 
 // Helper function for add_prevented_cert_override_test. This is much like
 // add_cert_override except it may not be the case that the connection has an
-// SSLStatus set on it. In this case, the error was not overridable anyway, so
+// SecInfo set on it. In this case, the error was not overridable anyway, so
 // we consider it a success.
 function attempt_adding_cert_override(aHost, aExpectedBits, aSecurityInfo) {
-  let sslstatus = aSecurityInfo.SSLStatus;
-  if (sslstatus) {
+  if (aSecurityInfo.serverCert) {
     let bits =
-      (sslstatus.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
-      (sslstatus.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
-      (sslstatus.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
+      (aSecurityInfo.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
+      (aSecurityInfo.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
+      (aSecurityInfo.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
     Assert.equal(bits, aExpectedBits,
                  "Actual and expected override bits should match");
-    let cert = sslstatus.serverCert;
+    let cert = aSecurityInfo.serverCert;
     let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
                                 .getService(Ci.nsICertOverrideService);
     certOverrideService.rememberValidityOverride(aHost, 8443, cert, aExpectedBits,
                                                  true);
   }
 }
 
 // Given a host, expected error bits (see nsICertOverrideService.idl), and
--- a/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js
+++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js
@@ -5,25 +5,24 @@
 "use strict";
 
 // Tests that permanent certificate error overrides can be added even if the
 // certificate/key databases are in read-only mode.
 
 // Helper function for add_read_only_cert_override_test. Probably doesn't need
 // to be called directly.
 function add_read_only_cert_override(aHost, aExpectedBits, aSecurityInfo) {
-  let sslstatus = aSecurityInfo.SSLStatus;
   let bits =
-    (sslstatus.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
-    (sslstatus.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
-    (sslstatus.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
+    (aSecurityInfo.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
+    (aSecurityInfo.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
+    (aSecurityInfo.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
 
   Assert.equal(bits, aExpectedBits,
                "Actual and expected override bits should match");
-  let cert = sslstatus.serverCert;
+  let cert = aSecurityInfo.serverCert;
   let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
                               .getService(Ci.nsICertOverrideService);
   // Setting the last argument to false here ensures that we attempt to store a
   // permanent override (which is what was failing in bug 1427273).
   certOverrideService.rememberValidityOverride(aHost, 8443, cert, aExpectedBits,
                                                false);
 }
 
--- a/security/manager/ssl/tests/unit/test_ct.js
+++ b/security/manager/ssl/tests/unit/test_ct.js
@@ -6,18 +6,17 @@
 "use strict";
 
 do_get_profile(); // must be called before getting nsIX509CertDB
 const certdb  = Cc["@mozilla.org/security/x509certdb;1"]
                   .getService(Ci.nsIX509CertDB);
 
 function expectCT(value) {
   return (securityInfo) => {
-    let sslStatus = securityInfo.SSLStatus;
-    Assert.equal(sslStatus.certificateTransparencyStatus, value,
+    Assert.equal(securityInfo.certificateTransparencyStatus, value,
                  "actual and expected CT status should match");
   };
 }
 
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref("security.pki.certificate_transparency.mode");
 });
 
@@ -25,15 +24,15 @@ function run_test() {
   Services.prefs.setIntPref("security.pki.certificate_transparency.mode", 1);
   add_tls_server_setup("BadCertServer", "test_ct");
   // These certificates have a validity period of 800 days, which is a little
   // over 2 years and 2 months. This gets rounded down to 2 years (since it's
   // less than 2 years and 3 months). Our policy requires N + 1 embedded SCTs,
   // where N is 2 in this case. So, a policy-compliant certificate would have at
   // least 3 SCTs.
   add_connection_test("ct-valid.example.com", PRErrorCodeSuccess, null,
-    expectCT(Ci.nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT));
+    expectCT(Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT));
   // This certificate has only 2 embedded SCTs, and so is not policy-compliant.
   add_connection_test("ct-insufficient-scts.example.com", PRErrorCodeSuccess,
     null,
-    expectCT(Ci.nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS));
+    expectCT(Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS));
   run_next_test();
 }
--- a/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js
+++ b/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js
@@ -36,29 +36,29 @@ addCertFromFile(certdb, "test_pinning_dy
 
 var sss = Cc["@mozilla.org/ssservice;1"]
             .getService(Ci.nsISiteSecurityService);
 var uri = Services.io.newURI("https://a.pinning2.example.com");
 
 // This test re-uses certificates from pinning tests because that's easier and
 // simpler than recreating new certificates, hence the slightly longer than
 // necessary domain name.
-var sslStatus = new FakeSSLStatus(constructCertFromFile(
+var secInfo = new FakeTransportSecurityInfo(constructCertFromFile(
   "test_pinning_dynamic/a.pinning2.example.com-pinningroot.pem"));
 
 // Test the normal case of processing HSTS and HPKP headers for
 // a.pinning2.example.com, using "Forget About Site" on a.pinning2.example.com,
 // and then checking that the platform doesn't consider a.pinning2.example.com
 // to be HSTS or HPKP any longer.
 add_task(async function() {
   sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, GOOD_MAX_AGE,
-                    sslStatus, 0,
+                    secInfo, 0,
                     Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   sss.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                    GOOD_MAX_AGE + VALID_PIN + BACKUP_PIN, sslStatus, 0,
+                    GOOD_MAX_AGE + VALID_PIN + BACKUP_PIN, secInfo, 0,
                     Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
 
   Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0),
             "a.pinning2.example.com should be HSTS");
   Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0),
             "a.pinning2.example.com should be HPKP");
 
   await ForgetAboutSite.removeDataFromDomain("a.pinning2.example.com");
@@ -70,32 +70,32 @@ add_task(async function() {
 });
 
 // Test the case of processing HSTS and HPKP headers for a.pinning2.example.com,
 // using "Forget About Site" on example.com, and then checking that the platform
 // doesn't consider the subdomain to be HSTS or HPKP any longer. Also test that
 // unrelated sites don't also get removed.
 add_task(async function() {
   sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, GOOD_MAX_AGE,
-                    sslStatus, 0,
+                    secInfo, 0,
                     Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   sss.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                    GOOD_MAX_AGE + VALID_PIN + BACKUP_PIN, sslStatus, 0,
+                    GOOD_MAX_AGE + VALID_PIN + BACKUP_PIN, secInfo, 0,
                     Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
 
   Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0),
             "a.pinning2.example.com should be HSTS (subdomain case)");
   Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0),
             "a.pinning2.example.com should be HPKP (subdomain case)");
 
   // Add an unrelated site to HSTS.  Not HPKP because we have no valid keys for
   // example.org.
   let unrelatedURI = Services.io.newURI("https://example.org");
   sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, unrelatedURI,
-                    GOOD_MAX_AGE, sslStatus, 0,
+                    GOOD_MAX_AGE, secInfo, 0,
                     Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                              unrelatedURI, 0), "example.org should be HSTS");
 
   await ForgetAboutSite.removeDataFromDomain("example.com");
 
   Assert.ok(!sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0),
             "a.pinning2.example.com should not be HSTS now (subdomain case)");
@@ -119,34 +119,34 @@ add_task(async function() {
     { firstPartyDomain: "foo.com" },
     { userContextId: 1, firstPartyDomain: "foo.com" },
   ];
 
   let unrelatedURI = Services.io.newURI("https://example.org");
 
   for (let originAttributes of originAttributesList) {
     sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, GOOD_MAX_AGE,
-                      sslStatus, 0,
+                      secInfo, 0,
                       Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST,
                       originAttributes);
     sss.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                      GOOD_MAX_AGE + VALID_PIN + BACKUP_PIN, sslStatus, 0,
+                      GOOD_MAX_AGE + VALID_PIN + BACKUP_PIN, secInfo, 0,
                       Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST,
                       originAttributes);
 
     Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                                0, originAttributes),
               "a.pinning2.example.com should be HSTS (originAttributes case)");
     Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
                                0, originAttributes),
               "a.pinning2.example.com should be HPKP (originAttributes case)");
 
     // Add an unrelated site to HSTS.  Not HPKP because we have no valid keys.
     sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, unrelatedURI,
-                      GOOD_MAX_AGE, sslStatus, 0,
+                      GOOD_MAX_AGE, secInfo, 0,
                       Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST,
                       originAttributes);
     Assert.ok(sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                               unrelatedURI, 0, originAttributes),
               "example.org should be HSTS (originAttributes case)");
   }
 
   await ForgetAboutSite.removeDataFromDomain("example.com");
--- a/security/manager/ssl/tests/unit/test_ocsp_must_staple.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_must_staple.js
@@ -32,19 +32,19 @@ function add_tests() {
     Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1);
     Services.prefs.setBoolPref("security.cert_pinning.process_headers_from_non_builtin_roots", true);
     let uri = Services.io.newURI("https://ocsp-stapling-must-staple-ee-with-must-staple-int.example.com");
     let keyHash = "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=";
     let backupKeyHash = "KHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN=";
     let header = `max-age=1000; pin-sha256="${keyHash}"; pin-sha256="${backupKeyHash}"`;
     let ssservice = Cc["@mozilla.org/ssservice;1"]
                       .getService(Ci.nsISiteSecurityService);
-    let sslStatus = new FakeSSLStatus();
-    sslStatus.serverCert = constructCertFromFile("ocsp_certs/must-staple-ee-with-must-staple-int.pem");
-    ssservice.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri, header, sslStatus, 0,
+    let secInfo = new FakeTransportSecurityInfo();
+    secInfo.serverCert = constructCertFromFile("ocsp_certs/must-staple-ee-with-must-staple-int.pem");
+    ssservice.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri, header, secInfo, 0,
                             Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
     ok(ssservice.isSecureURI(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0),
        "ocsp-stapling-must-staple-ee-with-must-staple-int.example.com should have HPKP set");
 
     // Clear accumulated state.
     ssservice.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
     Services.prefs.clearUserPref("security.cert_pinning.process_headers_from_non_builtin_roots");
     Services.prefs.clearUserPref("security.cert_pinning.enforcement_level");
--- a/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js
@@ -37,18 +37,18 @@ function run_test() {
   add_connection_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess);
   add_test(function () { run_next_test(); });
 
   add_test(function () { ocspResponder.stop(run_next_test); });
 
   let SSService = Cc["@mozilla.org/ssservice;1"]
                     .getService(Ci.nsISiteSecurityService);
   let uri = Services.io.newURI("http://localhost");
-  let sslStatus = new FakeSSLStatus();
+  let secInfo = new FakeTransportSecurityInfo();
   SSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                          "max-age=10000", sslStatus, 0,
+                          "max-age=10000", secInfo, 0,
                           Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0),
      "Domain for the OCSP AIA URI should be considered a HSTS host, otherwise" +
      " we wouldn't be testing what we think we're testing");
 
   run_next_test();
 }
--- a/security/manager/ssl/tests/unit/test_pinning_header_parsing.js
+++ b/security/manager/ssl/tests/unit/test_pinning_header_parsing.js
@@ -18,46 +18,46 @@ function certFromFile(cert_name) {
 
 function loadCert(cert_name, trust_string) {
   let cert_filename = "test_pinning_dynamic/" + cert_name + ".pem";
   addCertFromFile(certdb, cert_filename, trust_string);
   return constructCertFromFile(cert_filename);
 }
 
 function checkFailParseInvalidPin(pinValue) {
-  let sslStatus = new FakeSSLStatus(
+  let secInfo = new FakeTransportSecurityInfo(
                         certFromFile("a.pinning2.example.com-pinningroot"));
   let uri = Services.io.newURI("https://a.pinning2.example.com");
   throws(() => {
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                             pinValue, sslStatus, 0,
+                             pinValue, secInfo, 0,
                              Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   }, /NS_ERROR_FAILURE/, `Invalid pin "${pinValue}" should be rejected`);
 }
 
 function checkPassValidPin(pinValue, settingPin, expectedMaxAge) {
-  let sslStatus = new FakeSSLStatus(
+  let secInfo = new FakeTransportSecurityInfo(
                         certFromFile("a.pinning2.example.com-pinningroot"));
   let uri = Services.io.newURI("https://a.pinning2.example.com");
   let maxAge = {};
 
   // setup preconditions for the test, if setting ensure there is no previous
   // state, if removing ensure there is a valid pin in place.
   if (settingPin) {
     gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
   } else {
     // add a known valid pin!
     let validPinValue = "max-age=5000;" + VALID_PIN1 + BACKUP_PIN1;
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                             validPinValue, sslStatus, 0,
+                             validPinValue, secInfo, 0,
                              Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   }
   try {
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri,
-                             pinValue, sslStatus, 0,
+                             pinValue, secInfo, 0,
                              Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST,
                              {}, maxAge);
     ok(true, "Valid pin should be accepted");
   } catch (e) {
     ok(false, "Valid pin should have been accepted");
   }
 
   // check that maxAge was processed correctly
--- a/security/manager/ssl/tests/unit/test_session_resumption.js
+++ b/security/manager/ssl/tests/unit/test_session_resumption.js
@@ -36,51 +36,49 @@ function add_resume_non_ev_with_override
   // This connects again, using session resumption. Note that we don't clear
   // the TLS session cache between these operations (that would defeat the
   // purpose).
   add_connection_test("expired.example.com", PRErrorCodeSuccess, null,
     (transportSecurityInfo) => {
       ok(transportSecurityInfo.securityState &
          Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN,
          "expired.example.com should have STATE_CERT_USER_OVERRIDDEN flag");
-      let sslStatus = transportSecurityInfo.SSLStatus;
-      ok(!sslStatus.succeededCertChain,
+      ok(!transportSecurityInfo.succeededCertChain,
          "ev-test.example.com should not have succeededCertChain set");
-      ok(!sslStatus.isDomainMismatch,
+      ok(!transportSecurityInfo.isDomainMismatch,
          "expired.example.com should not have isDomainMismatch set");
-      ok(sslStatus.isNotValidAtThisTime,
+      ok(transportSecurityInfo.isNotValidAtThisTime,
          "expired.example.com should have isNotValidAtThisTime set");
-      ok(!sslStatus.isUntrusted,
+      ok(!transportSecurityInfo.isUntrusted,
          "expired.example.com should not have isUntrusted set");
-      ok(!sslStatus.isExtendedValidation,
+      ok(!transportSecurityInfo.isExtendedValidation,
          "expired.example.com should not have isExtendedValidation set");
     }
   );
 }
 
 // Helper function that adds a test that connects to ev-test.example.com and
 // verifies that it validates as EV (or not, if we're running a non-debug
 // build). This assumes that an appropriate OCSP responder is running or that
 // good responses are cached.
 function add_one_ev_test() {
   add_connection_test("ev-test.example.com", PRErrorCodeSuccess, null,
     (transportSecurityInfo) => {
       ok(!(transportSecurityInfo.securityState &
            Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN),
          "ev-test.example.com should not have STATE_CERT_USER_OVERRIDDEN flag");
-      let sslStatus = transportSecurityInfo.SSLStatus;
-      ok(sslStatus.succeededCertChain,
+      ok(transportSecurityInfo.succeededCertChain,
          "ev-test.example.com should have succeededCertChain set");
-      ok(!sslStatus.isDomainMismatch,
+      ok(!transportSecurityInfo.isDomainMismatch,
          "ev-test.example.com should not have isDomainMismatch set");
-      ok(!sslStatus.isNotValidAtThisTime,
+      ok(!transportSecurityInfo.isNotValidAtThisTime,
          "ev-test.example.com should not have isNotValidAtThisTime set");
-      ok(!sslStatus.isUntrusted,
+      ok(!transportSecurityInfo.isUntrusted,
          "ev-test.example.com should not have isUntrusted set");
-      ok(!gEVExpected || sslStatus.isExtendedValidation,
+      ok(!gEVExpected || transportSecurityInfo.isExtendedValidation,
          "ev-test.example.com should have isExtendedValidation set " +
          "(or this is a non-debug build)");
     }
   );
 }
 
 // This test is similar, except with extended validation. We should connect
 // successfully, and the certificate should be EV in debug builds. Without
@@ -121,26 +119,25 @@ const GOOD_DOMAIN = "good.include-subdom
 // succeed (but isn't EV) and verifies that its succeededCertChain gets set
 // appropriately.
 function add_one_non_ev_test() {
   add_connection_test(GOOD_DOMAIN, PRErrorCodeSuccess, null,
     (transportSecurityInfo) => {
       ok(!(transportSecurityInfo.securityState &
            Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN),
          `${GOOD_DOMAIN} should not have STATE_CERT_USER_OVERRIDDEN flag`);
-      let sslStatus = transportSecurityInfo.SSLStatus;
-      ok(sslStatus.succeededCertChain,
+      ok(transportSecurityInfo.succeededCertChain,
          `${GOOD_DOMAIN} should have succeededCertChain set`);
-      ok(!sslStatus.isDomainMismatch,
+      ok(!transportSecurityInfo.isDomainMismatch,
          `${GOOD_DOMAIN} should not have isDomainMismatch set`);
-      ok(!sslStatus.isNotValidAtThisTime,
+      ok(!transportSecurityInfo.isNotValidAtThisTime,
          `${GOOD_DOMAIN} should not have isNotValidAtThisTime set`);
-      ok(!sslStatus.isUntrusted,
+      ok(!transportSecurityInfo.isUntrusted,
          `${GOOD_DOMAIN} should not have isUntrusted set`);
-      ok(!sslStatus.isExtendedValidation,
+      ok(!transportSecurityInfo.isExtendedValidation,
          `${GOOD_DOMAIN} should not have isExtendedValidation set`);
     }
   );
 }
 
 // This test is similar, except with non-extended validation. We should connect
 // successfully, and the certificate should not be EV. Without clearing the
 // session cache, we should connect successfully again, this time with session
--- a/security/manager/ssl/tests/unit/test_ssl_status.js
+++ b/security/manager/ssl/tests/unit/test_ssl_status.js
@@ -16,33 +16,31 @@ function run_test() {
   });
   fakeOCSPResponder.start(8888);
 
   // Test successful connection (failedCertChain should be null,
   // succeededCertChain should be set as expected)
   add_connection_test(
     "good.include-subdomains.pinning.example.com", PRErrorCodeSuccess, null,
     function withSecurityInfo(aSecInfo) {
-      let sslstatus = aSecInfo.SSLStatus;
-      equal(sslstatus.failedCertChain, null,
+      equal(aSecInfo.failedCertChain, null,
             "failedCertChain for a successful connection should be null");
-      ok(sslstatus.succeededCertChain.equals(build_cert_chain(["default-ee", "test-ca"])),
+      ok(aSecInfo.succeededCertChain.equals(build_cert_chain(["default-ee", "test-ca"])),
             "succeededCertChain for a successful connection should be as expected");
     }
   );
 
   // Test failed connection (failedCertChain should be set as expected,
   // succeededCertChain should be null)
   add_connection_test(
     "expired.example.com", SEC_ERROR_EXPIRED_CERTIFICATE, null,
     function withSecurityInfo(aSecInfo) {
-      let sslstatus = aSecInfo.SSLStatus;
-      equal(sslstatus.succeededCertChain, null,
+      equal(aSecInfo.succeededCertChain, null,
             "succeededCertChain for a failed connection should be null");
-      ok(sslstatus.failedCertChain.equals(build_cert_chain(["expired-ee", "test-ca"])),
+      ok(aSecInfo.failedCertChain.equals(build_cert_chain(["expired-ee", "test-ca"])),
             "failedCertChain for a failed connection should be as expected");
     }
   );
 
   // Ensure the correct failed cert chain is set on cert override
   let overrideStatus = {
     failedCertChain: build_cert_chain(["expired-ee", "test-ca"])
   };
--- a/security/manager/ssl/tests/unit/test_sss_enumerate.js
+++ b/security/manager/ssl/tests/unit/test_sss_enumerate.js
@@ -38,32 +38,32 @@ let certdb = Cc["@mozilla.org/security/x
                .getService(Ci.nsIX509CertDB);
 addCertFromFile(certdb, "test_pinning_dynamic/pinningroot.pem", "CTu,CTu,CTu");
 
 let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
 
 function insertEntries() {
   for (let testcase of TESTCASES) {
     let uri = Services.io.newURI("https://" + testcase.hostname);
-    let sslStatus = new FakeSSLStatus(constructCertFromFile(
+    let secInfo = new FakeTransportSecurityInfo(constructCertFromFile(
       `test_pinning_dynamic/${testcase.hostname}-pinningroot.pem`));
     // MaxAge is in seconds.
     let maxAge = Math.round((testcase.expireTime - Date.now()) / 1000);
     let header = `max-age=${maxAge}`;
     if (testcase.includeSubdomains) {
       header += "; includeSubdomains";
     }
     sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, header,
-                      sslStatus, 0,
+                      secInfo, 0,
                       Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
     for (let key of KEY_HASHES) {
       header += `; pin-sha256="${key}"`;
     }
     sss.processHeader(Ci.nsISiteSecurityService.HEADER_HPKP, uri, header,
-                      sslStatus, 0,
+                      secInfo, 0,
                       Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   }
 }
 
 function getEntries(type) {
   return Array.from(sss.enumerate(type));
 }
 
--- a/security/manager/ssl/tests/unit/test_sss_eviction.js
+++ b/security/manager/ssl/tests/unit/test_sss_eviction.js
@@ -49,21 +49,21 @@ function do_state_read(aSubject, aTopic,
     return;
   }
 
   equal(aData, SSS_STATE_FILE_NAME);
 
   ok(gSSService.isSecureURI(
        Ci.nsISiteSecurityService.HEADER_HSTS,
        Services.io.newURI("https://frequentlyused.example.com"), 0));
-  let sslStatus = new FakeSSLStatus();
+  let secInfo = new FakeTransportSecurityInfo();
   for (let i = 0; i < 2000; i++) {
     let uri = Services.io.newURI("http://bad" + i + ".example.com");
     gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                            "max-age=1000", sslStatus, 0,
+                            "max-age=1000", secInfo, 0,
                             Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   }
   do_test_pending();
   Services.obs.addObserver(do_state_written, "data-storage-written");
   do_test_finished();
 }
 
 function run_test() {
--- a/security/manager/ssl/tests/unit/test_sss_originAttributes.js
+++ b/security/manager/ssl/tests/unit/test_sss_originAttributes.js
@@ -34,31 +34,31 @@ addCertFromFile(certdb, "test_pinning_dy
 let sss = Cc["@mozilla.org/ssservice;1"]
             .getService(Ci.nsISiteSecurityService);
 let host = "a.pinning2.example.com";
 let uri = Services.io.newURI("https://" + host);
 
 // This test re-uses certificates from pinning tests because that's easier and
 // simpler than recreating new certificates, hence the slightly longer than
 // necessary domain name.
-let sslStatus = new FakeSSLStatus(constructCertFromFile(
+let secInfo = new FakeTransportSecurityInfo(constructCertFromFile(
   "test_pinning_dynamic/a.pinning2.example.com-pinningroot.pem"));
 
 // Check if originAttributes1 and originAttributes2 are isolated with respect
 // to HSTS/HPKP storage.
 function doTest(originAttributes1, originAttributes2, shouldShare) {
   sss.clearAll();
   for (let type of [Ci.nsISiteSecurityService.HEADER_HSTS,
                     Ci.nsISiteSecurityService.HEADER_HPKP]) {
     let header = GOOD_MAX_AGE;
     if (type == Ci.nsISiteSecurityService.HEADER_HPKP) {
       header += VALID_PIN + BACKUP_PIN;
     }
     // Set HSTS or HPKP for originAttributes1.
-    sss.processHeader(type, uri, header, sslStatus, 0,
+    sss.processHeader(type, uri, header, secInfo, 0,
                       Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST,
                       originAttributes1);
     ok(sss.isSecureURI(type, uri, 0, originAttributes1),
        "URI should be secure given original origin attributes");
     equal(sss.isSecureURI(type, uri, 0, originAttributes2), shouldShare,
           "URI should be secure given different origin attributes if and " +
           "only if shouldShare is true");
 
@@ -96,17 +96,17 @@ function testInvalidOriginAttributes(ori
   for (let type of [Ci.nsISiteSecurityService.HEADER_HSTS,
                     Ci.nsISiteSecurityService.HEADER_HPKP]) {
     let header = GOOD_MAX_AGE;
     if (type == Ci.nsISiteSecurityService.HEADER_HPKP) {
       header += VALID_PIN + BACKUP_PIN;
     }
 
     let callbacks = [
-      () => sss.processHeader(type, uri, header, sslStatus, 0,
+      () => sss.processHeader(type, uri, header, secInfo, 0,
                               Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST,
                               originAttributes),
       () => sss.isSecureURI(type, uri, 0, originAttributes),
       () => sss.removeState(type, uri, 0, originAttributes),
     ];
 
     for (let callback of callbacks) {
       throws(callback, /NS_ERROR_ILLEGAL_VALUE/,
--- a/security/manager/ssl/tests/unit/test_sss_savestate.js
+++ b/security/manager/ssl/tests/unit/test_sss_savestate.js
@@ -110,18 +110,18 @@ function run_test() {
                Services.io.newURI("http://d.example.com") ];
 
   for (let i = 0; i < 1000; i++) {
     let uriIndex = i % uris.length;
     // vary max-age
     let maxAge = "max-age=" + (i * 1000);
      // alternate setting includeSubdomains
     let includeSubdomains = (i % 2 == 0 ? "; includeSubdomains" : "");
-    let sslStatus = new FakeSSLStatus();
+    let secInfo = new FakeTransportSecurityInfo();
     SSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS,
                             uris[uriIndex], maxAge + includeSubdomains,
-                            sslStatus, 0,
+                            secInfo, 0,
                             Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   }
 
   do_test_pending();
   Services.obs.addObserver(checkStateWritten, "data-storage-written");
 }
--- a/security/manager/ssl/tests/unit/test_sts_fqdn.js
+++ b/security/manager/ssl/tests/unit/test_sts_fqdn.js
@@ -10,19 +10,19 @@ function run_test() {
   let uri = Services.io.newURI("https://example.com");
   let uri1 = Services.io.newURI("https://example.com.");
   let uri2 = Services.io.newURI("https://example.com..");
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0));
   // These cases are only relevant as long as bug 1118522 hasn't been fixed.
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0));
 
-  let sslStatus = new FakeSSLStatus();
+  let secInfo = new FakeTransportSecurityInfo();
   SSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                          "max-age=1000;includeSubdomains", sslStatus, 0,
+                          "max-age=1000;includeSubdomains", secInfo, 0,
                           Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
   ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0));
   ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0));
 
   SSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0));
--- a/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js
+++ b/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js
@@ -1,12 +1,12 @@
 "use strict";
 
 function check_ip(s, v, ip) {
-  let sslStatus = new FakeSSLStatus();
+  let secInfo = new FakeTransportSecurityInfo();
 
   let str = "https://";
   if (v == 6) {
     str += "[";
   }
   str += ip;
   if (v == 6) {
     str += "]";
@@ -14,17 +14,17 @@ function check_ip(s, v, ip) {
   str += "/";
 
   let uri = Services.io.newURI(str);
   ok(!s.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
 
   let parsedMaxAge = {};
   let parsedIncludeSubdomains = {};
   s.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                  "max-age=1000;includeSubdomains", sslStatus, 0,
+                  "max-age=1000;includeSubdomains", secInfo, 0,
                   Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, {},
                   parsedMaxAge, parsedIncludeSubdomains);
   ok(!s.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0),
      "URI should not be secure if it contains an IP address");
 
   /* Test that processHeader will ignore headers for an uri, if the uri
    * contains an IP address not a hostname.
    * If processHeader indeed ignore the header, then the output parameters will
--- a/security/manager/ssl/tests/unit/test_sts_parser.js
+++ b/security/manager/ssl/tests/unit/test_sts_parser.js
@@ -4,40 +4,40 @@
  * 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";
 
 // STS parser tests
 
 let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
-let sslStatus = new FakeSSLStatus();
+let secInfo = new FakeTransportSecurityInfo();
 
 function testSuccess(header, expectedMaxAge, expectedIncludeSubdomains) {
   let dummyUri = Services.io.newURI("https://foo.com/bar.html");
   let maxAge = {};
   let includeSubdomains = {};
 
   sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, dummyUri, header,
-                    sslStatus, 0, sss.SOURCE_ORGANIC_REQUEST, {}, maxAge,
+                    secInfo, 0, sss.SOURCE_ORGANIC_REQUEST, {}, maxAge,
                     includeSubdomains);
 
   equal(maxAge.value, expectedMaxAge, "Did not correctly parse maxAge");
   equal(includeSubdomains.value, expectedIncludeSubdomains,
         "Did not correctly parse presence/absence of includeSubdomains");
 }
 
 function testFailure(header) {
   let dummyUri = Services.io.newURI("https://foo.com/bar.html");
   let maxAge = {};
   let includeSubdomains = {};
 
   throws(() => {
     sss.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, dummyUri, header,
-                      sslStatus, 0, sss.SOURCE_ORGANIC_REQUEST, {}, maxAge,
+                      secInfo, 0, sss.SOURCE_ORGANIC_REQUEST, {}, maxAge,
                       includeSubdomains);
   }, /NS_ERROR_FAILURE/, "Parsed invalid header: " + header);
 }
 
 function run_test() {
     // SHOULD SUCCEED:
     testSuccess("max-age=100", 100, false);
     testSuccess("max-age  =100", 100, false);
--- a/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js
+++ b/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js
@@ -10,17 +10,17 @@
 // * checks that includeSubdomains is honored
 // * checks that clearing preloads works correctly
 // * checks that clearing a host's HSTS state via a header correctly
 //   overrides dynamic preload entries
 
 function run_test() {
   let SSService = Cc["@mozilla.org/ssservice;1"]
                     .getService(Ci.nsISiteSecurityService);
-  let sslStatus = new FakeSSLStatus();
+  let secInfo = new FakeTransportSecurityInfo();
   let unlikelyHost = "highlyunlikely.example.com";
   let uri = Services.io.newURI("https://" + unlikelyHost);
   let subDomainUri = Services.io.newURI("https://subdomain." + unlikelyHost);
 
   // first check that a host probably not on the preload list is not identified
   // as an sts host
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
 
@@ -55,14 +55,14 @@ function run_test() {
 
   // check that it's now including subdomains
   ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, subDomainUri,
                            0));
 
   // Now let's simulate overriding the entry by setting an entry from a header
   // with max-age set to 0
   SSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                          "max-age=0", sslStatus, 0,
+                          "max-age=0", secInfo, 0,
                           Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
 
   // this should no longer be an HSTS host
   ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
 }
--- a/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js
+++ b/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js
@@ -8,17 +8,17 @@ Observer.prototype = {
   observe(subject, topic, data) {
     if (topic == "last-pb-context-exited") {
       run_next_test();
     }
   }
 };
 
 var gObserver = new Observer();
-var sslStatus = new FakeSSLStatus();
+var secInfo = new FakeTransportSecurityInfo();
 
 function cleanup() {
   Services.obs.removeObserver(gObserver, "last-pb-context-exited");
   gSSService.clearAll();
 }
 
 function run_test() {
   registerCleanupFunction(cleanup);
@@ -72,46 +72,46 @@ function test_part1() {
        Services.io.newURI("https://notsts.nonexistent.example.com."), 0));
 
   // check that processing a header with max-age: 0 will remove a preloaded
   // site from the list
   let uri = Services.io.newURI("https://includesubdomains.preloaded.test");
   let subDomainUri =
     Services.io.newURI("https://subdomain.includesubdomains.preloaded.test");
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=0", sslStatus, 0,
+                           "max-age=0", secInfo, 0,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                              subDomainUri, 0));
   // check that processing another header (with max-age non-zero) will
   // re-enable a site's sts status
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=1000", sslStatus, 0,
+                           "max-age=1000", secInfo, 0,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
   // but this time include subdomains was not set, so test for that
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                              subDomainUri, 0));
   gSSService.clearAll();
 
   // check that processing a header with max-age: 0 from a subdomain of a site
   // will not remove that (ancestor) site from the list
   uri = Services.io.newURI("https://subdomain.noincludesubdomains.preloaded.test");
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=0", sslStatus, 0,
+                           "max-age=0", secInfo, 0,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                             Services.io.newURI("https://noincludesubdomains.preloaded.test"),
                             0));
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
 
   uri = Services.io.newURI("https://subdomain.includesubdomains.preloaded.test");
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=0", sslStatus, 0,
+                           "max-age=0", secInfo, 0,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   // we received a header with "max-age=0", so we have "no information"
   // regarding the sts state of subdomain.includesubdomains.preloaded.test specifically,
   // but it is actually still an STS host, because of the preloaded
   // includesubdomains.preloaded.test including subdomains.
   // Here's a drawing:
   // |-- includesubdomains.preloaded.test (in preload list, includes subdomains) IS sts host
   //     |-- subdomain.includesubdomains.preloaded.test                          IS sts host
@@ -127,17 +127,17 @@ function test_part1() {
        Ci.nsISiteSecurityService.HEADER_HSTS,
        Services.io.newURI("https://sibling.includesubdomains.preloaded.test"), 0));
   ok(gSSService.isSecureURI(
        Ci.nsISiteSecurityService.HEADER_HSTS,
        Services.io.newURI("https://another.subdomain.includesubdomains.preloaded.test"),
        0));
 
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=1000", sslStatus, 0,
+                           "max-age=1000", secInfo, 0,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   // Here's what we have now:
   // |-- includesubdomains.preloaded.test (in preload list, includes subdomains) IS sts host
   //     |-- subdomain.includesubdomains.preloaded.test (include subdomains is false) IS sts host
   //     |   `-- another.subdomain.includesubdomains.preloaded.test              IS NOT sts host
   //     `-- sibling.includesubdomains.preloaded.test                            IS sts host
   ok(gSSService.isSecureURI(
        Ci.nsISiteSecurityService.HEADER_HSTS,
@@ -154,17 +154,17 @@ function test_part1() {
   // identifying a host that is on the preload list as no longer sts.
   // (This happens when we're in regular browsing mode, we get a header from
   // a site on the preload list, and that header later expires. We need to
   // then treat that host as no longer an sts host.)
   // (sanity check first - this should be in the preload list)
   uri = Services.io.newURI("https://includesubdomains2.preloaded.test");
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=1", sslStatus, 0,
+                           "max-age=1", secInfo, 0,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   do_timeout(1250, function() {
     ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
     run_next_test();
   });
 }
 
 const IS_PRIVATE = Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
@@ -176,52 +176,52 @@ function test_private_browsing1() {
     Services.io.newURI("https://a.b.c.subdomain.includesubdomains.preloaded.test");
   // sanity - includesubdomains.preloaded.test is preloaded, includeSubdomains set
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                             IS_PRIVATE));
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, subDomainUri,
                             IS_PRIVATE));
 
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=0", sslStatus, IS_PRIVATE,
+                           "max-age=0", secInfo, IS_PRIVATE,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                              IS_PRIVATE));
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                              subDomainUri, IS_PRIVATE));
 
   // check adding it back in
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=1000", sslStatus, IS_PRIVATE,
+                           "max-age=1000", secInfo, IS_PRIVATE,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, IS_PRIVATE));
   // but no includeSubdomains this time
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                              subDomainUri, IS_PRIVATE));
 
   // do the hokey-pokey...
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=0", sslStatus, IS_PRIVATE,
+                           "max-age=0", secInfo, IS_PRIVATE,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                              IS_PRIVATE));
   ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS,
                              subDomainUri, IS_PRIVATE));
 
   // Test that an expired private browsing entry results in correctly
   // identifying a host that is on the preload list as no longer sts.
   // (This happens when we're in private browsing mode, we get a header from
   // a site on the preload list, and that header later expires. We need to
   // then treat that host as no longer an sts host.)
   // (sanity check first - this should be in the preload list)
   uri = Services.io.newURI("https://includesubdomains2.preloaded.test");
   ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                             IS_PRIVATE));
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
-                           "max-age=1", sslStatus, IS_PRIVATE,
+                           "max-age=1", secInfo, IS_PRIVATE,
                            Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST);
   do_timeout(1250, function() {
     ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                                IS_PRIVATE));
     // Simulate leaving private browsing mode
     Services.obs.notifyObservers(null, "last-pb-context-exited");
   });
 }
--- a/services/common/rest.js
+++ b/services/common/rest.js
@@ -483,17 +483,17 @@ RESTRequest.prototype = {
   /** nsIInterfaceRequestor **/
 
   getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
 
   /** nsIBadCertListener2 **/
 
-  notifyCertProblem(socketInfo, sslStatus, targetHost) {
+  notifyCertProblem(socketInfo, secInfo, targetHost) {
     this._log.warn("Invalid HTTPS certificate encountered!");
     // Suppress invalid HTTPS certificate warnings in the UI.
     // (The request will still fail.)
     return true;
   },
 
   /**
    * Returns true if headers from the old channel should be
--- a/taskcluster/docker/periodic-updates/scripts/getHSTSPreloadList.js
+++ b/taskcluster/docker/periodic-updates/scripts/getHSTSPreloadList.js
@@ -111,18 +111,18 @@ function processStsHeader(host, header, 
   };
   let includeSubdomains = {
     value: false,
   };
   let error = ERROR_NONE;
   if (header != null && securityInfo != null) {
     try {
       let uri = Services.io.newURI("https://" + host.name);
-      let sslStatus = securityInfo.QueryInterface(Ci.nsITransportSecurityInfo).SSLStatus;
-      gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, header, sslStatus, 0, Ci.nsISiteSecurityService.SOURCE_PRELOAD_LIST, {}, maxAge, includeSubdomains);
+      let secInfo = securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
+      gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, header, secInfo, 0, Ci.nsISiteSecurityService.SOURCE_PRELOAD_LIST, {}, maxAge, includeSubdomains);
     } catch (e) {
       dump("ERROR: could not process header '" + header + "' from " + host.name + ": " + e + "\n");
       error = e;
     }
   } else if (status == 0) {
     error = ERROR_CONNECTING_TO_HOST;
   } else {
     error = ERROR_NO_HSTS_HEADER;
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/security.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/security.py
@@ -34,20 +34,19 @@ class Security(BaseLib):
     def get_certificate_for_page(self, tab_element):
         """The SSL certificate assiciated with the loaded web page in the given tab.
 
         :param tab_element: The inner tab DOM element.
 
         :returns: Certificate details as JSON object.
         """
         cert = self.marionette.execute_script("""
-          var securityUI = arguments[0].linkedBrowser.securityUI;
-          var status = securityUI.secInfo && securityUI.secInfo.SSLStatus;
+          var secInfo = arguments[0].linkedBrowser.securityUI.secInfo;
 
-          return status ? status.serverCert : null;
+          return secInfo ? secInfo.serverCert : null;
         """, script_args=[tab_element])
 
         uri = self.marionette.execute_script("""
           return arguments[0].linkedBrowser.currentURI.spec;
         """, script_args=[tab_element])
 
         if cert is None:
             raise NoCertificateError('No certificate found for "{}"'.format(uri))
--- a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp
+++ b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp
@@ -877,17 +877,18 @@ ChannelWrapper::GetRemoteAddress(nsCStri
 
 void
 ChannelWrapper::GetErrorString(nsString& aRetVal) const
 {
   if (nsCOMPtr<nsIChannel> chan = MaybeChannel()) {
     nsCOMPtr<nsISupports> securityInfo;
     Unused << chan->GetSecurityInfo(getter_AddRefs(securityInfo));
     if (nsCOMPtr<nsITransportSecurityInfo> tsi = do_QueryInterface(securityInfo)) {
-      auto errorCode = tsi->GetErrorCode();
+      int32_t errorCode = 0;
+      tsi->GetErrorCode(&errorCode);
       if (psm::IsNSSErrorCode(errorCode)) {
         nsCOMPtr<nsINSSErrorsService> nsserr =
           do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID);
 
         nsresult rv = psm::GetXPCOMFromNSSError(errorCode);
         if (nsserr && NS_SUCCEEDED(nsserr->GetErrorMessage(rv, aRetVal))) {
           return;
         }
--- a/toolkit/modules/CertUtils.jsm
+++ b/toolkit/modules/CertUtils.jsm
@@ -137,28 +137,27 @@ function checkCert(aChannel, aAllowNonBu
     // Require https if there are certificate values to verify
     if (aCerts) {
       throw new Ce("SSL is required and URI scheme is not https.",
                    Cr.NS_ERROR_UNEXPECTED);
     }
     return;
   }
 
-  let sslStatus = aChannel.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
-                          .SSLStatus;
-  let cert = sslStatus.serverCert;
+  let secInfo = aChannel.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
+  let cert = secInfo.serverCert;
 
   validateCert(cert, aCerts);
 
   if (aAllowNonBuiltInCerts === true) {
     return;
   }
 
   let issuerCert = null;
-  for (issuerCert of sslStatus.succeededCertChain.getEnumerator());
+  for (issuerCert of secInfo.succeededCertChain.getEnumerator());
 
   const certNotBuiltInErr = "Certificate issuer is not built-in.";
   if (!issuerCert) {
     throw new Ce(certNotBuiltInErr, Cr.NS_ERROR_ABORT);
   }
 
   if (!issuerCert.isBuiltInRoot) {
     throw new Ce(certNotBuiltInErr, Cr.NS_ERROR_ABORT);
--- a/toolkit/modules/addons/SecurityInfo.jsm
+++ b/toolkit/modules/addons/SecurityInfo.jsm
@@ -90,23 +90,23 @@ const SecurityInfo = {
 
     let securityInfo = channel.securityInfo;
     if (!securityInfo) {
       return info;
     }
 
     securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
 
-    const SSLStatus = securityInfo.SSLStatus;
     if (NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
       // The connection failed.
       info.state = "broken";
       info.errorMessage = securityInfo.errorMessage;
-      if (options.certificateChain && SSLStatus.failedCertChain) {
-        info.certificates = this.getCertificateChain(SSLStatus.failedCertChain, options);
+      if (options.certificateChain && securityInfo.failedCertChain) {
+        info.certificates = this.getCertificateChain(
+          securityInfo.failedCertChain, options);
       }
       return info;
     }
 
     const state = securityInfo.securityState;
 
     let uri = channel.URI;
     if (uri && !uri.schemeIs("https") && !uri.schemeIs("wss")) {
@@ -128,42 +128,43 @@ const SecurityInfo = {
       // validation. Return info as info.state = insecure.
       return info;
     } else {
       // No known STATE_IS_* flags.
       return info;
     }
 
     // Cipher suite.
-    info.cipherSuite = SSLStatus.cipherName;
+    info.cipherSuite = securityInfo.cipherName;
 
     // Key exchange group name.
-    if (SSLStatus.keaGroupName !== "none") {
-      info.keaGroupName = SSLStatus.keaGroupName;
+    if (securityInfo.keaGroupName !== "none") {
+      info.keaGroupName = securityInfo.keaGroupName;
     }
 
     // Certificate signature scheme.
-    if (SSLStatus.signatureSchemeName !== "none") {
-      info.signatureSchemeName = SSLStatus.signatureSchemeName;
+    if (securityInfo.signatureSchemeName !== "none") {
+      info.signatureSchemeName = securityInfo.signatureSchemeName;
     }
 
-    info.isDomainMismatch = SSLStatus.isDomainMismatch;
-    info.isExtendedValidation = SSLStatus.isExtendedValidation;
-    info.isNotValidAtThisTime = SSLStatus.isNotValidAtThisTime;
-    info.isUntrusted = SSLStatus.isUntrusted;
+    info.isDomainMismatch = securityInfo.isDomainMismatch;
+    info.isExtendedValidation = securityInfo.isExtendedValidation;
+    info.isNotValidAtThisTime = securityInfo.isNotValidAtThisTime;
+    info.isUntrusted = securityInfo.isUntrusted;
 
-    info.certificateTransparencyStatus = this.getTransparencyStatus(SSLStatus.certificateTransparencyStatus);
+    info.certificateTransparencyStatus = this.getTransparencyStatus(
+      securityInfo.certificateTransparencyStatus);
 
     // Protocol version.
-    info.protocolVersion = this.formatSecurityProtocol(SSLStatus.protocolVersion);
+    info.protocolVersion = this.formatSecurityProtocol(securityInfo.protocolVersion);
 
-    if (options.certificateChain && SSLStatus.succeededCertChain) {
-      info.certificates = this.getCertificateChain(SSLStatus.succeededCertChain, options);
+    if (options.certificateChain && securityInfo.succeededCertChain) {
+      info.certificates = this.getCertificateChain(securityInfo.succeededCertChain, options);
     } else {
-      info.certificates = [this.parseCertificateInfo(SSLStatus.serverCert, options)];
+      info.certificates = [this.parseCertificateInfo(securityInfo.serverCert, options)];
     }
 
     // HSTS and HPKP if available.
     if (uri && uri.host) {
       // SiteSecurityService uses different storage if the channel is
       // private. Thus we must give isSecureURI correct flags or we
       // might get incorrect results.
       let flags = 0;
@@ -230,47 +231,47 @@ const SecurityInfo = {
       certData.rawDER = cert.getRawDER({});
     }
     return certData;
   },
 
   // Bug 1355903 Transparency is currently disabled using security.pki.certificate_transparency.mode
   getTransparencyStatus(status) {
     switch (status) {
-      case Ci.nsISSLStatus.CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE:
+      case Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE:
         return "not_applicable";
-      case Ci.nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT:
+      case Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT:
         return "policy_compliant";
-      case Ci.nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS:
+      case Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS:
         return "policy_not_enough_scts";
-      case Ci.nsISSLStatus.CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS:
+      case Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS:
         return "policy_not_diverse_scts";
     }
     return "unknown";
   },
 
   /**
-   * Takes protocolVersion of SSLStatus object and returns human readable
+   * Takes protocolVersion of TransportSecurityInfo object and returns human readable
    * description.
    *
    * @param {number} version
-   *        One of nsISSLStatus version constants.
+   *        One of nsITransportSecurityInfo version constants.
    * @returns {string}
    *         One of TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 if version
    *         is valid, Unknown otherwise.
    */
   formatSecurityProtocol(version) {
     switch (version) {
-      case Ci.nsISSLStatus.TLS_VERSION_1:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1:
         return "TLSv1";
-      case Ci.nsISSLStatus.TLS_VERSION_1_1:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1_1:
         return "TLSv1.1";
-      case Ci.nsISSLStatus.TLS_VERSION_1_2:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1_2:
         return "TLSv1.2";
-      case Ci.nsISSLStatus.TLS_VERSION_1_3:
+      case Ci.nsITransportSecurityInfo.TLS_VERSION_1_3:
         return "TLSv1.3";
     }
     return "unknown";
   },
 
   /**
    * Takes the securityState bitfield and returns reasons for weak connection
    * as an array of strings.
--- a/toolkit/modules/tests/chrome/test_bug544442_checkCert.xul
+++ b/toolkit/modules/tests/chrome/test_bug544442_checkCert.xul
@@ -83,17 +83,17 @@ function testXHRLoad(aEvent) {
 
   certs = [ { issuerName: "Incorrect issuerName" } ];
   is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ILLEGAL_VALUE,
      "checkCert should throw NS_ERROR_ILLEGAL_VALUE when the certificate " +
      "attributes array passed to checkCert has an element that has an " +
      "issuerName that is not the same as the certificate's");
 
   var cert = channel.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo).
-             SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
+             serverCert;
 
   certs = [ { issuerName: cert.issuerName,
               commonName: cert.commonName } ];
   is(getCheckCertResult(channel, false, certs), Cr.NS_ERROR_ABORT,
      "checkCert should throw NS_ERROR_ABORT when the certificate attributes " +
      "array passed to checkCert has a single element that has the same " +
      "issuerName and commonName as the certificate's and the certificate is " +
      "not builtin");
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -614,19 +614,18 @@ CertOverrideListener.prototype = {
   bits: null,
 
   getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIBadCertListener2", "nsIInterfaceRequestor"]),
 
-  notifyCertProblem(socketInfo, sslStatus, targetHost) {
-    var cert = sslStatus.QueryInterface(Ci.nsISSLStatus)
-                        .serverCert;
+  notifyCertProblem(socketInfo, secInfo, targetHost) {
+    var cert = secInfo.serverCert;
     var cos = Cc["@mozilla.org/security/certoverride;1"].
               getService(Ci.nsICertOverrideService);
     cos.rememberValidityOverride(this.host, -1, cert, this.bits, false);
     return true;
   },
 };
 
 // Add overrides for the bad certificates
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -3102,25 +3102,23 @@ Checker.prototype = {
    */
   onError: function UC_onError(event) {
     var request = event.target;
     var status = this._getChannelStatus(request);
     LOG("Checker:onError - request.status: " + status);
 
     // Set MitM pref.
     try {
-      var sslStatus = request.channel.QueryInterface(Ci.nsIRequest)
-                        .securityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
-                        .SSLStatus.QueryInterface(Ci.nsISSLStatus);
-      if (sslStatus && sslStatus.serverCert && sslStatus.serverCert.issuerName) {
+      var secInfo = request.channel.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
+      if (secInfo.serverCert && secInfo.serverCert.issuerName) {
         Services.prefs.setStringPref("security.pki.mitm_canary_issuer",
-                                     sslStatus.serverCert.issuerName);
+                                     secInfo.serverCert.issuerName);
       }
     } catch (e) {
-      LOG("Checker:onError - Getting sslStatus failed.");
+      LOG("Checker:onError - Getting secInfo failed.");
     }
 
     // If we can't find an error string specific to this status code,
     // just use the 200 message from above, which means everything
     // "looks" fine but there was probably an XML error or a bogus file.
     var update = new Update(null);
     update.errorCode = status;
     update.statusText = getStatusTextFromCode(status, 200);