Bug 1122642 - Have an error page for H2 INADEQUATE_SECURITY r=mcmanus,bz
authorNicholas Hurley <hurley@todesschaf.org>
Thu, 14 Apr 2016 19:24:46 -0700
changeset 294577 1f5f16c88c5b4d13a687cd0f268c9b3d9988bf5f
parent 294576 93d4b13155d8fa60f058a4b98bd0849782ff8b94
child 294578 8dc88a0d88bba681ddf5e1c25f4025e0af4c647f
push id30208
push usercbook@mozilla.com
push dateMon, 25 Apr 2016 09:55:37 +0000
treeherdermozilla-central@1c6385ae1fe7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus, bz
bugs1122642
milestone48.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 1122642 - Have an error page for H2 INADEQUATE_SECURITY r=mcmanus,bz
browser/base/content/aboutNetError.xhtml
browser/base/content/test/general/browser_misused_characters_in_strings.js
browser/locales/en-US/chrome/overrides/appstrings.properties
browser/locales/en-US/chrome/overrides/netError.dtd
docshell/base/nsDocShell.cpp
docshell/resources/content/netError.xhtml
dom/locales/en-US/chrome/appstrings.properties
dom/locales/en-US/chrome/netError.dtd
mobile/android/chrome/content/netError.xhtml
mobile/locales/en-US/overrides/appstrings.properties
mobile/locales/en-US/overrides/netError.dtd
netwerk/protocol/http/Http2Session.cpp
xpcom/base/ErrorList.h
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -339,16 +339,27 @@
           if (getErrorCode() == "weakCryptoUsed" || getErrorCode() == "sslv3Used") {
             showAdvancedButton(getErrorCode() == "weakCryptoUsed");
           }
         }.bind(this), true, true);
 
         var event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
         document.dispatchEvent(event);
 
+        if (err == "inadequateSecurityError") {
+          // Remove the "Try again" button for HTTP/2 inadequate security as it
+          // is useless.
+          document.getElementById("errorTryAgain").style.display = "none";
+
+          var container = document.getElementById("errorLongDesc");
+          for (var span of container.querySelectorAll("span.hostname")) {
+            span.textContent = document.location.hostname;
+          }
+        }
+
         addDomainErrorLinks();
       }
 
       /* Try to preserve the links contained in the error description, like
          the error code.
 
          Also, in the case of SSL error pages about domain mismatch, see if
          we can hyperlink the user to the correct site.  We don't want
@@ -503,16 +514,17 @@
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&certerror.longpagetitle1;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
         <h1 id="et_sslv3Used">&sslv3Used.title;</h1>
         <h1 id="et_weakCryptoUsed">&weakCryptoUsed.title;</h1>
+        <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
         <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
@@ -531,16 +543,17 @@
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&certerror.introPara;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
         <div id="ed_sslv3Used">&sslv3Used.longDesc2;</div>
         <div id="ed_weakCryptoUsed">&weakCryptoUsed.longDesc2;</div>
+        <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
       <!-- Error Title -->
       <div id="errorTitle">
--- a/browser/base/content/test/general/browser_misused_characters_in_strings.js
+++ b/browser/base/content/test/general/browser_misused_characters_in_strings.js
@@ -24,16 +24,20 @@ let gWhitelist = [{
     file: "netError.dtd",
     key: "weakCryptoAdvanced.longDesc",
     type: "single-quote"
   }, {
     file: "netError.dtd",
     key: "weakCryptoAdvanced.override",
     type: "single-quote"
   }, {
+    file: "netError.dtd",
+    key: "inadequateSecurityError.longDesc",
+    type: "single-quote"
+  }, {
     file: "phishing-afterload-warning-message.dtd",
     key: "safeb.blocked.malwarePage.shortDesc",
     type: "single-quote"
   }, {
     file: "phishing-afterload-warning-message.dtd",
     key: "safeb.blocked.unwantedPage.shortDesc",
     type: "single-quote"
   }, {
--- a/browser/locales/en-US/chrome/overrides/appstrings.properties
+++ b/browser/locales/en-US/chrome/overrides/appstrings.properties
@@ -36,8 +36,9 @@ deceptiveBlocked=This web page at %S has
 forbiddenBlocked=The site at %S has been blocked by your browser configuration.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
 ## LOCALIZATION NOTE (sslv3Used) - Do not translate "%S".
 sslv3Used=Firefox cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
 ## LOCALIZATION NOTE (weakCryptoUsed) - Do not translate "%S".
 weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.
+inadequateSecurityError=The website tried to negotiate an inadequate level of security.
--- a/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -190,9 +190,14 @@ was trying to connect. -->
 <!ENTITY weakCryptoAdvanced.longDesc "<span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe.">
 <!ENTITY weakCryptoAdvanced.override "(Not secure) Try loading <span class='hostname'></span> using outdated security">
 
 <!ENTITY certerror.pagetitle1  "Insecure Connection">
 <!ENTITY certerror.whatShouldIDo.badStsCertExplanation "This site uses HTTP
 Strict Transport Security (HSTS) to specify that &brandShortName; only connect
 to it securely. As a result, it is not possible to add an exception for this
 certificate.">
-<!ENTITY certerror.copyToClipboard.label "Copy text to clipboard">
\ No newline at end of file
+<!ENTITY certerror.copyToClipboard.label "Copy text to clipboard">
+
+<!ENTITY inadequateSecurityError.title "Your connection is not secure">
+<!-- LOCALIZATION NOTE (inadequateSecurityError.longDesc) - Do not translate
+     "NS_ERROR_NET_INADEQUATE_SECURITY". -->
+<!ENTITY inadequateSecurityError.longDesc "<p><span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe. The website administrator will need to fix the server first before you can visit the site.</p><p>Error code: NS_ERROR_NET_INADEQUATE_SECURITY</p>">
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -5052,16 +5052,21 @@ nsDocShell::DisplayLoadError(nsresult aE
       case NS_ERROR_CORRUPTED_CONTENT:
         // Broken Content Detected. e.g. Content-MD5 check failure.
         error.AssignLiteral("corruptedContentError");
         break;
       case NS_ERROR_INTERCEPTION_FAILED:
         // ServiceWorker intercepted request, but something went wrong.
         error.AssignLiteral("corruptedContentError");
         break;
+      case NS_ERROR_NET_INADEQUATE_SECURITY:
+        // Server negotiated bad TLS for HTTP/2.
+        error.AssignLiteral("inadequateSecurityError");
+        addHostPort = true;
+        break;
       default:
         break;
     }
   }
 
   // Test if the error should be displayed
   if (error.IsEmpty()) {
     return NS_OK;
@@ -7791,16 +7796,17 @@ nsDocShell::EndPageLoad(nsIWebProgress* 
                aStatus == NS_ERROR_OFFLINE ||
                aStatus == NS_ERROR_MALWARE_URI ||
                aStatus == NS_ERROR_PHISHING_URI ||
                aStatus == NS_ERROR_UNWANTED_URI ||
                aStatus == NS_ERROR_FORBIDDEN_URI ||
                aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
                aStatus == NS_ERROR_REMOTE_XUL ||
                aStatus == NS_ERROR_INTERCEPTION_FAILED ||
+               aStatus == NS_ERROR_NET_INADEQUATE_SECURITY ||
                NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
       // Errors to be shown for any frame
       DisplayLoadError(aStatus, url, nullptr, aChannel);
     } else if (aStatus == NS_ERROR_DOCUMENT_NOT_CACHED) {
       // Non-caching channels will simply return NS_ERROR_OFFLINE.
       // Caching channels would have to look at their flags to work
       // out which error to return. Or we can fix up the error here.
       if (!(mLoadType & LOAD_CMD_HISTORY)) {
--- a/docshell/resources/content/netError.xhtml
+++ b/docshell/resources/content/netError.xhtml
@@ -172,16 +172,27 @@
           addDomainErrorLink();
         }
         else {
           // Remove the override block for non-certificate errors.  CSS-hiding
           // isn't good enough here, because of bug 39098
           var secOverride = document.getElementById("securityOverrideDiv");
           secOverride.parentNode.removeChild(secOverride);
         }
+
+        if (err == "inadequateSecurityError") {
+          // Remove the "Try again" button for HTTP/2 inadequate security as it
+          // is useless.
+          document.getElementById("errorTryAgain").style.display = "none";
+
+          var container = document.getElementById("errorLongDesc");
+          for (var span of container.querySelectorAll("span.hostname")) {
+            span.textContent = document.location.hostname;
+          }
+        }
       }
 
       function showSecuritySection() {
         // Swap link out, content in
         document.getElementById('securityOverrideContent').style.display = '';
         document.getElementById('securityOverrideLink').style.display = 'none';
       }
 
@@ -292,16 +303,17 @@
         <h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
         <h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
+        <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
         <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
@@ -318,16 +330,17 @@
         <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
         <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
+        <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
       <!-- Error Title -->
       <div id="errorTitle">
--- a/dom/locales/en-US/chrome/appstrings.properties
+++ b/dom/locales/en-US/chrome/appstrings.properties
@@ -33,8 +33,9 @@ malwareBlocked=The site at %S has been r
 unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
 deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
 forbiddenBlocked=The site at %S has been blocked by your browser configuration.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default.
 sslv3Used=The safety of your data on %S could not be guaranteed because it uses SSLv3, a broken security protocol.
 weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, the connection to this website has not been established.
+inadequateSecurityError=The website tried to negotiate an inadequate level of security.
--- a/dom/locales/en-US/chrome/netError.dtd
+++ b/dom/locales/en-US/chrome/netError.dtd
@@ -87,8 +87,13 @@
 <!ENTITY cspBlocked.title "Blocked by Content Security Policy">
 <!ENTITY cspBlocked.longDesc "<p>The browser prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
 
 <!ENTITY corruptedContentError.title "Corrupted Content Error">
 <!ENTITY corruptedContentError.longDesc "<p>The page you are trying to view cannot be shown because an error in the data transmission was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
 
 <!ENTITY remoteXUL.title "Remote XUL">
 <!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>">
+
+<!ENTITY inadequateSecurityError.title "Your connection is not secure">
+<!-- LOCALIZATION NOTE (inadequateSecurityError.longDesc) - Do not translate
+     "NS_ERROR_NET_INADEQUATE_SECURITY". -->
+<!ENTITY inadequateSecurityError.longDesc "<p><span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe. The website administrator will need to fix the server first before you can visit the site.</p><p>Error code: NS_ERROR_NET_INADEQUATE_SECURITY</p>">
--- a/mobile/android/chrome/content/netError.xhtml
+++ b/mobile/android/chrome/content/netError.xhtml
@@ -167,16 +167,28 @@
           document.getElementById("errorPage").setAttribute("class", "certerror");
         }
         else {
           // Remove the override block for non-certificate errors.  CSS-hiding
           // isn't good enough here, because of bug 39098
           var secOverride = document.getElementById("securityOverrideDiv");
           secOverride.parentNode.removeChild(secOverride);
         }
+
+        if (err == "inadequateSecurityError") {
+          // Remove the "Try again" button for HTTP/2 inadequate security as it
+          // is useless.
+          document.getElementById("errorTryAgain").style.display = "none";
+
+          var container = document.getElementById("errorLongDesc");
+          for (var span of container.querySelectorAll("span.hostname")) {
+            span.textContent = document.location.hostname;
+          }
+        }
+
         addDomainErrorLinks();
       }
 
       function showSecuritySection() {
         // Swap link out, content in
         document.getElementById('securityOverrideContent').style.display = '';
         document.getElementById('securityOverrideLink').style.display = 'none';
       }
@@ -309,16 +321,17 @@
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
         <h1 id="et_sslv3Used">&sslv3Used.title;</h1>
         <h1 id="et_weakCryptoUsed">&weakCryptoUsed.title;</h1>
+        <h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc4;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc2;</div>
         <div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
@@ -341,16 +354,17 @@
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
         <div id="ed_sslv3Used">&sslv3Used.longDesc;</div>
         <div id="ed_weakCryptoUsed">&weakCryptoUsed.longDesc;</div>
+        <div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
       <!-- Error Title -->
       <div id="errorTitle">
--- a/mobile/locales/en-US/overrides/appstrings.properties
+++ b/mobile/locales/en-US/overrides/appstrings.properties
@@ -34,8 +34,9 @@ malwareBlocked=The site at %S has been r
 deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
 unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
 forbiddenBlocked=The site at %S has been blocked by your browser configuration.
 cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
 sslv3Used=Firefox cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
 weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.
+inadequateSecurityError=The website tried to negotiate an inadequate level of security.
--- a/mobile/locales/en-US/overrides/netError.dtd
+++ b/mobile/locales/en-US/overrides/netError.dtd
@@ -210,8 +210,13 @@ netError.xhtml) because it exposes funct
 <!-- LOCALIZATION NOTE (sslv3Used.longDesc) - Do not translate
      "SSL_ERROR_UNSUPPORTED_VERSION". -->
 <!ENTITY sslv3Used.longDesc "Advanced info: SSL_ERROR_UNSUPPORTED_VERSION">
 
 <!ENTITY weakCryptoUsed.title "Your connection is not secure">
 <!-- LOCALIZATION NOTE (weakCryptoUsed.longDesc) - Do not translate
      "SSL_ERROR_NO_CYPHER_OVERLAP". -->
 <!ENTITY weakCryptoUsed.longDesc "Advanced info: SSL_ERROR_NO_CYPHER_OVERLAP">
+
+<!ENTITY inadequateSecurityError.title "Your connection is not secure">
+<!-- LOCALIZATION NOTE (inadequateSecurityError.longDesc) - Do not translate
+     "NS_ERROR_NET_INADEQUATE_SECURITY". -->
+<!ENTITY inadequateSecurityError.longDesc "<p><span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe. The website administrator will need to fix the server first before you can visit the site.</p><p>Error code: NS_ERROR_NET_INADEQUATE_SECURITY</p>">
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -148,16 +148,18 @@ Http2Session::Shutdown()
     // server guarantees it was not partially processed. Streams that have not
     // registered an ID haven't actually been sent yet so they can always be
     // restarted.
     if (mCleanShutdown &&
         (stream->StreamID() > mGoAwayID || !stream->HasRegisteredID())) {
       CloseStream(stream, NS_ERROR_NET_RESET);  // can be restarted
     } else if (stream->RecvdData()) {
       CloseStream(stream, NS_ERROR_NET_PARTIAL_TRANSFER);
+    } else if (mGoAwayReason == INADEQUATE_SECURITY) {
+      CloseStream(stream, NS_ERROR_NET_INADEQUATE_SECURITY);
     } else {
       CloseStream(stream, NS_ERROR_ABORT);
     }
   }
 }
 
 Http2Session::~Http2Session()
 {
@@ -2275,18 +2277,24 @@ Http2Session::ReadSegmentsAgain(nsAHttpS
                                 uint32_t count, uint32_t *countRead, bool *again)
 {
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
   MOZ_ASSERT(!mSegmentReader || !reader || (mSegmentReader == reader),
              "Inconsistent Write Function Callback");
 
   nsresult rv = ConfirmTLSProfile();
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
+    if (mGoAwayReason == INADEQUATE_SECURITY) {
+      LOG3(("Http2Session::ReadSegments %p returning INADEQUATE_SECURITY %x",
+            this, NS_ERROR_NET_INADEQUATE_SECURITY));
+      rv = NS_ERROR_NET_INADEQUATE_SECURITY;
+    }
     return rv;
+  }
 
   if (reader)
     mSegmentReader = reader;
 
   *countRead = 0;
 
   LOG3(("Http2Session::ReadSegments %p", this));
 
--- a/xpcom/base/ErrorList.h
+++ b/xpcom/base/ErrorList.h
@@ -212,16 +212,18 @@
   /* The connection was established, but no data was ever received. */
   ERROR(NS_ERROR_NET_RESET,                 FAILURE(20)),
   /* The connection was established, but the data transfer was interrupted. */
   ERROR(NS_ERROR_NET_INTERRUPT,             FAILURE(71)),
   /* The connection attempt to a proxy failed. */
   ERROR(NS_ERROR_PROXY_CONNECTION_REFUSED,  FAILURE(72)),
   /* A transfer was only partially done when it completed. */
   ERROR(NS_ERROR_NET_PARTIAL_TRANSFER,      FAILURE(76)),
+  /* HTTP/2 detected invalid TLS configuration */
+  ERROR(NS_ERROR_NET_INADEQUATE_SECURITY,   FAILURE(82)),
 
   /* XXX really need to better rationalize these error codes.  are consumers of
    * necko really expected to know how to discern the meaning of these?? */
   /* This request is not resumable, but it was tried to resume it, or to
    * request resume-specific data. */
   ERROR(NS_ERROR_NOT_RESUMABLE,        FAILURE(25)),
   /* The request failed as a result of a detected redirection loop.  */
   ERROR(NS_ERROR_REDIRECT_LOOP,        FAILURE(31)),