Merge mozilla-inbound to mozilla-central. a=merge
authorDaniel Varga <dvarga@mozilla.com>
Wed, 03 Oct 2018 00:47:40 +0300
changeset 439283 0d4e73bc2cd705d7a021c75a0e8aeb174ab4db59
parent 439282 4392b5198fb7773f6148d2caedff82da5f527bfe (current diff)
parent 439196 0fd47bc8f7c2758ce9b9d47e860054be0b2260a5 (diff)
child 439284 e6820b5308f7d9c008b79113983c9a975ea44d6f
child 439334 47338cf5abdffbb55ed0a8d9f462249f971e7d09
push id108542
push userdvarga@mozilla.com
push dateTue, 02 Oct 2018 22:18:02 +0000
treeherdermozilla-inbound@e6820b5308f7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
0d4e73bc2cd7 / 64.0a1 / 20181002220140 / files
nightly linux64
0d4e73bc2cd7 / 64.0a1 / 20181002220140 / files
nightly mac
0d4e73bc2cd7 / 64.0a1 / 20181002220140 / files
nightly win32
0d4e73bc2cd7 / 64.0a1 / 20181002220140 / files
nightly win64
0d4e73bc2cd7 / 64.0a1 / 20181002220140 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central. a=merge
browser/app/profile/firefox.js
browser/config/mozconfigs/macosx64/opt-dmd
security/pkix/include/pkix/Input.h
security/pkix/include/pkix/Result.h
security/pkix/include/pkix/Time.h
security/pkix/include/pkix/pkix.h
security/pkix/include/pkix/pkixnss.h
security/pkix/include/pkix/pkixtypes.h
security/pkix/lib/ScopedPtr.h
security/pkix/lib/pkixbuild.cpp
security/pkix/lib/pkixcert.cpp
security/pkix/lib/pkixcheck.cpp
security/pkix/lib/pkixcheck.h
security/pkix/lib/pkixder.cpp
security/pkix/lib/pkixder.h
security/pkix/lib/pkixnames.cpp
security/pkix/lib/pkixnss.cpp
security/pkix/lib/pkixocsp.cpp
security/pkix/lib/pkixresult.cpp
security/pkix/lib/pkixtime.cpp
security/pkix/lib/pkixutil.h
security/pkix/lib/pkixverify.cpp
security/pkix/moz.build
security/pkix/test/gtest/README.txt
security/pkix/test/gtest/moz.build
security/pkix/test/gtest/pkixbuild_tests.cpp
security/pkix/test/gtest/pkixcert_extension_tests.cpp
security/pkix/test/gtest/pkixcert_signature_algorithm_tests.cpp
security/pkix/test/gtest/pkixcheck_CheckExtendedKeyUsage_tests.cpp
security/pkix/test/gtest/pkixcheck_CheckIssuer_tests.cpp
security/pkix/test/gtest/pkixcheck_CheckKeyUsage_tests.cpp
security/pkix/test/gtest/pkixcheck_CheckSignatureAlgorithm_tests.cpp
security/pkix/test/gtest/pkixcheck_CheckValidity_tests.cpp
security/pkix/test/gtest/pkixcheck_ParseValidity_tests.cpp
security/pkix/test/gtest/pkixcheck_TLSFeaturesSatisfiedInternal_tests.cpp
security/pkix/test/gtest/pkixder_input_tests.cpp
security/pkix/test/gtest/pkixder_pki_types_tests.cpp
security/pkix/test/gtest/pkixder_universal_types_tests.cpp
security/pkix/test/gtest/pkixgtest.cpp
security/pkix/test/gtest/pkixgtest.h
security/pkix/test/gtest/pkixnames_tests.cpp
security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp
security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
security/pkix/test/lib/moz.build
security/pkix/test/lib/pkixtestalg.cpp
security/pkix/test/lib/pkixtestnss.cpp
security/pkix/test/lib/pkixtestnss.h
security/pkix/test/lib/pkixtestutil.cpp
security/pkix/test/lib/pkixtestutil.h
security/pkix/tools/DottedOIDToCode.py
security/pkix/warnings.mozbuild
taskcluster/ci/test/test-sets.yml
taskcluster/taskgraph/transforms/tests.py
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1497,16 +1497,21 @@ pref("toolkit.telemetry.hybridContent.en
 pref("browser.ping-centre.telemetry", true);
 pref("browser.ping-centre.log", false);
 pref("browser.ping-centre.staging.endpoint", "https://onyx_tiles.stage.mozaws.net/v3/links/ping-centre");
 pref("browser.ping-centre.production.endpoint", "https://tiles.services.mozilla.com/v3/links/ping-centre");
 
 // Enable GMP support in the addon manager.
 pref("media.gmp-provider.enabled", true);
 
+// Enable blocking access to storage from tracking resources by default on Nightly
+#ifdef NIGHTLY_BUILD
+pref("network.cookie.cookieBehavior", 4 /* BEHAVIOR_REJECT_TRACKER */);
+#endif
+
 pref("browser.contentblocking.allowlist.storage.enabled", true);
 
 pref("browser.contentblocking.global-toggle.enabled", true);
 
 // Define a set of default features for the Content Blocking UI
 pref("browser.contentblocking.fastblock.ui.enabled", true);
 pref("browser.contentblocking.fastblock.control-center.ui.enabled", true);
 pref("browser.contentblocking.trackingprotection.ui.enabled", true);
--- a/browser/config/mozconfigs/linux64/debug-searchfox-clang
+++ b/browser/config/mozconfigs/linux64/debug-searchfox-clang
@@ -8,18 +8,18 @@ ac_add_options --enable-debug
 ac_add_options --enable-dmd
 
 . $topsrcdir/build/mozconfig.stylo
 
 # Use Clang as specified in manifest
 export CC="$topsrcdir/clang/bin/clang"
 export CXX="$topsrcdir/clang/bin/clang++"
 
-# Save rust analysis (this requires unlocking the unstable features)
-export RUSTC_BOOTSTRAP=1
+# Save rust analysis (this requires unlocking the unstable features,
+# which is done in the taskcluster task definition via RUSTC_BOOTSTRAP)
 export RUSTFLAGS="-Zsave-analysis"
 
 # Add the static checker
 ac_add_options --enable-clang-plugin
 ac_add_options --enable-mozsearch-plugin
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
--- a/browser/config/mozconfigs/macosx64/debug-searchfox
+++ b/browser/config/mozconfigs/macosx64/debug-searchfox
@@ -2,16 +2,16 @@ MOZ_AUTOMATION_BUILD_SYMBOLS=0
 MOZ_AUTOMATION_PACKAGE_TESTS=0
 MOZ_AUTOMATION_L10N_CHECK=0
 
 . $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-debug
 ac_add_options --enable-dmd
 
-# Save rust analysis (this requires unlocking the unstable features)
-export RUSTC_BOOTSTRAP=1
+# Save rust analysis (this requires unlocking the unstable features,
+# which is done in the taskcluster task definition via RUSTC_BOOTSTRAP)
 export RUSTFLAGS="-Zsave-analysis"
 
 ac_add_options --enable-clang-plugin
 ac_add_options --enable-mozsearch-plugin
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 90
+Version 92
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-89...release-90
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-91...release-92
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.2
 - babel-preset-react @6.24.1
 - react @16.4.1
 - react-dom @16.4.1
 - webpack @3.12.0
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -1798,17 +1798,17 @@ html .toggle-button.end.vertical svg {
 .source-outline-tabs {
   width: 100%;
   background: var(--theme-body-background);
   border-top: 1px solid var(--theme-splitter-color);
   display: flex;
   -moz-user-select: none;
   user-select: none;
   box-sizing: border-box;
-  height: 30px;
+  height: 29px;
   margin: 0;
   padding: 0;
 }
 
 .source-outline-tabs .tab {
   background-color: var(--theme-toolbar-background);
   border-bottom: 1px solid transparent;
   border-color: var(--theme-splitter-color);
@@ -2226,16 +2226,22 @@ menuseparator {
 :root.theme-dark .source-footer > .commands > .action {
   fill: var(--theme-body-color);
 }
 
 :root.theme-dark .source-footer > .commands > .action:hover {
   fill: var(--theme-selection-color);
 }
 
+.source-footer > .commands > div.loader {
+  vertical-align: top;
+  width: 20px;
+  margin: 0 4px;
+}
+
 .source-footer > .commands > .action > img.prettyPrint {
   mask: url("chrome://devtools/skin/images/debugger/prettyPrint.svg") no-repeat;
   height: 16px;
   width: 16px;
   background: var(--theme-body-color);
 }
 
 .source-footer > .commands > .action > img.blackBox {
@@ -2271,41 +2277,59 @@ menuseparator {
   text-overflow: ellipsis;
 }
 /* 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/>. */
 
 .search-bar {
   display: flex;
-  flex-direction: column;
+  border: 1px solid transparent;
+  border-top: 1px solid var(--theme-splitter-color);
+  height: var(--editor-searchbar-height);
+}
+
+.search-bar.search-bar-focused {
+  border: 1px solid var(--blue-50);
+  transition: border-color 0.2s ease-in-out;
 }
 
 .search-bar .search-field {
   padding-left: 7px;
-  height: var(--editor-searchbar-height);
+}
+
+.search-bar .search-shadow {
+  flex-grow: 1;
+}
+
+.search-bar .search-shadow.focused {
+  border-color: transparent;
+  transition: none;
+}
+
+.search-bar .search-field {
+  border-bottom: none;
+  padding-right: 0;
+  height: 100%;
 }
 
 .search-field .close-btn {
   align-self: center;
 }
 
 .search-bottom-bar * {
   -moz-user-select: none;
   user-select: none;
 }
 
 .search-bottom-bar {
   display: flex;
   flex-shrink: 0;
   justify-content: flex-end;
-  width: calc(100% - 1px);
-  height: var(--editor-second-searchbar-height);
   background-color: var(--theme-toolbar-background);
-  border-bottom: 1px solid var(--theme-splitter-color);
   padding: 0 13px;
 }
 
 .search-bottom-bar .search-modifiers {
   display: flex;
   align-items: center;
 }
 
@@ -2676,17 +2700,16 @@ menuseparator {
 /* 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/>. */
 
 .editor-wrapper {
   --debug-line-border: rgb(145, 188, 219);
   --debug-expression-background: rgba(202, 227, 255, 0.5);
   --editor-searchbar-height: 27px;
-  --editor-second-searchbar-height: 27px;
   --debug-line-error-border: rgb(255, 0, 0);
   --debug-expression-error-background: rgba(231, 116, 113, 0.3);
   --editor-header-height: 30px;
 }
 
 .theme-dark .editor-wrapper {
   --debug-expression-background: rgba(202, 227, 255, 0.3);
   --debug-line-border: #7786a2;
@@ -3441,17 +3464,17 @@ html[dir="rtl"] .breakpoints-list .break
 }
 
 .frames .badge {
   flex-shrink: 0;
   margin-right: 4px;
 }
 
 .frames .location {
-  font-weight: lighter;
+  font-weight: normal;
   display: flex;
   justify-content: space-between;
   flex-direction: row;
   align-items: center;
   margin: 0;
   flex-shrink: 0;
 }
 
@@ -3681,17 +3704,17 @@ html[dir="rtl"] .breakpoints-list .break
 .accordion .arrow svg {
   fill: var(--disclosure-arrow);
 }
 /* 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/>. */
 
 .command-bar {
-  flex: 0 0 30px;
+  flex: 0 0 29px;
   border-bottom: 1px solid var(--theme-splitter-color);
   display: flex;
   overflow: hidden;
   z-index: 1;
   background-color: var(--theme-toolbar-background);
 }
 
 html[dir="rtl"] .command-bar {
@@ -4036,17 +4059,17 @@ html .welcomebox .toggle-button-end.coll
 }
 /* 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/>. */
 
 .source-header {
   border-bottom: 1px solid var(--theme-splitter-color);
   width: 100%;
-  height: 30px;
+  height: 29px;
   display: flex;
 }
 
 .source-header * {
   -moz-user-select: none;
   user-select: none;
 }
 
@@ -4160,16 +4183,17 @@ html[dir="rtl"] img.moreTabs {
 }
 
 .source-tab .filename {
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
   padding: 0 4px;
   align-self: center;
+  margin-bottom: 2px;
 }
 
 .source-tab .filename span {
   opacity: 0.7;
   padding-left: 4px;
 }
 
 .source-tab .close-btn {
--- a/devtools/client/debugger/new/dist/parser-worker.js
+++ b/devtools/client/debugger/new/dist/parser-worker.js
@@ -1599,17 +1599,26 @@ function extractSymbol(path, symbols) {
       location: { start, end },
       expression: getSnippet(path.parentPath)
     });
   }
 
   if (t.isCallExpression(path)) {
     const callee = path.node.callee;
     const args = path.node.arguments;
-    if (!t.isMemberExpression(callee)) {
+    if (t.isMemberExpression(callee)) {
+      const {
+        property: { name, loc }
+      } = callee;
+      symbols.callExpressions.push({
+        name: name,
+        values: args.filter(arg => arg.value).map(arg => arg.value),
+        location: loc
+      });
+    } else {
       const { start, end, identifierName } = callee.loc;
       symbols.callExpressions.push({
         name: identifierName,
         values: args.filter(arg => arg.value).map(arg => arg.value),
         location: { start, end }
       });
     }
   }
@@ -2590,26 +2599,18 @@ function requiresReact(callExpressions) 
 
 function extendsReactComponent(classes) {
   return classes.some(classObj => t.isIdentifier(classObj.parent, { name: "Component" }) || t.isIdentifier(classObj.parent, { name: "PureComponent" }) || t.isMemberExpression(classObj.parent, { computed: false }) && t.isIdentifier(classObj.parent, { name: "Component" }));
 }
 
 // Angular
 
 const isAngularComponent = sourceSymbols => {
-  const { memberExpressions, identifiers } = sourceSymbols;
-  return identifiesAngular(identifiers) && hasAngularExpressions(memberExpressions);
-};
-
-const identifiesAngular = identifiers => {
-  return identifiers.some(item => item.name == "angular");
-};
-
-const hasAngularExpressions = memberExpressions => {
-  return memberExpressions.some(item => item.name == "controller" || item.name == "module");
+  const { memberExpressions } = sourceSymbols;
+  return memberExpressions.some(item => item.expression == "angular.controller" || item.expression == "angular.module");
 };
 
 // Vue
 
 const isVueComponent = sourceSymbols => {
   const { identifiers } = sourceSymbols;
   return identifiers.some(identifier => identifier.name == "Vue");
 };
--- a/devtools/client/debugger/new/dist/search-worker.js
+++ b/devtools/client/debugger/new/dist/search-worker.js
@@ -1,18 +1,18 @@
 (function webpackUniversalModuleDefinition(root, factory) {
 	if(typeof exports === 'object' && typeof module === 'object')
-		module.exports = factory();
+		module.exports = factory(require("devtools/shared/flags"));
 	else if(typeof define === 'function' && define.amd)
-		define([], factory);
+		define(["devtools/shared/flags"], factory);
 	else {
-		var a = factory();
+		var a = typeof exports === 'object' ? factory(require("devtools/shared/flags")) : factory(root["devtools/shared/flags"]);
 		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
 	}
-})(typeof self !== 'undefined' ? self : this, function() {
+})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_52__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
 /******/
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/
 /******/ 		// Check if module is in cache
@@ -259,24 +259,238 @@ function arrayMap(array, iteratee) {
   return result;
 }
 
 module.exports = arrayMap;
 
 
 /***/ }),
 
+/***/ 120:
+/***/ (function(module, exports) {
+
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+
+/***/ }),
+
 /***/ 1284:
 /***/ (function(module, exports, __webpack_require__) {
 
 module.exports = __webpack_require__(1631);
 
 
 /***/ }),
 
+/***/ 1384:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = assert;
+
+var _devtoolsEnvironment = __webpack_require__(3721);
+
+function assert(condition, message) {
+  if ((0, _devtoolsEnvironment.isDevelopment)() && !condition) {
+    throw new Error(`Assertion failure: ${message}`);
+  }
+} /* 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/>. */
+
+/***/ }),
+
 /***/ 14:
 /***/ (function(module, exports) {
 
 /**
  * Checks if `value` is object-like. A value is object-like if it's not `null`
  * and has a `typeof` result of "object".
  *
  * @static
@@ -338,42 +552,56 @@ self.onmessage = workerHandler({ getMatc
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.default = getMatches;
 
+var _assert = __webpack_require__(1384);
+
+var _assert2 = _interopRequireDefault(_assert);
+
 var _buildQuery = __webpack_require__(3761);
 
 var _buildQuery2 = _interopRequireDefault(_buildQuery);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 function getMatches(query, text, modifiers) {
   if (!query || !text || !modifiers) {
     return [];
   }
   const regexQuery = (0, _buildQuery2.default)(query, modifiers, {
     isGlobal: true
   });
   const matchedLocations = [];
   const lines = text.split("\n");
   for (let i = 0; i < lines.length; i++) {
     let singleMatch;
     const line = lines[i];
     while ((singleMatch = regexQuery.exec(line)) !== null) {
       matchedLocations.push({ line: i, ch: singleMatch.index });
+
+      // When the match is an empty string the regexQuery.lastIndex will not
+      // change resulting in an infinite loop so we need to check for this and
+      // increment it manually in that case.  See issue #7023
+      if (singleMatch[0] === "") {
+        (0, _assert2.default)(!regexQuery.unicode, "lastIndex++ can cause issues in unicode mode");
+        regexQuery.lastIndex++;
+      }
     }
   }
   return matchedLocations;
-} /* 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/>. */
+}
 
 /***/ }),
 
 /***/ 1633:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -672,16 +900,68 @@ function streamingWorkerHandler(publicIn
 module.exports = {
   WorkerDispatcher,
   workerHandler,
   streamingWorkerHandler
 };
 
 /***/ }),
 
+/***/ 3721:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {
+
+/* 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/>. */
+
+const flag = __webpack_require__(52);
+
+function isBrowser() {
+  return typeof window == "object";
+}
+
+function isNode() {
+  return process && process.release && process.release.name == 'node';
+}
+
+function isDevelopment() {
+  if (!isNode() && isBrowser()) {
+    const href = window.location ? window.location.href : "";
+    return href.match(/^file:/) || href.match(/localhost:/);
+  }
+
+  return "production" != "production";
+}
+
+function isTesting() {
+  return flag.testing;
+}
+
+function isFirefoxPanel() {
+  return !isDevelopment();
+}
+
+function isFirefox() {
+  return (/firefox/i.test(navigator.userAgent)
+  );
+}
+
+module.exports = {
+  isDevelopment,
+  isTesting,
+  isFirefoxPanel,
+  isFirefox
+};
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(120)))
+
+/***/ }),
+
 /***/ 3761:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -754,16 +1034,23 @@ function buildQuery(originalQuery, modif
     return new RegExp(query, flags);
   }
 
   return new RegExp(query);
 }
 
 /***/ }),
 
+/***/ 52:
+/***/ (function(module, exports) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE_52__;
+
+/***/ }),
+
 /***/ 6:
 /***/ (function(module, exports, __webpack_require__) {
 
 var Symbol = __webpack_require__(7),
     getRawTag = __webpack_require__(10),
     objectToString = __webpack_require__(11);
 
 /** `Object#toString` result references. */
--- a/devtools/client/debugger/new/dist/vendors.js
+++ b/devtools/client/debugger/new/dist/vendors.js
@@ -2954,17 +2954,18 @@ const svg = {
   pug: __webpack_require__(1004),
   extjs: __webpack_require__(1043),
   mobx: __webpack_require__(1733),
   marko: __webpack_require__(1649),
   nextjs: __webpack_require__(1650),
   showSources: __webpack_require__(1044),
   showOutline: __webpack_require__(1045),
   nuxtjs: __webpack_require__(1651),
-  rxjs: __webpack_require__(1808)
+  rxjs: __webpack_require__(1808),
+  loader: __webpack_require__(3789)
 };
 
 function Svg({ name, className, onClick, "aria-label": ariaLabel }) {
   if (!svg[name]) {
     const error = `Unknown SVG: ${name}`;
     console.warn(error);
     return null;
   }
@@ -8075,16 +8076,23 @@ function formatKeyShortcut(shortcut) {
   if (isMacOS) {
     return shortcut.replace(/Shift\+/g, "\u21E7").replace(/Command\+|Cmd\+/g, "\u2318").replace(/CommandOrControl\+|CmdOrCtrl\+/g, "\u2318").replace(/Alt\+/g, "\u2325");
   }
   return shortcut.replace(/CommandOrControl\+|CmdOrCtrl\+/g, "Ctrl").replace(/Shift\+/g, "Shift");
 }
 
 /***/ }),
 
+/***/ 3789:
+/***/ (function(module, exports) {
+
+module.exports = "<!-- 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/. --><svg version=\"1.1\" id=\"loader-1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 40 40\" enable-background=\"new 0 0 40 40\" xml:space=\"preserve\"><path opacity=\"0.2\" fill=\"#000\" d=\"M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634 c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z\"></path><path fill=\"#000\" d=\"M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 C22.32,8.481,24.301,9.057,26.013,10.047z\"><animateTransform attributeType=\"xml\" attributeName=\"transform\" type=\"rotate\" from=\"0 20 20\" to=\"360 20 20\" dur=\"0.5s\" repeatCount=\"indefinite\"></animateTransform></path></svg>"
+
+/***/ }),
+
 /***/ 4:
 /***/ (function(module, exports) {
 
 module.exports = __WEBPACK_EXTERNAL_MODULE_4__;
 
 /***/ }),
 
 /***/ 52:
--- a/devtools/client/debugger/new/src/actions/sources/prettyPrint.js
+++ b/devtools/client/debugger/new/src/actions/sources/prettyPrint.js
@@ -25,16 +25,18 @@ var _source = require("../../utils/sourc
 var _loadSourceText = require("./loadSourceText");
 
 var _pause = require("../pause/index");
 
 var _sources = require("../sources/index");
 
 var _selectors = require("../../selectors/index");
 
+var _select = require("./select");
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/>. */
 function createPrettySource(sourceId) {
   return async ({
     dispatch,
@@ -53,16 +55,17 @@ function createPrettySource(sourceId) {
       isWasm: false,
       contentType: "text/javascript",
       loadedState: "loading"
     };
     dispatch({
       type: "ADD_SOURCE",
       source: prettySource
     });
+    dispatch((0, _select.selectSource)(prettySource.id));
     const {
       code,
       mappings
     } = await (0, _prettyPrint.prettyPrint)({
       source,
       url
     });
     await sourceMaps.applySourceMap(source.id, url, code, mappings);
--- a/devtools/client/debugger/new/src/client/index.js
+++ b/devtools/client/debugger/new/src/client/index.js
@@ -28,18 +28,20 @@ function loadFromPrefs(actions) {
 
   if (pauseOnExceptions || pauseOnCaughtExceptions) {
     return actions.pauseOnExceptions(pauseOnExceptions, pauseOnCaughtExceptions);
   }
 }
 
 async function loadInitialState() {
   const pendingBreakpoints = await _prefs.asyncStore.pendingBreakpoints;
+  const tabs = await _prefs.asyncStore.tabs;
   return {
-    pendingBreakpoints
+    pendingBreakpoints,
+    tabs
   };
 }
 
 async function onConnect(connection, {
   services,
   toolboxActions
 }) {
   // NOTE: the landing page does not connect to a JS process
--- a/devtools/client/debugger/new/src/components/Editor/Footer.js
+++ b/devtools/client/debugger/new/src/components/Editor/Footer.js
@@ -11,16 +11,20 @@ var _react2 = _interopRequireDefault(_re
 var _reactRedux = require("devtools/client/shared/vendor/react-redux");
 
 var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
 
 var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
+var _Svg = require("devtools/client/debugger/new/dist/vendors").vendored["Svg"];
+
+var _Svg2 = _interopRequireDefault(_Svg);
+
 var _actions = require("../../actions/index");
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = require("../../selectors/index");
 
 var _prefs = require("../../utils/prefs");
 
@@ -38,23 +42,31 @@ function _interopRequireDefault(obj) { r
  * 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/>. */
 class SourceFooter extends _react.PureComponent {
   prettyPrintButton() {
     const {
       selectedSource,
       togglePrettyPrint
     } = this.props;
-    const sourceLoaded = selectedSource && (0, _source.isLoaded)(selectedSource);
+
+    if ((0, _source.isLoading)(selectedSource) && selectedSource.isPrettyPrinted) {
+      return _react2.default.createElement("div", {
+        className: "loader"
+      }, _react2.default.createElement(_Svg2.default, {
+        name: "loader"
+      }));
+    }
 
     if (!(0, _editor.shouldShowPrettyPrint)(selectedSource)) {
       return;
     }
 
     const tooltip = L10N.getStr("sourceTabs.prettyPrint");
+    const sourceLoaded = selectedSource && (0, _source.isLoaded)(selectedSource);
     const type = "prettyPrint";
     return _react2.default.createElement("button", {
       onClick: () => togglePrettyPrint(selectedSource.id),
       className: (0, _classnames2.default)("action", type, {
         active: sourceLoaded,
         pretty: (0, _source.isPretty)(selectedSource)
       }),
       key: type,
--- a/devtools/client/debugger/new/src/components/Editor/SearchBar.js
+++ b/devtools/client/debugger/new/src/components/Editor/SearchBar.js
@@ -164,16 +164,22 @@ class SearchBar extends _react.Component
 
     this.onChange = e => {
       this.setState({
         query: e.target.value
       });
       return this.doSearch(e.target.value);
     };
 
+    this.onFocus = e => {
+      this.setState({
+        inputFocused: true
+      });
+    };
+
     this.onBlur = e => {
       this.setState({
         inputFocused: false
       });
     };
 
     this.onKeyDown = e => {
       if (e.key !== "Enter" && e.key !== "F3") {
@@ -332,24 +338,28 @@ class SearchBar extends _react.Component
       },
       searchOn
     } = this.props;
 
     if (!searchOn) {
       return _react2.default.createElement("div", null);
     }
 
+    const classes = (0, _classnames2.default)("search-bar", {
+      "search-bar-focused": this.state.inputFocused
+    });
     return _react2.default.createElement("div", {
-      className: "search-bar"
+      className: classes
     }, _react2.default.createElement(_SearchInput2.default, {
       query: this.state.query,
       count: count,
       placeholder: L10N.getStr("sourceSearch.search.placeholder2"),
       summaryMsg: this.buildSummaryMsg(),
       onChange: this.onChange,
+      onFocus: this.onFocus,
       onBlur: this.onBlur,
       showErrorEmoji: this.shouldShowErrorEmoji(),
       onKeyDown: this.onKeyDown,
       onHistoryScroll: this.onHistoryScroll,
       handleNext: e => this.traverseResults(e, false),
       handlePrev: e => this.traverseResults(e, true),
       handleClose: this.closeSearch,
       shouldFocus: this.state.inputFocused
--- a/devtools/client/debugger/new/src/components/Editor/index.js
+++ b/devtools/client/debugger/new/src/components/Editor/index.js
@@ -95,17 +95,16 @@ var _ui = require("../../utils/ui");
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/>. */
 // Redux actions
 const cssVars = {
   searchbarHeight: "var(--editor-searchbar-height)",
-  secondSearchbarHeight: "var(--editor-second-searchbar-height)",
   footerHeight: "var(--editor-footer-height)"
 };
 
 class Editor extends _react.PureComponent {
   constructor(props) {
     super(props);
 
     this.onToggleBreakpoint = (key, e) => {
@@ -234,21 +233,19 @@ class Editor extends _react.PureComponen
     (0, _editor.endOperation)();
   }
 
   componentWillUpdate(nextProps) {
     if (!this.state.editor) {
       return;
     }
 
-    (0, _editor.startOperation)();
     this.setText(nextProps);
     this.setSize(nextProps);
     this.scrollToLocation(nextProps);
-    (0, _editor.endOperation)();
   }
 
   setupEditor() {
     const editor = (0, _editor.getEditor)(); // disables the default search shortcuts
     // $FlowIgnore
 
     editor._initShortcuts = () => {};
 
@@ -335,20 +332,18 @@ class Editor extends _react.PureComponen
     // the source loads so we need to wait until the editor is
     // set to update the text and size.
 
     if (!prevState.editor && selectedSource) {
       if (!this.state.editor) {
         const editor = this.setupEditor();
         (0, _editor.updateDocument)(editor, selectedSource);
       } else {
-        (0, _editor.startOperation)();
         this.setText(this.props);
         this.setSize(this.props);
-        (0, _editor.endOperation)();
       }
     }
   }
 
   getCurrentLine() {
     const {
       codeMirror
     } = this.state.editor;
@@ -535,17 +530,16 @@ class Editor extends _react.PureComponen
     const subtractions = [];
 
     if ((0, _editor.shouldShowFooter)(selectedSource, horizontal)) {
       subtractions.push(cssVars.footerHeight);
     }
 
     if (searchOn) {
       subtractions.push(cssVars.searchbarHeight);
-      subtractions.push(cssVars.secondSearchbarHeight);
     }
 
     return {
       height: subtractions.length === 0 ? "100%" : `calc(100% - ${subtractions.join(" - ")})`
     };
   }
 
   renderHitCounts() {
@@ -583,17 +577,16 @@ class Editor extends _react.PureComponen
     }), _react2.default.createElement(_HighlightLine2.default, null), _react2.default.createElement(_EmptyLines2.default, {
       editor: editor
     }), _react2.default.createElement(_Breakpoints2.default, {
       editor: editor
     }), _react2.default.createElement(_Preview2.default, {
       editor: editor,
       editorRef: this.$editorWrapper
     }), ";", _react2.default.createElement(_Footer2.default, {
-      editor: editor,
       horizontal: horizontal
     }), _react2.default.createElement(_HighlightLines2.default, {
       editor: editor
     }), _react2.default.createElement(_EditorMenu2.default, {
       editor: editor
     }), _react2.default.createElement(_GutterMenu2.default, {
       editor: editor
     }), _react2.default.createElement(_ConditionalPanel2.default, {
@@ -621,20 +614,20 @@ class Editor extends _react.PureComponen
     const {
       coverageOn
     } = this.props;
     return _react2.default.createElement("div", {
       className: (0, _classnames2.default)("editor-wrapper", {
         "coverage-on": coverageOn
       }),
       ref: c => this.$editorWrapper = c
-    }, this.renderSearchBar(), _react2.default.createElement("div", {
+    }, _react2.default.createElement("div", {
       className: "editor-mount devtools-monospace",
       style: this.getInlineEditorStyles()
-    }), this.renderItems());
+    }), this.renderSearchBar(), this.renderItems());
   }
 
 }
 
 Editor.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
--- a/devtools/client/debugger/new/src/components/PrimaryPanes/SourcesTree.js
+++ b/devtools/client/debugger/new/src/components/PrimaryPanes/SourcesTree.js
@@ -61,16 +61,26 @@ class SourcesTree extends _react.Compone
     } = this.props;
     this.state = (0, _sourcesTree.createTree)({
       projectRoot,
       debuggeeUrl,
       sources
     });
   }
 
+  componentDidMount() {
+    const {
+      selectedSource
+    } = this.props;
+
+    if (selectedSource) {
+      this.setHighlightFocusItems(selectedSource);
+    }
+  }
+
   componentWillReceiveProps(nextProps) {
     const {
       projectRoot,
       debuggeeUrl,
       sources,
       shownSource,
       selectedSource
     } = this.props;
@@ -85,43 +95,52 @@ class SourcesTree extends _react.Compone
       return this.setState((0, _sourcesTree.createTree)({
         sources: nextProps.sources,
         debuggeeUrl: nextProps.debuggeeUrl,
         projectRoot: nextProps.projectRoot
       }));
     }
 
     if (nextProps.shownSource && nextProps.shownSource != shownSource) {
-      const listItems = (0, _sourcesTree.getDirectories)(nextProps.shownSource, sourceTree);
-      return this.setState({
-        listItems
-      });
+      return this.setHighlightFocusItems(nextProps.shownSource);
     }
 
     if (nextProps.selectedSource && nextProps.selectedSource != selectedSource) {
-      const highlightItems = (0, _sourcesTree.getDirectories)(nextProps.selectedSource, sourceTree);
-      this.setState({
-        highlightItems
-      });
+      this.setHighlightFocusItems(nextProps.selectedSource);
     } // NOTE: do not run this every time a source is clicked,
     // only when a new source is added
 
 
     if (nextProps.sources != this.props.sources) {
       this.setState((0, _sourcesTree.updateTree)({
         newSources: nextProps.sources,
         prevSources: sources,
         debuggeeUrl,
         projectRoot,
         uncollapsedTree,
         sourceTree
       }));
     }
   }
 
+  setHighlightFocusItems(source) {
+    const {
+      sourceTree,
+      parentMap
+    } = this.state;
+
+    if (source) {
+      const items = (0, _sourcesTree.getDirectories)(source, parentMap, sourceTree);
+      return this.setState({
+        listItems: items,
+        highlightItems: items
+      });
+    }
+  }
+
   // NOTE: we get the source from sources because item.contents is cached
   getSource(item) {
     const source = (0, _sourcesTree.getSourceFromNode)(item);
 
     if (source) {
       return this.props.sources[source.id];
     }
 
--- a/devtools/client/debugger/new/src/components/PrimaryPanes/SourcesTreeItem.js
+++ b/devtools/client/debugger/new/src/components/PrimaryPanes/SourcesTreeItem.js
@@ -215,22 +215,21 @@ class SourceTreeItem extends _react.Comp
     }, this.renderItemArrow(), this.getIcon(item, depth), _react2.default.createElement("span", {
       className: "label"
     }, " ", this.renderItemName(), " ", suffix));
   }
 
 }
 
 function getHasMatchingGeneratedSource(state, source) {
-  if (!source) {
+  if (!source || !_devtoolsSourceMap.isOriginalId(source.id)) {
     return false;
   }
 
-  const sources = (0, _selectors.getSourcesByURL)(state, source.url);
-  return (0, _devtoolsSourceMap.isOriginalId)(source.id) && sources.length > 1;
+  return !!(0, _selectors.getSourceByURL)(state, source.url, false);
 }
 
 const mapStateToProps = (state, props) => {
   const {
     source
   } = props;
   return {
     hasMatchingGeneratedSource: getHasMatchingGeneratedSource(state, source)
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/CommandBar.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/CommandBar.js
@@ -27,57 +27,51 @@ var _text = require("../../utils/text");
 var _actions = require("../../actions/index");
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _CommandBarButton = require("../shared/Button/CommandBarButton");
 
 var _devtoolsServices = require("Services");
 
-var _devtoolsServices2 = _interopRequireDefault(_devtoolsServices);
-
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* -*- indent-tabs-mode: nil; js-indent-level: 2; js-indent-level: 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/>. */
-const {
-  appinfo
-} = _devtoolsServices2.default;
-const isMacOS = appinfo.OS === "Darwin";
+const isMacOS = _devtoolsServices.appinfo.OS === "Darwin"; // NOTE: the "resume" command will call either the resume or breakOnNext action
+// depending on whether or not the debugger is paused or running
+
 const COMMANDS = ["resume", "stepOver", "stepIn", "stepOut"];
 const KEYS = {
   WINNT: {
     resume: "F8",
-    pause: "F8",
     stepOver: "F10",
     stepIn: "F11",
     stepOut: "Shift+F11"
   },
   Darwin: {
     resume: "Cmd+\\",
-    pause: "Cmd+\\",
     stepOver: "Cmd+'",
     stepIn: "Cmd+;",
     stepOut: "Cmd+Shift+:",
     stepOutDisplay: "Cmd+Shift+;"
   },
   Linux: {
     resume: "F8",
-    pause: "F8",
     stepOver: "F10",
     stepIn: "Ctrl+F11",
     stepOut: "Ctrl+Shift+F11"
   }
 };
 
 function getKey(action) {
-  return getKeyForOS(appinfo.OS, action);
+  return getKeyForOS(_devtoolsServices.appinfo.OS, action);
 }
 
 function getKeyForOS(os, action) {
   const osActions = KEYS[os] || KEYS.Linux;
   return osActions[action];
 }
 
 function formatKey(action) {
@@ -111,17 +105,22 @@ class CommandBar extends _react.Componen
       // as well as the Mac non-Function keys
       COMMANDS.forEach(action => shortcuts.on(getKeyForOS("WINNT", action), (_, e) => this.handleEvent(e, action)));
     }
   }
 
   handleEvent(e, action) {
     e.preventDefault();
     e.stopPropagation();
-    this.props[action]();
+
+    if (action === "resume") {
+      this.props.isPaused ? this.props.resume() : this.props.breakOnNext();
+    } else {
+      this.props[action]();
+    }
   }
 
   renderStepButtons() {
     const {
       isPaused,
       canRewind
     } = this.props;
     const className = isPaused ? "active" : "disabled";
@@ -157,17 +156,17 @@ class CommandBar extends _react.Componen
     if (_prefs.features.removeCommandBarOptions && !this.props.canRewind) {
       return;
     }
 
     if (isWaitingOnBreak) {
       return (0, _CommandBarButton.debugBtn)(null, "pause", "disabled", L10N.getStr("pausePendingButtonTooltip"), true);
     }
 
-    return (0, _CommandBarButton.debugBtn)(breakOnNext, "pause", "active", L10N.getFormatStr("pauseButtonTooltip", formatKey("pause")));
+    return (0, _CommandBarButton.debugBtn)(breakOnNext, "pause", "active", L10N.getFormatStr("pauseButtonTooltip", formatKey("resume")));
   }
 
   renderTimeTravelButtons() {
     const {
       isPaused,
       canRewind
     } = this.props;
 
--- a/devtools/client/debugger/new/src/reducers/sources.js
+++ b/devtools/client/debugger/new/src/reducers/sources.js
@@ -5,16 +5,17 @@ Object.defineProperty(exports, "__esModu
 });
 exports.getSelectedSource = exports.getSelectedLocation = exports.getSourceCount = undefined;
 exports.initialSourcesState = initialSourcesState;
 exports.createSource = createSource;
 exports.getBlackBoxList = getBlackBoxList;
 exports.getSource = getSource;
 exports.getSourceFromId = getSourceFromId;
 exports.getSourceByURL = getSourceByURL;
+exports.getSourcesByURLs = getSourcesByURLs;
 exports.getSourcesByURL = getSourcesByURL;
 exports.getGeneratedSource = getGeneratedSource;
 exports.getPendingSelectedLocation = getPendingSelectedLocation;
 exports.getPrettySource = getPrettySource;
 exports.hasPrettySource = hasPrettySource;
 exports.getSourceByUrlInSources = getSourceByUrlInSources;
 exports.getSourceInSources = getSourceInSources;
 exports.getSources = getSources;
@@ -289,16 +290,20 @@ function getSource(state, id) {
 function getSourceFromId(state, id) {
   return getSourcesState(state).sources[id];
 }
 
 function getSourceByURL(state, url) {
   return getSourceByUrlInSources(getSources(state), getUrls(state), url);
 }
 
+function getSourcesByURLs(state, urls) {
+  return urls.map(url => getSourceByURL(state, url)).filter(Boolean);
+}
+
 function getSourcesByURL(state, url) {
   return getSourcesByUrlInSources(getSources(state), getUrls(state), url);
 }
 
 function getGeneratedSource(state, source) {
   if (!(0, _devtoolsSourceMap.isOriginalId)(source.id)) {
     return source;
   }
--- a/devtools/client/debugger/new/src/reducers/tabs.js
+++ b/devtools/client/debugger/new/src/reducers/tabs.js
@@ -23,28 +23,32 @@ function _interopRequireDefault(obj) { r
 /* 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/>. */
 
 /**
  * Tabs reducer
  * @module reducers/tabs
  */
-function update(state = _prefs.prefs.tabs || [], action) {
+function isSimilarTab(tab, url, isOriginal) {
+  return tab.url === url && tab.isOriginal === isOriginal;
+}
+
+function update(state = [], action) {
   switch (action.type) {
     case "ADD_TAB":
     case "UPDATE_TAB":
       return updateTabList(state, action);
 
     case "MOVE_TAB":
       return moveTabInList(state, action);
 
     case "CLOSE_TAB":
     case "CLOSE_TABS":
-      _prefs.prefs.tabs = action.tabs;
+      _prefs.asyncStore.tabs = action.tabs;
       return action.tabs;
 
     default:
       return state;
   }
 }
 
 function removeSourceFromTabList(tabs, url) {
@@ -71,27 +75,27 @@ function updateTabList(tabs, {
     tabs = [{
       url,
       framework
     }, ...tabs];
   } else if (framework) {
     tabs[currentIndex].framework = framework;
   }
 
-  _prefs.prefs.tabs = tabs;
+  _prefs.asyncStore.tabs = tabs;
   return tabs;
 }
 
 function moveTabInList(tabs, {
   url,
   tabIndex: newIndex
 }) {
   const currentIndex = tabs.findIndex(tab => tab.url == url);
   tabs = (0, _lodashMove2.default)(tabs, currentIndex, newIndex);
-  _prefs.prefs.tabs = tabs;
+  _prefs.asyncStore.tabs = tabs;
   return tabs;
 }
 /**
  * Gets the next tab to select when a tab closes. Heuristics:
  * 1. if the selected tab is available, it remains selected
  * 2. if it is gone, the next available tab to the left should be active
  * 3. if the first tab is active and closed, select the second tab
  *
--- a/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
@@ -8,37 +8,30 @@ exports.getVisibleBreakpoints = undefine
 var _breakpoints = require("../reducers/breakpoints");
 
 var _sources = require("../reducers/sources");
 
 var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
 
 var _reselect = require("devtools/client/debugger/new/dist/vendors").vendored["reselect"];
 
+var _memoize = require("../utils/memoize");
+
+var _memoize2 = _interopRequireDefault(_memoize);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
 /* 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/>. */
 function getLocation(breakpoint, isGeneratedSource) {
   return isGeneratedSource ? breakpoint.generatedLocation || breakpoint.location : breakpoint.location;
 }
 
-function memoize(func) {
-  const store = new WeakMap();
-  return function (key, ...rest) {
-    if (store.has(key)) {
-      return store.get(key);
-    }
-
-    const value = func.apply(null, arguments);
-    store.set(key, value);
-    return value;
-  };
-}
-
-const formatBreakpoint = memoize(function (breakpoint, selectedSource) {
+const formatBreakpoint = (0, _memoize2.default)(function (breakpoint, selectedSource) {
   const {
     condition,
     loading,
     disabled,
     hidden
   } = breakpoint;
   const sourceId = selectedSource.id;
   const isGeneratedSource = (0, _devtoolsSourceMap.isGeneratedId)(sourceId);
--- a/devtools/client/debugger/new/src/utils/editor/source-documents.js
+++ b/devtools/client/debugger/new/src/utils/editor/source-documents.js
@@ -88,27 +88,29 @@ function clearEditor(editor) {
   editor.setText("");
   editor.setMode({
     name: "text"
   });
   resetLineNumberFormat(editor);
 }
 
 function showLoading(editor) {
-  if (hasDocument("loading")) {
-    return;
-  }
+  let doc = getDocument("loading");
 
-  const doc = editor.createDocument();
-  setDocument("loading", doc);
-  editor.replaceDocument(doc);
-  editor.setText(L10N.getStr("loadingText"));
-  editor.setMode({
-    name: "text"
-  });
+  if (doc) {
+    editor.replaceDocument(doc);
+  } else {
+    doc = editor.createDocument();
+    setDocument("loading", doc);
+    doc.setValue(L10N.getStr("loadingText"));
+    editor.replaceDocument(doc);
+    editor.setMode({
+      name: "text"
+    });
+  }
 }
 
 function showErrorMessage(editor, msg) {
   let error;
 
   if (msg.includes("WebAssembly binary source is not available")) {
     error = L10N.getStr("wasmIsNotAvailable");
   } else {
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/src/utils/memoize.js
@@ -0,0 +1,73 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = memoize;
+
+/* 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/>. */
+function hasValue(keys, store) {
+  let currentStore = store;
+
+  for (const key of keys) {
+    if (!currentStore || !currentStore.has(key)) {
+      return false;
+    }
+
+    currentStore = currentStore.get(key);
+  }
+
+  return true;
+}
+
+function getValue(keys, store) {
+  let currentStore = store;
+
+  for (const key of keys) {
+    if (!currentStore) {
+      return null;
+    }
+
+    currentStore = currentStore.get(key);
+  }
+
+  return currentStore;
+}
+
+function setValue(keys, store, value) {
+  const keysExceptLast = keys.slice(0, -1);
+  const lastKey = keys[keys.length - 1];
+  let currentStore = store;
+
+  for (const key of keysExceptLast) {
+    if (!currentStore) {
+      return;
+    }
+
+    if (!currentStore.has(key)) {
+      currentStore.set(key, new WeakMap());
+    }
+
+    currentStore = currentStore.get(key);
+  }
+
+  if (currentStore) {
+    currentStore.set(lastKey, value);
+  }
+} // memoize with n arguments
+
+
+function memoize(func) {
+  const store = new WeakMap();
+  return function (...keys) {
+    if (hasValue(keys, store)) {
+      return getValue(keys, store);
+    }
+
+    const newValue = func.apply(null, keys);
+    setValue(keys, store, newValue);
+    return newValue;
+  };
+}
\ No newline at end of file
--- a/devtools/client/debugger/new/src/utils/moz.build
+++ b/devtools/client/debugger/new/src/utils/moz.build
@@ -23,16 +23,17 @@ DevToolsModules(
     'expressions.js',
     'fromJS.js',
     'function.js',
     'indentation.js',
     'isMinified.js',
     'location.js',
     'log.js',
     'makeRecord.js',
+    'memoize.js',
     'path.js',
     'prefs.js',
     'preview.js',
     'project-search.js',
     'quick-open.js',
     'result-list.js',
     'source-maps.js',
     'source-queue.js',
--- a/devtools/client/debugger/new/src/utils/prefs.js
+++ b/devtools/client/debugger/new/src/utils/prefs.js
@@ -15,17 +15,17 @@ var _devtoolsServices2 = _interopRequire
 
 var _asyncStoreHelper = require("./asyncStoreHelper");
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/>. */
-const prefsSchemaVersion = "1.0.4";
+const prefsSchemaVersion = "1.0.5";
 const pref = _devtoolsServices2.default.pref;
 
 if ((0, _devtoolsEnvironment.isDevelopment)()) {
   pref("devtools.debugger.alphabetize-outline", false);
   pref("devtools.debugger.auto-pretty-print", false);
   pref("devtools.source-map.client-service.enabled", true);
   pref("devtools.debugger.pause-on-exceptions", false);
   pref("devtools.debugger.pause-on-caught-exceptions", false);
@@ -50,24 +50,23 @@ if ((0, _devtoolsEnvironment.isDevelopme
   pref("devtools.debugger.project-directory-root", "");
   pref("devtools.debugger.prefs-schema-version", "1.0.1");
   pref("devtools.debugger.skip-pausing", false);
   pref("devtools.debugger.features.workers", true);
   pref("devtools.debugger.features.async-stepping", true);
   pref("devtools.debugger.features.wasm", true);
   pref("devtools.debugger.features.shortcuts", true);
   pref("devtools.debugger.features.root", true);
-  pref("devtools.debugger.features.column-breakpoints", false);
   pref("devtools.debugger.features.map-scopes", true);
   pref("devtools.debugger.features.remove-command-bar-options", true);
   pref("devtools.debugger.features.code-coverage", false);
   pref("devtools.debugger.features.event-listeners", false);
   pref("devtools.debugger.features.code-folding", false);
   pref("devtools.debugger.features.outline", true);
-  pref("devtools.debugger.features.column-breakpoints", true);
+  pref("devtools.debugger.features.column-breakpoints", false);
   pref("devtools.debugger.features.pause-points", true);
   pref("devtools.debugger.features.skip-pausing", true);
   pref("devtools.debugger.features.component-pane", false);
   pref("devtools.debugger.features.autocomplete-expressions", false);
   pref("devtools.debugger.features.map-expression-bindings", true);
   pref("devtools.debugger.features.map-await-expression", true);
 }
 
@@ -115,17 +114,18 @@ const features = exports.features = new 
   pausePoints: ["Bool", "pause-points"],
   skipPausing: ["Bool", "skip-pausing"],
   autocompleteExpression: ["Bool", "autocomplete-expressions"],
   mapExpressionBindings: ["Bool", "map-expression-bindings"],
   mapAwaitExpression: ["Bool", "map-await-expression"],
   componentPane: ["Bool", "component-pane"]
 });
 const asyncStore = exports.asyncStore = (0, _asyncStoreHelper.asyncStoreHelper)("debugger", {
-  pendingBreakpoints: ["pending-breakpoints", {}]
+  pendingBreakpoints: ["pending-breakpoints", {}],
+  tabs: ["tabs", []]
 });
 
 if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) {
   // clear pending Breakpoints
   prefs.pendingBreakpoints = {};
   prefs.tabs = [];
   prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion;
 }
\ No newline at end of file
--- a/devtools/client/debugger/new/src/utils/quick-open.js
+++ b/devtools/client/debugger/new/src/utils/quick-open.js
@@ -67,17 +67,17 @@ function parseLineColumn(query) {
 
 function formatSourcesForList(source, tabs) {
   const title = (0, _source.getFilename)(source);
   const subtitle = (0, _utils.endTruncateStr)(source.relativeUrl, 100);
   return {
     value: source.relativeUrl,
     title,
     subtitle,
-    icon: tabs.includes(source.url) ? "tab result-item-icon" : (0, _classnames2.default)((0, _source.getSourceClassnames)(source), "result-item-icon"),
+    icon: tabs.some(tab => tab.url == source.url) ? "tab result-item-icon" : (0, _classnames2.default)((0, _source.getSourceClassnames)(source), "result-item-icon"),
     id: source.id,
     url: source.url
   };
 }
 
 function formatSymbol(symbol) {
   return {
     id: `${symbol.name}:${symbol.location.start.line}`,
--- a/devtools/client/debugger/new/src/utils/sources-tree/getDirectories.js
+++ b/devtools/client/debugger/new/src/utils/sources-tree/getDirectories.js
@@ -1,20 +1,19 @@
 "use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.getDirectories = getDirectories;
 
-var _utils = require("./utils");
-
 /* 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/>. */
+// import { createParentMap } from "./utils";
 function _traverse(subtree, source) {
   if (subtree.type === "source") {
     if (subtree.contents.id === source.id) {
       return subtree;
     }
 
     return null;
   }
@@ -22,33 +21,32 @@ function _traverse(subtree, source) {
   const matches = subtree.contents.map(child => _traverse(child, source));
   return matches && matches.filter(Boolean)[0];
 }
 
 function findSourceItem(sourceTree, source) {
   return _traverse(sourceTree, source);
 }
 
-function getAncestors(sourceTree, item) {
+function getAncestors(sourceTree, parentMap, item) {
   if (!item) {
     return null;
   }
 
-  const parentMap = (0, _utils.createParentMap)(sourceTree);
   const directories = [];
   directories.push(item);
 
   while (true) {
     item = parentMap.get(item);
 
     if (!item) {
       return directories;
     }
 
     directories.push(item);
   }
 }
 
-function getDirectories(source, sourceTree) {
+function getDirectories(source, parentMap, sourceTree) {
   const item = findSourceItem(sourceTree, source);
-  const ancestors = getAncestors(sourceTree, item);
+  const ancestors = getAncestors(sourceTree, parentMap, item);
   return ancestors || [sourceTree];
 }
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-asm.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-asm.js
@@ -4,20 +4,16 @@ add_task(async function() {
 
   // After reload() we are getting getSources notifiction for old sources,
   // using the debugger statement to really stop are reloaded page.
   await waitForPaused(dbg);
   await resume(dbg);
 
   await waitForSources(dbg, "doc-asm.html", "asm.js");
 
-  // Expand nodes and make sure more sources appear.
-  is(findAllElements(dbg, "sourceNodes").length, 2);
-
-  await clickElement(dbg, "sourceDirectoryLabel", 2);
   is(findAllElements(dbg, "sourceNodes").length, 4);
 
   await selectSource(dbg, "asm.js");
 
   await addBreakpoint(dbg, "asm.js", 7);
   invokeInTab("runAsm");
 
   await waitForPaused(dbg);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-quick-open.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-quick-open.js
@@ -48,16 +48,25 @@ function resultCount(dbg) {
 }
 
 function quickOpen(dbg, query, shortcut = "quickOpen") {
   pressKey(dbg, shortcut);
   assertEnabled(dbg);
   query !== "" && type(dbg, query);
 }
 
+function findResultEl(dbg, index = 1) {
+  return waitForElementWithSelector(dbg, `.result-item:nth-child(${index})`);
+}
+
+async function assertResultIsTab(dbg, index)  {
+  const el = await findResultEl(dbg, index);
+  ok(el && !!el.querySelector('.tab.result-item-icon'), 'Result should be a tab');
+}
+
 // Testing quick open
 add_task(async function() {
   const dbg = await initDebugger("doc-script-switching.html");
 
   info("test opening and closing");
   quickOpen(dbg, "");
   pressKey(dbg, "Escape");
   assertDisabled(dbg);
@@ -69,16 +78,21 @@ add_task(async function() {
 
   info("Testing source search and check to see if source is selected");
   await waitForSource(dbg, "switching-01");
   quickOpen(dbg, "sw1");
   is(resultCount(dbg), 1, "one file results");
   pressKey(dbg, "Enter");
   await waitForSelectedSource(dbg, "switching-01");
 
+  info("Test that results show tab icons");
+  quickOpen(dbg, "sw1");
+  await assertResultIsTab(dbg, 1);
+  pressKey(dbg, "Tab");
+
   info("Testing arrow keys in source search and check to see if source is selected");
   quickOpen(dbg, "sw2");
   is(resultCount(dbg), 1, "one file results");
   pressKey(dbg, "Down");
   pressKey(dbg, "Enter");
   await waitForSelectedSource(dbg, "switching-02");
 
   info("Testing tab closes the search");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemapped-scopes.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemapped-scopes.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // This test can be really slow on debug platforms and should be split.
-requestLongerTimeout(20);
+requestLongerTimeout(30);
 
 // Tests loading sourcemapped sources for Babel's compile output.
 
 const ACTIVE_TARGETS = new Set([
   // "webpack3",
   "webpack3-babel6",
   // "webpack3-babel7",
   // "webpack4",
--- a/devtools/client/framework/components/ToolboxTabs.js
+++ b/devtools/client/framework/components/ToolboxTabs.js
@@ -1,17 +1,16 @@
 /* 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";
 
-const { Component, createFactory } = require("devtools/client/shared/vendor/react");
+const { Component, createFactory, createRef } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
-const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
 const { ToolboxTabsOrderManager } = require("devtools/client/framework/toolbox-tabs-order-manager");
 
 const { div } = dom;
 
 const ToolboxTab = createFactory(require("devtools/client/framework/components/ToolboxTab"));
 
 loader.lazyGetter(this, "MenuButton", function() {
   return createFactory(require("devtools/client/shared/components/menu/MenuButton"));
@@ -46,16 +45,18 @@ class ToolboxTabs extends Component {
   constructor(props) {
     super(props);
 
     this.state = {
       // Array of overflowed tool id.
       overflowedTabIds: [],
     };
 
+    this.wrapperEl = createRef();
+
     // Map with tool Id and its width size. This lifecycle is out of React's
     // lifecycle. If a tool is registered, ToolboxTabs will add target tool id
     // to this map. ToolboxTabs will never remove tool id from this cache.
     this._cachedToolTabsWidthMap = new Map();
 
     this._resizeTimerId = null;
     this.resizeHandler = this.resizeHandler.bind(this);
 
@@ -117,38 +118,36 @@ class ToolboxTabs extends Component {
     const nextPanels = nextProps.panelDefinitions.map(def => def.id);
     return !this.equalToolIdArray(prevPanels, nextPanels);
   }
 
   /**
    * Update the Map of tool id and tool tab width.
    */
   updateCachedToolTabsWidthMap() {
-    const thisNode = findDOMNode(this);
     const utils = window.windowUtils;
     // Force a reflow before calling getBoundingWithoutFlushing on each tab.
-    thisNode.clientWidth;
+    this.wrapperEl.current.clientWidth;
 
-    for (const tab of thisNode.querySelectorAll(".devtools-tab")) {
+    for (const tab of this.wrapperEl.current.querySelectorAll(".devtools-tab")) {
       const tabId = tab.id.replace("toolbox-tab-", "");
       if (!this._cachedToolTabsWidthMap.has(tabId)) {
         const rect = utils.getBoundsWithoutFlushing(tab);
         this._cachedToolTabsWidthMap.set(tabId, rect.width);
       }
     }
   }
 
   /**
    * Update the overflowed tab array from currently displayed tool tab.
    * If calculated result is the same as the current overflowed tab array, this
    * function will not update state.
    */
   updateOverflowedTabs() {
-    const node = findDOMNode(this);
-    const toolboxWidth = parseInt(getComputedStyle(node).width, 10);
+    const toolboxWidth = parseInt(getComputedStyle(this.wrapperEl.current).width, 10);
     const { currentToolId } = this.props;
     const enabledTabs = this.props.panelDefinitions.map(def => def.id);
     let sumWidth = 0;
     const visibleTabs = [];
 
     for (const id of enabledTabs) {
       const width = this._cachedToolTabsWidthMap.get(id);
       sumWidth += width;
@@ -271,17 +270,18 @@ class ToolboxTabs extends Component {
           selectTool,
         });
       }
       return null;
     });
 
     return div(
       {
-        className: "toolbox-tabs-wrapper"
+        className: "toolbox-tabs-wrapper",
+        ref: this.wrapperEl,
       },
       div(
         {
           className: "toolbox-tabs",
           onMouseDown: (e) => this._tabsOrderManager.onMouseDown(e),
         },
         tabs,
         (this.state.overflowedTabIds.length > 0)
--- a/devtools/client/inspector/boxmodel/components/BoxModelMain.js
+++ b/devtools/client/inspector/boxmodel/components/BoxModelMain.js
@@ -2,17 +2,16 @@
  * 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";
 
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
-const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
 const { KeyCodes } = require("devtools/client/shared/keycodes");
 const { LocalizationHelper } = require("devtools/shared/l10n");
 
 const BoxModelEditable = createFactory(require("./BoxModelEditable"));
 
 const Types = require("../types");
 
 const SHARED_STRINGS_URI = "devtools/client/locales/shared.properties";
@@ -211,17 +210,17 @@ class BoxModelMain extends PureComponent
    *         Node to be observed
    * @param  {Boolean} shiftKey
    *         Determines if shiftKey was pressed
    * @param  {String} level
    *         Current active layout
    */
   moveFocus({ target, shiftKey }, level) {
     const editBoxes = [
-      ...findDOMNode(this).querySelectorAll(`[data-box="${level}"].boxmodel-editable`)
+      ...this.positionLayout.querySelectorAll(`[data-box="${level}"].boxmodel-editable`)
     ];
     const editingMode = target.tagName === "input";
     // target.nextSibling is input field
     let position = editingMode ? editBoxes.indexOf(target.nextSibling)
                                : editBoxes.indexOf(target);
 
     if (position === editBoxes.length - 1 && !shiftKey) {
       position = 0;
--- a/devtools/client/inspector/grids/components/Grid.js
+++ b/devtools/client/inspector/grids/components/Grid.js
@@ -4,19 +4,28 @@
 
 "use strict";
 
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
 
-const GridDisplaySettings = createFactory(require("./GridDisplaySettings"));
-const GridList = createFactory(require("./GridList"));
-const GridOutline = createFactory(require("./GridOutline"));
+// Normally, we would only lazy load GridOutline, but we also lazy load
+// GridDisplaySettings and GridList because we assume the CSS grid usage is low
+// and usually will not appear on the page.
+loader.lazyGetter(this, "GridDisplaySettings", function() {
+  return createFactory(require("./GridDisplaySettings"));
+});
+loader.lazyGetter(this, "GridList", function() {
+  return createFactory(require("./GridList"));
+});
+loader.lazyGetter(this, "GridOutline", function() {
+  return createFactory(require("./GridOutline"));
+});
 
 const Types = require("../types");
 
 class Grid extends PureComponent {
   static get propTypes() {
     return {
       getSwatchColorPickerTooltip: PropTypes.func.isRequired,
       grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -6806,31 +6806,33 @@ const { rep: StringRep } = __webpack_req
 Accessible.propTypes = {
   object: PropTypes.object.isRequired,
   inspectIconTitle: PropTypes.string,
   nameMaxLength: PropTypes.number,
   onAccessibleClick: PropTypes.func,
   onAccessibleMouseOver: PropTypes.func,
   onAccessibleMouseOut: PropTypes.func,
   onInspectIconClick: PropTypes.func,
+  roleFirst: PropTypes.bool,
   separatorText: PropTypes.string
 };
 
 function Accessible(props) {
   const {
     object,
     inspectIconTitle,
     nameMaxLength,
     onAccessibleClick,
     onAccessibleMouseOver,
     onAccessibleMouseOut,
     onInspectIconClick,
+    roleFirst,
     separatorText
   } = props;
-  const elements = getElements(object, nameMaxLength, separatorText);
+  const elements = getElements(object, nameMaxLength, roleFirst, separatorText);
   const isInTree = object.preview && object.preview.isConnected === true;
   const baseConfig = {
     "data-link-actor-id": object.actor,
     className: "objectBox objectBox-accessible"
   };
 
   let inspectIcon;
   if (isInTree) {
@@ -6866,30 +6868,29 @@ function Accessible(props) {
         }
       });
     }
   }
 
   return span(baseConfig, ...elements, inspectIcon);
 }
 
-function getElements(grip, nameMaxLength, separatorText = ": ") {
+function getElements(grip, nameMaxLength, roleFirst = false, separatorText = ": ") {
   const { name, role } = grip.preview;
   const elements = [];
-
-  elements.push(span({ className: "accessible-role" }, role));
   if (name) {
-    elements.push(span({ className: "separator" }, separatorText), StringRep({
+    elements.push(StringRep({
       className: "accessible-name",
       object: name,
       cropLimit: nameMaxLength
-    }));
-  }
-
-  return elements;
+    }), span({ className: "separator" }, separatorText));
+  }
+
+  elements.push(span({ className: "accessible-role" }, role));
+  return roleFirst ? elements.reverse() : elements;
 }
 
 // Registration
 function supportsObject(object, noGrip = false) {
   if (noGrip === true || !isGrip(object)) {
     return false;
   }
 
--- a/devtools/client/shared/components/splitter/Draggable.js
+++ b/devtools/client/shared/components/splitter/Draggable.js
@@ -1,45 +1,47 @@
 /* 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";
 
-const { Component } = require("devtools/client/shared/vendor/react");
+const { createRef, Component } = require("devtools/client/shared/vendor/react");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
-const ReactDOM = require("devtools/client/shared/vendor/react-dom");
 
 class Draggable extends Component {
   static get propTypes() {
     return {
       onMove: PropTypes.func.isRequired,
       onStart: PropTypes.func,
       onStop: PropTypes.func,
       style: PropTypes.object,
       className: PropTypes.string
     };
   }
 
   constructor(props) {
     super(props);
+
+    this.draggableEl = createRef();
+
     this.startDragging = this.startDragging.bind(this);
     this.onMove = this.onMove.bind(this);
     this.onUp = this.onUp.bind(this);
   }
 
   startDragging(ev) {
     if (this.isDragging) {
       return;
     }
     this.isDragging = true;
 
     ev.preventDefault();
-    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+    const doc = this.draggableEl.current.ownerDocument;
     doc.addEventListener("mousemove", this.onMove);
     doc.addEventListener("mouseup", this.onUp);
     this.props.onStart && this.props.onStart();
   }
 
   onMove(ev) {
     if (!this.isDragging) {
       return;
@@ -53,24 +55,25 @@ class Draggable extends Component {
 
   onUp(ev) {
     if (!this.isDragging) {
       return;
     }
     this.isDragging = false;
 
     ev.preventDefault();
-    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+    const doc = this.draggableEl.current.ownerDocument;
     doc.removeEventListener("mousemove", this.onMove);
     doc.removeEventListener("mouseup", this.onUp);
     this.props.onStop && this.props.onStop();
   }
 
   render() {
     return dom.div({
+      ref: this.draggableEl,
       role: "presentation",
       style: this.props.style,
       className: this.props.className,
       onMouseDown: this.startDragging
     });
   }
 }
 
--- a/devtools/client/shared/components/splitter/SplitBox.js
+++ b/devtools/client/shared/components/splitter/SplitBox.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/. */
 
 "use strict";
 
 const { Component, createFactory } = require("devtools/client/shared/vendor/react");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
-const ReactDOM = require("devtools/client/shared/vendor/react-dom");
+
 const Draggable = createFactory(require("devtools/client/shared/components/splitter/Draggable"));
 
 /**
  * This component represents a Splitter. The splitter supports vertical
  * as well as horizontal mode.
  */
 class SplitBox extends Component {
   static get propTypes() {
@@ -134,52 +134,49 @@ class SplitBox extends Component {
   // Dragging Events
 
   /**
    * Set 'resizing' cursor on entire document during splitter dragging.
    * This avoids cursor-flickering that happens when the mouse leaves
    * the splitter bar area (happens frequently).
    */
   onStartMove() {
-    const splitBox = ReactDOM.findDOMNode(this);
-    const doc = splitBox.ownerDocument;
+    const doc = this.splitBox.ownerDocument;
     const defaultCursor = doc.documentElement.style.cursor;
     doc.documentElement.style.cursor = (this.state.vert ? "ew-resize" : "ns-resize");
 
-    splitBox.classList.add("dragging");
+    this.splitBox.classList.add("dragging");
 
     this.setState({
       defaultCursor: defaultCursor
     });
   }
 
   onStopMove() {
-    const splitBox = ReactDOM.findDOMNode(this);
-    const doc = splitBox.ownerDocument;
+    const doc = this.splitBox.ownerDocument;
     doc.documentElement.style.cursor = this.state.defaultCursor;
 
-    splitBox.classList.remove("dragging");
+    this.splitBox.classList.remove("dragging");
   }
 
   /**
    * Adjust size of the controlled panel. Depending on the current
    * orientation we either remember the width or height of
    * the splitter box.
    */
   onMove(x, y) {
-    const node = ReactDOM.findDOMNode(this);
-    const nodeBounds = node.getBoundingClientRect();
+    const nodeBounds = this.splitBox.getBoundingClientRect();
 
     let size;
     let { endPanelControl, vert } = this.state;
 
     if (vert) {
       // Use the document owning the SplitBox to detect rtl. The global document might be
       // the one bound to the toolbox shared BrowserRequire, which is irrelevant here.
-      const doc = node.ownerDocument;
+      const doc = this.splitBox.ownerDocument;
 
       // Switch the control flag in case of RTL. Note that RTL
       // has impact on vertical splitter only.
       if (doc.dir === "rtl") {
         endPanelControl = !endPanelControl;
       }
 
       size = endPanelControl ?
@@ -244,19 +241,23 @@ class SplitBox extends Component {
     }
 
     // Calculate splitter size
     const splitterStyle = {
       flex: "0 0 " + splitterSize + "px"
     };
 
     return (
-      dom.div({
-        className: classNames.join(" "),
-        style: style },
+      dom.div(
+        {
+          className: classNames.join(" "),
+          ref: div => {
+            this.splitBox = div;
+          },
+          style },
         startPanel ?
           dom.div({
             className: endPanelControl ? "uncontrolled" : "controlled",
             style: leftPanelStyle,
             role: "presentation",
             ref: div => {
               this.startPanelContainer = div;
             }},
--- a/devtools/client/shared/components/tabs/Tabs.js
+++ b/devtools/client/shared/components/tabs/Tabs.js
@@ -2,20 +2,19 @@
 /* vim: set ft=javascript ts=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/. */
 
 "use strict";
 
 define(function(require, exports, module) {
-  const { Component } = require("devtools/client/shared/vendor/react");
+  const { Component, createRef } = require("devtools/client/shared/vendor/react");
   const dom = require("devtools/client/shared/vendor/react-dom-factories");
   const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
-  const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
 
   /**
    * Renders simple 'tab' widget.
    *
    * Based on ReactSimpleTabs component
    * https://github.com/pedronauck/react-simpletabs
    *
    * Component markup (+CSS) example:
@@ -85,27 +84,29 @@ define(function(require, exports, module
         // E.g. in case of an iframe being used as a tab-content we want the iframe to
         // stay in the DOM.
         created: [],
 
         // True if tabs can't fit into available horizontal space.
         overflow: false,
       };
 
+      this.tabsEl = createRef();
+
       this.onOverflow = this.onOverflow.bind(this);
       this.onUnderflow = this.onUnderflow.bind(this);
       this.onKeyDown = this.onKeyDown.bind(this);
       this.onClickTab = this.onClickTab.bind(this);
       this.setActive = this.setActive.bind(this);
       this.renderMenuItems = this.renderMenuItems.bind(this);
       this.renderPanels = this.renderPanels.bind(this);
     }
 
     componentDidMount() {
-      const node = findDOMNode(this);
+      const node = this.tabsEl.current;
       node.addEventListener("keydown", this.onKeyDown);
 
       // Register overflow listeners to manage visibility
       // of all-tabs-menu. This menu is displayed when there
       // is not enough h-space to render all tabs.
       // It allows the user to select a tab even if it's hidden.
       if (this.props.showAllTabsMenu) {
         node.addEventListener("overflow", this.onOverflow);
@@ -158,17 +159,17 @@ define(function(require, exports, module
       }
 
       this.setState({
         created,
       });
     }
 
     componentWillUnmount() {
-      const node = findDOMNode(this);
+      const node = this.tabsEl.current;
       node.removeEventListener("keydown", this.onKeyDown);
 
       if (this.props.showAllTabsMenu) {
         node.removeEventListener("overflow", this.onOverflow);
         node.removeEventListener("underflow", this.onUnderflow);
       }
     }
 
@@ -241,18 +242,17 @@ define(function(require, exports, module
 
       const newState = Object.assign({}, this.state, {
         created,
         tabActive: index,
       });
 
       this.setState(newState, () => {
         // Properly set focus on selected tab.
-        const node = findDOMNode(this);
-        const selectedTab = node.querySelector(".is-active > a");
+        const selectedTab = this.tabsEl.current.querySelector(".is-active > a");
         if (selectedTab) {
           selectedTab.focus();
         }
 
         if (onAfterChange) {
           onAfterChange(index);
         }
       });
@@ -405,17 +405,20 @@ define(function(require, exports, module
         dom.div({className: "panels"},
           panels
         )
       );
     }
 
     render() {
       return (
-        dom.div({ className: ["tabs", this.props.className].join(" ") },
+        dom.div({
+          className: ["tabs", this.props.className].join(" "),
+          ref: this.tabsEl,
+        },
           this.renderMenuItems(),
           this.renderPanels()
         )
       );
     }
   }
 
   /**
--- a/devtools/client/shared/node-attribute-parser.js
+++ b/devtools/client/shared/node-attribute-parser.js
@@ -33,102 +33,185 @@ const TYPE_IDREF = "idref";
 const TYPE_IDREF_LIST = "idrefList";
 const TYPE_JS_RESOURCE_URI = "jsresource";
 const TYPE_CSS_RESOURCE_URI = "cssresource";
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
 /* eslint-disable max-len */
-const ATTRIBUTE_TYPES = [
-  {namespaceURI: HTML_NS, attributeName: "action", tagName: "form", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "background", tagName: "body", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "cite", tagName: "blockquote", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "cite", tagName: "q", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "cite", tagName: "del", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "cite", tagName: "ins", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "classid", tagName: "object", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "codebase", tagName: "object", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "codebase", tagName: "applet", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "command", tagName: "menuitem", type: TYPE_IDREF},
-  {namespaceURI: "*", attributeName: "contextmenu", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "data", tagName: "object", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "for", tagName: "label", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "for", tagName: "output", type: TYPE_IDREF_LIST},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "button", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "fieldset", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "input", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "keygen", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "label", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "object", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "output", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "select", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "form", tagName: "textarea", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "formaction", tagName: "button", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "formaction", tagName: "input", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "headers", tagName: "td", type: TYPE_IDREF_LIST},
-  {namespaceURI: HTML_NS, attributeName: "headers", tagName: "th", type: TYPE_IDREF_LIST},
-  {namespaceURI: HTML_NS, attributeName: "href", tagName: "a", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "href", tagName: "area", type: TYPE_URI},
-  {namespaceURI: "*", attributeName: "href", tagName: "link", type: TYPE_CSS_RESOURCE_URI,
-  /* eslint-enable */
-   isValid: (namespaceURI, tagName, attributes) => {
-     return getAttribute(attributes, "rel") === "stylesheet";
-   }},
-  /* eslint-disable max-len */
-  {namespaceURI: "*", attributeName: "href", tagName: "link", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "href", tagName: "base", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "icon", tagName: "menuitem", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "list", tagName: "input", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "longdesc", tagName: "img", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "longdesc", tagName: "frame", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "longdesc", tagName: "iframe", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "manifest", tagName: "html", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "menu", tagName: "button", type: TYPE_IDREF},
-  {namespaceURI: HTML_NS, attributeName: "ping", tagName: "a", type: TYPE_URI_LIST},
-  {namespaceURI: HTML_NS, attributeName: "ping", tagName: "area", type: TYPE_URI_LIST},
-  {namespaceURI: HTML_NS, attributeName: "poster", tagName: "video", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "profile", tagName: "head", type: TYPE_URI},
-  {namespaceURI: "*", attributeName: "src", tagName: "script", type: TYPE_JS_RESOURCE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "input", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "frame", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "iframe", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "img", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "audio", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "embed", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "source", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "track", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "src", tagName: "video", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "usemap", tagName: "img", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "usemap", tagName: "input", type: TYPE_URI},
-  {namespaceURI: HTML_NS, attributeName: "usemap", tagName: "object", type: TYPE_URI},
-  {namespaceURI: "*", attributeName: "xmlns", tagName: "*", type: TYPE_URI},
-  {namespaceURI: XUL_NS, attributeName: "command", tagName: "key", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "containment", tagName: "*", type: TYPE_URI},
-  {namespaceURI: XUL_NS, attributeName: "context", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "datasources", tagName: "*", type: TYPE_URI_LIST},
-  {namespaceURI: XUL_NS, attributeName: "insertafter", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "insertbefore", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "menu", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "observes", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "popup", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "ref", tagName: "*", type: TYPE_URI},
-  {namespaceURI: XUL_NS, attributeName: "removeelement", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "src", tagName: "stringbundle", type: TYPE_URI},
-  {namespaceURI: XUL_NS, attributeName: "template", tagName: "*", type: TYPE_IDREF},
-  {namespaceURI: XUL_NS, attributeName: "tooltip", tagName: "*", type: TYPE_IDREF},
+const ATTRIBUTE_TYPES = {
+  "action": [
+    {namespaceURI: HTML_NS, tagName: "form", type: TYPE_URI},
+  ],
+  "background": [
+    {namespaceURI: HTML_NS,  tagName: "body", type: TYPE_URI},
+  ],
+  "cite": [
+    {namespaceURI: HTML_NS, tagName: "blockquote", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "q", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "del", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "ins", type: TYPE_URI},
+  ],
+  "classid": [
+    {namespaceURI: HTML_NS, tagName: "object", type: TYPE_URI},
+  ],
+  "codebase": [
+    {namespaceURI: HTML_NS, tagName: "object", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "applet", type: TYPE_URI},
+  ],
+  "command": [
+    {namespaceURI: HTML_NS, tagName: "menuitem", type: TYPE_IDREF},
+    {namespaceURI: XUL_NS, tagName: "key", type: TYPE_IDREF},
+  ],
+  "contextmenu": [
+    {namespaceURI: "*", tagName: "*", type: TYPE_IDREF},
+  ],
+  "data": [
+    {namespaceURI: HTML_NS, tagName: "object", type: TYPE_URI},
+  ],
+  "for": [
+    {namespaceURI: HTML_NS, tagName: "label", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "output", type: TYPE_IDREF_LIST},
+  ],
+  "form": [
+    {namespaceURI: HTML_NS, tagName: "button", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "fieldset", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "input", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "keygen", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "label", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "object", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "output", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "select", type: TYPE_IDREF},
+    {namespaceURI: HTML_NS, tagName: "textarea", type: TYPE_IDREF},
+  ],
+  "formaction": [
+    {namespaceURI: HTML_NS, tagName: "button", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "input", type: TYPE_URI},
+  ],
+  "headers": [
+    {namespaceURI: HTML_NS, tagName: "td", type: TYPE_IDREF_LIST},
+    {namespaceURI: HTML_NS, tagName: "th", type: TYPE_IDREF_LIST},
+  ],
+  "href": [
+    {namespaceURI: HTML_NS, tagName: "a", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "area", type: TYPE_URI},
+    {namespaceURI: "*", tagName: "link", type: TYPE_CSS_RESOURCE_URI,
+     /* eslint-enable */
+     isValid: (namespaceURI, tagName, attributes) => {
+       return getAttribute(attributes, "rel") === "stylesheet";
+     }},
+    /* eslint-disable max-len */
+    {namespaceURI: "*", tagName: "link", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "base", type: TYPE_URI},
+  ],
+  "icon": [
+    {namespaceURI: HTML_NS, tagName: "menuitem", type: TYPE_URI},
+  ],
+  "list": [
+    {namespaceURI: HTML_NS, tagName: "input", type: TYPE_IDREF},
+  ],
+  "longdesc": [
+    {namespaceURI: HTML_NS, tagName: "img", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "frame", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "iframe", type: TYPE_URI},
+  ],
+  "manifest": [
+    {namespaceURI: HTML_NS, tagName: "html", type: TYPE_URI},
+  ],
+  "menu": [
+    {namespaceURI: HTML_NS, tagName: "button", type: TYPE_IDREF},
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "ping": [
+    {namespaceURI: HTML_NS, tagName: "a", type: TYPE_URI_LIST},
+    {namespaceURI: HTML_NS, tagName: "area", type: TYPE_URI_LIST},
+  ],
+  "poster": [
+    {namespaceURI: HTML_NS, tagName: "video", type: TYPE_URI},
+  ],
+  "profile": [
+    {namespaceURI: HTML_NS, tagName: "head", type: TYPE_URI},
+  ],
+  "src": [
+    {namespaceURI: "*", tagName: "script", type: TYPE_JS_RESOURCE_URI},
+    {namespaceURI: HTML_NS, tagName: "input", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "frame", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "iframe", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "img", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "audio", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "embed", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "source", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "track", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "video", type: TYPE_URI},
+    {namespaceURI: XUL_NS, tagName: "stringbundle", type: TYPE_URI},
+  ],
+  "usemap": [
+    {namespaceURI: HTML_NS, tagName: "img", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "input", type: TYPE_URI},
+    {namespaceURI: HTML_NS, tagName: "object", type: TYPE_URI},
+
+  ],
+  "xmlns": [
+    {namespaceURI: "*", tagName: "*", type: TYPE_URI},
+  ],
+  "containment": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_URI},
+  ],
+  "context": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "datasources": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_URI_LIST},
+  ],
+  "insertafter": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "insertbefore": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "observes": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "popup": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "ref": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_URI},
+  ],
+  "removeelement": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "template": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
+  "tooltip": [
+    {namespaceURI: XUL_NS, tagName: "*", type: TYPE_IDREF},
+  ],
   /* eslint-enable */
   // SVG links aren't handled yet, see bug 1158831.
-  // {namespaceURI: SVG_NS, attributeName: "fill", tagName: "*", type: },
-  // {namespaceURI: SVG_NS, attributeName: "stroke", tagName: "*", type: },
-  // {namespaceURI: SVG_NS, attributeName: "markerstart", tagName: "*", type: },
-  // {namespaceURI: SVG_NS, attributeName: "markermid", tagName: "*", type: },
-  // {namespaceURI: SVG_NS, attributeName: "markerend", tagName: "*", type: },
-  // {namespaceURI: SVG_NS, attributeName: "xlink:href", tagName: "*", type: }
-];
+  // "fill": [
+  //   {namespaceURI: SVG_NS, tagName: "*", type: },
+  // ],
+  // "stroke": [
+  //   {namespaceURI: SVG_NS, tagName: "*", type: },
+  // ],
+  // "markerstart": [
+  //   {namespaceURI: SVG_NS, tagName: "*", type: },
+  // ],
+  // "markermid": [
+  //   {namespaceURI: SVG_NS, tagName: "*", type: },
+  // ],
+  // "markerend": [
+  //   {namespaceURI: SVG_NS, tagName: "*", type: },
+  // ],
+  // "xlink:href": [
+  //   {namespaceURI: SVG_NS, tagName: "*", type: },
+  // ],
+};
 
 var parsers = {
   [TYPE_URI]: function(attributeValue) {
     return [{
       type: TYPE_URI,
       value: attributeValue
     }];
   },
@@ -210,31 +293,29 @@ function parseAttribute(namespaceURI, ta
  * @param {String} tagName The node's tagName.
  * @param {Array} attributes The node's attributes, as a list of {name, value}
  * objects.
  * @param {String} attributeName The name of the attribute to get the type for.
  * @return {Object} null if no type exist for this attribute on this node, the
  * type object otherwise.
  */
 function getType(namespaceURI, tagName, attributes, attributeName) {
-  for (const typeData of ATTRIBUTE_TYPES) {
-    const containsAttribute = attributeName === typeData.attributeName ||
-                            typeData.attributeName === "*";
+  if (!ATTRIBUTE_TYPES[attributeName]) {
+    return null;
+  }
+
+  for (const typeData of ATTRIBUTE_TYPES[attributeName]) {
     const hasNamespace = namespaceURI === typeData.namespaceURI ||
                        typeData.namespaceURI === "*";
     const hasTagName = tagName.toLowerCase() === typeData.tagName ||
                      typeData.tagName === "*";
-    const isValid = typeData.isValid
-                  ? typeData.isValid(namespaceURI,
-                                     tagName,
-                                     attributes,
-                                     attributeName)
-                  : true;
+    const isValid = typeData.isValid ?
+      typeData.isValid(namespaceURI, tagName, attributes, attributeName) : true;
 
-    if (containsAttribute && hasNamespace && hasTagName && isValid) {
+    if (hasNamespace && hasTagName && isValid) {
       return typeData.type;
     }
   }
 
   return null;
 }
 
 function getAttribute(attributes, attributeName) {
--- a/devtools/client/themes/images/debugger/disable-pausing.svg
+++ b/devtools/client/themes/images/debugger/disable-pausing.svg
@@ -1,1 +1,4 @@
-<svg height="16" viewBox="0 0 15 16" width="15" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" transform="translate(0 1)"><path d="m1.5 13.5 10-13" stroke="#000" stroke-linecap="square"/><path d="m7.58013626 3-.75408823 1h-4.82604803c-.53612439 0-.77556634.12770238-.9020017.32999894-.07178403.11485445-.0979983.24068295-.0979983.27000106v4.8c0 .02931811.02621427.15514661.0979983.27000106.12643536.20229656.36587731.32999894.9020017.32999894h.30151865l-.73328118.9724077c-1.56823747-.2118785-1.56823747-1.5724077-1.56823747-1.5724077v-4.8s0-1.6 2-1.6zm3.94638894.52652517 3.4734748 3.47347483-4 4h-5.10913424l.75408823-1h3.94083241l3-3-2.6672362-2.66723627z" fill="#000" fill-rule="nonzero"/></g></svg>
\ No newline at end of file
+<!-- 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/. -->
+<svg height="16" viewBox="0 0 15 16" width="15" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" transform="translate(0 1)"><path d="m1.5 13.5 10-13" stroke="#000" stroke-linecap="square"/><path d="m7.58013626 3-.75408823 1h-4.82604803c-.53612439 0-.77556634.12770238-.9020017.32999894-.07178403.11485445-.0979983.24068295-.0979983.27000106v4.8c0 .02931811.02621427.15514661.0979983.27000106.12643536.20229656.36587731.32999894.9020017.32999894h.30151865l-.73328118.9724077c-1.56823747-.2118785-1.56823747-1.5724077-1.56823747-1.5724077v-4.8s0-1.6 2-1.6zm3.94638894.52652517 3.4734748 3.47347483-4 4h-5.10913424l.75408823-1h3.94083241l3-3-2.6672362-2.66723627z" fill="#000" fill-rule="nonzero"/></g></svg>
--- a/dom/crypto/moz.build
+++ b/dom/crypto/moz.build
@@ -25,13 +25,12 @@ UNIFIED_SOURCES += [
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/security/manager/ssl',
-    '/security/pkix/include',
     '/xpcom/build',
 ]
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -80,17 +80,16 @@ include('/ipc/chromium/chromium-config.m
 LOCAL_INCLUDES += [
     '/dom/media',
     '/dom/media/encoder',
     '/dom/media/gmp',
     '/dom/media/mp4',
     '/dom/media/platforms',
     '/dom/media/platforms/agnostic',
     '/security/certverifier',
-    '/security/pkix/include',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
 
 if CONFIG['CC_TYPE'] == 'clang':
--- a/dom/u2f/moz.build
+++ b/dom/u2f/moz.build
@@ -20,14 +20,12 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/crypto',
     '/dom/webauthn',
     '/security/manager/ssl',
-    '/security/pkix/include',
-    '/security/pkix/lib',
 ]
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
--- a/dom/webauthn/WebAuthnUtil.cpp
+++ b/dom/webauthn/WebAuthnUtil.cpp
@@ -2,17 +2,17 @@
 /* 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 "mozilla/dom/WebAuthnUtil.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsNetUtil.h"
-#include "pkixutil.h"
+#include "mozpkix/pkixutil.h"
 
 namespace mozilla {
 namespace dom {
 
 // Bug #1436078 - Permit Google Accounts. Remove in Bug #1436085 in Jan 2023.
 NS_NAMED_LITERAL_STRING(kGoogleAccountsAppId1,
   "https://www.gstatic.com/securitykey/origins.json");
 NS_NAMED_LITERAL_STRING(kGoogleAccountsAppId2,
--- a/dom/webauthn/moz.build
+++ b/dom/webauthn/moz.build
@@ -55,18 +55,16 @@ UNIFIED_SOURCES += [
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/crypto',
     '/security/manager/ssl',
-    '/security/pkix/include',
-    '/security/pkix/lib',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     OS_LIBS += [
         'hid',
     ]
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -2036,19 +2036,23 @@ imgLoader::ValidateEntry(imgCacheEntry* 
 
   bool validateRequest = false;
 
   // If the request's loadId is the same as the aCX, then it is ok to use
   // this one because it has already been validated for this context.
   //
   // XXX: nullptr seems to be a 'special' key value that indicates that NO
   //      validation is required.
-  //
+  // XXX: we also check the window ID because the loadID() can return a reused
+  //      pointer of a document. This can still happen for non-document image
+  //      cache entries.
   void *key = (void*) aCX;
-  if (request->LoadId() != key) {
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(aCX);
+  uint64_t innerWindowID = doc ? doc->InnerWindowID() : 0;
+  if (request->LoadId() != key || request->InnerWindowID() != innerWindowID) {
     // If we would need to revalidate this entry, but we're being told to
     // bypass the cache, we don't allow this entry to be used.
     if (aLoadFlags & nsIRequest::LOAD_BYPASS_CACHE) {
       return false;
     }
 
     if (MOZ_UNLIKELY(ChaosMode::isActive(ChaosFeature::ImageCache))) {
       if (ChaosMode::randomUint32LessThan(4) < 1) {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/cacheir/bug1488786-2.js
@@ -0,0 +1,27 @@
+setJitCompilerOption('ion.forceinlineCaches', 1);
+
+function protoChange() {
+    var o = {0: 0, 1: 0, 0x10000: 0, 0x20000: 0};
+
+    var tests = [1, 0, 0x10000, 0x20000];
+
+    function result_map(key, i) {
+        if (i > 5 && key == 0x20000)
+            return undefined;
+        return 0;
+    }
+
+    for (var i = 0; i < 10; i++) {
+        for (var key of tests) {
+            assertEq(o[key], result_map(key, i));
+        }
+
+        if (i == 5) {
+            delete o[0x20000];
+        }
+    }
+}
+
+for (var i = 0; i < 10; i++) {
+    protoChange();
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/cacheir/bug1488786.js
@@ -0,0 +1,38 @@
+setJitCompilerOption('ion.forceinlineCaches', 1);
+
+var A = Array(2**18);
+A[0] = "A";
+A[1] = "B";
+A[2**14] = "C";
+A[2**31-1] = "D";
+A[-1] = "E";
+
+function get_thee(a,x) {
+    return a[x];
+}
+
+// Warmup IC
+for (var i = 0; i < 30; i++) {
+    get_thee(A, i % A.length);
+}
+
+// Math.hypot currently always returns a Number, so helps
+// us ensure we're accessing the array with a Number index.
+var y = Math.hypot(1,0);
+var z = 2**31-1;
+// Ensure we handle negative indices.
+var a = -1;
+
+function test() {
+    for (var i = 0; i < 30; i++) {
+        assertEq(get_thee(A,y), "B");
+        assertEq(get_thee(A,z), "D");
+        assertEq(get_thee(A,a), "E");
+    }
+}
+test();
+
+if (!('oomTest' in this))
+    quit();
+
+oomTest(test);
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -682,16 +682,41 @@ BaselineCacheIRCompiler::emitCallProxyHa
         }
     }
 
     stubFrame.leave(masm);
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitCallNativeGetElementResult()
+{
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    Register index = allocator.useRegister(masm, reader.int32OperandId());
+
+    AutoScratchRegister scratch(allocator, masm);
+
+    allocator.discardStack(masm);
+
+    AutoStubFrame stubFrame(*this);
+    stubFrame.enter(masm, scratch);
+
+    masm.Push(index);
+    masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
+    masm.Push(obj);
+
+    if (!callVM(masm, NativeGetElementInfo)) {
+        return false;
+    }
+
+    stubFrame.leave(masm);
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult()
 {
     AutoOutputRegister output(*this);
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
     JSValueType fieldType = reader.valueType();
     Address fieldOffset(stubAddress(reader.stubOffset()));
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -285,16 +285,19 @@ GetPropIRGenerator::tryAttachStub()
                 return true;
             }
             if (tryAttachUnboxedElementHole(obj, objId, index, indexId)) {
                 return true;
             }
             if (tryAttachArgumentsObjectArg(obj, objId, indexId)) {
                 return true;
             }
+            if (tryAttachGenericElement(obj, objId, index, indexId)) {
+                return true;
+            }
 
             trackAttached(IRGenerator::NotAttached);
             return false;
         }
 
         trackAttached(IRGenerator::NotAttached);
         return false;
     }
@@ -2338,16 +2341,41 @@ GetPropIRGenerator::tryAttachUnboxedElem
     // No monitor: We know undefined must be in the typeset already.
     writer.returnFromIC();
 
     trackAttached("UnboxedElementHole");
     return true;
 }
 
 bool
+GetPropIRGenerator::tryAttachGenericElement(HandleObject obj, ObjOperandId objId,
+                                            uint32_t index, Int32OperandId indexId)
+{
+    if (!obj->isNative()) {
+        return false;
+    }
+
+    // To allow other types to attach in the non-megamorphic case we test the specific
+    // matching native reciever; however, once megamorphic we can attach for any native
+    if (mode_ == ICState::Mode::Megamorphic) {
+        writer.guardIsNativeObject(objId);
+    } else {
+        NativeObject* nobj = &obj->as<NativeObject>();
+        TestMatchingNativeReceiver(writer, nobj, objId);
+    }
+    writer.callNativeGetElementResult(objId, indexId);
+    writer.typeMonitorResult();
+
+    trackAttached(mode_ == ICState::Mode::Megamorphic
+                  ? "GenericElementMegamorphic": "GenericElement");
+    return true;
+}
+
+
+bool
 GetPropIRGenerator::tryAttachProxyElement(HandleObject obj, ObjOperandId objId)
 {
     if (!obj->is<ProxyObject>()) {
         return false;
     }
 
     // The proxy stubs don't currently support |super| access.
     if (isSuper()) {
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -293,16 +293,17 @@ extern const char* const CacheKindNames[
     _(LoadEnvironmentDynamicSlotResult)   \
     _(LoadObjectResult)                   \
     _(CallScriptedGetterResult)           \
     _(CallNativeGetterResult)             \
     _(CallProxyGetResult)                 \
     _(CallProxyGetByValueResult)          \
     _(CallProxyHasPropResult)             \
     _(CallObjectHasSparseElementResult)   \
+    _(CallNativeGetElementResult)        \
     _(LoadUndefinedResult)                \
     _(LoadBooleanResult)                  \
     _(LoadStringResult)                   \
     _(LoadInstanceOfObjectResult)         \
     _(LoadTypeOfObjectResult)             \
     _(DoubleAddResult)                    \
     _(DoubleSubResult)                    \
     _(DoubleMulResult)                    \
@@ -1254,16 +1255,20 @@ class MOZ_RAII CacheIRWriter : public JS
         writeOpWithOperandId(CacheOp::CallProxyHasPropResult, obj);
         writeOperandId(idVal);
         buffer_.writeByte(uint32_t(hasOwn));
     }
     void callObjectHasSparseElementResult(ObjOperandId obj, Int32OperandId index) {
         writeOpWithOperandId(CacheOp::CallObjectHasSparseElementResult, obj);
         writeOperandId(index);
     }
+    void callNativeGetElementResult(ObjOperandId obj, Int32OperandId index) {
+        writeOpWithOperandId(CacheOp::CallNativeGetElementResult, obj);
+        writeOperandId(index);
+    }
     void loadEnvironmentFixedSlotResult(ObjOperandId obj, size_t offset) {
         writeOpWithOperandId(CacheOp::LoadEnvironmentFixedSlotResult, obj);
         addStubField(offset, StubField::Type::RawWord);
     }
     void loadEnvironmentDynamicSlotResult(ObjOperandId obj, size_t offset) {
         writeOpWithOperandId(CacheOp::LoadEnvironmentDynamicSlotResult, obj);
         addStubField(offset, StubField::Type::RawWord);
     }
@@ -1564,16 +1569,19 @@ class MOZ_RAII GetPropIRGenerator : publ
                                uint32_t index, Int32OperandId indexId);
     bool tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId,
                                    uint32_t index, Int32OperandId indexId);
     bool tryAttachTypedElement(HandleObject obj, ObjOperandId objId,
                                uint32_t index, Int32OperandId indexId);
     bool tryAttachUnboxedElementHole(HandleObject obj, ObjOperandId objId,
                                      uint32_t index, Int32OperandId indexId);
 
+    bool tryAttachGenericElement(HandleObject obj, ObjOperandId objId,
+                                 uint32_t index, Int32OperandId indexId);
+
     bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId);
 
     void attachMegamorphicNativeSlot(ObjOperandId objId, jsid id, bool handleMissing);
 
     ValOperandId getElemKeyValueId() const {
         MOZ_ASSERT(cacheKind_ == CacheKind::GetElem || cacheKind_ == CacheKind::GetElemSuper);
         return ValOperandId(1);
     }
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -7264,16 +7264,17 @@ IonBuilder::newPendingLoopHeader(MBasicB
             }
 
             if (existingType.isSingletonUnchecked()) {
                 checkNurseryObject(existingType.singleton());
             }
 
             // Extract typeset from value.
             LifoAlloc* lifoAlloc = alloc().lifoAlloc();
+            LifoAlloc::AutoFallibleScope fallibleAllocator(lifoAlloc);
             TemporaryTypeSet* typeSet =
                 lifoAlloc->new_<TemporaryTypeSet>(lifoAlloc, existingType);
             if (!typeSet) {
                 return abort(AbortReason::Alloc);
             }
             MIRType type = typeSet->getKnownMIRType();
             if (!phi->addBackedgeType(alloc(), type, typeSet)) {
                 return abort(AbortReason::Alloc);
@@ -8981,68 +8982,27 @@ IonBuilder::getElemTryArgumentsInlinedIn
     return Ok();
 }
 
 AbortReasonOr<Ok>
 IonBuilder::getElemAddCache(MDefinition* obj, MDefinition* index)
 {
     // Emit GetPropertyCache.
 
-    TemporaryTypeSet* types = bytecodeTypes(pc);
-
-    BarrierKind barrier;
-    if (obj->type() == MIRType::Object) {
-        // Always add a barrier if the index is not an int32 value, so we can
-        // attach stubs for particular properties.
-        if (index->type() == MIRType::Int32) {
-            barrier = PropertyReadNeedsTypeBarrier(analysisContext, alloc(), constraints(), obj,
-                                                   nullptr, types);
-        } else {
-            barrier = BarrierKind::TypeSet;
-        }
-    } else {
-        // PropertyReadNeedsTypeBarrier only accounts for object types, so for
-        // now always insert a barrier if the input is not known to be an
-        // object.
-        barrier = BarrierKind::TypeSet;
-    }
-
-    // Ensure we insert a type barrier for reads from typed objects, as type
-    // information does not account for the initial undefined/null types.
-    if (barrier != BarrierKind::TypeSet && !types->unknown()) {
-        MOZ_ASSERT(obj->resultTypeSet());
-        switch (obj->resultTypeSet()->forAllClasses(constraints(), IsTypedObjectClass)) {
-          case TemporaryTypeSet::ForAllResult::ALL_FALSE:
-          case TemporaryTypeSet::ForAllResult::EMPTY:
-            break;
-          case TemporaryTypeSet::ForAllResult::ALL_TRUE:
-          case TemporaryTypeSet::ForAllResult::MIXED:
-            barrier = BarrierKind::TypeSet;
-            break;
-        }
-    }
-
     MGetPropertyCache* ins = MGetPropertyCache::New(alloc(), obj, index,
-                                                    barrier == BarrierKind::TypeSet);
+                                                    /* monitoredResult = */ true);
     current->add(ins);
     current->push(ins);
 
     MOZ_TRY(resumeAfter(ins));
 
-    // Spice up type information.
-    if (index->type() == MIRType::Int32 && barrier == BarrierKind::NoBarrier) {
-        bool needHoleCheck = !ElementAccessIsPacked(constraints(), obj);
-        MIRType knownType = GetElemKnownType(needHoleCheck, types);
-
-        if (knownType != MIRType::Value && knownType != MIRType::Double) {
-            ins->setResultType(knownType);
-        }
-    }
-
-    MOZ_TRY(pushTypeBarrier(ins, types, barrier));
+    // We always barrier getElem to handle missing elements, as type inference doesn't
+    // handle missing properties (see Bug 1488786)
+    TemporaryTypeSet* types = bytecodeTypes(pc);
+    MOZ_TRY(pushTypeBarrier(ins, types, BarrierKind::TypeSet));
 
     trackOptimizationSuccess();
     return Ok();
 }
 
 TemporaryTypeSet*
 IonBuilder::computeHeapType(const TemporaryTypeSet* objTypes, const jsid id)
 {
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -1184,16 +1184,43 @@ IonCacheIRCompiler::emitCallProxyHasProp
             return false;
         }
     }
 
     masm.storeCallResultValue(output);
     return true;
 }
 
+
+bool
+IonCacheIRCompiler::emitCallNativeGetElementResult()
+{
+    AutoSaveLiveRegisters save(*this);
+    AutoOutputRegister output(*this);
+
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    Register index = allocator.useRegister(masm, reader.int32OperandId());
+
+    allocator.discardStack(masm);
+
+    prepareVMCall(masm, save);
+
+    masm.Push(index);
+    masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
+    masm.Push(obj);
+
+    if (!callVM(masm, NativeGetElementInfo)) {
+        return false;
+    }
+
+    masm.storeCallResultValue(output);
+    return true;
+}
+
+
 bool
 IonCacheIRCompiler::emitLoadUnboxedPropertyResult()
 {
     AutoOutputRegister output(*this);
     Register obj = allocator.useRegister(masm, reader.objOperandId());
 
     JSValueType fieldType = reader.valueType();
     int32_t fieldOffset = int32StubField(reader.stubOffset());
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -2062,10 +2062,15 @@ const VMFunction ProxySetPropertyByValue
     FunctionInfo<ProxySetPropertyByValueFn>(ProxySetPropertyByValue, "ProxySetPropertyByValue");
 
 typedef bool (*ProxyHasFn)(JSContext*, HandleObject, HandleValue, MutableHandleValue);
 const VMFunction ProxyHasInfo = FunctionInfo<ProxyHasFn>(ProxyHas, "ProxyHas");
 
 typedef bool (*ProxyHasOwnFn)(JSContext*, HandleObject, HandleValue, MutableHandleValue);
 const VMFunction ProxyHasOwnInfo = FunctionInfo<ProxyHasOwnFn>(ProxyHasOwn, "ProxyHasOwn");
 
+typedef bool (*NativeGetElementFn)(JSContext*, HandleNativeObject, HandleValue, int32_t,
+                                   MutableHandleValue);
+const VMFunction NativeGetElementInfo =
+    FunctionInfo<NativeGetElementFn>(NativeGetElement, "NativeGetProperty");
+
 } // namespace jit
 } // namespace js
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -975,15 +975,17 @@ extern const VMFunction StringSplitHelpe
 
 extern const VMFunction ProxyGetPropertyInfo;
 extern const VMFunction ProxyGetPropertyByValueInfo;
 extern const VMFunction ProxySetPropertyInfo;
 extern const VMFunction ProxySetPropertyByValueInfo;
 extern const VMFunction ProxyHasInfo;
 extern const VMFunction ProxyHasOwnInfo;
 
+extern const VMFunction NativeGetElementInfo;
+
 // TailCall VMFunctions
 extern const VMFunction DoConcatStringObjectInfo;
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_VMFunctions_h */
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -2565,16 +2565,35 @@ js::NativeGetProperty(JSContext* cx, Han
 bool
 js::NativeGetPropertyNoGC(JSContext* cx, NativeObject* obj, const Value& receiver, jsid id, Value* vp)
 {
     AutoAssertNoException noexc(cx);
     return NativeGetPropertyInline<NoGC>(cx, obj, receiver, id, NotNameLookup, vp);
 }
 
 bool
+js::NativeGetElement(JSContext* cx, HandleNativeObject obj, HandleValue receiver,
+                     int32_t index, MutableHandleValue vp)
+{
+    RootedId id(cx);
+
+    if (MOZ_LIKELY(index >=0)) {
+        if (!IndexToId(cx, index, &id)) {
+            return false;
+        }
+    } else {
+        RootedValue indexVal(cx, Int32Value(index));
+        if (!ValueToId<CanGC>(cx, indexVal, &id)) {
+            return false;
+        }
+    }
+    return NativeGetProperty(cx, obj, receiver, id, vp);
+}
+
+bool
 js::GetNameBoundInEnvironment(JSContext* cx, HandleObject envArg, HandleId id, MutableHandleValue vp)
 {
     // Manually unwrap 'with' environments to prevent looking up @@unscopables
     // twice.
     //
     // This is unfortunate because internally, the engine does not distinguish
     // HasProperty from HasBinding: both are implemented as a HasPropertyOp
     // hook on a WithEnvironmentObject.
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -1605,16 +1605,20 @@ NativeGetPropertyNoGC(JSContext* cx, Nat
 
 inline bool
 NativeGetProperty(JSContext* cx, HandleNativeObject obj, HandleId id, MutableHandleValue vp)
 {
     RootedValue receiver(cx, ObjectValue(*obj));
     return NativeGetProperty(cx, obj, receiver, id, vp);
 }
 
+extern bool
+NativeGetElement(JSContext* cx, HandleNativeObject obj, HandleValue reciever, int32_t index,
+                 MutableHandleValue vp);
+
 bool
 SetPropertyByDefining(JSContext* cx, HandleId id, HandleValue v, HandleValue receiver,
                       ObjectOpResult& result);
 
 bool
 SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
                    HandleValue receiver, ObjectOpResult& result);
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/popup.html
@@ -0,0 +1,9 @@
+<html>
+    <head><title>Hello, world!</title></head>
+    <body>
+        <p>Launching popup...</p>
+        <script>
+            window.open("hello.html");
+        </script>
+    </body>
+</html>
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -27,24 +27,25 @@ open class BaseSessionTest(noErrorCollec
     companion object {
         const val CLICK_TO_RELOAD_HTML_PATH = "/assets/www/clickToReload.html"
         const val CONTENT_CRASH_URL = "about:crashcontent"
         const val DOWNLOAD_HTML_PATH = "/assets/www/download.html"
         const val FORMS_HTML_PATH = "/assets/www/forms.html"
         const val HELLO_HTML_PATH = "/assets/www/hello.html"
         const val HELLO2_HTML_PATH = "/assets/www/hello2.html"
         const val INPUTS_PATH = "/assets/www/inputs.html"
-        const val UNKNOWN_HOST_URI = "http://www.test.invalid/"
         const val INVALID_URI = "not a valid uri"
         const val LOREM_IPSUM_HTML_PATH = "/assets/www/loremIpsum.html"
+        const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html"
         const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html"
-        const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html"
+        const val POPUP_HTML_PATH = "/assets/www/popup.html"
         const val SAVE_STATE_PATH = "/assets/www/saveState.html"
         const val TITLE_CHANGE_HTML_PATH = "/assets/www/titleChange.html"
         const val TRACKERS_PATH = "/assets/www/trackers.html"
+        const val UNKNOWN_HOST_URI = "http://www.test.invalid/"
     }
 
     @get:Rule val sessionRule = GeckoSessionTestRule()
 
     @get:Rule val errors = ErrorCollector()
 
     val mainSession get() = sessionRule.session
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PromptDelegateTest.kt
@@ -0,0 +1,93 @@
+package org.mozilla.geckoview.test
+
+import org.mozilla.geckoview.GeckoResult
+import org.mozilla.geckoview.GeckoSession
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
+import org.mozilla.geckoview.test.util.Callbacks
+
+import android.support.test.filters.MediumTest
+import android.support.test.runner.AndroidJUnit4
+import org.hamcrest.Matchers.*
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+@ReuseSession(false)
+@WithDevToolsAPI
+class PromptDelegateTest : BaseSessionTest() {
+    @Test fun popupTest() {
+        // Ensure popup blocking is enabled for this test.
+        sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to true))
+        sessionRule.session.loadTestPath(POPUP_HTML_PATH)
+
+        sessionRule.waitUntilCalled(object : Callbacks.PromptDelegate {
+            @AssertCalled(count = 1)
+            override fun onPopupRequest(session: GeckoSession, targetUri: String): GeckoResult<Boolean>? {
+                assertThat("Session should not be null", session, notNullValue())
+                assertThat("URL should not be null", targetUri, notNullValue())
+                assertThat("URL should match", targetUri, endsWith(HELLO_HTML_PATH))
+                return null
+            }
+        })
+    }
+
+    @Test fun popupTestAllow() {
+        // Ensure popup blocking is enabled for this test.
+        sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to true))
+
+        sessionRule.delegateDuringNextWait(object : Callbacks.PromptDelegate, Callbacks.NavigationDelegate {
+            @AssertCalled(count = 1)
+            override fun onPopupRequest(session: GeckoSession, targetUri: String): GeckoResult<Boolean>? {
+                assertThat("Session should not be null", session, notNullValue())
+                assertThat("URL should not be null", targetUri, notNullValue())
+                assertThat("URL should match", targetUri, endsWith(HELLO_HTML_PATH))
+                return GeckoResult.fromValue(true)
+            }
+
+            @AssertCalled(count = 2)
+            override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, flags: Int): GeckoResult<Boolean>? {
+                assertThat("Session should not be null", session, notNullValue())
+                assertThat("URL should not be null", uri, notNullValue())
+                assertThat("URL should match", uri, endsWith(forEachCall(POPUP_HTML_PATH, HELLO_HTML_PATH)))
+                return null
+            }
+        })
+
+        sessionRule.session.loadTestPath(POPUP_HTML_PATH)
+        sessionRule.waitUntilCalled(Callbacks.NavigationDelegate::class, "onNewSession")
+    }
+
+    @Test fun popupTestBlock() {
+        // Ensure popup blocking is enabled for this test.
+        sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to true))
+
+        sessionRule.delegateDuringNextWait(object : Callbacks.PromptDelegate, Callbacks.NavigationDelegate {
+            @AssertCalled(count = 1)
+            override fun onPopupRequest(session: GeckoSession, targetUri: String): GeckoResult<Boolean>? {
+                assertThat("Session should not be null", session, notNullValue())
+                assertThat("URL should not be null", targetUri, notNullValue())
+                assertThat("URL should match", targetUri, endsWith(HELLO_HTML_PATH))
+                return GeckoResult.fromValue(false)
+            }
+
+            @AssertCalled(count = 1)
+            override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, flags: Int): GeckoResult<Boolean>? {
+                assertThat("Session should not be null", session, notNullValue())
+                assertThat("URL should not be null", uri, notNullValue())
+                assertThat("URL should match", uri, endsWith(POPUP_HTML_PATH))
+                return null
+            }
+
+            @AssertCalled(count = 0)
+            override fun onNewSession(session: GeckoSession, uri: String): GeckoResult<GeckoSession>? {
+                return null
+            }
+        })
+
+        sessionRule.session.loadTestPath(POPUP_HTML_PATH)
+        sessionRule.session.waitForPageStop()
+    }
+}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java
@@ -13,17 +13,17 @@ import android.graphics.Rect;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.InputDevice;
 
 import java.util.ArrayList;
 
-public final class PanZoomController extends JNIObject {
+public class PanZoomController extends JNIObject {
     private static final String LOGTAG = "GeckoNPZC";
     private static final int EVENT_SOURCE_SCROLL = 0;
     private static final int EVENT_SOURCE_MOTION = 1;
     private static final int EVENT_SOURCE_MOUSE = 2;
 
     private final LayerSession mSession;
     private final Rect mTempRect = new Rect();
     private boolean mAttached;
@@ -144,17 +144,17 @@ public final class PanZoomController ext
         mSession.getSurfaceBounds(mTempRect);
         final float x = coords.x - mTempRect.left;
         final float y = coords.y - mTempRect.top;
 
         return handleMouseEvent(event.getActionMasked(), event.getEventTime(),
                                 event.getMetaState(), x, y, event.getButtonState());
     }
 
-    /* package */ PanZoomController(final LayerSession session) {
+    protected PanZoomController(final LayerSession session) {
         mSession = session;
         enableEventQueue();
     }
 
     /**
      * Set the current scroll factor. The scroll factor is the maximum scroll amount that
      * one scroll event may generate, in device pixels.
      *
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoDisplay.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoDisplay.java
@@ -12,17 +12,17 @@ import android.view.Surface;
  * Applications use a GeckoDisplay instance to provide {@link GeckoSession} with a {@link Surface} for
  * displaying content. To ensure drawing only happens on a valid {@link Surface}, {@link GeckoSession}
  * will only use the provided {@link Surface} after {@link #surfaceChanged(Surface, int, int)} is
  * called and before {@link #surfaceDestroyed()} returns.
  */
 public class GeckoDisplay {
     private final GeckoSession session;
 
-    /* package */ GeckoDisplay(final GeckoSession session) {
+    protected GeckoDisplay(final GeckoSession session) {
         this.session = session;
     }
 
     /**
      * Required callback. The display's Surface has been created or changed. Must be
      * called on the application main thread. GeckoSession may block this call to ensure
      * the Surface is valid while resuming drawing.
      *
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -2013,16 +2013,17 @@ public class GeckoSession extends LayerS
                 break;
             }
             case "popup": {
                 GeckoResult<Boolean> res = delegate.onPopupRequest(session, message.getString("targetUri"));
 
                 if (res == null) {
                     // Keep the popup blocked if the delegate returns null
                     callback.sendSuccess(false);
+                    return;
                 }
 
                 res.then(new GeckoResult.OnValueListener<Boolean, Void>() {
                     @Override
                     public GeckoResult<Void> onValue(Boolean value) throws Throwable {
                         callback.sendSuccess(value);
                         return null;
                     }
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -296,16 +296,15 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/docshell/base',
     '/dom/base',
     '/netwerk/protocol/http',
     '/netwerk/socket',
-    '/security/pkix/include'
 ]
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
 
 if CONFIG['CC_TYPE'] == 'clang-cl':
     AllowCompilerWarnings()  # workaround for bug 1090497
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -122,17 +122,16 @@ EXTRA_JS_MODULES += [
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/netwerk/base',
     '/netwerk/cookie',
-    '/security/pkix/include',
 ]
 
 EXTRA_COMPONENTS += [
     'UAOverridesBootstrapper.js',
     'UAOverridesBootstrapper.manifest',
     'WellKnownOpportunisticUtils.js',
     'WellKnownOpportunisticUtils.manifest',
 ]
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -34,17 +34,17 @@
 #include "nsISocketTransport.h"
 #include "nsSocketTransportService2.h"
 #include "nsISSLSocketControl.h"
 #include "nsISupportsPriority.h"
 #include "nsPreloadedStream.h"
 #include "nsProxyRelease.h"
 #include "nsSocketTransport2.h"
 #include "nsStringStream.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkixnss.h"
 #include "sslt.h"
 #include "NSSErrorsService.h"
 #include "TunnelUtils.h"
 #include "TCPFastOpenLayer.h"
 
 namespace mozilla {
 namespace net {
 
--- a/old-configure.in
+++ b/old-configure.in
@@ -1771,18 +1771,18 @@ dnl ====================================
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
     AM_PATH_NSS(3.40, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
+NSS_CFLAGS="$NSS_CFLAGS -I${DIST}/include/nss"
 if test -z "$MOZ_SYSTEM_NSS"; then
-   NSS_CFLAGS="-I${DIST}/include/nss"
    case "${OS_ARCH}" in
         # Only few platforms have been tested with GYP
         WINNT|Darwin|Linux|DragonFly|FreeBSD|NetBSD|OpenBSD|SunOS)
             ;;
         *)
             AC_MSG_ERROR([building in-tree NSS is not supported on this platform. Use --with-system-nss])
             ;;
    esac
--- a/security/apps/AppSignatureVerification.cpp
+++ b/security/apps/AppSignatureVerification.cpp
@@ -31,18 +31,18 @@
 #include "nsIInputStream.h"
 #include "nsIStringEnumerator.h"
 #include "nsIZipReader.h"
 #include "nsNSSCertificate.h"
 #include "nsNetUtil.h"
 #include "nsProxyRelease.h"
 #include "nsString.h"
 #include "nsTHashtable.h"
-#include "pkix/pkix.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkix.h"
+#include "mozpkix/pkixnss.h"
 #include "plstr.h"
 #include "secmime.h"
 
 
 using namespace mozilla::pkix;
 using namespace mozilla;
 using namespace mozilla::psm;
 
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -12,17 +12,17 @@
 #include "mozilla/Casting.h"
 #include "mozilla/Preferences.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIX509CertDB.h"
 #include "nsNSSCertificate.h"
 #include "nsNetUtil.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkixnss.h"
 #include "prerror.h"
 
 // Generated by gen_cert_header.py, which gets called by the build system.
 #include "xpcshell.inc"
 // Add-on signing Certificates
 #include "addons-public.inc"
 #include "addons-stage.inc"
 // Privileged Package Certificates
--- a/security/apps/AppTrustDomain.h
+++ b/security/apps/AppTrustDomain.h
@@ -2,17 +2,17 @@
 /* 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/. */
 
 #ifndef AppTrustDomain_h
 #define AppTrustDomain_h
 
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/UniquePtr.h"
 #include "nsDebug.h"
 #include "nsIX509CertDB.h"
 #include "ScopedNSSTypes.h"
 
 namespace mozilla { namespace psm {
 
--- a/security/apps/moz.build
+++ b/security/apps/moz.build
@@ -12,17 +12,16 @@ UNIFIED_SOURCES += [
     'AppTrustDomain.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/security/certverifier',
     '/security/manager/ssl',
-    '/security/pkix/include',
     '/third_party/rust/cose-c/include',
 ]
 
 DEFINES['NSS_ENABLE_ECC'] = 'True'
 for var in ('DLL_PREFIX', 'DLL_SUFFIX'):
     DEFINES[var] = '"%s"' % CONFIG[var]
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
--- a/security/certverifier/BRNameMatchingPolicy.h
+++ b/security/certverifier/BRNameMatchingPolicy.h
@@ -2,17 +2,17 @@
 /* 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/. */
 
 #ifndef BRNameMatchingPolicy_h
 #define BRNameMatchingPolicy_h
 
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 
 namespace mozilla { namespace psm {
 
 // According to the Baseline Requirements version 1.3.3 section 7.1.4.2.2.a,
 // the requirements of the subject common name field are as follows:
 // "If present, this field MUST contain a single IP address or Fully‐Qualified
 // Domain Name that is one of the values contained in the Certificate’s
 // subjectAltName extension". Consequently, since any name information present
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -18,18 +18,18 @@
 #include "cert.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Casting.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "nsNSSComponent.h"
 #include "nsPromiseFlatString.h"
 #include "nsServiceManagerUtils.h"
 #include "pk11pub.h"
-#include "pkix/pkix.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkix.h"
+#include "mozpkix/pkixnss.h"
 #include "secmod.h"
 
 using namespace mozilla::ct;
 using namespace mozilla::pkix;
 using namespace mozilla::psm;
 
 mozilla::LazyLogModule gCertVerifierLog("certverifier");
 
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -12,17 +12,17 @@
 #include "CTVerifyResult.h"
 #include "OCSPCache.h"
 #include "RootCertificateTelemetryUtils.h"
 #include "ScopedNSSTypes.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include "nsString.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 
 #if defined(_MSC_VER)
 #pragma warning(push)
 // Silence "RootingAPI.h(718): warning C4324: 'js::DispatchWrapper<T>':
 // structure was padded due to alignment specifier with [ T=void * ]"
 #pragma warning(disable:4324)
 #endif /* defined(_MSC_VER) */
 #include "mozilla/BasePrincipal.h"
--- a/security/certverifier/ExtendedValidation.cpp
+++ b/security/certverifier/ExtendedValidation.cpp
@@ -11,17 +11,17 @@
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Casting.h"
 #include "mozilla/PodOperations.h"
 #include "nsDependentString.h"
 #include "nsString.h"
 #include "pk11pub.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 
 namespace mozilla { namespace psm {
 
 struct EVInfo
 {
   // See bug 1338873 about making these fields const.
   const char* dottedOid;
   const char* oidName; // Set this to null to signal an invalid structure,
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -23,19 +23,19 @@
 #include "nsCRTGlue.h"
 #include "nsNSSCertHelper.h"
 #include "nsNSSCertValidity.h"
 #include "nsNSSCertificate.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nss.h"
 #include "pk11pub.h"
-#include "pkix/Result.h"
-#include "pkix/pkix.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/Result.h"
+#include "mozpkix/pkix.h"
+#include "mozpkix/pkixnss.h"
 #include "prerror.h"
 #include "secerr.h"
 
 #include "TrustOverrideUtils.h"
 #include "TrustOverride-StartComAndWoSignData.inc"
 #include "TrustOverride-GlobalSignData.inc"
 #include "TrustOverride-SymantecData.inc"
 #include "TrustOverride-AppleGoogleDigiCertData.inc"
--- a/security/certverifier/NSSCertDBTrustDomain.h
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -8,17 +8,17 @@
 #define NSSCertDBTrustDomain_h
 
 #include "CertVerifier.h"
 #include "ScopedNSSTypes.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/TimeStamp.h"
 #include "nsICertBlocklist.h"
 #include "nsString.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "secmodt.h"
 
 namespace mozilla { namespace psm {
 
 enum class ValidityCheckingMode {
   CheckingOff = 0,
   CheckForEV = 1,
 };
--- a/security/certverifier/OCSPCache.cpp
+++ b/security/certverifier/OCSPCache.cpp
@@ -23,17 +23,17 @@
  */
 
 #include "OCSPCache.h"
 
 #include <limits>
 
 #include "NSSCertDBTrustDomain.h"
 #include "pk11pub.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkixnss.h"
 #include "ScopedNSSTypes.h"
 #include "secerr.h"
 
 extern mozilla::LazyLogModule gCertVerifierLog;
 
 using namespace mozilla::pkix;
 
 namespace mozilla { namespace psm {
--- a/security/certverifier/OCSPCache.h
+++ b/security/certverifier/OCSPCache.h
@@ -23,18 +23,18 @@
  */
 
 #ifndef mozilla_psm_OCSPCache_h
 #define mozilla_psm_OCSPCache_h
 
 #include "hasht.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Vector.h"
-#include "pkix/Result.h"
-#include "pkix/Time.h"
+#include "mozpkix/Result.h"
+#include "mozpkix/Time.h"
 #include "prerror.h"
 #include "seccomon.h"
 
 namespace mozilla {
 class OriginAttributes;
 }
 
 namespace mozilla { namespace pkix {
--- a/security/certverifier/OCSPVerificationTrustDomain.h
+++ b/security/certverifier/OCSPVerificationTrustDomain.h
@@ -2,17 +2,17 @@
 /* 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/. */
 
 #ifndef mozilla_psm__OCSPVerificationTrustDomain_h
 #define mozilla_psm__OCSPVerificationTrustDomain_h
 
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "NSSCertDBTrustDomain.h"
 
 namespace mozilla { namespace psm {
 
 typedef mozilla::pkix::Result Result;
 
 class OCSPVerificationTrustDomain : public mozilla::pkix::TrustDomain
 {
--- a/security/certverifier/moz.build
+++ b/security/certverifier/moz.build
@@ -24,23 +24,20 @@ UNIFIED_SOURCES += [
 if not CONFIG['NSS_NO_EV_CERTS']:
     UNIFIED_SOURCES += [
         'ExtendedValidation.cpp',
     ]
 
 LOCAL_INCLUDES += [
     '/security/ct',
     '/security/manager/ssl',
-    '/security/pkix/include',
-    '/security/pkix/lib',
 ]
 
 DIRS += [
     '../ct',
-    '../pkix',
 ]
 
 TEST_DIRS += [
     'tests/gtest',
 ]
 
 if CONFIG['CC_TYPE'] == 'clang-cl':
     # -Wall on clang-cl maps to -Weverything, which turns on way too
--- a/security/ct/BTVerifier.h
+++ b/security/ct/BTVerifier.h
@@ -3,18 +3,18 @@
 /* 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 BTVerifier_h
 #define BTVerifier_h
 
 #include "BTInclusionProof.h"
-#include "pkix/Input.h"
-#include "pkix/Result.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
 
 namespace mozilla { namespace ct {
 
 // Decodes an Inclusion Proof (InclusionProofDataV2 as defined in RFC
 // 6962-bis). This consumes the entirety of the input.
 pkix::Result DecodeInclusionProof(pkix::Reader& input,
   InclusionProofDataV2& output);
 
--- a/security/ct/CTDiversityPolicy.h
+++ b/security/ct/CTDiversityPolicy.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef CTDiversityPolicy_h
 #define CTDiversityPolicy_h
 
 #include "CTLog.h"
 #include "CTVerifyResult.h"
 #include "certt.h"
-#include "pkix/Result.h"
+#include "mozpkix/Result.h"
 
 namespace mozilla { namespace ct {
 
 // Retuns the list of unique CT log operator IDs appearing in the provided
 // list of verified SCTs.
 void GetCTLogOperatorsFromVerifiedSCTList(const VerifiedSCTList& list,
                                           CTLogOperatorList& operators);
 
--- a/security/ct/CTLogVerifier.cpp
+++ b/security/ct/CTLogVerifier.cpp
@@ -5,18 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CTLogVerifier.h"
 
 #include <stdint.h>
 
 #include "CTSerialization.h"
 #include "hasht.h"
-#include "pkix/pkixnss.h"
-#include "pkixutil.h"
+#include "mozpkix/pkixnss.h"
+#include "mozpkix/pkixutil.h"
 
 namespace mozilla { namespace ct {
 
 using namespace mozilla::pkix;
 
 // A TrustDomain used to extract the SCT log signature parameters
 // given its subjectPublicKeyInfo.
 // Only RSASSA-PKCS1v15 with SHA-256 and ECDSA (using the NIST P-256 curve)
--- a/security/ct/CTLogVerifier.h
+++ b/security/ct/CTLogVerifier.h
@@ -8,19 +8,19 @@
 #define CTLogVerifier_h
 
 #include <memory>
 
 #include "CTLog.h"
 #include "CTUtils.h"
 #include "SignedCertificateTimestamp.h"
 #include "SignedTreeHead.h"
-#include "pkix/Input.h"
-#include "pkix/Result.h"
-#include "pkix/pkix.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
+#include "mozpkix/pkix.h"
 
 namespace mozilla { namespace ct {
 
 // Verifies Signed Certificate Timestamps (SCTs) provided by a specific log
 // using the public key of that log. Assumes the SCT being verified
 // matches the log by log key ID and signature parameters (an error is returned
 // otherwise).
 // The verification functions return Success if the provided SCT has passed
--- a/security/ct/CTObjectsExtractor.cpp
+++ b/security/ct/CTObjectsExtractor.cpp
@@ -5,18 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CTObjectsExtractor.h"
 
 #include <limits>
 #include <vector>
 
 #include "hasht.h"
-#include "pkix/pkixnss.h"
-#include "pkixutil.h"
+#include "mozpkix/pkixnss.h"
+#include "mozpkix/pkixutil.h"
 
 namespace mozilla { namespace ct {
 
 using namespace mozilla::pkix;
 
 // Holds a non-owning pointer to a byte buffer and allows writing chunks of data
 // to the buffer, placing the later chunks after the earlier ones
 // in a stream-like fashion.
--- a/security/ct/CTObjectsExtractor.h
+++ b/security/ct/CTObjectsExtractor.h
@@ -2,18 +2,18 @@
 /* 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/. */
 
 #ifndef CTObjectsExtractor_h
 #define CTObjectsExtractor_h
 
-#include "pkix/Input.h"
-#include "pkix/Result.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
 #include "SignedCertificateTimestamp.h"
 
 namespace mozilla { namespace ct {
 
 // Obtains a PrecertChain log entry for |leafCertificate|, a DER-encoded
 // X.509v3 certificate that contains an X.509v3 extension with the
 // OID 1.3.6.1.4.1.11129.2.4.2.
 // |issuerSubjectPublicKeyInfo| is a DER-encoded SPKI of |leafCertificate|'s
--- a/security/ct/CTPolicyEnforcer.h
+++ b/security/ct/CTPolicyEnforcer.h
@@ -4,17 +4,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/. */
 
 #ifndef CTPolicyEnforcer_h
 #define CTPolicyEnforcer_h
 
 #include "CTLog.h"
 #include "CTVerifyResult.h"
-#include "pkix/Result.h"
+#include "mozpkix/Result.h"
 
 namespace mozilla { namespace ct {
 
 // Information about the compliance of the TLS connection with the
 // Certificate Transparency policy.
 enum class CTPolicyCompliance
 {
   // Compliance not checked or not applicable.
--- a/security/ct/CTSerialization.h
+++ b/security/ct/CTSerialization.h
@@ -4,18 +4,18 @@
  * 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 CTSerialization_h
 #define CTSerialization_h
 
 #include <vector>
 
-#include "pkix/Input.h"
-#include "pkix/Result.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
 #include "SignedCertificateTimestamp.h"
 #include "SignedTreeHead.h"
 
 // Utility functions for encoding/decoding structures used by Certificate
 // Transparency to/from the TLS wire format encoding.
 namespace mozilla { namespace ct {
 
 // Encodes the DigitallySigned |data| to |output|.
--- a/security/ct/CTUtils.h
+++ b/security/ct/CTUtils.h
@@ -8,18 +8,18 @@
 #define CTUtils_h
 
 #include <memory>
 
 #include "cryptohi.h"
 #include "keyhi.h"
 #include "keythi.h"
 #include "pk11pub.h"
-#include "pkix/Input.h"
-#include "pkix/Result.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
 
 #define MOZILLA_CT_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
 
 struct DeleteHelper
 {
   void operator()(CERTSubjectPublicKeyInfo* value)
   {
     SECKEY_DestroySubjectPublicKeyInfo(value);
--- a/security/ct/MultiLogCTVerifier.h
+++ b/security/ct/MultiLogCTVerifier.h
@@ -6,19 +6,19 @@
 
 #ifndef MultiLogCTVerifier_h
 #define MultiLogCTVerifier_h
 
 #include <vector>
 
 #include "CTLogVerifier.h"
 #include "CTVerifyResult.h"
-#include "pkix/Input.h"
-#include "pkix/Result.h"
-#include "pkix/Time.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
+#include "mozpkix/Time.h"
 #include "SignedCertificateTimestamp.h"
 
 namespace mozilla { namespace ct {
 
 // A Certificate Transparency verifier that can verify Signed Certificate
 // Timestamps from multiple logs.
 class MultiLogCTVerifier
 {
--- a/security/ct/SignedCertificateTimestamp.h
+++ b/security/ct/SignedCertificateTimestamp.h
@@ -3,18 +3,18 @@
 /* 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 SignedCertificateTimestamp_h
 #define SignedCertificateTimestamp_h
 
 #include "Buffer.h"
-#include "pkix/Input.h"
-#include "pkix/Result.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Result.h"
 
 // Structures related to Certificate Transparency (RFC 6962).
 namespace mozilla { namespace ct {
 
 // LogEntry struct in RFC 6962, Section 3.1.
 struct LogEntry
 {
 
--- a/security/ct/moz.build
+++ b/security/ct/moz.build
@@ -26,25 +26,16 @@ UNIFIED_SOURCES += [
     'CTObjectsExtractor.cpp',
     'CTPolicyEnforcer.cpp',
     'CTSerialization.cpp',
     'CTVerifyResult.cpp',
     'MultiLogCTVerifier.cpp',
     'SignedCertificateTimestamp.cpp',
 ]
 
-LOCAL_INCLUDES += [
-    '/security/pkix/include',
-    '/security/pkix/lib',
-]
-
-DIRS += [
-    '../pkix',
-]
-
 TEST_DIRS += [
     'tests/gtest',
 ]
 
 if not CONFIG['MOZ_DEBUG']:
     DEFINES['NDEBUG'] = True
 
 if CONFIG['CC_TYPE'] == 'clang-cl':
--- a/security/ct/tests/gtest/CTTestUtils.cpp
+++ b/security/ct/tests/gtest/CTTestUtils.cpp
@@ -7,23 +7,23 @@
 #include "CTTestUtils.h"
 
 #include <stdint.h>
 #include <iomanip>
 
 #include "BTInclusionProof.h"
 #include "CTSerialization.h"
 #include "gtest/gtest.h"
-#include "pkix/Input.h"
-#include "pkix/pkix.h"
-#include "pkix/pkixnss.h"
-#include "pkix/pkixtypes.h"
-#include "pkix/Result.h"
-#include "pkixcheck.h"
-#include "pkixutil.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/pkix.h"
+#include "mozpkix/pkixnss.h"
+#include "mozpkix/pkixtypes.h"
+#include "mozpkix/Result.h"
+#include "mozpkix/pkixcheck.h"
+#include "mozpkix/pkixutil.h"
 #include "SignedCertificateTimestamp.h"
 #include "SignedTreeHead.h"
 
 namespace mozilla { namespace ct {
 
 using namespace mozilla::pkix;
 
 // The following test vectors are from the CT test data repository at
--- a/security/ct/tests/gtest/CTTestUtils.h
+++ b/security/ct/tests/gtest/CTTestUtils.h
@@ -4,18 +4,18 @@
  * 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 CTTestUtils_h
 #define CTTestUtils_h
 
 #include <iostream>
 
-#include "pkix/Input.h"
-#include "pkix/Time.h"
+#include "mozpkix/Input.h"
+#include "mozpkix/Time.h"
 #include "seccomon.h"
 #include "SignedCertificateTimestamp.h"
 #include "SignedTreeHead.h"
 
 namespace mozilla { namespace ct {
 
 // Note: unless specified otherwise, all test data is taken from
 // Certificate Transparency test data repository at
--- a/security/ct/tests/gtest/moz.build
+++ b/security/ct/tests/gtest/moz.build
@@ -12,16 +12,14 @@ SOURCES += [
     'CTPolicyEnforcerTest.cpp',
     'CTSerializationTest.cpp',
     'CTTestUtils.cpp',
     'MultiLogCTVerifierTest.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../..',
-    '/security/pkix/include',
-    '/security/pkix/lib',
 ]
 
 if not CONFIG['MOZ_DEBUG']:
     DEFINES['NDEBUG'] = True
 
 FINAL_LIBRARY = 'xul-gtest'
--- a/security/manager/ssl/CSTrustDomain.cpp
+++ b/security/manager/ssl/CSTrustDomain.cpp
@@ -7,17 +7,17 @@
 #include "CSTrustDomain.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Preferences.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "NSSCertDBTrustDomain.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkixnss.h"
 
 using namespace mozilla::pkix;
 
 namespace mozilla { namespace psm {
 
 static LazyLogModule gTrustDomainPRLog("CSTrustDomain");
 #define CSTrust_LOG(args) MOZ_LOG(gTrustDomainPRLog, LogLevel::Debug, args)
 
--- a/security/manager/ssl/CSTrustDomain.h
+++ b/security/manager/ssl/CSTrustDomain.h
@@ -2,17 +2,17 @@
 /* vim: set ts=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/. */
 
 #ifndef CSTrustDomain_h
 #define CSTrustDomain_h
 
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/UniquePtr.h"
 #include "nsDebug.h"
 #include "nsICertBlocklist.h"
 #include "nsIX509CertDB.h"
 #include "ScopedNSSTypes.h"
 
 namespace mozilla { namespace psm {
--- a/security/manager/ssl/CertBlocklist.cpp
+++ b/security/manager/ssl/CertBlocklist.cpp
@@ -21,17 +21,17 @@
 #include "nsILineInputStream.h"
 #include "nsISafeOutputStream.h"
 #include "nsIX509Cert.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsPromiseFlatString.h"
 #include "nsTHashtable.h"
 #include "nsThreadUtils.h"
-#include "pkix/Input.h"
+#include "mozpkix/Input.h"
 #include "prtime.h"
 
 NS_IMPL_ISUPPORTS(CertBlocklist, nsICertBlocklist)
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 
 #define PREF_BACKGROUND_UPDATE_TIMER "app.update.lastUpdateTime.blocklist-background-update-timer"
--- a/security/manager/ssl/CertBlocklist.h
+++ b/security/manager/ssl/CertBlocklist.h
@@ -9,17 +9,17 @@
 #include "mozilla/Mutex.h"
 #include "nsCOMPtr.h"
 #include "nsClassHashtable.h"
 #include "nsICertBlocklist.h"
 #include "nsIOutputStream.h"
 #include "nsIX509CertDB.h"
 #include "nsString.h"
 #include "nsTHashtable.h"
-#include "pkix/Input.h"
+#include "mozpkix/Input.h"
 
 #define NS_CERT_BLOCKLIST_CID \
 {0x11aefd53, 0x2fbb, 0x4c92, {0xa0, 0xc1, 0x05, 0x32, 0x12, 0xae, 0x42, 0xd0} }
 
 enum CertBlocklistItemMechanism {
   BlockByIssuerAndSerial,
   BlockBySubjectAndPubKey
 };
--- a/security/manager/ssl/ContentSignatureVerifier.cpp
+++ b/security/manager/ssl/ContentSignatureVerifier.cpp
@@ -18,18 +18,18 @@
 #include "nsContentUtils.h"
 #include "nsISupportsPriority.h"
 #include "nsIURI.h"
 #include "nsNSSComponent.h"
 #include "nsPromiseFlatString.h"
 #include "nsSecurityHeaderParser.h"
 #include "nsStreamUtils.h"
 #include "nsWhitespaceTokenizer.h"
-#include "pkix/pkix.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkix.h"
+#include "mozpkix/pkixtypes.h"
 #include "secerr.h"
 
 NS_IMPL_ISUPPORTS(ContentSignatureVerifier,
                   nsIContentSignatureVerifier,
                   nsIInterfaceRequestor,
                   nsIStreamListener)
 
 using namespace mozilla;
--- a/security/manager/ssl/NSSErrorsService.cpp
+++ b/security/manager/ssl/NSSErrorsService.cpp
@@ -1,17 +1,17 @@
 /* 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 "NSSErrorsService.h"
 
 #include "nsNSSComponent.h"
 #include "nsServiceManagerUtils.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkixnss.h"
 #include "secerr.h"
 #include "sslerr.h"
 
 #define PIPNSS_STRBUNDLE_URL "chrome://pipnss/locale/pipnss.properties"
 #define NSSERR_STRBUNDLE_URL "chrome://pipnss/locale/nsserrors.properties"
 
 namespace mozilla {
 namespace psm {
--- a/security/manager/ssl/PublicKeyPinningService.cpp
+++ b/security/manager/ssl/PublicKeyPinningService.cpp
@@ -10,17 +10,17 @@
 #include "mozilla/BinarySearch.h"
 #include "mozilla/Casting.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Telemetry.h"
 #include "nsDependentString.h"
 #include "nsISiteSecurityService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsSiteSecurityService.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "seccomon.h"
 #include "sechash.h"
 
 #include "StaticHPKPins.h" // autogenerated by genHPKPStaticpins.js
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 using namespace mozilla::psm;
--- a/security/manager/ssl/PublicKeyPinningService.h
+++ b/security/manager/ssl/PublicKeyPinningService.h
@@ -6,17 +6,17 @@
 #define PublicKeyPinningService_h
 
 #include "CertVerifier.h"
 #include "ScopedNSSTypes.h"
 #include "cert.h"
 #include "nsNSSCertificate.h"
 #include "nsString.h"
 #include "nsTArray.h"
-#include "pkix/Time.h"
+#include "mozpkix/Time.h"
 
 namespace mozilla {
 class OriginAttributes;
 }
 
 using mozilla::OriginAttributes;
 
 namespace mozilla {
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -125,18 +125,18 @@
 #include "nsNetUtil.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsNSSIOLayer.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsURLHelper.h"
 #include "nsXPCOMCIDInternal.h"
-#include "pkix/pkix.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkix.h"
+#include "mozpkix/pkixnss.h"
 #include "secerr.h"
 #include "secoidt.h"
 #include "secport.h"
 #include "ssl.h"
 #include "sslerr.h"
 
 extern mozilla::LazyLogModule gPIPNSSLog;
 
--- a/security/manager/ssl/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/TransportSecurityInfo.cpp
@@ -18,17 +18,17 @@
 #include "nsIX509CertValidity.h"
 #include "nsNSSCertHelper.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsNSSHelper.h"
 #include "nsReadableUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXULAppAPI.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "secerr.h"
 
 //#define DEBUG_SSL_VERBOSE //Enable this define to get minimal
                             //reports when doing SSL read/write
 
 //#define DUMP_BUFFER  //Enable this define along with
                        //DEBUG_SSL_VERBOSE to dump SSL
                        //read/write buffer to a log.
--- a/security/manager/ssl/TransportSecurityInfo.h
+++ b/security/manager/ssl/TransportSecurityInfo.h
@@ -15,17 +15,17 @@
 #include "mozilla/Mutex.h"
 #include "mozilla/RefPtr.h"
 #include "nsDataHashtable.h"
 #include "nsIClassInfo.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsITransportSecurityInfo.h"
 #include "nsNSSCertificate.h"
 #include "nsString.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 
 namespace mozilla { namespace psm {
 
 enum class EVStatus {
   NotEV = 0,
   EV = 1,
 };
 
--- a/security/manager/ssl/moz.build
+++ b/security/manager/ssl/moz.build
@@ -171,17 +171,16 @@ UNIFIED_SOURCES += [
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/crypto',
     '/security/certverifier',
-    '/security/pkix/include',
 ]
 
 LOCAL_INCLUDES += [
     '!/dist/public/nss',
 ]
 
 GENERATED_FILES = [
     'nsSTSPreloadList.h',
@@ -196,16 +195,20 @@ if CONFIG['NSS_DISABLE_DBM']:
 DEFINES['SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES'] = 'True'
 DEFINES['NSS_ENABLE_ECC'] = 'True'
 
 if not CONFIG['MOZ_SYSTEM_NSS']:
     USE_LIBS += [
         'crmf',
     ]
 
+# mozpkix is linked statically from the in-tree sources independent of whether
+# system NSS is used or not.
+USE_LIBS += [ 'mozpkix' ]
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += [
         '-Wextra',
         # -Wextra enables this warning, but it's too noisy to be useful.
         '-Wno-missing-field-initializers',
     ]
--- a/security/manager/ssl/nsCertTree.cpp
+++ b/security/manager/ssl/nsCertTree.cpp
@@ -18,17 +18,17 @@
 #include "nsNSSCertificateDB.h"
 #include "nsNSSHelper.h"
 #include "nsReadableUtils.h"
 #include "nsTHashtable.h"
 #include "nsUnicharUtils.h"
 #include "nsXPCOMCID.h"
 #include "nsString.h"
 #include "nsTreeColumns.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 
 using namespace mozilla;
 
 extern LazyLogModule gPIPNSSLog;
 
 static NS_DEFINE_CID(kCertOverrideCID, NS_CERTOVERRIDE_CID);
 
 // treeArrayElStr
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -28,17 +28,17 @@
 #include "nsNSSCertHelper.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsNSSIOLayer.h"
 #include "nsNetUtil.h"
 #include "nsProtectedAuthThread.h"
 #include "nsProxyRelease.h"
 #include "nsStringStream.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "ssl.h"
 #include "sslproto.h"
 
 #include "TrustOverrideUtils.h"
 #include "TrustOverride-SymantecData.inc"
 #include "TrustOverride-AppleGoogleDigiCertData.inc"
 #include "TrustOverride-TestImminentDistrustData.inc"
 
--- a/security/manager/ssl/nsNSSCallbacks.h
+++ b/security/manager/ssl/nsNSSCallbacks.h
@@ -9,17 +9,17 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Vector.h"
 #include "nspr.h"
 #include "nsString.h"
 #include "pk11func.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 
 using mozilla::OriginAttributes;
 using mozilla::TimeDuration;
 using mozilla::Vector;
 
 class nsILoadGroup;
 
 char*
--- a/security/manager/ssl/nsNSSCertificate.cpp
+++ b/security/manager/ssl/nsNSSCertificate.cpp
@@ -30,19 +30,19 @@
 #include "nsPK11TokenDB.h"
 #include "nsPKCS12Blob.h"
 #include "nsProxyRelease.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsUnicharUtils.h"
 #include "nspr.h"
-#include "pkix/pkixnss.h"
-#include "pkix/pkixtypes.h"
-#include "pkix/Result.h"
+#include "mozpkix/pkixnss.h"
+#include "mozpkix/pkixtypes.h"
+#include "mozpkix/Result.h"
 #include "prerror.h"
 #include "secasn1.h"
 #include "secder.h"
 #include "secerr.h"
 #include "ssl.h"
 
 #ifdef XP_WIN
 #include <winsock.h> // for htonl
--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -10,16 +10,19 @@
 #include "NSSCertDBTrustDomain.h"
 #include "SharedSSLState.h"
 #include "certdb.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Casting.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
+#include "mozpkix/Time.h"
+#include "mozpkix/pkixnss.h"
+#include "mozpkix/pkixtypes.h"
 #include "nsArray.h"
 #include "nsArrayUtils.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsICertificateDialogs.h"
 #include "nsIFile.h"
 #include "nsIMutableArray.h"
 #include "nsIObserverService.h"
@@ -32,19 +35,16 @@
 #include "nsNSSComponent.h"
 #include "nsNSSHelper.h"
 #include "nsPKCS12Blob.h"
 #include "nsPromiseFlatString.h"
 #include "nsProxyRelease.h"
 #include "nsReadableUtils.h"
 #include "nsThreadUtils.h"
 #include "nspr.h"
-#include "pkix/Time.h"
-#include "pkix/pkixnss.h"
-#include "pkix/pkixtypes.h"
 #include "secasn1.h"
 #include "secder.h"
 #include "secerr.h"
 #include "ssl.h"
 
 #ifdef XP_WIN
 #include <winsock.h> // for ntohl
 #endif
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -47,17 +47,17 @@
 #include "nsNSSHelper.h"
 #include "nsPK11TokenDB.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "nss.h"
 #include "p12plcy.h"
-#include "pkix/pkixnss.h"
+#include "mozpkix/pkixnss.h"
 #include "secerr.h"
 #include "secmod.h"
 #include "ssl.h"
 #include "sslerr.h"
 #include "sslproto.h"
 #include "prmem.h"
 
 #if defined(XP_LINUX) && !defined(ANDROID)
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -33,18 +33,18 @@
 #include "nsIPrefService.h"
 #include "nsISocketProvider.h"
 #include "nsIWebProgressListener.h"
 #include "nsNSSCertHelper.h"
 #include "nsNSSComponent.h"
 #include "nsNSSHelper.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
-#include "pkix/pkixnss.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixnss.h"
+#include "mozpkix/pkixtypes.h"
 #include "prmem.h"
 #include "prnetdb.h"
 #include "secder.h"
 #include "secerr.h"
 #include "ssl.h"
 #include "sslerr.h"
 #include "sslproto.h"
 #include "sslexp.h"
--- a/security/manager/ssl/nsPKCS12Blob.cpp
+++ b/security/manager/ssl/nsPKCS12Blob.cpp
@@ -16,17 +16,17 @@
 #include "nsIX509CertDB.h"
 #include "nsNSSCertHelper.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSHelper.h"
 #include "nsNetUtil.h"
 #include "nsReadableUtils.h"
 #include "nsThreadUtils.h"
 #include "p12plcy.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "secerr.h"
 
 using namespace mozilla;
 extern LazyLogModule gPIPNSSLog;
 
 #define PIP_PKCS12_BUFFER_SIZE 2048
 #define PIP_PKCS12_NOSMARTCARD_EXPORT 4
 #define PIP_PKCS12_RESTORE_FAILED 5
--- a/security/manager/ssl/nsSiteSecurityService.h
+++ b/security/manager/ssl/nsSiteSecurityService.h
@@ -9,17 +9,17 @@
 #include "mozilla/Dafsa.h"
 #include "mozilla/DataStorage.h"
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIObserver.h"
 #include "nsISiteSecurityService.h"
 #include "nsString.h"
 #include "nsTArray.h"
-#include "pkix/pkixtypes.h"
+#include "mozpkix/pkixtypes.h"
 #include "prtime.h"
 
 class nsIURI;
 class nsITransportSecurityInfo;
 
 using mozilla::OriginAttributes;
 
 // {16955eee-6c48-4152-9309-c42a465138a1}
--- a/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp
+++ b/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp
@@ -6,18 +6,18 @@
 
 #include "CertVerifier.h"
 #include "OCSPCache.h"
 #include "gtest/gtest.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/Casting.h"
 #include "mozilla/Sprintf.h"
 #include "nss.h"
-#include "pkix/pkixtypes.h"
-#include "pkixtestutil.h"
+#include "mozpkix/pkixtypes.h"
+#include "mozpkix/test/pkixtestutil.h"
 #include "prerr.h"
 #include "secerr.h"
 
 using namespace mozilla::pkix;
 using namespace mozilla::pkix::test;
 
 using mozilla::OriginAttributes;
 
--- a/security/manager/ssl/tests/gtest/moz.build
+++ b/security/manager/ssl/tests/gtest/moz.build
@@ -13,18 +13,16 @@ SOURCES += [
     'MD4Test.cpp',
     'OCSPCacheTest.cpp',
     'TLSIntoleranceTest.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/security/certverifier',
     '/security/manager/ssl',
-    '/security/pkix/include',
-    '/security/pkix/test/lib',
     '/third_party/rust/cose-c/include',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul-gtest'
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build
@@ -11,16 +11,15 @@ GeckoSimplePrograms([
     'SymantecSanctionsServer',
 ], linkage=None)
 
 LOCAL_INCLUDES += [
     '../lib',
 ]
 
 USE_LIBS += [
-    'mozillapkix',
+    'mozpkix',
     'nspr',
     'nss',
-    'pkixtestutil',
     'tlsserver',
 ]
 
 CXXFLAGS += CONFIG['TK_CFLAGS']
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
@@ -1,18 +1,18 @@
 /* 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 "OCSPCommon.h"
 
 #include <stdio.h>
 
-#include "pkixtestutil.h"
-#include "pkixtestnss.h"
+#include "mozpkix/test/pkixtestutil.h"
+#include "mozpkix/test/pkixtestnss.h"
 #include "TLSServer.h"
 #include "secder.h"
 #include "secerr.h"
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 using namespace mozilla::pkix::test;
 using namespace mozilla::test;
--- a/security/manager/ssl/tests/unit/tlsserver/lib/moz.build
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build
@@ -4,14 +4,13 @@
 # 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/.
 
 UNIFIED_SOURCES += [
     'OCSPCommon.cpp',
     'TLSServer.cpp',
 ]
 
-LOCAL_INCLUDES += [
-    '../../../../../../pkix/include',
-    '../../../../../../pkix/test/lib',
+USE_LIBS += [
+    'mozpkix-testlib',
 ]
 
 Library('tlsserver')
--- a/security/moz.build
+++ b/security/moz.build
@@ -14,135 +14,142 @@ with Files("nss/**"):
     BUG_COMPONENT = ("NSS", "Libraries")
 
 with Files("nss.symbols"):
     BUG_COMPONENT = ("NSS", "Libraries")
 
 if CONFIG['MOZ_SYSTEM_NSS']:
     Library('nss')
     OS_LIBS += CONFIG['NSS_LIBS']
-else:
-    include('/build/gyp_base.mozbuild')
-    if CONFIG['MOZ_FOLD_LIBS']:
-        GeckoSharedLibrary('nss', linkage=None)
-        # TODO: The library name can be changed when bug 845217 is fixed.
-        SHARED_LIBRARY_NAME = 'nss3'
+
+include('/build/gyp_base.mozbuild')
+if CONFIG['MOZ_FOLD_LIBS']:
+    GeckoSharedLibrary('nss', linkage=None)
+    # TODO: The library name can be changed when bug 845217 is fixed.
+    SHARED_LIBRARY_NAME = 'nss3'
 
-        USE_LIBS += [
-            'nspr4',
-            'nss3_static',
-            'nssutil',
-            'plc4',
-            'plds4',
-            'smime3_static',
-            'ssl',
-        ]
+    USE_LIBS += [
+        'nspr4',
+        'nss3_static',
+        'nssutil',
+        'plc4',
+        'plds4',
+        'smime3_static',
+        'ssl',
+    ]
 
-        OS_LIBS += CONFIG['REALTIME_LIBS']
+    OS_LIBS += CONFIG['REALTIME_LIBS']
 
-        SYMBOLS_FILE = 'nss.symbols'
-        # This changes the default targets in the NSS build, among
-        # other things.
-        gyp_vars['moz_fold_libs'] = 1
-        # Some things in NSS need to link against nssutil, which
-        # gets folded, so this tells them what to link against.
-        gyp_vars['moz_folded_library_name'] = 'nss'
-        # Force things in NSS that want to link against NSPR to link
-        # against the folded library.
-        gyp_vars['nspr_libs'] = 'nss'
-    else:
-        Library('nss')
-        USE_LIBS += [
-            'nss3',
-            'nssutil3',
-            'smime3',
-            'sqlite',
-            'ssl3',
-        ]
-        gyp_vars['nspr_libs'] = 'nspr'
+    SYMBOLS_FILE = 'nss.symbols'
+    # This changes the default targets in the NSS build, among
+    # other things.
+    gyp_vars['moz_fold_libs'] = 1
+    # Some things in NSS need to link against nssutil, which
+    # gets folded, so this tells them what to link against.
+    gyp_vars['moz_folded_library_name'] = 'nss'
+    # Force things in NSS that want to link against NSPR to link
+    # against the folded library.
+    gyp_vars['nspr_libs'] = 'nss'
+elif not CONFIG['MOZ_SYSTEM_NSS']:
+    Library('nss')
+    USE_LIBS += [
+        'nss3',
+        'nssutil3',
+        'smime3',
+        'sqlite',
+        'ssl3',
+    ]
+    gyp_vars['nspr_libs'] = 'nspr'
+else:
+    # Build mozpkix and mozpkix-test only
+    gyp_vars['nspr_libs'] = 'nspr'
+    gyp_vars['mozpkix_only'] = 1
 
-    # This disables building some NSS tools.
-    gyp_vars['mozilla_client'] = 1
-    # We run shlibsign as part of packaging, not build.
-    gyp_vars['sign_libs'] = 0
-    gyp_vars['python'] = CONFIG['PYTHON']
-    # The NSS gyp files do not have a default for this.
-    gyp_vars['nss_dist_dir'] = '$PRODUCT_DIR/dist'
-    # NSS wants to put public headers in $nss_dist_dir/public/nss by default,
-    # which would wind up being mapped to dist/include/public/nss (by
-    # gyp_reader's `handle_copies`).
-    # This forces it to put them in dist/include/nss.
-    gyp_vars['nss_public_dist_dir'] = '$PRODUCT_DIR/dist'
-    gyp_vars['nss_dist_obj_dir'] = '$PRODUCT_DIR/dist/bin'
-    # We don't currently build NSS tests.
-    gyp_vars['disable_tests'] = 1
-    if CONFIG['NSS_DISABLE_DBM']:
-        gyp_vars['disable_dbm'] = 1
-    gyp_vars['disable_libpkix'] = 1
-    # pkg-config won't reliably find zlib on our builders, so just force it.
-    # System zlib is only used for modutil and signtool unless
-    # SSL zlib is enabled, which we are disabling immediately below this.
-    gyp_vars['zlib_libs'] = '-lz'
-    gyp_vars['ssl_enable_zlib'] = 0
-    # System sqlite here is the in-tree mozsqlite.
-    gyp_vars['use_system_sqlite'] = 1
-    gyp_vars['sqlite_libs'] = 'sqlite'
+# This disables building some NSS tools.
+gyp_vars['mozilla_client'] = 1
+# We run shlibsign as part of packaging, not build.
+gyp_vars['sign_libs'] = 0
+gyp_vars['python'] = CONFIG['PYTHON']
+# The NSS gyp files do not have a default for this.
+gyp_vars['nss_dist_dir'] = '$PRODUCT_DIR/dist'
+# NSS wants to put public headers in $nss_dist_dir/public/nss by default,
+# which would wind up being mapped to dist/include/public/nss (by
+# gyp_reader's `handle_copies`).
+# This forces it to put them in dist/include/nss.
+gyp_vars['nss_public_dist_dir'] = '$PRODUCT_DIR/dist'
+gyp_vars['nss_dist_obj_dir'] = '$PRODUCT_DIR/dist/bin'
+# We don't currently build NSS tests.
+gyp_vars['disable_tests'] = 1
+if CONFIG['NSS_DISABLE_DBM']:
+    gyp_vars['disable_dbm'] = 1
+gyp_vars['disable_libpkix'] = 1
+# pkg-config won't reliably find zlib on our builders, so just force it.
+# System zlib is only used for modutil and signtool unless
+# SSL zlib is enabled, which we are disabling immediately below this.
+gyp_vars['zlib_libs'] = '-lz'
+gyp_vars['ssl_enable_zlib'] = 0
+# System sqlite here is the in-tree mozsqlite.
+gyp_vars['use_system_sqlite'] = 1
+gyp_vars['sqlite_libs'] = 'sqlite'
 
-    if CONFIG['MOZ_SYSTEM_NSPR']:
-        gyp_vars['nspr_include_dir'] = '%' + CONFIG['NSPR_INCLUDE_DIR']
-        gyp_vars['nspr_lib_dir'] = '%' + CONFIG['NSPR_LIB_DIR']
-    else:
-        gyp_vars['nspr_include_dir'] = '!/dist/include/nspr'
-        gyp_vars['nspr_lib_dir'] = ''  # gyp wants a value, but we don't need
-                                       # it to be valid.
+
+if CONFIG['MOZ_SYSTEM_NSPR']:
+    gyp_vars['nspr_include_dir'] = '%' + CONFIG['NSPR_INCLUDE_DIR']
+    gyp_vars['nspr_lib_dir'] = '%' + CONFIG['NSPR_LIB_DIR']
+else:
+    gyp_vars['nspr_include_dir'] = '!/dist/include/nspr'
+    gyp_vars['nspr_lib_dir'] = ''  # gyp wants a value, but we don't need
+                                   # it to be valid.
 
-    # The Python scripts that detect clang need it to be set as CC
-    # in the environment, which isn't true here. I don't know that
-    # setting that would be harmful, but we already have this information
-    # anyway.
-    if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'):
-        gyp_vars['cc_is_clang'] = 1
-    if CONFIG['GCC_USE_GNU_LD']:
-        gyp_vars['cc_use_gnu_ld'] = 1
+# The Python scripts that detect clang need it to be set as CC
+# in the environment, which isn't true here. I don't know that
+# setting that would be harmful, but we already have this information
+# anyway.
+if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'):
+    gyp_vars['cc_is_clang'] = 1
+if CONFIG['GCC_USE_GNU_LD']:
+    gyp_vars['cc_use_gnu_ld'] = 1
 
-    GYP_DIRS += ['nss']
-    GYP_DIRS['nss'].input = 'nss/nss.gyp'
-    GYP_DIRS['nss'].variables = gyp_vars
+GYP_DIRS += ['nss']
+GYP_DIRS['nss'].input = 'nss/nss.gyp'
+GYP_DIRS['nss'].variables = gyp_vars
 
-    sandbox_vars = {
-        # NSS explicitly exports its public symbols
-        # with linker scripts.
-        'COMPILE_FLAGS': {
-            'VISIBILITY': [],
-            # XXX: We should fix these warnings.
-            'WARNINGS_AS_ERRORS': [],
-        },
-        # NSS' build system doesn't currently build NSS with PGO.
-        # We could probably do so, but not without a lot of
-        # careful consideration.
-        'NO_PGO': True,
-    }
-    if CONFIG['OS_TARGET'] == 'WINNT':
-        if CONFIG['CPU_ARCH'] == 'x86':
-            # This should really be the default.
-            sandbox_vars['ASFLAGS'] = ['-safeseh']
-        if CONFIG['MOZ_FOLD_LIBS_FLAGS']:
-            sandbox_vars['CFLAGS'] = CONFIG['MOZ_FOLD_LIBS_FLAGS']
-    if CONFIG['OS_TARGET'] == 'Android':
-        sandbox_vars['CFLAGS'] = [
-            '-include', TOPSRCDIR + '/security/manager/android_stub.h',
-            # Setting sandbox_vars['DEFINES'] is broken currently.
-            '-DCHECK_FORK_GETPID',
-        ]
-        if CONFIG['ANDROID_VERSION']:
-            sandbox_vars['CFLAGS'] += ['-DANDROID_VERSION=' + CONFIG['ANDROID_VERSION']]
-    GYP_DIRS['nss'].sandbox_vars = sandbox_vars
-    GYP_DIRS['nss'].no_chromium = True
-    GYP_DIRS['nss'].no_unified = True
-    # This maps action names from gyp files to
-    # Python scripts that can be used in moz.build GENERATED_FILES.
-    GYP_DIRS['nss'].action_overrides = {
-        'generate_certdata_c': 'generate_certdata.py',
-        'generate_mapfile': 'generate_mapfile.py',
-    }
+sandbox_vars = {
+    # NSS explicitly exports its public symbols
+    # with linker scripts.
+    'COMPILE_FLAGS': {
+        'VISIBILITY': [],
+        # XXX: We should fix these warnings.
+        'WARNINGS_AS_ERRORS': [],
+    },
+    # NSS' build system doesn't currently build NSS with PGO.
+    # We could probably do so, but not without a lot of
+    # careful consideration.
+    'NO_PGO': True,
+}
+if CONFIG['OS_TARGET'] == 'WINNT':
+    if CONFIG['CPU_ARCH'] == 'x86':
+        # This should really be the default.
+        sandbox_vars['ASFLAGS'] = ['-safeseh']
+    if CONFIG['MOZ_FOLD_LIBS_FLAGS']:
+        sandbox_vars['CFLAGS'] = CONFIG['MOZ_FOLD_LIBS_FLAGS']
+if CONFIG['OS_TARGET'] == 'Android':
+    sandbox_vars['CFLAGS'] = [
+        '-include', TOPSRCDIR + '/security/manager/android_stub.h',
+        # Setting sandbox_vars['DEFINES'] is broken currently.
+        '-DCHECK_FORK_GETPID',
+    ]
+    if CONFIG['ANDROID_VERSION']:
+        sandbox_vars['CFLAGS'] += ['-DANDROID_VERSION=' + CONFIG['ANDROID_VERSION']]
+if CONFIG['MOZ_SYSTEM_NSS']:
+    sandbox_vars['CXXFLAGS'] = CONFIG['NSS_CFLAGS']
+GYP_DIRS['nss'].sandbox_vars = sandbox_vars
+GYP_DIRS['nss'].no_chromium = True
+GYP_DIRS['nss'].no_unified = True
+# This maps action names from gyp files to
+# Python scripts that can be used in moz.build GENERATED_FILES.
+GYP_DIRS['nss'].action_overrides = {
+    'generate_certdata_c': 'generate_certdata.py',
+    'generate_mapfile': 'generate_mapfile.py',
+}
 
 if CONFIG['NSS_EXTRA_SYMBOLS_FILE']:
     DEFINES['NSS_EXTRA_SYMBOLS_FILE'] = CONFIG['NSS_EXTRA_SYMBOLS_FILE']
deleted file mode 100644
--- a/security/pkix/include/pkix/Input.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_Input_h
-#define mozilla_pkix_Input_h
-
-#include <algorithm>
-
-#include "pkix/Result.h"
-#include "stdint.h"
-
-namespace mozilla { namespace pkix {
-
-class Reader;
-
-// An Input is a safety-oriented immutable weak reference to a array of bytes
-// of a known size. The data can only be legally accessed by constructing a
-// Reader object, which guarantees all accesses to the data are memory safe.
-// Neither Input not Reader provide any facilities for modifying the data
-// they reference.
-//
-// Inputs are small and should usually be passed by value, not by reference,
-// though for inline functions the distinction doesn't matter:
-//
-//    Result GoodExample(Input input);
-//    Result BadExample(const Input& input);
-//    Result WorseExample(const uint8_t* input, size_t len);
-//
-// Note that in the example, GoodExample has the same performance
-// characteristics as WorseExample, but with much better safety guarantees.
-class Input final
-{
-public:
-  typedef uint16_t size_type;
-
-  // This constructor is useful for inputs that are statically known to be of a
-  // fixed size, e.g.:
-  //
-  //   static const uint8_t EXPECTED_BYTES[] = { 0x00, 0x01, 0x02 };
-  //   const Input expected(EXPECTED_BYTES);
-  //
-  // This is equivalent to (and preferred over):
-  //
-  //   static const uint8_t EXPECTED_BYTES[] = { 0x00, 0x01, 0x02 };
-  //   Input expected;
-  //   Result rv = expected.Init(EXPECTED_BYTES, sizeof EXPECTED_BYTES);
-  template <size_type N>
-  explicit Input(const uint8_t (&aData)[N])
-    : data(aData)
-    , len(N)
-  {
-  }
-
-  // Construct a valid, empty, Init-able Input.
-  Input()
-    : data(nullptr)
-    , len(0u)
-  {
-  }
-
-  // This is intentionally not explicit in order to allow value semantics.
-  Input(const Input&) = default;
-
-  // Initialize the input. data must be non-null and len must be less than
-  // 65536. Init may not be called more than once.
-  Result Init(const uint8_t* aData, size_t aLen)
-  {
-    if (this->data) {
-      // already initialized
-      return Result::FATAL_ERROR_INVALID_ARGS;
-    }
-    if (!aData || aLen > 0xffffu) {
-      // input too large
-      return Result::ERROR_BAD_DER;
-    }
-
-    this->data = aData;
-    this->len = aLen;
-
-    return Success;
-  }
-
-  // Initialize the input to be equivalent to the given input. Init may not be
-  // called more than once.
-  //
-  // This is basically operator=, but it wasn't given that name because
-  // normally callers do not check the result of operator=, and normally
-  // operator= can be used multiple times.
-  Result Init(Input other)
-  {
-    return Init(other.data, other.len);
-  }
-
-  // Returns the length of the input.
-  //
-  // Having the return type be size_type instead of size_t avoids the need for
-  // callers to ensure that the result is small enough.
-  size_type GetLength() const { return static_cast<size_type>(len); }
-
-  // Don't use this. It is here because we have some "friend" functions that we
-  // don't want to declare in this header file.
-  const uint8_t* UnsafeGetData() const { return data; }
-
-private:
-  const uint8_t* data;
-  size_t len;
-
-  void operator=(const Input&) = delete; // Use Init instead.
-};
-
-inline bool
-InputsAreEqual(const Input& a, const Input& b)
-{
-  return a.GetLength() == b.GetLength() &&
-         std::equal(a.UnsafeGetData(), a.UnsafeGetData() + a.GetLength(), b.UnsafeGetData());
-}
-
-// An Reader is a cursor/iterator through the contents of an Input, designed to
-// maximize safety during parsing while minimizing the performance cost of that
-// safety. In particular, all methods do strict bounds checking to ensure
-// buffer overflows are impossible, and they are all inline so that the
-// compiler can coalesce as many of those checks together as possible.
-//
-// In general, Reader allows for one byte of lookahead and no backtracking.
-// However, the Match* functions internally may have more lookahead.
-class Reader final
-{
-public:
-  Reader()
-    : input(nullptr)
-    , end(nullptr)
-  {
-  }
-
-  explicit Reader(Input aInput)
-    : input(aInput.UnsafeGetData())
-    , end(aInput.UnsafeGetData() + aInput.GetLength())
-  {
-  }
-
-  Result Init(Input aInput)
-  {
-    if (this->input) {
-      return Result::FATAL_ERROR_INVALID_ARGS;
-    }
-    this->input = aInput.UnsafeGetData();
-    this->end = aInput.UnsafeGetData() + aInput.GetLength();
-    return Success;
-  }
-
-  bool Peek(uint8_t expectedByte) const
-  {
-    return input < end && *input == expectedByte;
-  }
-
-  Result Read(uint8_t& out)
-  {
-    Result rv = EnsureLength(1);
-    if (rv != Success) {
-      return rv;
-    }
-    out = *input++;
-    return Success;
-  }
-
-  Result Read(uint16_t& out)
-  {
-    Result rv = EnsureLength(2);
-    if (rv != Success) {
-      return rv;
-    }
-    out = *input++;
-    out <<= 8u;
-    out |= *input++;
-    return Success;
-  }
-
-  template <Input::size_type N>
-  bool MatchRest(const uint8_t (&toMatch)[N])
-  {
-    // Normally we use EnsureLength which compares (input + len < end), but
-    // here we want to be sure that there is nothing following the matched
-    // bytes
-    if (static_cast<size_t>(end - input) != N) {
-      return false;
-    }
-    if (!std::equal(input, end, toMatch)) {
-      return false;
-    }
-    input = end;
-    return true;
-  }
-
-  bool MatchRest(Input toMatch)
-  {
-    // Normally we use EnsureLength which compares (input + len < end), but
-    // here we want to be sure that there is nothing following the matched
-    // bytes
-    size_t remaining = static_cast<size_t>(end - input);
-    if (toMatch.GetLength() != remaining) {
-      return false;
-    }
-    if (!std::equal(input, end, toMatch.UnsafeGetData())) {
-      return false;
-    }
-    input = end;
-    return true;
-  }
-
-  Result Skip(Input::size_type len)
-  {
-    Result rv = EnsureLength(len);
-    if (rv != Success) {
-      return rv;
-    }
-    input += len;
-    return Success;
-  }
-
-  Result Skip(Input::size_type len, Reader& skipped)
-  {
-    Result rv = EnsureLength(len);
-    if (rv != Success) {
-      return rv;
-    }
-    rv = skipped.Init(input, len);
-    if (rv != Success) {
-      return rv;
-    }
-    input += len;
-    return Success;
-  }
-
-  Result Skip(Input::size_type len, /*out*/ Input& skipped)
-  {
-    Result rv = EnsureLength(len);
-    if (rv != Success) {
-      return rv;
-    }
-    rv = skipped.Init(input, len);
-    if (rv != Success) {
-      return rv;
-    }
-    input += len;
-    return Success;
-  }
-
-  void SkipToEnd()
-  {
-    input = end;
-  }
-
-  Result SkipToEnd(/*out*/ Input& skipped)
-  {
-    return Skip(static_cast<Input::size_type>(end - input), skipped);
-  }
-
-  Result EnsureLength(Input::size_type len)
-  {
-    if (static_cast<size_t>(end - input) < len) {
-      return Result::ERROR_BAD_DER;
-    }
-    return Success;
-  }
-
-  bool AtEnd() const { return input == end; }
-
-  class Mark final
-  {
-  public:
-    Mark(const Mark&) = default; // Intentionally not explicit.
-  private:
-    friend class Reader;
-    Mark(const Reader& aInput, const uint8_t* aMark) : input(aInput), mark(aMark) { }
-    const Reader& input;
-    const uint8_t* const mark;
-    void operator=(const Mark&) = delete;
-  };
-
-  Mark GetMark() const { return Mark(*this, input); }
-
-  Result GetInput(const Mark& mark, /*out*/ Input& item)
-  {
-    if (&mark.input != this || mark.mark > input) {
-      return NotReached("invalid mark", Result::FATAL_ERROR_INVALID_ARGS);
-    }
-    return item.Init(mark.mark,
-                     static_cast<Input::size_type>(input - mark.mark));
-  }
-
-private:
-  Result Init(const uint8_t* data, Input::size_type len)
-  {
-    if (input) {
-      // already initialized
-      return Result::FATAL_ERROR_INVALID_ARGS;
-    }
-    input = data;
-    end = data + len;
-    return Success;
-  }
-
-  const uint8_t* input;
-  const uint8_t* end;
-
-  Reader(const Reader&) = delete;
-  void operator=(const Reader&) = delete;
-};
-
-inline bool
-InputContains(const Input& input, uint8_t toFind)
-{
-  Reader reader(input);
-  for (;;) {
-    uint8_t b;
-    if (reader.Read(b) != Success) {
-      return false;
-    }
-    if (b == toFind) {
-      return true;
-    }
-  }
-}
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_Input_h
deleted file mode 100644
--- a/security/pkix/include/pkix/Result.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_Result_h
-#define mozilla_pkix_Result_h
-
-#include <cassert>
-
-namespace mozilla { namespace pkix {
-
-static const unsigned int FATAL_ERROR_FLAG = 0x800;
-
-// ----------------------------------------------------------------------------
-// SELECTED ERROR CODE EXPLANATIONS
-//
-// Result::ERROR_UNTRUSTED_CERT
-//         means that the end-entity certificate was actively distrusted.
-// Result::ERROR_UNTRUSTED_ISSUER
-//         means that path building failed because of active distrust.
-// Result::ERROR_INVALID_DER_TIME
-//         means the DER-encoded time was unexpected, such as being before the
-//         UNIX epoch (allowed by X500, but not valid here).
-// Result::ERROR_EXPIRED_CERTIFICATE
-//         means the end entity certificate expired.
-// Result::ERROR_EXPIRED_ISSUER_CERTIFICATE
-//         means the CA certificate expired.
-// Result::ERROR_UNKNOWN_ISSUER
-//         means that the CA could not be found in the root store.
-// Result::ERROR_POLICY_VALIDATION_FAILED
-//         means that an encoded policy could not be applied or wasn't present
-//         when expected. Usually this is in the context of Extended Validation.
-// Result::ERROR_BAD_CERT_DOMAIN
-//         means that the certificate's name couldn't be matched to the
-//         reference identifier.
-// Result::ERROR_CERT_NOT_IN_NAME_SPACE
-//         typically means the certificate violates name constraints applied
-//         by the issuer.
-// Result::ERROR_BAD_DER
-//         means the input was improperly encoded.
-// Result::ERROR_UNKNOWN_ERROR
-//         means that an external library (NSS) provided an error we didn't
-//         anticipate. See the map below in Result.h to add new ones.
-// Result::FATAL_ERROR_LIBRARY_FAILURE
-//         is an unexpected fatal error indicating a library had an unexpected
-//         failure, and we can't proceed.
-// Result::FATAL_ERROR_INVALID_ARGS
-//         means that we violated our own expectations on inputs and there's a
-//         bug somewhere.
-// Result::FATAL_ERROR_INVALID_STATE
-//         means that we violated our own expectations on state and there's a
-//         bug somewhere.
-// Result::FATAL_ERROR_NO_MEMORY
-//         means a memory allocation failed, prohibiting validation.
-// ----------------------------------------------------------------------------
-
-// The first argument to MOZILLA_PKIX_MAP() is used for building the mapping
-// from error code to error name in MapResultToName.
-//
-// The second argument is for defining the value for the enum literal in the
-// Result enum class.
-//
-// The third argument to MOZILLA_PKIX_MAP() is used, along with the first
-// argument, for maintaining the mapping of mozilla::pkix error codes to
-// NSS/NSPR error codes in pkixnss.cpp.
-#define MOZILLA_PKIX_MAP_LIST \
-    MOZILLA_PKIX_MAP(Success, 0, 0) \
-    MOZILLA_PKIX_MAP(ERROR_BAD_DER, 1, \
-                     SEC_ERROR_BAD_DER) \
-    MOZILLA_PKIX_MAP(ERROR_CA_CERT_INVALID, 2, \
-                     SEC_ERROR_CA_CERT_INVALID) \
-    MOZILLA_PKIX_MAP(ERROR_BAD_SIGNATURE, 3, \
-                     SEC_ERROR_BAD_SIGNATURE) \
-    MOZILLA_PKIX_MAP(ERROR_CERT_BAD_ACCESS_LOCATION, 4, \
-                     SEC_ERROR_CERT_BAD_ACCESS_LOCATION) \
-    MOZILLA_PKIX_MAP(ERROR_CERT_NOT_IN_NAME_SPACE, 5, \
-                     SEC_ERROR_CERT_NOT_IN_NAME_SPACE) \
-    MOZILLA_PKIX_MAP(ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, 6, \
-                     SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) \
-    MOZILLA_PKIX_MAP(ERROR_CONNECT_REFUSED, 7, \
-                     PR_CONNECT_REFUSED_ERROR) \
-    MOZILLA_PKIX_MAP(ERROR_EXPIRED_CERTIFICATE, 8, \
-                     SEC_ERROR_EXPIRED_CERTIFICATE) \
-    MOZILLA_PKIX_MAP(ERROR_EXTENSION_VALUE_INVALID, 9, \
-                     SEC_ERROR_EXTENSION_VALUE_INVALID) \
-    MOZILLA_PKIX_MAP(ERROR_INADEQUATE_CERT_TYPE, 10, \
-                     SEC_ERROR_INADEQUATE_CERT_TYPE) \
-    MOZILLA_PKIX_MAP(ERROR_INADEQUATE_KEY_USAGE, 11, \
-                     SEC_ERROR_INADEQUATE_KEY_USAGE) \
-    MOZILLA_PKIX_MAP(ERROR_INVALID_ALGORITHM, 12, \
-                     SEC_ERROR_INVALID_ALGORITHM) \
-    MOZILLA_PKIX_MAP(ERROR_INVALID_DER_TIME, 13, \
-                     SEC_ERROR_INVALID_TIME) \
-    MOZILLA_PKIX_MAP(ERROR_KEY_PINNING_FAILURE, 14, \
-                     MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE) \
-    MOZILLA_PKIX_MAP(ERROR_PATH_LEN_CONSTRAINT_INVALID, 15, \
-                     SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID) \
-    MOZILLA_PKIX_MAP(ERROR_POLICY_VALIDATION_FAILED, 16, \
-                     SEC_ERROR_POLICY_VALIDATION_FAILED) \
-    MOZILLA_PKIX_MAP(ERROR_REVOKED_CERTIFICATE, 17, \
-                     SEC_ERROR_REVOKED_CERTIFICATE) \
-    MOZILLA_PKIX_MAP(ERROR_UNKNOWN_CRITICAL_EXTENSION, 18, \
-                     SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION) \
-    MOZILLA_PKIX_MAP(ERROR_UNKNOWN_ERROR, 19, \
-                     PR_UNKNOWN_ERROR) \
-    MOZILLA_PKIX_MAP(ERROR_UNKNOWN_ISSUER, 20, \
-                     SEC_ERROR_UNKNOWN_ISSUER) \
-    MOZILLA_PKIX_MAP(ERROR_UNTRUSTED_CERT, 21, \
-                     SEC_ERROR_UNTRUSTED_CERT) \
-    MOZILLA_PKIX_MAP(ERROR_UNTRUSTED_ISSUER, 22, \
-                     SEC_ERROR_UNTRUSTED_ISSUER) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_BAD_SIGNATURE, 23, \
-                     SEC_ERROR_OCSP_BAD_SIGNATURE) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_INVALID_SIGNING_CERT, 24, \
-                     SEC_ERROR_OCSP_INVALID_SIGNING_CERT) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_MALFORMED_REQUEST, 25, \
-                     SEC_ERROR_OCSP_MALFORMED_REQUEST) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_MALFORMED_RESPONSE, 26, \
-                     SEC_ERROR_OCSP_MALFORMED_RESPONSE) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_OLD_RESPONSE, 27, \
-                     SEC_ERROR_OCSP_OLD_RESPONSE) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_REQUEST_NEEDS_SIG, 28, \
-                     SEC_ERROR_OCSP_REQUEST_NEEDS_SIG) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_RESPONDER_CERT_INVALID, 29, \
-                     SEC_ERROR_OCSP_RESPONDER_CERT_INVALID) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_SERVER_ERROR, 30, \
-                     SEC_ERROR_OCSP_SERVER_ERROR) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_TRY_SERVER_LATER, 31, \
-                     SEC_ERROR_OCSP_TRY_SERVER_LATER) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_UNAUTHORIZED_REQUEST, 32, \
-                     SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, 33, \
-                     SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_UNKNOWN_CERT, 34, \
-                     SEC_ERROR_OCSP_UNKNOWN_CERT) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_FUTURE_RESPONSE, 35, \
-                     SEC_ERROR_OCSP_FUTURE_RESPONSE) \
-    MOZILLA_PKIX_MAP(ERROR_INVALID_KEY, 36, \
-                     SEC_ERROR_INVALID_KEY) \
-    MOZILLA_PKIX_MAP(ERROR_UNSUPPORTED_KEYALG, 37, \
-                     SEC_ERROR_UNSUPPORTED_KEYALG) \
-    MOZILLA_PKIX_MAP(ERROR_EXPIRED_ISSUER_CERTIFICATE, 38, \
-                     SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE) \
-    MOZILLA_PKIX_MAP(ERROR_CA_CERT_USED_AS_END_ENTITY, 39, \
-                     MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY) \
-    MOZILLA_PKIX_MAP(ERROR_INADEQUATE_KEY_SIZE, 40, \
-                     MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE) \
-    MOZILLA_PKIX_MAP(ERROR_V1_CERT_USED_AS_CA, 41, \
-                     MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA) \
-    MOZILLA_PKIX_MAP(ERROR_BAD_CERT_DOMAIN, 42, \
-                     SSL_ERROR_BAD_CERT_DOMAIN) \
-    MOZILLA_PKIX_MAP(ERROR_NO_RFC822NAME_MATCH, 43, \
-                     MOZILLA_PKIX_ERROR_NO_RFC822NAME_MATCH) \
-    MOZILLA_PKIX_MAP(ERROR_UNSUPPORTED_ELLIPTIC_CURVE, 44, \
-                     SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE) \
-    MOZILLA_PKIX_MAP(ERROR_NOT_YET_VALID_CERTIFICATE, 45, \
-                     MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE) \
-    MOZILLA_PKIX_MAP(ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE, 46, \
-                     MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE) \
-    MOZILLA_PKIX_MAP(ERROR_UNSUPPORTED_EC_POINT_FORM, 47, \
-                     SEC_ERROR_UNSUPPORTED_EC_POINT_FORM) \
-    MOZILLA_PKIX_MAP(ERROR_SIGNATURE_ALGORITHM_MISMATCH, 48, \
-                     MOZILLA_PKIX_ERROR_SIGNATURE_ALGORITHM_MISMATCH) \
-    MOZILLA_PKIX_MAP(ERROR_OCSP_RESPONSE_FOR_CERT_MISSING, 49, \
-                     MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING) \
-    MOZILLA_PKIX_MAP(ERROR_VALIDITY_TOO_LONG, 50, \
-                     MOZILLA_PKIX_ERROR_VALIDITY_TOO_LONG) \
-    MOZILLA_PKIX_MAP(ERROR_REQUIRED_TLS_FEATURE_MISSING, 51, \
-                     MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING) \
-    MOZILLA_PKIX_MAP(ERROR_INVALID_INTEGER_ENCODING, 52, \
-                     MOZILLA_PKIX_ERROR_INVALID_INTEGER_ENCODING) \
-    MOZILLA_PKIX_MAP(ERROR_EMPTY_ISSUER_NAME, 53, \
-                     MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME) \
-    MOZILLA_PKIX_MAP(ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, 54, \
-                     MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED) \
-    MOZILLA_PKIX_MAP(ERROR_SELF_SIGNED_CERT, 55, \
-                     MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT) \
-    MOZILLA_PKIX_MAP(ERROR_MITM_DETECTED, 56, \
-                     MOZILLA_PKIX_ERROR_MITM_DETECTED) \
-    MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_ARGS, FATAL_ERROR_FLAG | 1, \
-                     SEC_ERROR_INVALID_ARGS) \
-    MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_STATE, FATAL_ERROR_FLAG | 2, \
-                     PR_INVALID_STATE_ERROR) \
-    MOZILLA_PKIX_MAP(FATAL_ERROR_LIBRARY_FAILURE, FATAL_ERROR_FLAG | 3, \
-                     SEC_ERROR_LIBRARY_FAILURE) \
-    MOZILLA_PKIX_MAP(FATAL_ERROR_NO_MEMORY, FATAL_ERROR_FLAG | 4, \
-                     SEC_ERROR_NO_MEMORY) \
-    /* nothing here */
-
-enum class Result
-{
-#define MOZILLA_PKIX_MAP(name, value, nss_name) name = value,
-  MOZILLA_PKIX_MAP_LIST
-#undef MOZILLA_PKIX_MAP
-};
-
-// Returns the stringified name of the given result, e.g. "Result::Success",
-// or nullptr if result is unknown (invalid).
-const char* MapResultToName(Result result);
-
-// We write many comparisons as (x != Success), and this shortened name makes
-// those comparisons clearer, especially because the shortened name often
-// results in less line wrapping.
-static const Result Success = Result::Success;
-
-inline bool
-IsFatalError(Result rv)
-{
-  return (static_cast<unsigned int>(rv) & FATAL_ERROR_FLAG) != 0;
-}
-
-inline Result
-NotReached(const char* /*explanation*/, Result result)
-{
-  assert(false);
-  return result;
-}
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_Result_h
deleted file mode 100644
--- a/security/pkix/include/pkix/Time.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2014 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_Time_h
-#define mozilla_pkix_Time_h
-
-#include <ctime>
-#include <limits>
-#include <stdint.h>
-
-#include "pkix/Result.h"
-
-namespace mozilla { namespace pkix {
-
-// Time with a range from the first second of year 0 (AD) through at least the
-// last second of year 9999, which is the range of legal times in X.509 and
-// OCSP. This type has second-level precision. The time zone is always UTC.
-//
-// Pass by value, not by reference.
-class Time final
-{
-public:
-  // Construct an uninitialized instance.
-  //
-  // This will fail to compile because there is no default constructor:
-  //    Time x;
-  //
-  // This will succeed, leaving the time uninitialized:
-  //    Time x(Time::uninitialized);
-  enum Uninitialized { uninitialized };
-  explicit Time(Uninitialized) { }
-
-  bool operator==(const Time& other) const
-  {
-    return elapsedSecondsAD == other.elapsedSecondsAD;
-  }
-  bool operator>(const Time& other) const
-  {
-    return elapsedSecondsAD > other.elapsedSecondsAD;
-  }
-  bool operator>=(const Time& other) const
-  {
-    return elapsedSecondsAD >= other.elapsedSecondsAD;
-  }
-  bool operator<(const Time& other) const
-  {
-    return elapsedSecondsAD < other.elapsedSecondsAD;
-  }
-  bool operator<=(const Time& other) const
-  {
-    return elapsedSecondsAD <= other.elapsedSecondsAD;
-  }
-
-  Result AddSeconds(uint64_t seconds)
-  {
-    if (std::numeric_limits<uint64_t>::max() - elapsedSecondsAD
-          < seconds) {
-      return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow
-    }
-    elapsedSecondsAD += seconds;
-    return Success;
-  }
-
-  Result SubtractSeconds(uint64_t seconds)
-  {
-    if (seconds > elapsedSecondsAD) {
-      return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow
-    }
-    elapsedSecondsAD -= seconds;
-    return Success;
-  }
-
-  static const uint64_t ONE_DAY_IN_SECONDS
-    = UINT64_C(24) * UINT64_C(60) * UINT64_C(60);
-
-private:
-  // This constructor is hidden to prevent accidents like this:
-  //
-  //    Time foo(time_t t)
-  //    {
-  //      // WRONG! 1970-01-01-00:00:00 == time_t(0), but not Time(0)!
-  //      return Time(t);
-  //    }
-  explicit Time(uint64_t aElapsedSecondsAD)
-    : elapsedSecondsAD(aElapsedSecondsAD)
-  {
-  }
-  friend Time TimeFromElapsedSecondsAD(uint64_t);
-  friend class Duration;
-
-  uint64_t elapsedSecondsAD;
-};
-
-inline Time TimeFromElapsedSecondsAD(uint64_t aElapsedSecondsAD)
-{
-  return Time(aElapsedSecondsAD);
-}
-
-Time Now();
-
-// Note the epoch is the unix epoch (ie 00:00:00 UTC, 1 January 1970)
-Time TimeFromEpochInSeconds(uint64_t secondsSinceEpoch);
-
-class Duration final
-{
-public:
-  Duration(Time timeA, Time timeB)
-    : durationInSeconds(timeA < timeB
-                        ? timeB.elapsedSecondsAD - timeA.elapsedSecondsAD
-                        : timeA.elapsedSecondsAD - timeB.elapsedSecondsAD)
-  {
-  }
-
-  explicit Duration(uint64_t aDurationInSeconds)
-    : durationInSeconds(aDurationInSeconds)
-  {
-  }
-
-  bool operator>(const Duration& other) const
-  {
-    return durationInSeconds > other.durationInSeconds;
-  }
-  bool operator<(const Duration& other) const
-  {
-    return durationInSeconds < other.durationInSeconds;
-  }
-
-private:
-  uint64_t durationInSeconds;
-};
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_Time_h
deleted file mode 100644
--- a/security/pkix/include/pkix/pkix.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_pkix_h
-#define mozilla_pkix_pkix_h
-
-#include "pkixtypes.h"
-
-namespace mozilla { namespace pkix {
-
-// ----------------------------------------------------------------------------
-// LIMITED SUPPORT FOR CERTIFICATE POLICIES
-//
-// If SEC_OID_X509_ANY_POLICY is passed as the value of the requiredPolicy
-// parameter then all policy validation will be skipped. Otherwise, path
-// building and validation will be done for the given policy.
-//
-// In RFC 5280 terms:
-//
-//    * user-initial-policy-set = { requiredPolicy }.
-//    * initial-explicit-policy = true
-//    * initial-any-policy-inhibit = false
-//
-// We allow intermediate cerificates to use this extension but since
-// we do not process the inhibit anyPolicy extesion we will fail if this
-// extension is present. TODO(bug 989051)
-// Because we force explicit policy and because we prohibit policy mapping, we
-// do not bother processing the policy mapping, or policy constraint.
-//
-// ----------------------------------------------------------------------------
-// ERROR RANKING
-//
-// BuildCertChain prioritizes certain checks ahead of others so that when a
-// certificate chain has multiple errors, the "most serious" error is
-// returned. In practice, this ranking of seriousness is tied directly to how
-// Firefox's certificate error override mechanism.
-//
-// The ranking is:
-//
-//    1. Active distrust (Result::ERROR_UNTRUSTED_CERT).
-//    2. Problems with issuer-independent properties for CA certificates.
-//    3. Unknown issuer (Result::ERROR_UNKNOWN_ISSUER).
-//    4. Problems with issuer-independent properties for EE certificates.
-//    5. Revocation.
-//
-// In particular, if BuildCertChain returns Result::ERROR_UNKNOWN_ISSUER then
-// the caller can call CERT_CheckCertValidTimes to determine if the certificate
-// is ALSO expired.
-//
-// It would be better if revocation were prioritized above expiration and
-// unknown issuer. However, it is impossible to do revocation checking without
-// knowing the issuer, since the issuer information is needed to validate the
-// revocation information. Also, generally revocation checking only works
-// during the validity period of the certificate.
-//
-// In general, when path building fails, BuildCertChain will return
-// Result::ERROR_UNKNOWN_ISSUER. However, if all attempted paths resulted in
-// the same error (which is trivially true when there is only one potential
-// path), more specific errors will be returned.
-//
-// ----------------------------------------------------------------------------
-// Meanings of specific error codes can be found in Result.h
-
-// This function attempts to find a trustworthy path from the supplied
-// certificate to a trust anchor. In the event that no trusted path is found,
-// the method returns an error result; the error ranking is described above.
-//
-// Parameters:
-//  time:
-//         Timestamp for which the chain should be valid; this is useful to
-//         analyze whether a record was trustworthy when it was made.
-//  requiredKeyUsageIfPresent:
-//         What key usage bits must be set, if the extension is present at all,
-//         to be considered a valid chain. Multiple values should be OR'd
-//         together. If you don't want to specify anything, use
-//         KeyUsage::noParticularKeyUsageRequired.
-//  requiredEKUIfPresent:
-//         What extended key usage bits must be set, if the EKU extension
-//         exists, to be considered a valid chain. Multiple values should be
-//         OR'd together. If you don't want to specify anything, use
-//         KeyPurposeId::anyExtendedKeyUsage.
-//  requiredPolicy:
-//         This is the policy to apply; typically included in EV certificates.
-//         If there is no policy, pass in CertPolicyId::anyPolicy.
-Result BuildCertChain(TrustDomain& trustDomain, Input cert,
-                      Time time, EndEntityOrCA endEntityOrCA,
-                      KeyUsage requiredKeyUsageIfPresent,
-                      KeyPurposeId requiredEKUIfPresent,
-                      const CertPolicyId& requiredPolicy,
-                      /*optional*/ const Input* stapledOCSPResponse);
-
-// Verify that the given end-entity cert, which is assumed to have been already
-// validated with BuildCertChain, is valid for the given hostname. The matching
-// function attempts to implement RFC 6125 with a couple of differences:
-// - IP addresses are out of scope of RFC 6125, but this method accepts them for
-//   backward compatibility (see SearchNames in pkixnames.cpp)
-// - A wildcard in a DNS-ID may only appear as the entirety of the first label.
-Result CheckCertHostname(Input cert, Input hostname,
-                         NameMatchingPolicy& nameMatchingPolicy);
-
-// Construct an RFC-6960-encoded OCSP request, ready for submission to a
-// responder, for the provided CertID. The request has no extensions.
-static const size_t OCSP_REQUEST_MAX_LENGTH = 127;
-Result CreateEncodedOCSPRequest(TrustDomain& trustDomain,
-                                const CertID& certID,
-                                /*out*/ uint8_t (&out)[OCSP_REQUEST_MAX_LENGTH],
-                                /*out*/ size_t& outLen);
-
-// The out parameter expired will be true if the response has expired. If the
-// response also indicates a revoked or unknown certificate, that error
-// will be returned. Otherwise, Result::ERROR_OCSP_OLD_RESPONSE will be
-// returned for an expired response.
-//
-// The optional parameter thisUpdate will be the thisUpdate value of
-// the encoded response if it is considered trustworthy. Only
-// good, unknown, or revoked responses that verify correctly are considered
-// trustworthy. If the response is not trustworthy, thisUpdate will be 0.
-// Similarly, the optional parameter validThrough will be the time through
-// which the encoded response is considered trustworthy (that is, as long as
-// the given time at which to validate is less than or equal to validThrough,
-// the response will be considered trustworthy).
-Result VerifyEncodedOCSPResponse(TrustDomain& trustDomain,
-                                 const CertID& certID, Time time,
-                                 uint16_t maxLifetimeInDays,
-                                 Input encodedResponse,
-                       /* out */ bool& expired,
-              /* optional out */ Time* thisUpdate = nullptr,
-              /* optional out */ Time* validThrough = nullptr);
-
-// Check that the TLSFeature extensions in a given end-entity cert (which is
-// assumed to have been already validated with BuildCertChain) are satisfied.
-// The only feature which we cancurrently process a requirement for is
-// status_request (OCSP stapling) so we reject any extension that specifies a
-// requirement for another value. Empty extensions are also rejected.
-Result CheckTLSFeaturesAreSatisfied(Input& cert,
-                                    const Input* stapledOCSPResponse);
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_pkix_h
deleted file mode 100644
--- a/security/pkix/include/pkix/pkixnss.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_pkixnss_h
-#define mozilla_pkix_pkixnss_h
-
-#include "pkixtypes.h"
-#include "prerror.h"
-#include "seccomon.h"
-
-namespace mozilla { namespace pkix {
-
-// Verifies the PKCS#1.5 signature on the given data using the given RSA public
-// key.
-Result VerifyRSAPKCS1SignedDigestNSS(const SignedDigest& sd,
-                                     Input subjectPublicKeyInfo,
-                                     void* pkcs11PinArg);
-
-// Verifies the ECDSA signature on the given data using the given ECC public
-// key.
-Result VerifyECDSASignedDigestNSS(const SignedDigest& sd,
-                                  Input subjectPublicKeyInfo,
-                                  void* pkcs11PinArg);
-
-// Computes the digest of the given data using the given digest algorithm.
-//
-// item contains the data to hash.
-// digestBuf must point to a buffer to where the digest will be written.
-// digestBufLen must be the size of the buffer, which must be exactly equal
-//              to the size of the digest output (20 for SHA-1, 32 for SHA-256,
-//              etc.)
-//
-// TODO: Taking the output buffer as (uint8_t*, size_t) is counter to our
-// other, extensive, memory safety efforts in mozilla::pkix, and we should find
-// a way to provide a more-obviously-safe interface.
-Result DigestBufNSS(Input item,
-                    DigestAlgorithm digestAlg,
-                    /*out*/ uint8_t* digestBuf,
-                    size_t digestBufLen);
-
-Result MapPRErrorCodeToResult(PRErrorCode errorCode);
-PRErrorCode MapResultToPRErrorCode(Result result);
-
-// The error codes within each module must fit in 16 bits. We want these
-// errors to fit in the same module as the NSS errors but not overlap with
-// any of them. Converting an NSS SEC, NSS SSL, or PSM error to an NS error
-// involves negating the value of the error and then synthesizing an error
-// in the NS_ERROR_MODULE_SECURITY module. Hence, PSM errors will start at
-// a negative value that both doesn't overlap with the current value
-// ranges for NSS errors and that will fit in 16 bits when negated.
-static const PRErrorCode ERROR_BASE = -0x4000;
-static const PRErrorCode ERROR_LIMIT = ERROR_BASE + 1000;
-
-enum ErrorCode
-{
-  MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE = ERROR_BASE + 0,
-  MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY = ERROR_BASE + 1,
-  MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE = ERROR_BASE + 2,
-  MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA = ERROR_BASE + 3,
-  MOZILLA_PKIX_ERROR_NO_RFC822NAME_MATCH = ERROR_BASE + 4,
-  MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = ERROR_BASE + 5,
-  MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = ERROR_BASE + 6,
-  MOZILLA_PKIX_ERROR_SIGNATURE_ALGORITHM_MISMATCH = ERROR_BASE + 7,
-  MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING = ERROR_BASE + 8,
-  MOZILLA_PKIX_ERROR_VALIDITY_TOO_LONG = ERROR_BASE + 9,
-  MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING = ERROR_BASE + 10,
-  MOZILLA_PKIX_ERROR_INVALID_INTEGER_ENCODING = ERROR_BASE + 11,
-  MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME = ERROR_BASE + 12,
-  MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = ERROR_BASE + 13,
-  MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT = ERROR_BASE + 14,
-  MOZILLA_PKIX_ERROR_MITM_DETECTED = ERROR_BASE + 15,
-  END_OF_LIST
-};
-
-void RegisterErrorTable();
-
-inline SECItem UnsafeMapInputToSECItem(Input input)
-{
-  SECItem result = {
-    siBuffer,
-    const_cast<uint8_t*>(input.UnsafeGetData()),
-    input.GetLength()
-  };
-  static_assert(sizeof(decltype(input.GetLength())) <= sizeof(result.len),
-                "input.GetLength() must fit in a SECItem");
-  return result;
-}
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_pkixnss_h
deleted file mode 100644
--- a/security/pkix/include/pkix/pkixtypes.h
+++ /dev/null
@@ -1,411 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_pkixtypes_h
-#define mozilla_pkix_pkixtypes_h
-
-#include "pkix/Input.h"
-#include "pkix/Time.h"
-#include "stdint.h"
-
-namespace mozilla { namespace pkix {
-
-enum class DigestAlgorithm
-{
-  sha512 = 1,
-  sha384 = 2,
-  sha256 = 3,
-  sha1 = 4,
-};
-
-enum class NamedCurve
-{
-  // secp521r1 (OID 1.3.132.0.35, RFC 5480)
-  secp521r1 = 1,
-
-  // secp384r1 (OID 1.3.132.0.34, RFC 5480)
-  secp384r1 = 2,
-
-  // secp256r1 (OID 1.2.840.10045.3.1.7, RFC 5480)
-  secp256r1 = 3,
-};
-
-struct SignedDigest final
-{
-  Input digest;
-  DigestAlgorithm digestAlgorithm;
-  Input signature;
-
-  void operator=(const SignedDigest&) = delete;
-};
-
-enum class EndEntityOrCA { MustBeEndEntity = 0, MustBeCA = 1 };
-
-enum class KeyUsage : uint8_t
-{
-  digitalSignature = 0,
-  nonRepudiation   = 1,
-  keyEncipherment  = 2,
-  dataEncipherment = 3,
-  keyAgreement     = 4,
-  keyCertSign      = 5,
-  // cRLSign       = 6,
-  // encipherOnly  = 7,
-  // decipherOnly  = 8,
-  noParticularKeyUsageRequired = 0xff,
-};
-
-enum class KeyPurposeId
-{
-  anyExtendedKeyUsage = 0,
-  id_kp_serverAuth = 1,           // id-kp-serverAuth
-  id_kp_clientAuth = 2,           // id-kp-clientAuth
-  id_kp_codeSigning = 3,          // id-kp-codeSigning
-  id_kp_emailProtection = 4,      // id-kp-emailProtection
-  id_kp_OCSPSigning = 9,          // id-kp-OCSPSigning
-};
-
-struct CertPolicyId final
-{
-  uint16_t numBytes;
-  static const uint16_t MAX_BYTES = 24;
-  uint8_t bytes[MAX_BYTES];
-
-  bool IsAnyPolicy() const;
-  bool operator==(const CertPolicyId& other) const;
-
-  static const CertPolicyId anyPolicy;
-};
-
-enum class TrustLevel
-{
-  TrustAnchor = 1,        // certificate is a trusted root CA certificate or
-                          // equivalent *for the given policy*.
-  ActivelyDistrusted = 2, // certificate is known to be bad
-  InheritsTrust = 3       // certificate must chain to a trust anchor
-};
-
-// Extensions extracted during the verification flow.
-// See TrustDomain::NoteAuxiliaryExtension.
-enum class AuxiliaryExtension
-{
-  // Certificate Transparency data, specifically Signed Certificate
-  // Timestamps (SCTs). See RFC 6962.
-
-  // SCT list embedded in the end entity certificate. Called by BuildCertChain
-  // after the certificate containing the SCTs has passed the revocation checks.
-  EmbeddedSCTList = 1,
-  // SCT list from OCSP response. Called by VerifyEncodedOCSPResponse
-  // when its result is a success and the SCT list is present.
-  SCTListFromOCSPResponse = 2
-};
-
-// CertID references the information needed to do revocation checking for the
-// certificate issued by the given issuer with the given serial number.
-//
-// issuer must be the DER-encoded issuer field from the certificate for which
-// revocation checking is being done, **NOT** the subject field of the issuer
-// certificate. (Those two fields must be equal to each other, but they may not
-// be encoded exactly the same, and the encoding matters for OCSP.)
-// issuerSubjectPublicKeyInfo is the entire DER-encoded subjectPublicKeyInfo
-// field from the issuer's certificate. serialNumber is the entire DER-encoded
-// serial number from the subject certificate (the certificate for which we are
-// checking the revocation status).
-struct CertID final
-{
-public:
-  CertID(Input aIssuer, Input aIssuerSubjectPublicKeyInfo, Input aSerialNumber)
-    : issuer(aIssuer)
-    , issuerSubjectPublicKeyInfo(aIssuerSubjectPublicKeyInfo)
-    , serialNumber(aSerialNumber)
-  {
-  }
-  const Input issuer;
-  const Input issuerSubjectPublicKeyInfo;
-  const Input serialNumber;
-
-  void operator=(const CertID&) = delete;
-};
-
-class DERArray
-{
-public:
-  // Returns the number of DER-encoded items in the array.
-  virtual size_t GetLength() const = 0;
-
-  // Returns a weak (non-owning) pointer the ith DER-encoded item in the array
-  // (0-indexed). The result is guaranteed to be non-null if i < GetLength(),
-  // and the result is guaranteed to be nullptr if i >= GetLength().
-  virtual const Input* GetDER(size_t i) const = 0;
-protected:
-  DERArray() { }
-  virtual ~DERArray() { }
-};
-
-// Applications control the behavior of path building and verification by
-// implementing the TrustDomain interface. The TrustDomain is used for all
-// cryptography and for determining which certificates are trusted or
-// distrusted.
-class TrustDomain
-{
-public:
-  virtual ~TrustDomain() { }
-
-  // Determine the level of trust in the given certificate for the given role.
-  // This will be called for every certificate encountered during path
-  // building.
-  //
-  // When policy.IsAnyPolicy(), then no policy-related checking should be done.
-  // When !policy.IsAnyPolicy(), then GetCertTrust MUST NOT return with
-  // trustLevel == TrustAnchor unless the given cert is considered a trust
-  // anchor *for that policy*. In particular, if the user has marked an
-  // intermediate certificate as trusted, but that intermediate isn't in the
-  // list of EV roots, then GetCertTrust must result in
-  // trustLevel == InheritsTrust instead of trustLevel == TrustAnchor
-  // (assuming the candidate cert is not actively distrusted).
-  virtual Result GetCertTrust(EndEntityOrCA endEntityOrCA,
-                              const CertPolicyId& policy,
-                              Input candidateCertDER,
-                              /*out*/ TrustLevel& trustLevel) = 0;
-
-  class IssuerChecker
-  {
-  public:
-    // potentialIssuerDER is the complete DER encoding of the certificate to
-    // be checked as a potential issuer.
-    //
-    // If additionalNameConstraints is not nullptr then it must point to an
-    // encoded NameConstraints extension value; in that case, those name
-    // constraints will be checked in addition to any any name constraints
-    // contained in potentialIssuerDER.
-    virtual Result Check(Input potentialIssuerDER,
-            /*optional*/ const Input* additionalNameConstraints,
-                 /*out*/ bool& keepGoing) = 0;
-  protected:
-    IssuerChecker();
-    virtual ~IssuerChecker();
-
-    IssuerChecker(const IssuerChecker&) = delete;
-    void operator=(const IssuerChecker&) = delete;
-  };
-
-  // Search for a CA certificate with the given name. The implementation must
-  // call checker.Check with the DER encoding of the potential issuer
-  // certificate. The implementation must follow these rules:
-  //
-  // * The implementation must be reentrant and must limit the amount of stack
-  //   space it uses; see the note on reentrancy and stack usage below.
-  // * When checker.Check does not return Success then immediately return its
-  //   return value.
-  // * When checker.Check returns Success and sets keepGoing = false, then
-  //   immediately return Success.
-  // * When checker.Check returns Success and sets keepGoing = true, then
-  //   call checker.Check again with a different potential issuer certificate,
-  //   if any more are available.
-  // * When no more potential issuer certificates are available, return
-  //   Success.
-  // * Don't call checker.Check with the same potential issuer certificate more
-  //   than once in a given call of FindIssuer.
-  // * The given time parameter may be used to filter out certificates that are
-  //   not valid at the given time, or it may be ignored.
-  //
-  // Note on reentrancy and stack usage: checker.Check will attempt to
-  // recursively build a certificate path from the potential issuer it is given
-  // to a trusted root, as determined by this TrustDomain. That means that
-  // checker.Check may call any/all of the methods on this TrustDomain. In
-  // particular, there will be call stacks that look like this:
-  //
-  //    BuildCertChain
-  //      [...]
-  //        TrustDomain::FindIssuer
-  //          [...]
-  //            IssuerChecker::Check
-  //              [...]
-  //                TrustDomain::FindIssuer
-  //                  [...]
-  //                    IssuerChecker::Check
-  //                      [...]
-  //
-  // checker.Check is responsible for limiting the recursion to a reasonable
-  // limit.
-  //
-  // checker.Check will verify that the subject's issuer field matches the
-  // potential issuer's subject field. It will also check that the potential
-  // issuer is valid at the given time. However, if the FindIssuer
-  // implementation has an efficient way of filtering potential issuers by name
-  // and/or validity period itself, then it is probably better for performance
-  // for it to do so.
-  virtual Result FindIssuer(Input encodedIssuerName,
-                            IssuerChecker& checker, Time time) = 0;
-
-  // Called as soon as we think we have a valid chain but before revocation
-  // checks are done. This function can be used to compute additional checks,
-  // especially checks that require the entire certificate chain. This callback
-  // can also be used to save a copy of the built certificate chain for later
-  // use.
-  //
-  // This function may be called multiple times, regardless of whether it
-  // returns success or failure. It is guaranteed that BuildCertChain will not
-  // return Success unless the last call to IsChainValid returns Success. Further,
-  // it is guaranteed that when BuildCertChain returns Success the last chain
-  // passed to IsChainValid is the valid chain that should be used for further
-  // operations that require the whole chain.
-  //
-  // Keep in mind, in particular, that if the application saves a copy of the
-  // certificate chain the last invocation of IsChainValid during a validation,
-  // it is still possible for BuildCertChain to fail, in which case the
-  // application must not assume anything about the validity of the last
-  // certificate chain passed to IsChainValid; especially, it would be very
-  // wrong to assume that the certificate chain is valid.
-  //
-  // certChain.GetDER(0) is the trust anchor.
-  virtual Result IsChainValid(const DERArray& certChain, Time time,
-                              const CertPolicyId& requiredPolicy) = 0;
-
-  virtual Result CheckRevocation(EndEntityOrCA endEntityOrCA,
-                                 const CertID& certID, Time time,
-                                 Duration validityDuration,
-                    /*optional*/ const Input* stapledOCSPresponse,
-                    /*optional*/ const Input* aiaExtension) = 0;
-
-  // Check that the given digest algorithm is acceptable for use in signatures.
-  //
-  // Return Success if the algorithm is acceptable,
-  // Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED if the algorithm is not
-  // acceptable, or another error code if another error occurred.
-  virtual Result CheckSignatureDigestAlgorithm(DigestAlgorithm digestAlg,
-                                               EndEntityOrCA endEntityOrCA,
-                                               Time notBefore) = 0;
-
-  // Check that the RSA public key size is acceptable.
-  //
-  // Return Success if the key size is acceptable,
-  // Result::ERROR_INADEQUATE_KEY_SIZE if the key size is not acceptable,
-  // or another error code if another error occurred.
-  virtual Result CheckRSAPublicKeyModulusSizeInBits(
-                   EndEntityOrCA endEntityOrCA,
-                   unsigned int modulusSizeInBits) = 0;
-
-  // Verify the given RSA PKCS#1.5 signature on the given digest using the
-  // given RSA public key.
-  //
-  // CheckRSAPublicKeyModulusSizeInBits will be called before calling this
-  // function, so it is not necessary to repeat those checks here. However,
-  // VerifyRSAPKCS1SignedDigest *is* responsible for doing the mathematical
-  // verification of the public key validity as specified in NIST SP 800-56A.
-  virtual Result VerifyRSAPKCS1SignedDigest(
-                   const SignedDigest& signedDigest,
-                   Input subjectPublicKeyInfo) = 0;
-
-  // Check that the given named ECC curve is acceptable for ECDSA signatures.
-  //
-  // Return Success if the curve is acceptable,
-  // Result::ERROR_UNSUPPORTED_ELLIPTIC_CURVE if the curve is not acceptable,
-  // or another error code if another error occurred.
-  virtual Result CheckECDSACurveIsAcceptable(EndEntityOrCA endEntityOrCA,
-                                             NamedCurve curve) = 0;
-
-  // Verify the given ECDSA signature on the given digest using the given ECC
-  // public key.
-  //
-  // CheckECDSACurveIsAcceptable will be called before calling this function,
-  // so it is not necessary to repeat that check here. However,
-  // VerifyECDSASignedDigest *is* responsible for doing the mathematical
-  // verification of the public key validity as specified in NIST SP 800-56A.
-  virtual Result VerifyECDSASignedDigest(const SignedDigest& signedDigest,
-                                         Input subjectPublicKeyInfo) = 0;
-
-  // Check that the validity duration is acceptable.
-  //
-  // Return Success if the validity duration is acceptable,
-  // Result::ERROR_VALIDITY_TOO_LONG if the validity duration is not acceptable,
-  // or another error code if another error occurred.
-  virtual Result CheckValidityIsAcceptable(Time notBefore, Time notAfter,
-                                           EndEntityOrCA endEntityOrCA,
-                                           KeyPurposeId keyPurpose) = 0;
-
-  // For compatibility, a CA certificate with an extended key usage that
-  // contains the id-Netscape-stepUp OID but does not contain the
-  // id-kp-serverAuth OID may be considered valid for issuing server auth
-  // certificates. This function allows TrustDomain implementations to control
-  // this setting based on the start of the validity period of the certificate
-  // in question.
-  virtual Result NetscapeStepUpMatchesServerAuth(Time notBefore,
-                                                 /*out*/ bool& matches) = 0;
-
-  // Some certificate or OCSP response extensions do not directly participate
-  // in the verification flow, but might still be of interest to the clients
-  // (notably Certificate Transparency data, RFC 6962). Such extensions are
-  // extracted and passed to this function for further processing.
-  virtual void NoteAuxiliaryExtension(AuxiliaryExtension extension,
-                                      Input extensionData) = 0;
-
-  // Compute a digest of the data in item using the given digest algorithm.
-  //
-  // item contains the data to hash.
-  // digestBuf points to a buffer to where the digest will be written.
-  // digestBufLen will be the size of the digest output (20 for SHA-1,
-  // 32 for SHA-256, etc.).
-  //
-  // TODO: Taking the output buffer as (uint8_t*, size_t) is counter to our
-  // other, extensive, memory safety efforts in mozilla::pkix, and we should
-  // find a way to provide a more-obviously-safe interface.
-  virtual Result DigestBuf(Input item,
-                           DigestAlgorithm digestAlg,
-                           /*out*/ uint8_t* digestBuf,
-                           size_t digestBufLen) = 0;
-protected:
-  TrustDomain() { }
-
-  TrustDomain(const TrustDomain&) = delete;
-  void operator=(const TrustDomain&) = delete;
-};
-
-enum class FallBackToSearchWithinSubject { No = 0, Yes = 1 };
-
-// Applications control the behavior of matching presented name information from
-// a certificate against a reference hostname by implementing the
-// NameMatchingPolicy interface. Used in concert with CheckCertHostname.
-class NameMatchingPolicy
-{
-public:
-  virtual ~NameMatchingPolicy() { }
-
-  // Given that the certificate in question has a notBefore field with the given
-  // value, should name matching fall back to searching within the subject
-  // common name field?
-  virtual Result FallBackToCommonName(
-    Time notBefore,
-    /*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) = 0;
-
-protected:
-  NameMatchingPolicy() { }
-
-  NameMatchingPolicy(const NameMatchingPolicy&) = delete;
-  void operator=(const NameMatchingPolicy&) = delete;
-};
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_pkixtypes_h
deleted file mode 100644
--- a/security/pkix/lib/ScopedPtr.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_ScopedPtr_h
-#define mozilla_pkix_ScopedPtr_h
-
-namespace mozilla { namespace pkix {
-
-// A subset polyfill of std::unique_ptr that does not support move construction
-// or move assignment. This is used instead of std::unique_ptr because some
-// important toolchains still don't provide std::unique_ptr, including in
-// particular Android NDK projects with APP_STL=stlport_static or
-// ALL_STL=stlport_shared.
-template <typename T, void (&Destroyer)(T*)>
-class ScopedPtr final
-{
-public:
-  explicit ScopedPtr(T* value = nullptr) : mValue(value) { }
-
-  ScopedPtr(const ScopedPtr&) = delete;
-
-  ~ScopedPtr()
-  {
-    if (mValue) {
-      Destroyer(mValue);
-    }
-  }
-
-  void operator=(const ScopedPtr&) = delete;
-
-  T& operator*() const { return *mValue; }
-  T* operator->() const { return mValue; }
-
-  explicit operator bool() const { return mValue; }
-
-  T* get() const { return mValue; }
-
-  T* release()
-  {
-    T* result = mValue;
-    mValue = nullptr;
-    return result;
-  }
-
-  void reset(T* newValue = nullptr)
-  {
-    // The C++ standard requires std::unique_ptr to destroy the old value
-    // pointed to by mValue, if any, *after* assigning the new value to mValue.
-    T* oldValue = mValue;
-    mValue = newValue;
-    if (oldValue) {
-      Destroyer(oldValue);
-    }
-  }
-
-private:
-  T* mValue;
-};
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_ScopedPtr_h
deleted file mode 100644
--- a/security/pkix/lib/pkixbuild.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pkix/pkix.h"
-
-#include "pkixcheck.h"
-#include "pkixutil.h"
-
-namespace mozilla { namespace pkix {
-
-static Result BuildForward(TrustDomain& trustDomain,
-                           const BackCert& subject,
-                           Time time,
-                           KeyUsage requiredKeyUsageIfPresent,
-                           KeyPurposeId requiredEKUIfPresent,
-                           const CertPolicyId& requiredPolicy,
-                           /*optional*/ const Input* stapledOCSPResponse,
-                           unsigned int subCACount,
-                           unsigned int& buildForwardCallBudget);
-
-TrustDomain::IssuerChecker::IssuerChecker() { }
-TrustDomain::IssuerChecker::~IssuerChecker() { }
-
-// The implementation of TrustDomain::IssuerTracker is in a subclass only to
-// hide the implementation from external users.
-class PathBuildingStep final : public TrustDomain::IssuerChecker
-{
-public:
-  PathBuildingStep(TrustDomain& aTrustDomain, const BackCert& aSubject,
-                   Time aTime, KeyPurposeId aRequiredEKUIfPresent,
-                   const CertPolicyId& aRequiredPolicy,
-                   /*optional*/ const Input* aStapledOCSPResponse,
-                   unsigned int aSubCACount, Result aDeferredSubjectError,
-                   unsigned int& aBuildForwardCallBudget)
-    : trustDomain(aTrustDomain)
-    , subject(aSubject)
-    , time(aTime)
-    , requiredEKUIfPresent(aRequiredEKUIfPresent)
-    , requiredPolicy(aRequiredPolicy)
-    , stapledOCSPResponse(aStapledOCSPResponse)
-    , subCACount(aSubCACount)
-    , deferredSubjectError(aDeferredSubjectError)
-    , subjectSignaturePublicKeyAlg(der::PublicKeyAlgorithm::Uninitialized)
-    , result(Result::FATAL_ERROR_LIBRARY_FAILURE)
-    , resultWasSet(false)
-    , buildForwardCallBudget(aBuildForwardCallBudget)
-  {
-  }
-
-  Result Check(Input potentialIssuerDER,
-               /*optional*/ const Input* additionalNameConstraints,
-               /*out*/ bool& keepGoing) override;
-
-  Result CheckResult() const;
-
-private:
-  TrustDomain& trustDomain;
-  const BackCert& subject;
-  const Time time;
-  const KeyPurposeId requiredEKUIfPresent;
-  const CertPolicyId& requiredPolicy;
-  /*optional*/ Input const* const stapledOCSPResponse;
-  const unsigned int subCACount;
-  const Result deferredSubjectError;
-
-  // Initialized lazily.
-  uint8_t subjectSignatureDigestBuf[MAX_DIGEST_SIZE_IN_BYTES];
-  der::PublicKeyAlgorithm subjectSignaturePublicKeyAlg;
-  SignedDigest subjectSignature;
-
-  Result RecordResult(Result currentResult, /*out*/ bool& keepGoing);
-  Result result;
-  bool resultWasSet;
-  unsigned int& buildForwardCallBudget;
-
-  PathBuildingStep(const PathBuildingStep&) = delete;
-  void operator=(const PathBuildingStep&) = delete;
-};
-
-Result
-PathBuildingStep::RecordResult(Result newResult, /*out*/ bool& keepGoing)
-{
-  if (newResult == Result::ERROR_UNTRUSTED_CERT) {
-    newResult = Result::ERROR_UNTRUSTED_ISSUER;
-  } else if (newResult == Result::ERROR_EXPIRED_CERTIFICATE) {
-    newResult = Result::ERROR_EXPIRED_ISSUER_CERTIFICATE;
-  } else if (newResult == Result::ERROR_NOT_YET_VALID_CERTIFICATE) {
-    newResult = Result::ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE;
-  }
-
-  if (resultWasSet) {
-    if (result == Success) {
-      return NotReached("RecordResult called after finding a chain",
-                        Result::FATAL_ERROR_INVALID_STATE);
-    }
-    // If every potential issuer has the same problem (e.g. expired) and/or if
-    // there is only one bad potential issuer, then return a more specific
-    // error. Otherwise, punt on trying to decide which error should be
-    // returned by returning the generic Result::ERROR_UNKNOWN_ISSUER error.
-    if (newResult != Success && newResult != result) {
-      newResult = Result::ERROR_UNKNOWN_ISSUER;
-    }
-  }
-
-  result = newResult;
-  resultWasSet = true;
-  keepGoing = result != Success;
-  return Success;
-}
-
-Result
-PathBuildingStep::CheckResult() const
-{
-  if (!resultWasSet) {
-    return Result::ERROR_UNKNOWN_ISSUER;
-  }
-  return result;
-}
-
-// The code that executes in the inner loop of BuildForward
-Result
-PathBuildingStep::Check(Input potentialIssuerDER,
-           /*optional*/ const Input* additionalNameConstraints,
-                /*out*/ bool& keepGoing)
-{
-  BackCert potentialIssuer(potentialIssuerDER, EndEntityOrCA::MustBeCA,
-                           &subject);
-  Result rv = potentialIssuer.Init();
-  if (rv != Success) {
-    return RecordResult(rv, keepGoing);
-  }
-
-  // Simple TrustDomain::FindIssuers implementations may pass in all possible
-  // CA certificates without any filtering. Because of this, we don't consider
-  // a mismatched name to be an error. Instead, we just pretend that any
-  // certificate without a matching name was never passed to us. In particular,
-  // we treat the case where the TrustDomain only asks us to check CA
-  // certificates with mismatched names as equivalent to the case where the
-  // TrustDomain never called Check() at all.
-  if (!InputsAreEqual(potentialIssuer.GetSubject(), subject.GetIssuer())) {
-    keepGoing = true;
-    return Success;
-  }
-
-  // Loop prevention, done as recommended by RFC4158 Section 5.2
-  // TODO: this doesn't account for subjectAltNames!
-  // TODO(perf): This probably can and should be optimized in some way.
-  for (const BackCert* prev = potentialIssuer.childCert; prev;
-       prev = prev->childCert) {
-    if (InputsAreEqual(potentialIssuer.GetSubjectPublicKeyInfo(),
-                       prev->GetSubjectPublicKeyInfo()) &&
-        InputsAreEqual(potentialIssuer.GetSubject(), prev->GetSubject())) {
-      // XXX: error code
-      return RecordResult(Result::ERROR_UNKNOWN_ISSUER, keepGoing);
-    }
-  }
-
-  if (potentialIssuer.GetNameConstraints()) {
-    rv = CheckNameConstraints(*potentialIssuer.GetNameConstraints(),
-                              subject, requiredEKUIfPresent);
-    if (rv != Success) {
-       return RecordResult(rv, keepGoing);
-    }
-  }
-
-  if (additionalNameConstraints) {
-    rv = CheckNameConstraints(*additionalNameConstraints, subject,
-                              requiredEKUIfPresent);
-    if (rv != Success) {
-       return RecordResult(rv, keepGoing);
-    }
-  }
-
-  rv = CheckTLSFeatures(subject, potentialIssuer);
-  if (rv != Success) {
-    return RecordResult(rv, keepGoing);
-  }
-
-  // If we've ran out of budget, stop searching.
-  if (buildForwardCallBudget == 0) {
-    Result savedRv = RecordResult(Result::ERROR_UNKNOWN_ISSUER, keepGoing);
-    keepGoing = false;
-    return savedRv;
-  }
-  buildForwardCallBudget--;
-
-  // RFC 5280, Section 4.2.1.3: "If the keyUsage extension is present, then the
-  // subject public key MUST NOT be used to verify signatures on certificates
-  // or CRLs unless the corresponding keyCertSign or cRLSign bit is set."
-  rv = BuildForward(trustDomain, potentialIssuer, time, KeyUsage::keyCertSign,
-                    requiredEKUIfPresent, requiredPolicy, nullptr, subCACount,
-                    buildForwardCallBudget);
-  if (rv != Success) {
-    return RecordResult(rv, keepGoing);
-  }
-
-  // Calculate the digest of the subject's signed data if we haven't already
-  // done so. We do this lazily to avoid doing it at all if we backtrack before
-  // getting to this point. We cache the result to avoid recalculating it if we
-  // backtrack after getting to this point.
-  if (subjectSignature.digest.GetLength() == 0) {
-    rv = DigestSignedData(trustDomain, subject.GetSignedData(),
-                          subjectSignatureDigestBuf,
-                          subjectSignaturePublicKeyAlg, subjectSignature);
-    if (rv != Success) {
-      return rv;
-    }
-  }
-
-  rv = VerifySignedDigest(trustDomain, subjectSignaturePublicKeyAlg,
-                          subjectSignature,
-                          potentialIssuer.GetSubjectPublicKeyInfo());
-  if (rv != Success) {
-    return RecordResult(rv, keepGoing);
-  }
-
-  // We avoid doing revocation checking for expired certificates because OCSP
-  // responders are allowed to forget about expired certificates, and many OCSP
-  // responders return an error when asked for the status of an expired
-  // certificate.
-  if (deferredSubjectError != Result::ERROR_EXPIRED_CERTIFICATE) {
-    CertID certID(subject.GetIssuer(), potentialIssuer.GetSubjectPublicKeyInfo(),
-                  subject.GetSerialNumber());
-    Time notBefore(Time::uninitialized);
-    Time notAfter(Time::uninitialized);
-    // This should never fail. If we're here, we've already parsed the validity
-    // and checked that the given time is in the certificate's validity period.
-    rv = ParseValidity(subject.GetValidity(), &notBefore, &notAfter);
-    if (rv != Success) {
-      return rv;
-    }
-    Duration validityDuration(notAfter, notBefore);
-    rv = trustDomain.CheckRevocation(subject.endEntityOrCA, certID, time,
-                                     validityDuration, stapledOCSPResponse,
-                                     subject.GetAuthorityInfoAccess());
-    if (rv != Success) {
-      // Since this is actually a problem with the current subject certificate
-      // (rather than the issuer), it doesn't make sense to keep going; all
-      // paths through this certificate will fail.
-      Result savedRv = RecordResult(rv, keepGoing);
-      keepGoing = false;
-      return savedRv;
-    }
-
-    if (subject.endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
-      const Input* sctExtension = subject.GetSignedCertificateTimestamps();
-      if (sctExtension) {
-        Input sctList;
-        rv = ExtractSignedCertificateTimestampListFromExtension(*sctExtension,
-                                                                sctList);
-        if (rv != Success) {
-          // Again, the problem is with this certificate, and all paths through
-          // it will fail.
-          Result savedRv = RecordResult(rv, keepGoing);
-          keepGoing = false;
-          return savedRv;
-        }
-        trustDomain.NoteAuxiliaryExtension(AuxiliaryExtension::EmbeddedSCTList,
-                                           sctList);
-      }
-    }
-  }
-
-  return RecordResult(Success, keepGoing);
-}
-
-// Recursively build the path from the given subject certificate to the root.
-//
-// Be very careful about changing the order of checks. The order is significant
-// because it affects which error we return when a certificate or certificate
-// chain has multiple problems. See the error ranking documentation in
-// pkix/pkix.h.
-static Result
-BuildForward(TrustDomain& trustDomain,
-             const BackCert& subject,
-             Time time,
-             KeyUsage requiredKeyUsageIfPresent,
-             KeyPurposeId requiredEKUIfPresent,
-             const CertPolicyId& requiredPolicy,
-             /*optional*/ const Input* stapledOCSPResponse,
-             unsigned int subCACount,
-             unsigned int& buildForwardCallBudget)
-{
-  Result rv;
-
-  TrustLevel trustLevel;
-  // If this is an end-entity and not a trust anchor, we defer reporting
-  // any error found here until after attempting to find a valid chain.
-  // See the explanation of error prioritization in pkix.h.
-  rv = CheckIssuerIndependentProperties(trustDomain, subject, time,
-                                        requiredKeyUsageIfPresent,
-                                        requiredEKUIfPresent, requiredPolicy,
-                                        subCACount, trustLevel);
-  Result deferredEndEntityError = Success;
-  if (rv != Success) {
-    if (subject.endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
-        trustLevel != TrustLevel::TrustAnchor) {
-      deferredEndEntityError = rv;
-    } else {
-      return rv;
-    }
-  }
-
-  if (trustLevel == TrustLevel::TrustAnchor) {
-    // End of the recursion.
-
-    NonOwningDERArray chain;
-    for (const BackCert* cert = &subject; cert; cert = cert->childCert) {
-      rv = chain.Append(cert->GetDER());
-      if (rv != Success) {
-        return NotReached("NonOwningDERArray::SetItem failed.", rv);
-      }
-    }
-
-    // This must be done here, after the chain is built but before any
-    // revocation checks have been done.
-    return trustDomain.IsChainValid(chain, time, requiredPolicy);
-  }
-
-  if (subject.endEntityOrCA == EndEntityOrCA::MustBeCA) {
-    // Avoid stack overflows and poor performance by limiting cert chain
-    // length.
-    static const unsigned int MAX_SUBCA_COUNT = 6;
-    static_assert(1/*end-entity*/ + MAX_SUBCA_COUNT + 1/*root*/ ==
-                  NonOwningDERArray::MAX_LENGTH,
-                  "MAX_SUBCA_COUNT and NonOwningDERArray::MAX_LENGTH mismatch.");
-    if (subCACount >= MAX_SUBCA_COUNT) {
-      return Result::ERROR_UNKNOWN_ISSUER;
-    }
-    ++subCACount;
-  } else {
-    assert(subCACount == 0);
-  }
-
-  // Find a trusted issuer.
-
-  PathBuildingStep pathBuilder(trustDomain, subject, time,
-                               requiredEKUIfPresent, requiredPolicy,
-                               stapledOCSPResponse, subCACount,
-                               deferredEndEntityError, buildForwardCallBudget);
-
-  // TODO(bug 965136): Add SKI/AKI matching optimizations
-  rv = trustDomain.FindIssuer(subject.GetIssuer(), pathBuilder, time);
-  if (rv != Success) {
-    return rv;
-  }
-
-  rv = pathBuilder.CheckResult();
-  if (rv != Success) {
-    return rv;
-  }
-
-  // If we found a valid chain but deferred reporting an error with the
-  // end-entity certificate, report it now.
-  if (deferredEndEntityError != Success) {
-    return deferredEndEntityError;
-  }
-
-  // We've built a valid chain from the subject cert up to a trusted root.
-  return Success;
-}
-
-Result
-BuildCertChain(TrustDomain& trustDomain, Input certDER,
-               Time time, EndEntityOrCA endEntityOrCA,
-               KeyUsage requiredKeyUsageIfPresent,
-               KeyPurposeId requiredEKUIfPresent,
-               const CertPolicyId& requiredPolicy,
-               /*optional*/ const Input* stapledOCSPResponse)
-{
-  // XXX: Support the legacy use of the subject CN field for indicating the
-  // domain name the certificate is valid for.
-  BackCert cert(certDER, endEntityOrCA, nullptr);
-  Result rv = cert.Init();
-  if (rv != Success) {
-    return rv;
-  }
-
-  // See bug 1056341 for context. If mozilla::pkix is being used in an
-  // environment where there are many certificates that all have the same
-  // distinguished name as their subject and issuer (but different SPKIs - see
-  // the loop prevention as per RFC4158 Section 5.2 in PathBuildingStep::Check),
-  // the space to search becomes exponential. Because it would be prohibitively
-  // expensive to explore the entire space, we introduce a budget here that,
-  // when exhausted, terminates the search with the result
-  // Result::ERROR_UNKNOWN_ISSUER. Essentially, we limit the total number of
-  // times `BuildForward` can be called. The current value appears to be a good
-  // balance between finding a path when one exists (when the space isn't too
-  // large) and timing out quickly enough when the space is too large or there
-  // is no valid path to a trust anchor.
-  unsigned int buildForwardCallBudget = 200000;
-  return BuildForward(trustDomain, cert, time, requiredKeyUsageIfPresent,
-                      requiredEKUIfPresent, requiredPolicy, stapledOCSPResponse,
-                      0/*subCACount*/, buildForwardCallBudget);
-}
-
-} } // namespace mozilla::pkix
deleted file mode 100644
--- a/security/pkix/lib/pkixcert.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2014 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pkixutil.h"
-
-namespace mozilla { namespace pkix {
-
-Result
-BackCert::Init()
-{
-  Result rv;
-
-  // Certificate  ::=  SEQUENCE  {
-  //         tbsCertificate       TBSCertificate,
-  //         signatureAlgorithm   AlgorithmIdentifier,
-  //         signatureValue       BIT STRING  }
-
-  Reader tbsCertificate;
-
-  // The scope of |input| and |certificate| are limited to this block so we
-  // don't accidentally confuse them for tbsCertificate later.
-  {
-    Reader certificate;
-    rv = der::ExpectTagAndGetValueAtEnd(der, der::SEQUENCE, certificate);
-    if (rv != Success) {
-      return rv;
-    }
-    rv = der::SignedData(certificate, tbsCertificate, signedData);
-    if (rv != Success) {
-      return rv;
-    }
-    rv = der::End(certificate);
-    if (rv != Success) {
-      return rv;
-    }
-  }
-
-  // TBSCertificate  ::=  SEQUENCE  {
-  //      version         [0]  EXPLICIT Version DEFAULT v1,
-  //      serialNumber         CertificateSerialNumber,
-  //      signature            AlgorithmIdentifier,
-  //      issuer               Name,
-  //      validity             Validity,
-  //      subject              Name,
-  //      subjectPublicKeyInfo SubjectPublicKeyInfo,
-  //      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
-  //                           -- If present, version MUST be v2 or v3
-  //      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
-  //                           -- If present, version MUST be v2 or v3
-  //      extensions      [3]  EXPLICIT Extensions OPTIONAL
-  //                           -- If present, version MUST be v3
-  //      }
-  rv = der::OptionalVersion(tbsCertificate, version);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::CertificateSerialNumber(tbsCertificate, serialNumber);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::ExpectTagAndGetValue(tbsCertificate, der::SEQUENCE, signature);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE, issuer);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::ExpectTagAndGetValue(tbsCertificate, der::SEQUENCE, validity);
-  if (rv != Success) {
-    return rv;
-  }
-  // TODO(bug XXXXXXX): We rely on the the caller of mozilla::pkix to validate
-  // that the name is syntactically valid, if they care. In Gecko we do this
-  // implicitly by parsing the certificate into a CERTCertificate object.
-  // Instead of relying on the caller to do this, we should do it ourselves.
-  rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE, subject);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE,
-                               subjectPublicKeyInfo);
-  if (rv != Success) {
-    return rv;
-  }
-
-  static const uint8_t CSC = der::CONTEXT_SPECIFIC | der::CONSTRUCTED;
-
-  // According to RFC 5280, all fields below this line are forbidden for
-  // certificate versions less than v3.  However, for compatibility reasons,
-  // we parse v1/v2 certificates in the same way as v3 certificates.  So if
-  // these fields appear in a v1 certificate, they will be used.
-
-  // Ignore issuerUniqueID if present.
-  if (tbsCertificate.Peek(CSC | 1)) {
-    rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 1);
-    if (rv != Success) {
-      return rv;
-    }
-  }
-
-  // Ignore subjectUniqueID if present.
-  if (tbsCertificate.Peek(CSC | 2)) {
-    rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 2);
-    if (rv != Success) {
-      return rv;
-    }
-  }
-
-  rv = der::OptionalExtensions(
-         tbsCertificate, CSC | 3,
-         [this](Reader& extnID, const Input& extnValue, bool critical,
-                /*out*/ bool& understood) {
-           return RememberExtension(extnID, extnValue, critical, understood);
-         });
-  if (rv != Success) {
-    return rv;
-  }
-
-  // The Netscape Certificate Type extension is an obsolete
-  // Netscape-proprietary mechanism that we ignore in favor of the standard
-  // extensions. However, some CAs have issued certificates with the Netscape
-  // Cert Type extension marked critical. Thus, for compatibility reasons, we
-  // "understand" this extension by ignoring it when it is not critical, and
-  // by ensuring that the equivalent standardized extensions are present when
-  // it is marked critical, based on the assumption that the information in
-  // the Netscape Cert Type extension is consistent with the information in
-  // the standard extensions.
-  //
-  // Here is a mapping between the Netscape Cert Type extension and the
-  // standard extensions:
-  //
-  // Netscape Cert Type  |  BasicConstraints.cA  |  Extended Key Usage
-  // --------------------+-----------------------+----------------------
-  // SSL Server          |  false                |  id_kp_serverAuth
-  // SSL Client          |  false                |  id_kp_clientAuth
-  // S/MIME Client       |  false                |  id_kp_emailProtection
-  // Object Signing      |  false                |  id_kp_codeSigning
-  // SSL Server CA       |  true                 |  id_kp_serverAuth
-  // SSL Client CA       |  true                 |  id_kp_clientAuth
-  // S/MIME CA           |  true                 |  id_kp_emailProtection
-  // Object Signing CA   |  true                 |  id_kp_codeSigning
-  if (criticalNetscapeCertificateType.GetLength() > 0 &&
-      (basicConstraints.GetLength() == 0 || extKeyUsage.GetLength() == 0)) {
-    return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION;
-  }
-
-  return der::End(tbsCertificate);
-}
-
-Result
-BackCert::RememberExtension(Reader& extnID, Input extnValue,
-                            bool critical, /*out*/ bool& understood)
-{
-  understood = false;
-
-  // python DottedOIDToCode.py id-ce-keyUsage 2.5.29.15
-  static const uint8_t id_ce_keyUsage[] = {
-    0x55, 0x1d, 0x0f
-  };
-  // python DottedOIDToCode.py id-ce-subjectAltName 2.5.29.17
-  static const uint8_t id_ce_subjectAltName[] = {
-    0x55, 0x1d, 0x11
-  };
-  // python DottedOIDToCode.py id-ce-basicConstraints 2.5.29.19
-  static const uint8_t id_ce_basicConstraints[] = {
-    0x55, 0x1d, 0x13
-  };
-  // python DottedOIDToCode.py id-ce-nameConstraints 2.5.29.30
-  static const uint8_t id_ce_nameConstraints[] = {
-    0x55, 0x1d, 0x1e
-  };
-  // python DottedOIDToCode.py id-ce-certificatePolicies 2.5.29.32
-  static const uint8_t id_ce_certificatePolicies[] = {
-    0x55, 0x1d, 0x20
-  };
-  // python DottedOIDToCode.py id-ce-policyConstraints 2.5.29.36
-  static const uint8_t id_ce_policyConstraints[] = {
-    0x55, 0x1d, 0x24
-  };
-  // python DottedOIDToCode.py id-ce-extKeyUsage 2.5.29.37
-  static const uint8_t id_ce_extKeyUsage[] = {
-    0x55, 0x1d, 0x25
-  };
-  // python DottedOIDToCode.py id-ce-inhibitAnyPolicy 2.5.29.54
-  static const uint8_t id_ce_inhibitAnyPolicy[] = {
-    0x55, 0x1d, 0x36
-  };
-  // python DottedOIDToCode.py id-pe-authorityInfoAccess 1.3.6.1.5.5.7.1.1
-  static const uint8_t id_pe_authorityInfoAccess[] = {
-    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
-  };
-  // python DottedOIDToCode.py id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5
-  static const uint8_t id_pkix_ocsp_nocheck[] = {
-    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05
-  };
-  // python DottedOIDToCode.py Netscape-certificate-type 2.16.840.1.113730.1.1
-  static const uint8_t Netscape_certificate_type[] = {
-    0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01
-  };
-  // python DottedOIDToCode.py id-pe-tlsfeature 1.3.6.1.5.5.7.1.24
-  static const uint8_t id_pe_tlsfeature[] = {
-    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x18
-  };
-  // python DottedOIDToCode.py id-embeddedSctList 1.3.6.1.4.1.11129.2.4.2
-  // See Section 3.3 of RFC 6962.
-  static const uint8_t id_embeddedSctList[] = {
-    0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x04, 0x02
-  };
-
-  Input* out = nullptr;
-
-  // We already enforce the maximum possible constraints for policies so we
-  // can safely ignore even critical policy constraint extensions.
-  //
-  // XXX: Doing it this way won't allow us to detect duplicate
-  // policyConstraints extensions, but that's OK because (and only because) we
-  // ignore the extension.
-  Input dummyPolicyConstraints;
-
-  // We don't need to save the contents of this extension if it is present. We
-  // just need to handle its presence (it is essentially ignored right now).
-  Input dummyOCSPNocheck;
-
-  // For compatibility reasons, for some extensions we have to allow empty
-  // extension values. This would normally interfere with our duplicate
-  // extension checking code. However, as long as the extensions we allow to
-  // have empty values are also the ones we implicitly allow duplicates of,
-  // this will work fine.
-  bool emptyValueAllowed = false;
-
-  // RFC says "Conforming CAs MUST mark this extension as non-critical" for
-  // both authorityKeyIdentifier and subjectKeyIdentifier, and we do not use
-  // them for anything, so we totally ignore them here.
-
-  if (extnID.MatchRest(id_ce_keyUsage)) {
-    out = &keyUsage;
-  } else if (extnID.MatchRest(id_ce_subjectAltName)) {
-    out = &subjectAltName;
-  } else if (extnID.MatchRest(id_ce_basicConstraints)) {
-    out = &basicConstraints;
-  } else if (extnID.MatchRest(id_ce_nameConstraints)) {
-    out = &nameConstraints;
-  } else if (extnID.MatchRest(id_ce_certificatePolicies)) {
-    out = &certificatePolicies;
-  } else if (extnID.MatchRest(id_ce_policyConstraints)) {
-    out = &dummyPolicyConstraints;
-  } else if (extnID.MatchRest(id_ce_extKeyUsage)) {
-    out = &extKeyUsage;
-  } else if (extnID.MatchRest(id_ce_inhibitAnyPolicy)) {
-    out = &inhibitAnyPolicy;
-  } else if (extnID.MatchRest(id_pe_authorityInfoAccess)) {
-    out = &authorityInfoAccess;
-  } else if (extnID.MatchRest(id_pe_tlsfeature)) {
-    out = &requiredTLSFeatures;
-  } else if (extnID.MatchRest(id_embeddedSctList)) {
-    out = &signedCertificateTimestamps;
-  } else if (extnID.MatchRest(id_pkix_ocsp_nocheck) && critical) {
-    // We need to make sure we don't reject delegated OCSP response signing
-    // certificates that contain the id-pkix-ocsp-nocheck extension marked as
-    // critical when validating OCSP responses. Without this, an application
-    // that implements soft-fail OCSP might ignore a valid Revoked or Unknown
-    // response, and an application that implements hard-fail OCSP might fail
-    // to connect to a server given a valid Good response.
-    out = &dummyOCSPNocheck;
-    // We allow this extension to have an empty value.
-    // See http://comments.gmane.org/gmane.ietf.x509/30947
-    emptyValueAllowed = true;
-  } else if (extnID.MatchRest(Netscape_certificate_type) && critical) {
-    out = &criticalNetscapeCertificateType;
-  }
-
-  if (out) {
-    // Don't allow an empty value for any extension we understand. This way, we
-    // can test out->GetLength() != 0 or out->Init() to check for duplicates.
-    if (extnValue.GetLength() == 0 && !emptyValueAllowed) {
-      return Result::ERROR_EXTENSION_VALUE_INVALID;
-    }
-    if (out->Init(extnValue) != Success) {
-      // Duplicate extension
-      return Result::ERROR_EXTENSION_VALUE_INVALID;
-    }
-    understood = true;
-  }
-
-  return Success;
-}
-
-Result
-ExtractSignedCertificateTimestampListFromExtension(Input extnValue,
-                                                   Input& sctList)
-{
-  Reader decodedValue;
-  Result rv = der::ExpectTagAndGetValueAtEnd(extnValue, der::OCTET_STRING,
-                                             decodedValue);
-  if (rv != Success) {
-    return rv;
-  }
-  return decodedValue.SkipToEnd(sctList);
-}
-
-} } // namespace mozilla::pkix
deleted file mode 100644
--- a/security/pkix/lib/pkixcheck.cpp
+++ /dev/null
@@ -1,1100 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pkixcheck.h"
-
-#include "pkixder.h"
-#include "pkixutil.h"
-
-namespace mozilla { namespace pkix {
-
-// 4.1.1.2 signatureAlgorithm
-// 4.1.2.3 signature
-
-Result
-CheckSignatureAlgorithm(TrustDomain& trustDomain,
-                        EndEntityOrCA endEntityOrCA,
-                        Time notBefore,
-                        const der::SignedDataWithSignature& signedData,
-                        Input signatureValue)
-{
-  // 4.1.1.2. signatureAlgorithm
-  der::PublicKeyAlgorithm publicKeyAlg;
-  DigestAlgorithm digestAlg;
-  Reader signatureAlgorithmReader(signedData.algorithm);
-  Result rv = der::SignatureAlgorithmIdentifierValue(signatureAlgorithmReader,
-                                                     publicKeyAlg, digestAlg);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::End(signatureAlgorithmReader);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.1.2.3. Signature
-  der::PublicKeyAlgorithm signedPublicKeyAlg;
-  DigestAlgorithm signedDigestAlg;
-  Reader signedSignatureAlgorithmReader(signatureValue);
-  rv = der::SignatureAlgorithmIdentifierValue(signedSignatureAlgorithmReader,
-                                              signedPublicKeyAlg,
-                                              signedDigestAlg);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::End(signedSignatureAlgorithmReader);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // "This field MUST contain the same algorithm identifier as the
-  // signatureAlgorithm field in the sequence Certificate." However, it may
-  // be encoded differently. In particular, one of the fields may have a NULL
-  // parameter while the other one may omit the parameter field altogether, and
-  // these are considered equivalent. Some certificates generation software
-  // actually generates certificates like that, so we compare the parsed values
-  // instead of comparing the encoded values byte-for-byte.
-  //
-  // Along the same lines, we accept two different OIDs for RSA-with-SHA1, and
-  // we consider those OIDs to be equivalent here.
-  if (publicKeyAlg != signedPublicKeyAlg || digestAlg != signedDigestAlg) {
-    return Result::ERROR_SIGNATURE_ALGORITHM_MISMATCH;
-  }
-
-  // During the time of the deprecation of SHA-1 and the deprecation of RSA
-  // keys of less than 2048 bits, we will encounter many certs signed using
-  // SHA-1 and/or too-small RSA keys. With this in mind, we ask the trust
-  // domain early on if it knows it will reject the signature purely based on
-  // the digest algorithm and/or the RSA key size (if an RSA signature). This
-  // is a good optimization because it completely avoids calling
-  // trustDomain.FindIssuers (which may be slow) for such rejected certs, and
-  // more generally it short-circuits any path building with them (which, of
-  // course, is even slower).
-
-  rv = trustDomain.CheckSignatureDigestAlgorithm(digestAlg, endEntityOrCA,
-                                                 notBefore);
-  if (rv != Success) {
-    return rv;
-  }
-
-  switch (publicKeyAlg) {
-    case der::PublicKeyAlgorithm::RSA_PKCS1:
-    {
-      // The RSA computation may give a result that requires fewer bytes to
-      // encode than the public key (since it is modular arithmetic). However,
-      // the last step of generating a PKCS#1.5 signature is the I2OSP
-      // procedure, which pads any such shorter result with zeros so that it
-      // is exactly the same length as the public key.
-      unsigned int signatureSizeInBits = signedData.signature.GetLength() * 8u;
-      return trustDomain.CheckRSAPublicKeyModulusSizeInBits(
-               endEntityOrCA, signatureSizeInBits);
-    }
-
-    case der::PublicKeyAlgorithm::ECDSA:
-      // In theory, we could implement a similar early-pruning optimization for
-      // ECDSA curves. However, since there has been no similar deprecation for
-      // for any curve that we support, the chances of us encountering a curve
-      // during path building is too low to be worth bothering with.
-      break;
-    case der::PublicKeyAlgorithm::Uninitialized:
-    {
-      assert(false);
-      return Result::FATAL_ERROR_LIBRARY_FAILURE;
-    }
-    MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
-  }
-
-  return Success;
-}
-
-// 4.1.2.4 Issuer
-
-Result
-CheckIssuer(Input encodedIssuer)
-{
-  // "The issuer field MUST contain a non-empty distinguished name (DN)."
-  Reader issuer(encodedIssuer);
-  Input encodedRDNs;
-  ExpectTagAndGetValue(issuer, der::SEQUENCE, encodedRDNs);
-  Reader rdns(encodedRDNs);
-  // Check that the issuer name contains at least one RDN
-  // (Note: this does not check related grammar rules, such as there being one
-  // or more AVAs in each RDN, or the values in AVAs not being empty strings)
-  if (rdns.AtEnd()) {
-    return Result::ERROR_EMPTY_ISSUER_NAME;
-  }
-  return Success;
-}
-
-// 4.1.2.5 Validity
-
-Result
-ParseValidity(Input encodedValidity,
-              /*optional out*/ Time* notBeforeOut,
-              /*optional out*/ Time* notAfterOut)
-{
-  Reader validity(encodedValidity);
-  Time notBefore(Time::uninitialized);
-  if (der::TimeChoice(validity, notBefore) != Success) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-
-  Time notAfter(Time::uninitialized);
-  if (der::TimeChoice(validity, notAfter) != Success) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-
-  if (der::End(validity) != Success) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-
-  if (notBefore > notAfter) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-
-  if (notBeforeOut) {
-    *notBeforeOut = notBefore;
-  }
-  if (notAfterOut) {
-    *notAfterOut = notAfter;
-  }
-
-  return Success;
-}
-
-Result
-CheckValidity(Time time, Time notBefore, Time notAfter)
-{
-  if (time < notBefore) {
-    return Result::ERROR_NOT_YET_VALID_CERTIFICATE;
-  }
-
-  if (time > notAfter) {
-    return Result::ERROR_EXPIRED_CERTIFICATE;
-  }
-
-  return Success;
-}
-
-// 4.1.2.7 Subject Public Key Info
-
-Result
-CheckSubjectPublicKeyInfoContents(Reader& input, TrustDomain& trustDomain,
-                                  EndEntityOrCA endEntityOrCA)
-{
-  // Here, we validate the syntax and do very basic semantic validation of the
-  // public key of the certificate. The intention here is to filter out the
-  // types of bad inputs that are most likely to trigger non-mathematical
-  // security vulnerabilities in the TrustDomain, like buffer overflows or the
-  // use of unsafe elliptic curves.
-  //
-  // We don't check (all of) the mathematical properties of the public key here
-  // because it is more efficient for the TrustDomain to do it during signature
-  // verification and/or other use of the public key. In particular, we
-  // delegate the arithmetic validation of the public key, as specified in
-  // NIST SP800-56A section 5.6.2, to the TrustDomain, at least for now.
-
-  Reader algorithm;
-  Input subjectPublicKey;
-  Result rv = der::ExpectTagAndGetValue(input, der::SEQUENCE, algorithm);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::BitStringWithNoUnusedBits(input, subjectPublicKey);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::End(input);
-  if (rv != Success) {
-    return rv;
-  }
-
-  Reader subjectPublicKeyReader(subjectPublicKey);
-
-  Reader algorithmOID;
-  rv = der::ExpectTagAndGetValue(algorithm, der::OIDTag, algorithmOID);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // RFC 3279 Section 2.3.1
-  // python DottedOIDToCode.py rsaEncryption 1.2.840.113549.1.1.1
-  static const uint8_t rsaEncryption[] = {
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01
-  };
-
-  // RFC 3279 Section 2.3.5 and RFC 5480 Section 2.1.1
-  // python DottedOIDToCode.py id-ecPublicKey 1.2.840.10045.2.1
-  static const uint8_t id_ecPublicKey[] = {
-    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01
-  };
-
-  if (algorithmOID.MatchRest(id_ecPublicKey)) {
-    // An id-ecPublicKey AlgorithmIdentifier has a parameter that identifes
-    // the curve being used. Although RFC 5480 specifies multiple forms, we
-    // only supported the NamedCurve form, where the curve is identified by an
-    // OID.
-
-    Reader namedCurveOIDValue;
-    rv = der::ExpectTagAndGetValue(algorithm, der::OIDTag,
-                                   namedCurveOIDValue);
-    if (rv != Success) {
-      return rv;
-    }
-
-    // RFC 5480
-    // python DottedOIDToCode.py secp256r1 1.2.840.10045.3.1.7
-    static const uint8_t secp256r1[] = {
-      0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
-    };
-
-    // RFC 5480
-    // python DottedOIDToCode.py secp384r1 1.3.132.0.34
-    static const uint8_t secp384r1[] = {
-      0x2b, 0x81, 0x04, 0x00, 0x22
-    };
-
-    // RFC 5480
-    // python DottedOIDToCode.py secp521r1 1.3.132.0.35
-    static const uint8_t secp521r1[] = {
-      0x2b, 0x81, 0x04, 0x00, 0x23
-    };
-
-    // Matching is attempted based on a rough estimate of the commonality of the
-    // elliptic curve, to minimize the number of MatchRest calls.
-    NamedCurve curve;
-    unsigned int bits;
-    if (namedCurveOIDValue.MatchRest(secp256r1)) {
-      curve = NamedCurve::secp256r1;
-      bits = 256;
-    } else if (namedCurveOIDValue.MatchRest(secp384r1)) {
-      curve = NamedCurve::secp384r1;
-      bits = 384;
-    } else if (namedCurveOIDValue.MatchRest(secp521r1)) {
-      curve = NamedCurve::secp521r1;
-      bits = 521;
-    } else {
-      return Result::ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
-    }
-
-    rv = trustDomain.CheckECDSACurveIsAcceptable(endEntityOrCA, curve);
-    if (rv != Success) {
-      return rv;
-    }
-
-    // RFC 5480 Section 2.2 says that the first octet will be 0x04 to indicate
-    // an uncompressed point, which is the only encoding we support.
-    uint8_t compressedOrUncompressed;
-    rv = subjectPublicKeyReader.Read(compressedOrUncompressed);
-    if (rv != Success) {
-      return rv;
-    }
-    if (compressedOrUncompressed != 0x04) {
-      return Result::ERROR_UNSUPPORTED_EC_POINT_FORM;
-    }
-
-    // The point is encoded as two raw (not DER-encoded) integers, each padded
-    // to the bit length (rounded up to the nearest byte).
-    Input point;
-    rv = subjectPublicKeyReader.SkipToEnd(point);
-    if (rv != Success) {
-      return rv;
-    }
-    if (point.GetLength() != ((bits + 7) / 8u) * 2u) {
-      return Result::ERROR_BAD_DER;
-    }
-
-    // XXX: We defer the mathematical verification of the validity of the point
-    // until signature verification. This means that if we never verify a
-    // signature, we'll never fully check whether the public key is valid.
-  } else if (algorithmOID.MatchRest(rsaEncryption)) {
-    // RFC 3279 Section 2.3.1 says "The parameters field MUST have ASN.1 type
-    // NULL for this algorithm identifier."
-    rv = der::ExpectTagAndEmptyValue(algorithm, der::NULLTag);
-    if (rv != Success) {
-      return rv;
-    }
-
-    // RSAPublicKey :: = SEQUENCE{
-    //    modulus            INTEGER,    --n
-    //    publicExponent     INTEGER  }  --e
-    rv = der::Nested(subjectPublicKeyReader, der::SEQUENCE,
-                     [&trustDomain, endEntityOrCA](Reader& r) {
-      Input modulus;
-      Input::size_type modulusSignificantBytes;
-      Result nestedRv =
-        der::PositiveInteger(r, modulus, &modulusSignificantBytes);
-      if (nestedRv != Success) {
-        return nestedRv;
-      }
-      // XXX: Should we do additional checks of the modulus?
-      nestedRv = trustDomain.CheckRSAPublicKeyModulusSizeInBits(
-        endEntityOrCA, modulusSignificantBytes * 8u);
-      if (nestedRv != Success) {
-        return nestedRv;
-      }
-
-      // XXX: We don't allow the TrustDomain to validate the exponent.
-      // XXX: We don't do our own sanity checking of the exponent.
-      Input exponent;
-      return der::PositiveInteger(r, exponent);
-    });
-    if (rv != Success) {
-      return rv;
-    }
-  } else {
-    return Result::ERROR_UNSUPPORTED_KEYALG;
-  }
-
-  rv = der::End(algorithm);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = der::End(subjectPublicKeyReader);
-  if (rv != Success) {
-    return rv;
-  }
-
-  return Success;
-}
-
-Result
-CheckSubjectPublicKeyInfo(Input subjectPublicKeyInfo, TrustDomain& trustDomain,
-                          EndEntityOrCA endEntityOrCA)
-{
-  Reader spkiReader(subjectPublicKeyInfo);
-  Result rv = der::Nested(spkiReader, der::SEQUENCE, [&](Reader& r) {
-    return CheckSubjectPublicKeyInfoContents(r, trustDomain, endEntityOrCA);
-  });
-  if (rv != Success) {
-    return rv;
-  }
-  return der::End(spkiReader);
-}
-
-// 4.2.1.3. Key Usage (id-ce-keyUsage)
-
-// As explained in the comment in CheckKeyUsage, bit 0 is the most significant
-// bit and bit 7 is the least significant bit.
-inline uint8_t KeyUsageToBitMask(KeyUsage keyUsage)
-{
-  assert(keyUsage != KeyUsage::noParticularKeyUsageRequired);
-  return 0x80u >> static_cast<uint8_t>(keyUsage);
-}
-
-Result
-CheckKeyUsage(EndEntityOrCA endEntityOrCA, const Input* encodedKeyUsage,
-              KeyUsage requiredKeyUsageIfPresent)
-{
-  if (!encodedKeyUsage) {
-    // TODO(bug 970196): Reject certificates that are being used to verify
-    // certificate signatures unless the certificate is a trust anchor, to
-    // reduce the chances of an end-entity certificate being abused as a CA
-    // certificate.
-    // if (endEntityOrCA == EndEntityOrCA::MustBeCA && !isTrustAnchor) {
-    //   return Result::ERROR_INADEQUATE_KEY_USAGE;
-    // }
-    //
-    // TODO: Users may configure arbitrary certificates as trust anchors, not
-    // just roots. We should only allow a certificate without a key usage to be
-    // used as a CA when it is self-issued and self-signed.
-    return Success;
-  }
-
-  Reader input(*encodedKeyUsage);
-  Reader value;
-  if (der::ExpectTagAndGetValue(input, der::BIT_STRING, value) != Success) {
-    return Result::ERROR_INADEQUATE_KEY_USAGE;
-  }
-
-  uint8_t numberOfPaddingBits;
-  if (value.Read(numberOfPaddingBits) != Success) {
-    return Result::ERROR_INADEQUATE_KEY_USAGE;
-  }
-  if (numberOfPaddingBits > 7) {
-    return Result::ERROR_INADEQUATE_KEY_USAGE;
-  }
-
-  uint8_t bits;
-  if (value.Read(bits) != Success) {
-    // Reject empty bit masks.
-    return Result::ERROR_INADEQUATE_KEY_USAGE;
-  }
-
-  // The most significant bit is numbered 0 (digitalSignature) and the least
-  // significant bit is numbered 7 (encipherOnly), and the padding is in the
-  // least significant bits of the last byte. The numbering of bits in a byte
-  // is backwards from how we usually interpret them.
-  //
-  // For example, let's say bits is encoded in one byte with of value 0xB0 and
-  // numberOfPaddingBits == 4. Then, bits is 10110000 in binary:
-  //
-  //      bit 0  bit 3
-  //          |  |
-  //          v  v
-  //          10110000
-  //              ^^^^
-  //               |
-  //               4 padding bits
-  //
-  // Since bits is the last byte, we have to consider the padding by ensuring
-  // that the least significant 4 bits are all zero, since DER rules require
-  // all padding bits to be zero. Then we have to look at the bit N bits to the
-  // right of the most significant bit, where N is a value from the KeyUsage
-  // enumeration.
-  //
-  // Let's say we're interested in the keyCertSign (5) bit. We'd need to look
-  // at bit 5, which is zero, so keyCertSign is not asserted. (Since we check
-  // that the padding is all zeros, it is OK to read from the padding bits.)
-  //
-  // Let's say we're interested in the digitalSignature (0) bit. We'd need to
-  // look at the bit 0 (the most significant bit), which is set, so that means
-  // digitalSignature is asserted. Similarly, keyEncipherment (2) and
-  // dataEncipherment (3) are asserted.
-  //
-  // Note that since the KeyUsage enumeration is limited to values 0-7, we
-  // only ever need to examine the first byte test for
-  // requiredKeyUsageIfPresent.
-
-  if (requiredKeyUsageIfPresent != KeyUsage::noParticularKeyUsageRequired) {
-    // Check that the required key usage bit is set.
-    if ((bits & KeyUsageToBitMask(requiredKeyUsageIfPresent)) == 0) {
-      return Result::ERROR_INADEQUATE_KEY_USAGE;
-    }
-  }
-
-  // RFC 5280 says "The keyCertSign bit is asserted when the subject public
-  // key is used for verifying signatures on public key certificates. If the
-  // keyCertSign bit is asserted, then the cA bit in the basic constraints
-  // extension (Section 4.2.1.9) MUST also be asserted."
-  // However, we allow end-entity certificates (i.e. certificates without
-  // basicConstraints.cA set to TRUE) to claim keyCertSign for compatibility
-  // reasons. This does not compromise security because we only allow
-  // certificates with basicConstraints.cA set to TRUE to act as CAs.
-  if (requiredKeyUsageIfPresent == KeyUsage::keyCertSign &&
-      endEntityOrCA != EndEntityOrCA::MustBeCA) {
-    return Result::ERROR_INADEQUATE_KEY_USAGE;
-  }
-
-  // The padding applies to the last byte, so skip to the last byte.
-  while (!value.AtEnd()) {
-    if (value.Read(bits) != Success) {
-      return Result::ERROR_INADEQUATE_KEY_USAGE;
-    }
-  }
-
-  // All of the padding bits must be zero, according to DER rules.
-  uint8_t paddingMask = static_cast<uint8_t>((1 << numberOfPaddingBits) - 1);
-  if ((bits & paddingMask) != 0) {
-    return Result::ERROR_INADEQUATE_KEY_USAGE;
-  }
-
-  return Success;
-}
-
-// RFC5820 4.2.1.4. Certificate Policies
-
-// "The user-initial-policy-set contains the special value any-policy if the
-// user is not concerned about certificate policy."
-//
-// python DottedOIDToCode.py anyPolicy 2.5.29.32.0
-
-static const uint8_t anyPolicy[] = {
-  0x55, 0x1d, 0x20, 0x00
-};
-
-/*static*/ const CertPolicyId CertPolicyId::anyPolicy = {
-  4, { 0x55, 0x1d, 0x20, 0x00 }
-};
-
-bool
-CertPolicyId::IsAnyPolicy() const {
-  if (this == &CertPolicyId::anyPolicy) {
-    return true;
-  }
-  return numBytes == sizeof(::mozilla::pkix::anyPolicy) &&
-         std::equal(bytes, bytes + numBytes, ::mozilla::pkix::anyPolicy);
-}
-
-bool
-CertPolicyId::operator==(const CertPolicyId& other) const
-{
-  return numBytes == other.numBytes &&
-         std::equal(bytes, bytes + numBytes, other.bytes);
-}
-
-// certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
-Result
-CheckCertificatePolicies(EndEntityOrCA endEntityOrCA,
-                         const Input* encodedCertificatePolicies,
-                         const Input* encodedInhibitAnyPolicy,
-                         TrustLevel trustLevel,
-                         const CertPolicyId& requiredPolicy)
-{
-  if (requiredPolicy.numBytes == 0 ||
-      requiredPolicy.numBytes > sizeof requiredPolicy.bytes) {
-    return Result::FATAL_ERROR_INVALID_ARGS;
-  }
-
-  bool requiredPolicyFound = requiredPolicy.IsAnyPolicy();
-  if (requiredPolicyFound) {
-    return Success;
-  }
-
-  // Bug 989051. Until we handle inhibitAnyPolicy we will fail close when
-  // inhibitAnyPolicy extension is present and we are validating for a policy.
-  if (!requiredPolicyFound && encodedInhibitAnyPolicy) {
-    return Result::ERROR_POLICY_VALIDATION_FAILED;
-  }
-
-  // The root CA certificate may omit the policies that it has been
-  // trusted for, so we cannot require the policies to be present in those
-  // certificates. Instead, the determination of which roots are trusted for
-  // which policies is made by the TrustDomain's GetCertTrust method.
-  if (trustLevel == TrustLevel::TrustAnchor &&
-      endEntityOrCA == EndEntityOrCA::MustBeCA) {
-    requiredPolicyFound = true;
-  }
-
-  Input requiredPolicyDER;
-  if (requiredPolicyDER.Init(requiredPolicy.bytes, requiredPolicy.numBytes)
-        != Success) {
-    return Result::FATAL_ERROR_INVALID_ARGS;
-  }
-
-  if (encodedCertificatePolicies) {
-    Reader extension(*encodedCertificatePolicies);
-    Reader certificatePolicies;
-    Result rv = der::ExpectTagAndGetValue(extension, der::SEQUENCE,
-                                          certificatePolicies);
-    if (rv != Success) {
-      return Result::ERROR_POLICY_VALIDATION_FAILED;
-    }
-    if (!extension.AtEnd()) {
-      return Result::ERROR_POLICY_VALIDATION_FAILED;
-    }
-
-    do {
-      // PolicyInformation ::= SEQUENCE {
-      //         policyIdentifier   CertPolicyId,
-      //         policyQualifiers   SEQUENCE SIZE (1..MAX) OF
-      //                                 PolicyQualifierInfo OPTIONAL }
-      Reader policyInformation;
-      rv = der::ExpectTagAndGetValue(certificatePolicies, der::SEQUENCE,
-                                     policyInformation);
-      if (rv != Success) {
-        return Result::ERROR_POLICY_VALIDATION_FAILED;
-      }
-
-      Reader policyIdentifier;
-      rv = der::ExpectTagAndGetValue(policyInformation, der::OIDTag,
-                                     policyIdentifier);
-      if (rv != Success) {
-        return rv;
-      }
-
-      if (policyIdentifier.MatchRest(requiredPolicyDER)) {
-        requiredPolicyFound = true;
-      } else if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
-                 policyIdentifier.MatchRest(anyPolicy)) {
-        requiredPolicyFound = true;
-      }
-
-      // RFC 5280 Section 4.2.1.4 says "Optional qualifiers, which MAY be
-      // present, are not expected to change the definition of the policy." Also,
-      // it seems that Section 6, which defines validation, does not require any
-      // matching of qualifiers. Thus, doing anything with the policy qualifiers
-      // would be a waste of time and a source of potential incompatibilities, so
-      // we just ignore them.
-    } while (!requiredPolicyFound && !certificatePolicies.AtEnd());
-  }
-
-  if (!requiredPolicyFound) {
-    return Result::ERROR_POLICY_VALIDATION_FAILED;
-  }
-
-  return Success;
-}
-
-static const long UNLIMITED_PATH_LEN = -1; // must be less than zero
-
-//  BasicConstraints ::= SEQUENCE {
-//          cA                      BOOLEAN DEFAULT FALSE,
-//          pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
-
-// RFC5280 4.2.1.9. Basic Constraints (id-ce-basicConstraints)
-Result
-CheckBasicConstraints(EndEntityOrCA endEntityOrCA,
-                      const Input* encodedBasicConstraints,
-                      const der::Version version, TrustLevel trustLevel,
-                      unsigned int subCACount)
-{
-  bool isCA = false;
-  long pathLenConstraint = UNLIMITED_PATH_LEN;
-
-  if (encodedBasicConstraints) {
-    Reader input(*encodedBasicConstraints);
-    Result rv = der::Nested(input, der::SEQUENCE,
-                            [&isCA, &pathLenConstraint](Reader& r) {
-      Result nestedRv = der::OptionalBoolean(r, isCA);
-      if (nestedRv != Success) {
-        return nestedRv;
-      }
-      // TODO(bug 985025): If isCA is false, pathLenConstraint
-      // MUST NOT be included (as per RFC 5280 section
-      // 4.2.1.9), but for compatibility reasons, we don't
-      // check this.
-      return der::OptionalInteger(r, UNLIMITED_PATH_LEN, pathLenConstraint);
-    });
-    if (rv != Success) {
-      return Result::ERROR_EXTENSION_VALUE_INVALID;
-    }
-    if (der::End(input) != Success) {
-      return Result::ERROR_EXTENSION_VALUE_INVALID;
-    }
-  } else {
-    // "If the basic constraints extension is not present in a version 3
-    //  certificate, or the extension is present but the cA boolean is not
-    //  asserted, then the certified public key MUST NOT be used to verify
-    //  certificate signatures."
-    //
-    // For compatibility, we must accept v1 trust anchors without basic
-    // constraints as CAs.
-    //
-    // There are devices with v1 certificates that are unlikely to be trust
-    // anchors. In order to allow applications to treat this case differently
-    // from other basic constraints violations (e.g. allowing certificate error
-    // overrides for only this case), we return a different error code.
-    //
-    // TODO: add check for self-signedness?
-    if (endEntityOrCA == EndEntityOrCA::MustBeCA && version == der::Version::v1) {
-      if (trustLevel == TrustLevel::TrustAnchor) {
-        isCA = true;
-      } else {
-        return Result::ERROR_V1_CERT_USED_AS_CA;
-      }
-    }
-  }
-
-  if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
-    // CA certificates are not trusted as EE certs.
-
-    if (isCA) {
-      // Note that this check prevents a delegated OCSP response signing
-      // certificate with the CA bit from successfully validating when we check
-      // it from pkixocsp.cpp, which is a good thing.
-      return Result::ERROR_CA_CERT_USED_AS_END_ENTITY;
-    }
-
-    return Success;
-  }
-
-  assert(endEntityOrCA == EndEntityOrCA::MustBeCA);
-
-  // End-entity certificates are not allowed to act as CA certs.
-  if (!isCA) {
-    return Result::ERROR_CA_CERT_INVALID;
-  }
-
-  if (pathLenConstraint >= 0 &&
-      static_cast<long>(subCACount) > pathLenConstraint) {
-    return Result::ERROR_PATH_LEN_CONSTRAINT_INVALID;
-  }
-
-  return Success;
-}
-
-// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
-
-static Result
-MatchEKU(Reader& value, KeyPurposeId requiredEKU,
-         EndEntityOrCA endEntityOrCA, TrustDomain& trustDomain,
-         Time notBefore, /*in/out*/ bool& found,
-         /*in/out*/ bool& foundOCSPSigning)
-{
-  // See Section 5.9 of "A Layman's Guide to a Subset of ASN.1, BER, and DER"
-  // for a description of ASN.1 DER encoding of OIDs.
-
-  // id-pkix  OBJECT IDENTIFIER  ::=
-  //            { iso(1) identified-organization(3) dod(6) internet(1)
-  //                    security(5) mechanisms(5) pkix(7) }
-  // id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
-  // id-kp-serverAuth      OBJECT IDENTIFIER ::= { id-kp 1 }
-  // id-kp-clientAuth      OBJECT IDENTIFIER ::= { id-kp 2 }
-  // id-kp-codeSigning     OBJECT IDENTIFIER ::= { id-kp 3 }
-  // id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
-  // id-kp-OCSPSigning     OBJECT IDENTIFIER ::= { id-kp 9 }
-  static const uint8_t server[] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 1 };
-  static const uint8_t client[] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 2 };
-  static const uint8_t code  [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 3 };
-  static const uint8_t email [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 4 };
-  static const uint8_t ocsp  [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 9 };
-
-  // id-Netscape        OBJECT IDENTIFIER ::= { 2 16 840 1 113730 }
-  // id-Netscape-policy OBJECT IDENTIFIER ::= { id-Netscape 4 }
-  // id-Netscape-stepUp OBJECT IDENTIFIER ::= { id-Netscape-policy 1 }
-  static const uint8_t serverStepUp[] =
-    { (40*2)+16, 128+6,72, 1, 128+6,128+120,66, 4, 1 };
-
-  bool match = false;
-
-  if (!found) {
-    switch (requiredEKU) {
-      case KeyPurposeId::id_kp_serverAuth: {
-        if (value.MatchRest(server)) {
-          match = true;
-          break;
-        }
-        // Potentially treat CA certs with step-up OID as also having SSL server
-        // type. Comodo has issued certificates that require this behavior that
-        // don't expire until June 2020!
-        if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
-            value.MatchRest(serverStepUp)) {
-          Result rv = trustDomain.NetscapeStepUpMatchesServerAuth(notBefore,
-                                                                  match);
-          if (rv != Success) {
-            return rv;
-          }
-        }
-        break;
-      }
-
-      case KeyPurposeId::id_kp_clientAuth:
-        match = value.MatchRest(client);
-        break;
-
-      case KeyPurposeId::id_kp_codeSigning:
-        match = value.MatchRest(code);
-        break;
-
-      case KeyPurposeId::id_kp_emailProtection:
-        match = value.MatchRest(email);
-        break;
-
-      case KeyPurposeId::id_kp_OCSPSigning:
-        match = value.MatchRest(ocsp);
-        break;
-
-      case KeyPurposeId::anyExtendedKeyUsage:
-        return NotReached("anyExtendedKeyUsage should start with found==true",
-                          Result::FATAL_ERROR_LIBRARY_FAILURE);
-    }
-  }
-
-  if (match) {
-    found = true;
-    if (requiredEKU == KeyPurposeId::id_kp_OCSPSigning) {
-      foundOCSPSigning = true;
-    }
-  } else if (value.MatchRest(ocsp)) {
-    foundOCSPSigning = true;
-  }
-
-  value.SkipToEnd(); // ignore unmatched OIDs.
-
-  return Success;
-}
-
-Result
-CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA,
-                      const Input* encodedExtendedKeyUsage,
-                      KeyPurposeId requiredEKU, TrustDomain& trustDomain,
-                      Time notBefore)
-{
-  // XXX: We're using Result::ERROR_INADEQUATE_CERT_TYPE here so that callers
-  // can distinguish EKU mismatch from KU mismatch from basic constraints
-  // mismatch. We should probably add a new error code that is more clear for
-  // this type of problem.
-
-  bool foundOCSPSigning = false;
-
-  if (encodedExtendedKeyUsage) {
-    bool found = requiredEKU == KeyPurposeId::anyExtendedKeyUsage;
-
-    Reader input(*encodedExtendedKeyUsage);
-    Result rv = der::NestedOf(input, der::SEQUENCE, der::OIDTag,
-                              der::EmptyAllowed::No, [&](Reader& r) {
-      return MatchEKU(r, requiredEKU, endEntityOrCA, trustDomain, notBefore,
-                      found, foundOCSPSigning);
-    });
-    if (rv != Success) {
-      return Result::ERROR_INADEQUATE_CERT_TYPE;
-    }
-    if (der::End(input) != Success) {
-      return Result::ERROR_INADEQUATE_CERT_TYPE;
-    }
-
-    // If the EKU extension was included, then the required EKU must be in the
-    // list.
-    if (!found) {
-      return Result::ERROR_INADEQUATE_CERT_TYPE;
-    }
-  }
-
-  // pkixocsp.cpp depends on the following additional checks.
-
-  if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
-    // When validating anything other than an delegated OCSP signing cert,
-    // reject any cert that also claims to be an OCSP responder, because such
-    // a cert does not make sense. For example, if an SSL certificate were to
-    // assert id-kp-OCSPSigning then it could sign OCSP responses for itself,
-    // if not for this check.
-    // That said, we accept CA certificates with id-kp-OCSPSigning because
-    // some CAs in Mozilla's CA program have issued such intermediate
-    // certificates, and because some CAs have reported some Microsoft server
-    // software wrongly requires CA certificates to have id-kp-OCSPSigning.
-    // Allowing this exception does not cause any security issues because we
-    // require delegated OCSP response signing certificates to be end-entity
-    // certificates.
-    if (foundOCSPSigning && requiredEKU != KeyPurposeId::id_kp_OCSPSigning) {
-      return Result::ERROR_INADEQUATE_CERT_TYPE;
-    }
-    // http://tools.ietf.org/html/rfc6960#section-4.2.2.2:
-    // "OCSP signing delegation SHALL be designated by the inclusion of
-    // id-kp-OCSPSigning in an extended key usage certificate extension
-    // included in the OCSP response signer's certificate."
-    //
-    // id-kp-OCSPSigning is the only EKU that isn't implicitly assumed when the
-    // EKU extension is missing from an end-entity certificate. However, any CA
-    // certificate can issue a delegated OCSP response signing certificate, so
-    // we can't require the EKU be explicitly included for CA certificates.
-    if (!foundOCSPSigning && requiredEKU == KeyPurposeId::id_kp_OCSPSigning) {
-      return Result::ERROR_INADEQUATE_CERT_TYPE;
-    }
-  }
-
-  return Success;
-}
-
-Result
-CheckTLSFeatures(const BackCert& subject, BackCert& potentialIssuer)
-{
-  const Input* issuerTLSFeatures = potentialIssuer.GetRequiredTLSFeatures();
-  if (!issuerTLSFeatures) {
-    return Success;
-  }
-
-  const Input* subjectTLSFeatures = subject.GetRequiredTLSFeatures();
-  if (issuerTLSFeatures->GetLength() == 0 ||
-      !subjectTLSFeatures ||
-      !InputsAreEqual(*issuerTLSFeatures, *subjectTLSFeatures)) {
-    return Result::ERROR_REQUIRED_TLS_FEATURE_MISSING;
-  }
-
-  return Success;
-}
-
-Result
-TLSFeaturesSatisfiedInternal(const Input* requiredTLSFeatures,
-                             const Input* stapledOCSPResponse)
-{
-  if (!requiredTLSFeatures) {
-    return Success;
-  }
-
-  // RFC 6066 10.2: ExtensionType status_request
-  const static uint8_t status_request = 5;
-  const static uint8_t status_request_bytes[] = { status_request };
-
-  Reader input(*requiredTLSFeatures);
-  return der::NestedOf(input, der::SEQUENCE, der::INTEGER,
-                       der::EmptyAllowed::No, [&](Reader& r) {
-    if (!r.MatchRest(status_request_bytes)) {
-      return Result::ERROR_REQUIRED_TLS_FEATURE_MISSING;
-    }
-
-    if (!stapledOCSPResponse) {
-      return Result::ERROR_REQUIRED_TLS_FEATURE_MISSING;
-    }
-
-    return Result::Success;
-  });
-}
-
-Result
-CheckTLSFeaturesAreSatisfied(Input& cert,
-                             const Input* stapledOCSPResponse)
-{
-  BackCert backCert(cert, EndEntityOrCA::MustBeEndEntity, nullptr);
-  Result rv = backCert.Init();
-  if (rv != Success) {
-    return rv;
-  }
-
-  return TLSFeaturesSatisfiedInternal(backCert.GetRequiredTLSFeatures(),
-                                      stapledOCSPResponse);
-}
-
-Result
-CheckIssuerIndependentProperties(TrustDomain& trustDomain,
-                                 const BackCert& cert,
-                                 Time time,
-                                 KeyUsage requiredKeyUsageIfPresent,
-                                 KeyPurposeId requiredEKUIfPresent,
-                                 const CertPolicyId& requiredPolicy,
-                                 unsigned int subCACount,
-                                 /*out*/ TrustLevel& trustLevel)
-{
-  Result rv;
-
-  const EndEntityOrCA endEntityOrCA = cert.endEntityOrCA;
-
-  // Check the cert's trust first, because we want to minimize the amount of
-  // processing we do on a distrusted cert, in case it is trying to exploit
-  // some bug in our processing.
-  rv = trustDomain.GetCertTrust(endEntityOrCA, requiredPolicy, cert.GetDER(),
-                                trustLevel);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // IMPORTANT: We parse the validity interval here, so that we can use the
-  // notBefore and notAfter values in checks for things that might be deprecated
-  // over time. However, we must not fail for semantic errors until the end of
-  // this method, in order to preserve error ranking.
-  Time notBefore(Time::uninitialized);
-  Time notAfter(Time::uninitialized);
-  rv = ParseValidity(cert.GetValidity(), &notBefore, &notAfter);
-  if (rv != Success) {
-    return rv;
-  }
-
-  if (trustLevel == TrustLevel::TrustAnchor &&
-      endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
-      requiredEKUIfPresent == KeyPurposeId::id_kp_OCSPSigning) {
-    // OCSP signer certificates can never be trust anchors, especially
-    // since we don't support designated OCSP responders. All of the checks
-    // below that are dependent on trustLevel rely on this overriding of the
-    // trust level for OCSP signers.
-    trustLevel = TrustLevel::InheritsTrust;
-  }
-
-  switch (trustLevel) {
-    case TrustLevel::InheritsTrust:
-      rv = CheckSignatureAlgorithm(trustDomain, endEntityOrCA, notBefore,
-                                   cert.GetSignedData(), cert.GetSignature());
-      if (rv != Success) {
-        return rv;
-      }
-      break;
-
-    case TrustLevel::TrustAnchor:
-      // We don't even bother checking signatureAlgorithm or signature for
-      // syntactic validity for trust anchors, because we don't use those
-      // fields for anything, and because the trust anchor might be signed
-      // with a signature algorithm we don't actually support.
-      break;
-
-    case TrustLevel::ActivelyDistrusted:
-      return Result::ERROR_UNTRUSTED_CERT;
-  }
-
-  // Check the SPKI early, because it is one of the most selective properties
-  // of the certificate due to SHA-1 deprecation and the deprecation of
-  // certificates with keys weaker than RSA 2048.
-  rv = CheckSubjectPublicKeyInfo(cert.GetSubjectPublicKeyInfo(), trustDomain,
-                                 endEntityOrCA);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.1.2.4. Issuer
-  rv = CheckIssuer(cert.GetIssuer());
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.2.1.1. Authority Key Identifier is ignored (see bug 965136).
-
-  // 4.2.1.2. Subject Key Identifier is ignored (see bug 965136).
-
-  // 4.2.1.3. Key Usage
-  rv = CheckKeyUsage(endEntityOrCA, cert.GetKeyUsage(),
-                     requiredKeyUsageIfPresent);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.2.1.4. Certificate Policies
-  rv = CheckCertificatePolicies(endEntityOrCA, cert.GetCertificatePolicies(),
-                                cert.GetInhibitAnyPolicy(), trustLevel,
-                                requiredPolicy);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.2.1.5. Policy Mappings are not supported; see the documentation about
-  //          policy enforcement in pkix.h.
-
-  // 4.2.1.6. Subject Alternative Name dealt with during name constraint
-  //          checking and during name verification (CERT_VerifyCertName).
-
-  // 4.2.1.7. Issuer Alternative Name is not something that needs checking.
-
-  // 4.2.1.8. Subject Directory Attributes is not something that needs
-  //          checking.
-
-  // 4.2.1.9. Basic Constraints.
-  rv = CheckBasicConstraints(endEntityOrCA, cert.GetBasicConstraints(),
-                             cert.GetVersion(), trustLevel, subCACount);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.2.1.10. Name Constraints is dealt with in during path building.
-
-  // 4.2.1.11. Policy Constraints are implicitly supported; see the
-  //           documentation about policy enforcement in pkix.h.
-
-  // 4.2.1.12. Extended Key Usage
-  rv = CheckExtendedKeyUsage(endEntityOrCA, cert.GetExtKeyUsage(),
-                             requiredEKUIfPresent, trustDomain, notBefore);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // 4.2.1.13. CRL Distribution Points is not supported, though the
-  //           TrustDomain's CheckRevocation method may parse it and process it
-  //           on its own.
-
-  // 4.2.1.14. Inhibit anyPolicy is implicitly supported; see the documentation
-  //           about policy enforcement in pkix.h.
-
-  // IMPORTANT: Even though we parse validity above, we wait until this point to
-  // check it, so that error ranking works correctly.
-  rv = CheckValidity(time, notBefore, notAfter);
-  if (rv != Success) {
-    return rv;
-  }
-
-  rv = trustDomain.CheckValidityIsAcceptable(notBefore, notAfter, endEntityOrCA,
-                                             requiredEKUIfPresent);
-  if (rv != Success) {
-    return rv;
-  }
-
-  return Success;
-}
-
-} } // namespace mozilla::pkix
deleted file mode 100644
--- a/security/pkix/lib/pkixcheck.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_pkixcheck_h
-#define mozilla_pkix_pkixcheck_h
-
-#include "pkix/pkixtypes.h"
-
-namespace mozilla { namespace pkix {
-
-class BackCert;
-
-Result CheckIssuerIndependentProperties(
-          TrustDomain& trustDomain,
-          const BackCert& cert,
-          Time time,
-          KeyUsage requiredKeyUsageIfPresent,
-          KeyPurposeId requiredEKUIfPresent,
-          const CertPolicyId& requiredPolicy,
-          unsigned int subCACount,
-          /*out*/ TrustLevel& trustLevel);
-
-Result CheckNameConstraints(Input encodedNameConstraints,
-                            const BackCert& firstChild,
-                            KeyPurposeId requiredEKUIfPresent);
-
-Result CheckIssuer(Input encodedIssuer);
-
-// ParseValidity and CheckValidity are usually used together.  First you parse
-// the dates from the DER Validity sequence, then you compare them to the time
-// at which you are validating.  They are separate so that the notBefore and
-// notAfter times can be used for other things before they are checked against
-// the time of validation.
-Result ParseValidity(Input encodedValidity,
-                     /*optional out*/ Time* notBeforeOut = nullptr,
-                     /*optional out*/ Time* notAfterOut = nullptr);
-Result CheckValidity(Time time, Time notBefore, Time notAfter);
-
-// Check that a subject has TLS Feature (rfc7633) requirements that match its
-// potential issuer
-Result CheckTLSFeatures(const BackCert& subject, BackCert& potentialIssuer);
-
-} } // namespace mozilla::pkix
-
-#endif // mozilla_pkix_pkixcheck_h
deleted file mode 100644
--- a/security/pkix/lib/pkixder.cpp
+++ /dev/null
@@ -1,611 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pkixder.h"
-
-#include "pkixutil.h"
-
-namespace mozilla { namespace pkix { namespace der {
-
-// Too complicated to be inline
-Result
-ReadTagAndGetValue(Reader& input, /*out*/ uint8_t& tag, /*out*/ Input& value)
-{
-  Result rv;
-
-  rv = input.Read(tag);
-  if (rv != Success) {
-    return rv;
-  }
-  if ((tag & 0x1F) == 0x1F) {
-    return Result::ERROR_BAD_DER; // high tag number form not allowed
-  }
-
-  uint16_t length;
-
-  // The short form of length is a single byte with the high order bit set
-  // to zero. The long form of length is one byte with the high order bit
-  // set, followed by N bytes, where N is encoded in the lowest 7 bits of
-  // the first byte.
-  uint8_t length1;
-  rv = input.Read(length1);
-  if (rv != Success) {
-    return rv;
-  }
-  if (!(length1 & 0x80)) {
-    length = length1;
-  } else if (length1 == 0x81) {
-    uint8_t length2;
-    rv = input.Read(length2);
-    if (rv != Success) {
-      return rv;
-    }
-    if (length2 < 128) {
-      // Not shortest possible encoding
-      return Result::ERROR_BAD_DER;
-    }
-    length = length2;
-  } else if (length1 == 0x82) {
-    rv = input.Read(length);
-    if (rv != Success) {
-      return rv;
-    }
-    if (length < 256) {
-      // Not shortest possible encoding
-      return Result::ERROR_BAD_DER;
-    }
-  } else {
-    // We don't support lengths larger than 2^16 - 1.
-    return Result::ERROR_BAD_DER;
-  }
-
-  return input.Skip(length, value);
-}
-
-static Result
-OptionalNull(Reader& input)
-{
-  if (input.Peek(NULLTag)) {
-    return Null(input);
-  }
-  return Success;
-}
-
-namespace {
-
-Result
-AlgorithmIdentifierValue(Reader& input, /*out*/ Reader& algorithmOIDValue)
-{
-  Result rv = ExpectTagAndGetValue(input, der::OIDTag, algorithmOIDValue);
-  if (rv != Success) {
-    return rv;
-  }
-  return OptionalNull(input);
-}
-
-} // namespace
-
-Result
-SignatureAlgorithmIdentifierValue(Reader& input,
-                                 /*out*/ PublicKeyAlgorithm& publicKeyAlgorithm,
-                                 /*out*/ DigestAlgorithm& digestAlgorithm)
-{
-  // RFC 5758 Section 3.2 (ECDSA with SHA-2), and RFC 3279 Section 2.2.3
-  // (ECDSA with SHA-1) say that parameters must be omitted.
-  //
-  // RFC 4055 Section 5 and RFC 3279 Section 2.2.1 both say that parameters for
-  // RSA must be encoded as NULL; we relax that requirement by allowing the
-  // NULL to be omitted, to match all the other signature algorithms we support
-  // and for compatibility.
-  Reader algorithmID;
-  Result rv = AlgorithmIdentifierValue(input, algorithmID);
-  if (rv != Success) {
-    return rv;
-  }
-
-  // RFC 5758 Section 3.2 (ecdsa-with-SHA224 is intentionally excluded)
-  // python DottedOIDToCode.py ecdsa-with-SHA256 1.2.840.10045.4.3.2
-  static const uint8_t ecdsa_with_SHA256[] = {
-    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02
-  };
-  // python DottedOIDToCode.py ecdsa-with-SHA384 1.2.840.10045.4.3.3
-  static const uint8_t ecdsa_with_SHA384[] = {
-    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03
-  };
-  // python DottedOIDToCode.py ecdsa-with-SHA512 1.2.840.10045.4.3.4
-  static const uint8_t ecdsa_with_SHA512[] = {
-    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
-  };
-
-  // RFC 4055 Section 5 (sha224WithRSAEncryption is intentionally excluded)
-  // python DottedOIDToCode.py sha256WithRSAEncryption 1.2.840.113549.1.1.11
-  static const uint8_t sha256WithRSAEncryption[] = {
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
-  };
-  // python DottedOIDToCode.py sha384WithRSAEncryption 1.2.840.113549.1.1.12
-  static const uint8_t sha384WithRSAEncryption[] = {
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c
-  };
-  // python DottedOIDToCode.py sha512WithRSAEncryption 1.2.840.113549.1.1.13
-  static const uint8_t sha512WithRSAEncryption[] = {
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
-  };
-
-  // RFC 3279 Section 2.2.1
-  // python DottedOIDToCode.py sha-1WithRSAEncryption 1.2.840.113549.1.1.5
-  static const uint8_t sha_1WithRSAEncryption[] = {
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05
-  };
-
-  // NIST Open Systems Environment (OSE) Implementor's Workshop (OIW)
-  // http://www.oiw.org/agreements/stable/12s-9412.txt (no longer works).
-  // http://www.imc.org/ietf-pkix/old-archive-97/msg01166.html
-  // We need to support this this non-PKIX OID for compatibility.
-  // python DottedOIDToCode.py sha1WithRSASignature 1.3.14.3.2.29
-  static const uint8_t sha1WithRSASignature[] = {
-    0x2b, 0x0e, 0x03, 0x02, 0x1d
-  };
-
-  // RFC 3279 Section 2.2.3
-  // python DottedOIDToCode.py ecdsa-with-SHA1 1.2.840.10045.4.1
-  static const uint8_t ecdsa_with_SHA1[] = {
-    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01
-  };
-
-  // Matching is attempted based on a rough estimate of the commonality of the
-  // algorithm, to minimize the number of MatchRest calls.
-  if (algorithmID.MatchRest(sha256WithRSAEncryption)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::RSA_PKCS1;
-    digestAlgorithm = DigestAlgorithm::sha256;
-  } else if (algorithmID.MatchRest(ecdsa_with_SHA256)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::ECDSA;
-    digestAlgorithm = DigestAlgorithm::sha256;
-  } else if (algorithmID.MatchRest(sha_1WithRSAEncryption)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::RSA_PKCS1;
-    digestAlgorithm = DigestAlgorithm::sha1;
-  } else if (algorithmID.MatchRest(ecdsa_with_SHA1)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::ECDSA;
-    digestAlgorithm = DigestAlgorithm::sha1;
-  } else if (algorithmID.MatchRest(ecdsa_with_SHA384)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::ECDSA;
-    digestAlgorithm = DigestAlgorithm::sha384;
-  } else if (algorithmID.MatchRest(ecdsa_with_SHA512)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::ECDSA;
-    digestAlgorithm = DigestAlgorithm::sha512;
-  } else if (algorithmID.MatchRest(sha384WithRSAEncryption)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::RSA_PKCS1;
-    digestAlgorithm = DigestAlgorithm::sha384;
-  } else if (algorithmID.MatchRest(sha512WithRSAEncryption)) {
-    publicKeyAlgorithm = PublicKeyAlgorithm::RSA_PKCS1;
-    digestAlgorithm = DigestAlgorithm::sha512;
-  } else if (algorithmID.MatchRest(sha1WithRSASignature)) {
-    // XXX(bug 1042479): recognize this old OID for compatibility.
-    publicKeyAlgorithm = PublicKeyAlgorithm::RSA_PKCS1;
-    digestAlgorithm = DigestAlgorithm::sha1;
-  } else {
-    return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
-  }
-
-  return Success;
-}
-
-Result
-DigestAlgorithmIdentifier(Reader& input, /*out*/ DigestAlgorithm& algorithm)
-{
-  return der::Nested(input, SEQUENCE, [&algorithm](Reader& r) -> Result {
-    Reader algorithmID;
-    Result rv = AlgorithmIdentifierValue(r, algorithmID);
-    if (rv != Success) {
-      return rv;
-    }
-
-    // RFC 4055 Section 2.1
-    // python DottedOIDToCode.py id-sha1 1.3.14.3.2.26
-    static const uint8_t id_sha1[] = {
-      0x2b, 0x0e, 0x03, 0x02, 0x1a
-    };
-    // python DottedOIDToCode.py id-sha256 2.16.840.1.101.3.4.2.1
-    static const uint8_t id_sha256[] = {
-      0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
-    };
-    // python DottedOIDToCode.py id-sha384 2.16.840.1.101.3.4.2.2
-    static const uint8_t id_sha384[] = {
-      0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
-    };
-    // python DottedOIDToCode.py id-sha512 2.16.840.1.101.3.4.2.3
-    static const uint8_t id_sha512[] = {
-      0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
-    };
-
-    // Matching is attempted based on a rough estimate of the commonality of the
-    // algorithm, to minimize the number of MatchRest calls.
-    if (algorithmID.MatchRest(id_sha1)) {
-      algorithm = DigestAlgorithm::sha1;
-    } else if (algorithmID.MatchRest(id_sha256)) {
-      algorithm = DigestAlgorithm::sha256;
-    } else if (algorithmID.MatchRest(id_sha384)) {
-      algorithm = DigestAlgorithm::sha384;
-    } else if (algorithmID.MatchRest(id_sha512)) {
-      algorithm = DigestAlgorithm::sha512;
-    } else {
-      return Result::ERROR_INVALID_ALGORITHM;
-    }
-
-    return Success;
-  });
-}
-
-Result
-SignedData(Reader& input, /*out*/ Reader& tbs,
-           /*out*/ SignedDataWithSignature& signedData)
-{
-  Reader::Mark mark(input.GetMark());
-
-  Result rv;
-  rv = ExpectTagAndGetValue(input, SEQUENCE, tbs);
-  if (rv != Success) {
-    return rv;
-  }
-
-  rv = input.GetInput(mark, signedData.data);
-  if (rv != Success) {
-    return rv;
-  }
-
-  rv = ExpectTagAndGetValue(input, der::SEQUENCE, signedData.algorithm);
-  if (rv != Success) {
-    return rv;
-  }
-
-  rv = BitStringWithNoUnusedBits(input, signedData.signature);
-  if (rv == Result::ERROR_BAD_DER) {
-    rv = Result::ERROR_BAD_SIGNATURE;
-  }
-  return rv;
-}
-
-Result
-BitStringWithNoUnusedBits(Reader& input, /*out*/ Input& value)
-{
-  Reader valueWithUnusedBits;
-  Result rv = ExpectTagAndGetValue(input, BIT_STRING, valueWithUnusedBits);
-  if (rv != Success) {
-    return rv;
-  }
-
-  uint8_t unusedBitsAtEnd;
-  if (valueWithUnusedBits.Read(unusedBitsAtEnd) != Success) {
-    return Result::ERROR_BAD_DER;
-  }
-  // XXX: Really the constraint should be that unusedBitsAtEnd must be less
-  // than 7. But, we suspect there are no real-world values in OCSP responses
-  // or certificates with non-zero unused bits. It seems like NSS assumes this
-  // in various places, so we enforce it too in order to simplify this code. If
-  // we find compatibility issues, we'll know we're wrong and we'll have to
-  // figure out how to shift the bits around.
-  if (unusedBitsAtEnd != 0) {
-    return Result::ERROR_BAD_DER;
-  }
-  return valueWithUnusedBits.SkipToEnd(value);
-}
-
-static inline Result
-ReadDigit(Reader& input, /*out*/ unsigned int& value)
-{
-  uint8_t b;
-  if (input.Read(b) != Success) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-  if (b < '0' || b > '9') {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-  value = static_cast<unsigned int>(b - static_cast<uint8_t>('0'));
-  return Success;
-}
-
-static inline Result
-ReadTwoDigits(Reader& input, unsigned int minValue, unsigned int maxValue,
-              /*out*/ unsigned int& value)
-{
-  unsigned int hi;
-  Result rv = ReadDigit(input, hi);
-  if (rv != Success) {
-    return rv;
-  }
-  unsigned int lo;
-  rv = ReadDigit(input, lo);
-  if (rv != Success) {
-    return rv;
-  }
-  value = (hi * 10) + lo;
-  if (value < minValue || value > maxValue) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-  return Success;
-}
-
-namespace internal {
-
-// We parse GeneralizedTime and UTCTime according to RFC 5280 and we do not
-// accept all time formats allowed in the ASN.1 spec. That is,
-// GeneralizedTime must always be in the format YYYYMMDDHHMMSSZ and UTCTime
-// must always be in the format YYMMDDHHMMSSZ. Timezone formats of the form
-// +HH:MM or -HH:MM or NOT accepted.
-Result
-TimeChoice(Reader& tagged, uint8_t expectedTag, /*out*/ Time& time)
-{
-  unsigned int days;
-
-  Reader input;
-  Result rv = ExpectTagAndGetValue(tagged, expectedTag, input);
-  if (rv != Success) {
-    return rv;
-  }
-
-  unsigned int yearHi;
-  unsigned int yearLo;
-  if (expectedTag == GENERALIZED_TIME) {
-    rv = ReadTwoDigits(input, 0, 99, yearHi);
-    if (rv != Success) {
-      return rv;
-    }
-    rv = ReadTwoDigits(input, 0, 99, yearLo);
-    if (rv != Success) {
-      return rv;
-    }
-  } else if (expectedTag == UTCTime) {
-    rv = ReadTwoDigits(input, 0, 99, yearLo);
-    if (rv != Success) {
-      return rv;
-    }
-    yearHi = yearLo >= 50u ? 19u : 20u;
-  } else {
-    return NotReached("invalid tag given to TimeChoice",
-                      Result::ERROR_INVALID_DER_TIME);
-  }
-  unsigned int year = (yearHi * 100u) + yearLo;
-  if (year < 1970u) {
-    // We don't support dates before January 1, 1970 because that is the epoch.
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-  days = DaysBeforeYear(year);
-
-  unsigned int month;
-  rv = ReadTwoDigits(input, 1u, 12u, month);
-  if (rv != Success) {
-    return rv;
-  }
-  unsigned int daysInMonth;
-  static const unsigned int jan = 31u;
-  const unsigned int feb = ((year % 4u == 0u) &&
-                           ((year % 100u != 0u) || (year % 400u == 0u)))
-                         ? 29u
-                         : 28u;
-  static const unsigned int mar = 31u;
-  static const unsigned int apr = 30u;
-  static const unsigned int may = 31u;
-  static const unsigned int jun = 30u;
-  static const unsigned int jul = 31u;
-  static const unsigned int aug = 31u;
-  static const unsigned int sep = 30u;
-  static const unsigned int oct = 31u;
-  static const unsigned int nov = 30u;
-  static const unsigned int dec = 31u;
-  switch (month) {
-    case 1:  daysInMonth = jan; break;
-    case 2:  daysInMonth = feb; days += jan; break;
-    case 3:  daysInMonth = mar; days += jan + feb; break;
-    case 4:  daysInMonth = apr; days += jan + feb + mar; break;
-    case 5:  daysInMonth = may; days += jan + feb + mar + apr; break;
-    case 6:  daysInMonth = jun; days += jan + feb + mar + apr + may; break;
-    case 7:  daysInMonth = jul; days += jan + feb + mar + apr + may + jun;
-             break;
-    case 8:  daysInMonth = aug; days += jan + feb + mar + apr + may + jun +
-                                        jul;
-             break;
-    case 9:  daysInMonth = sep; days += jan + feb + mar + apr + may + jun +
-                                        jul + aug;
-             break;
-    case 10: daysInMonth = oct; days += jan + feb + mar + apr + may + jun +
-                                        jul + aug + sep;
-             break;
-    case 11: daysInMonth = nov; days += jan + feb + mar + apr + may + jun +
-                                        jul + aug + sep + oct;
-             break;
-    case 12: daysInMonth = dec; days += jan + feb + mar + apr + may + jun +
-                                        jul + aug + sep + oct + nov;
-             break;
-    default:
-      return NotReached("month already bounds-checked by ReadTwoDigits",
-                        Result::FATAL_ERROR_INVALID_STATE);
-  }
-
-  unsigned int dayOfMonth;
-  rv = ReadTwoDigits(input, 1u, daysInMonth, dayOfMonth);
-  if (rv != Success) {
-    return rv;
-  }
-  days += dayOfMonth - 1;
-
-  unsigned int hours;
-  rv = ReadTwoDigits(input, 0u, 23u, hours);
-  if (rv != Success) {
-    return rv;
-  }
-  unsigned int minutes;
-  rv = ReadTwoDigits(input, 0u, 59u, minutes);
-  if (rv != Success) {
-    return rv;
-  }
-  unsigned int seconds;
-  rv = ReadTwoDigits(input, 0u, 59u, seconds);
-  if (rv != Success) {
-    return rv;
-  }
-
-  uint8_t b;
-  if (input.Read(b) != Success) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-  if (b != 'Z') {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-  if (End(input) != Success) {
-    return Result::ERROR_INVALID_DER_TIME;
-  }
-
-  uint64_t totalSeconds = (static_cast<uint64_t>(days) * 24u * 60u * 60u) +
-                          (static_cast<uint64_t>(hours)      * 60u * 60u) +
-                          (static_cast<uint64_t>(minutes)          * 60u) +
-                          seconds;
-
-  time = TimeFromElapsedSecondsAD(totalSeconds);
-  return Success;
-}
-
-Result
-IntegralBytes(Reader& input, uint8_t tag,
-              IntegralValueRestriction valueRestriction,
-              /*out*/ Input& value,
-              /*optional out*/ Input::size_type* significantBytes)
-{
-  Result rv = ExpectTagAndGetValue(input, tag, value);
-  if (rv != Success) {
-    return rv;
-  }
-  Reader reader(value);
-
-  // There must be at least one byte in the value. (Zero is encoded with a
-  // single 0x00 value byte.)
-  uint8_t firstByte;
-  rv = reader.Read(firstByte);
-  if (rv != Success) {
-    if (rv == Result::ERROR_BAD_DER) {
-      return Result::ERROR_INVALID_INTEGER_ENCODING;
-    }
-
-    return rv;
-  }
-
-  // If there is a byte after an initial 0x00/0xFF, then the initial byte
-  // indicates a positive/negative integer value with its high bit set/unset.
-  bool prefixed = !reader.AtEnd() && (firstByte == 0 || firstByte == 0xff);
-
-  if (prefixed) {
-    uint8_t nextByte;
-    if (reader.Read(nextByte) != Success) {
-      return NotReached("Read of one byte failed but not at end.",
-                        Result::FATAL_ERROR_LIBRARY_FAILURE);
-    }
-    if ((firstByte & 0x80) == (nextByte & 0x80)) {
-      return Result::ERROR_INVALID_INTEGER_ENCODING;
-    }
-  }
-
-  switch (valueRestriction) {
-    case IntegralValueRestriction::MustBe0To127:
-      if (value.GetLength() != 1 || (firstByte & 0x80) != 0) {
-        return Result::ERROR_INVALID_INTEGER_ENCODING;
-      }
-      break;
-
-    case IntegralValueRestriction::MustBePositive:
-      if ((value.GetLength() == 1 && firstByte == 0) ||
-          (firstByte & 0x80) != 0) {
-        return Result::ERROR_INVALID_INTEGER_ENCODING;
-      }
-      break;
-
-    case IntegralValueRestriction::NoRestriction:
-      break;
-  }
-
-  if (significantBytes) {
-    *significantBytes = value.GetLength();
-    if (prefixed) {
-      assert(*significantBytes > 1);
-      --*significantBytes;
-    }
-
-    assert(*significantBytes > 0);
-  }
-
-  return Success;
-}
-
-// This parser will only parse values between 0..127. If this range is
-// increased then callers will need to be changed.
-Result
-IntegralValue(Reader& input, uint8_t tag, /*out*/ uint8_t& value)
-{
-  // Conveniently, all the Integers that we actually have to be able to parse
-  // are positive and very small. Consequently, this parser is *much* simpler
-  // than a general Integer parser would need to be.
-  Input valueBytes;
-  Result rv = IntegralBytes(input, tag, IntegralValueRestriction::MustBe0To127,
-                            valueBytes, nullptr);
-  if (rv != Success) {
-    return rv;
-  }
-  Reader valueReader(valueBytes);
-  rv = valueReader.Read(value);
-  if (rv != Success) {
-    return NotReached("IntegralBytes already validated the value.", rv);
-  }
-  rv = End(valueReader);
-  assert(rv == Success); // guaranteed by IntegralBytes's range checks.
-  return rv;
-}
-
-} // namespace internal
-
-Result
-OptionalVersion(Reader& input, /*out*/ Version& version)
-{
-  static const uint8_t TAG = CONTEXT_SPECIFIC | CONSTRUCTED | 0;
-  if (!input.Peek(TAG)) {
-    version = Version::v1;
-    return Success;
-  }
-  return Nested(input, TAG, [&version](Reader& value) -> Result {
-    uint8_t integerValue;
-    Result rv = Integer(value, integerValue);
-    if (rv != Success) {
-      return rv;
-    }
-    // XXX(bug 1031093): We shouldn't accept an explicit encoding of v1,
-    // but we do here for compatibility reasons.
-    switch (integerValue) {
-      case static_cast<uint8_t>(Version::v3): version = Version::v3; break;
-      case static_cast<uint8_t>(Version::v2): version = Version::v2; break;
-      case static_cast<uint8_t>(Version::v1): version = Version::v1; break;
-      case static_cast<uint8_t>(Version::v4): version = Version::v4; break;
-      default:
-        return Result::ERROR_BAD_DER;
-    }
-    return Success;
-  });
-}
-
-} } } // namespace mozilla::pkix::der
deleted file mode 100644
--- a/security/pkix/lib/pkixder.h
+++ /dev/null
@@ -1,566 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2013 Mozilla Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_pkix_pkixder_h
-#define mozilla_pkix_pkixder_h
-
-// Expect* functions advance the input mark and return Success if the input
-// matches the given criteria; they fail with the input mark in an undefined
-// state if the input does not match the criteria.
-//
-// Match* functions advance the input mark and return true if the input matches
-// the given criteria; they return false without changing the input mark if the
-// input does not match the criteria.
-//
-// Skip* functions unconditionally advance the input mark and return Success if
-// they are able to do so; otherwise they fail with the input mark in an
-// undefined state.
-
-#include "pkix/Input.h"
-#include "pkix/pkixtypes.h"
-
-namespace mozilla { namespace pkix { namespace der {
-
-enum Class : uint8_t
-{
-   UNIVERSAL = 0 << 6,
-// APPLICATION = 1 << 6, // unused
-   CONTEXT_SPECIFIC = 2 << 6,
-// PRIVATE = 3 << 6 // unused
-};
-
-enum Constructed
-{
-  CONSTRUCTED = 1 << 5
-};
-
-enum Tag : uint8_t
-{
-  BOOLEAN = UNIVERSAL | 0x01,
-  INTEGER = UNIVERSAL | 0x02,
-  BIT_STRING = UNIVERSAL | 0x03,
-  OCTET_STRING = UNIVERSAL | 0x04,
-  NULLTag = UNIVERSAL | 0x05,
-  OIDTag = UNIVERSAL | 0x06,
-  ENUMERATED = UNIVERSAL | 0x0a,
-  UTF8String = UNIVERSAL | 0x0c,
-  SEQUENCE = UNIVERSAL | CONSTRUCTED | 0x10, // 0x30
-  SET = UNIVERSAL | CONSTRUCTED | 0x11, // 0x31
-  PrintableString = UNIVERSAL | 0x13,
-  TeletexString = UNIVERSAL | 0x14,
-  IA5String = UNIVERSAL | 0x16,
-  UTCTime = UNIVERSAL | 0x17,
-  GENERALIZED_TIME = UNIVERSAL | 0x18,
-};
-
-enum class EmptyAllowed { No = 0, Yes = 1 };
-
-Result ReadTagAndGetValue(Reader& input, /*out*/ uint8_t& tag,
-                          /*out*/ Input& value);
-Result End(Reader& input);
-
-inline Result
-ExpectTagAndGetValue(Reader& input, uint8_t tag, /*out*/ Input& value)
-{
-  uint8_t actualTag;
-  Result rv = ReadTagAndGetValue(input, actualTag, value);
-  if (rv != Success) {
-    return rv;
-  }
-  if (tag != actualTag) {
-    return Result::ERROR_BAD_DER;
-  }
-  return Success;
-}
-
-inline Result
-ExpectTagAndGetValue(Reader& input, uint8_t tag, /*out*/ Reader& value)
-{
-  Input valueInput;
-  Result rv = ExpectTagAndGetValue(input, tag, valueInput);
-  if (rv != Success) {
-    return rv;
-  }
-  return value.Init(valueInput);
-}
-
-inline Result
-ExpectTagAndEmptyValue(Reader& input, uint8_t tag)
-{
-  Reader value;
-  Result rv = ExpectTagAndGetValue(input, tag, value);
-  if (rv != Success) {
-    return rv;
-  }
-  return End(value);
-}
-
-inline Result
-ExpectTagAndSkipValue(Reader& input, uint8_t tag)
-{
-  Input ignoredValue;
-  return ExpectTagAndGetValue(input, tag, ignoredValue);
-}
-
-// Like ExpectTagAndGetValue, except the output Input will contain the
-// encoded tag and length along with the value.
-inline Result
-ExpectTagAndGetTLV(Reader& input, uint8_t tag, /*out*/ Input& tlv)
-{
-  Reader::Mark mark(input.GetMark());
-  Result rv = ExpectTagAndSkipValue(input, tag);
-  if (rv != Success) {
-    return rv;
-  }
-  return input.GetInput(mark, tlv);
-}
-
-inline Result
-End(Reader& input)
-{
-  if (!input.AtEnd()) {
-    return Result::ERROR_BAD_DER;
-  }
-
-  return Success;
-}
-
-template <typename Decoder>
-inline Result
-Nested(Reader& input, uint8_t tag, Decoder decoder)
-{
-  Reader nested;
-  Result rv = ExpectTagAndGetValue(input, tag, nested);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = decoder(nested);
-  if (rv != Success) {
-    return rv;
-  }
-  return End(nested);
-}
-
-template <typename Decoder>
-inline Result
-Nested(Reader& input, uint8_t outerTag, uint8_t innerTag, Decoder decoder)
-{
-  Reader nestedInput;
-  Result rv = ExpectTagAndGetValue(input, outerTag, nestedInput);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = Nested(nestedInput, innerTag, decoder);
-  if (rv != Success) {
-    return rv;
-  }
-  return End(nestedInput);
-}
-
-// This can be used to decode constructs like this:
-//
-//     ...
-//     foos SEQUENCE OF Foo,
-//     ...
-//     Foo ::= SEQUENCE {
-//     }
-//
-// using code like this:
-//
-//    Result Foo(Reader& r) { /*...*/ }
-//
-//    rv = der::NestedOf(input, der::SEQEUENCE, der::SEQUENCE, Foo);
-//
-// or:
-//
-//    Result Bar(Reader& r, int value) { /*...*/ }
-//
-//    int value = /*...*/;
-//
-//    rv = der::NestedOf(input, der::SEQUENCE, [value](Reader& r) {
-//      return Bar(r, value);
-//    });
-//
-// In these examples the function will get called once for each element of
-// foos.
-//
-template <typename Decoder>
-inline Result
-NestedOf(Reader& input, uint8_t outerTag, uint8_t innerTag,
-         EmptyAllowed mayBeEmpty, Decoder decoder)
-{
-  Reader inner;
-  Result rv = ExpectTagAndGetValue(input, outerTag, inner);
-  if (rv != Success) {
-    return rv;
-  }
-
-  if (inner.AtEnd()) {
-    if (mayBeEmpty != EmptyAllowed::Yes) {
-      return Result::ERROR_BAD_DER;
-    }
-    return Success;
-  }
-
-  do {
-    rv = Nested(inner, innerTag, decoder);
-    if (rv != Success) {
-      return rv;
-    }
-  } while (!inner.AtEnd());
-
-  return Success;
-}
-
-// Often, a function will need to decode an Input or Reader that contains
-// DER-encoded data wrapped in a SEQUENCE (or similar) with nothing after it.
-// This function reduces the boilerplate necessary for stripping the outermost
-// SEQUENCE (or similar) and ensuring that nothing follows it.
-inline Result
-ExpectTagAndGetValueAtEnd(Reader& outer, uint8_t expectedTag,
-                          /*out*/ Reader& inner)
-{
-  Result rv = der::ExpectTagAndGetValue(outer, expectedTag, inner);
-  if (rv != Success) {
-    return rv;
-  }
-  return der::End(outer);
-}
-
-// Similar to the above, but takes an Input instead of a Reader&.
-inline Result
-ExpectTagAndGetValueAtEnd(Input outer, uint8_t expectedTag,
-                          /*out*/ Reader& inner)
-{
-  Reader outerReader(outer);
-  return ExpectTagAndGetValueAtEnd(outerReader, expectedTag, inner);
-}
-
-// Universal types
-
-namespace internal {
-
-enum class IntegralValueRestriction
-{
-  NoRestriction,
-  MustBePositive,
-  MustBe0To127,
-};
-
-Result IntegralBytes(Reader& input, uint8_t tag,
-                     IntegralValueRestriction valueRestriction,
-             /*out*/ Input& value,
-    /*optional out*/ Input::size_type* significantBytes = nullptr);
-
-// This parser will only parse values between 0..127. If this range is
-// increased then callers will need to be changed.
-Result IntegralValue(Reader& input, uint8_t tag, /*out*/ uint8_t& value);
-
-} // namespace internal
-
-Result
-BitStringWithNoUnusedBits(Reader& input, /*out*/ Input& value);
-
-inline Result
-Boolean(Reader& input, /*out*/ bool& value)
-{
-  Reader valueReader;
-  Result rv = ExpectTagAndGetValue(input, BOOLEAN, valueReader);
-  if (rv != Success) {
-    return rv;
-  }
-
-  uint8_t intValue;
-  rv = valueReader.Read(intValue);
-  if (rv != Success) {
-    return rv;
-  }
-  rv = End(valueReader);
-  if (rv != Success) {
-    return rv;
-  }
-  switch (intValue) {
-    case 0: value = false; return Success;
-    case 0xFF: value = true; return Success;
-    default:
-      return Result::ERROR_BAD_DER;
-  }
-}
-
-// This is for BOOLEAN DEFAULT FALSE.
-// The standard stipulates that "The encoding of a set value or sequence value
-// shall not include an encoding for any component value which is equal to its
-// default value." However, it appears to be common that other libraries
-// incorrectly include the value of a BOOLEAN even when it's equal to the
-// default value, so we allow invalid explicit encodings here.
-inline Result
-OptionalBoolean(Reader& input, /*out*/ bool& value)
-{
-  value = false;
-  if (input.Peek(BOOLEAN)) {
-    Result rv = Boolean(input, value);
-    if (rv != Success) {
-      return rv;
-    }
-  }
-  return Success;
-}
-
-// This parser will only parse values between 0..127. If this range is
-// increased then callers will need to be changed.
-inline Result
-Enumerated(Reader& input, uint8_t& value)
-{
-  return internal::IntegralValue(input, ENUMERATED | 0, value);
-}
-
-namespace internal {
-
-// internal::TimeChoice implements the shared functionality of GeneralizedTime
-// and TimeChoice. tag must be either UTCTime or GENERALIZED_TIME.
-//
-// Only times from 1970-01-01-00:00:00 onward are accepted, in order to
-// eliminate the chance for complications in converting times to traditional
-// time formats that start at 1970.
-Result TimeChoice(Reader& input, uint8_t tag, /*out*/ Time& time);
-
-} // namespace internal
-
-// Only times from 1970-01-01-00:00:00 onward are accepted, in order to
-// eliminate the chance for complications in converting times to traditional
-// time formats that start at 1970.
-inline Result
-GeneralizedTime(Reader& input, /*out*/ Time& time)
-{
-  return internal::TimeChoice(input, GENERALIZED_TIME, time);
-}
-
-// Only times from 1970-01-01-00:00:00 onward are accepted, in order to
-// eliminate the chance for complications in converting times to traditional
-// time formats that start at 1970.
-inline Result
-TimeChoice(Reader& input, /*out*/ Time& time)
-{
-  uint8_t expectedTag = input.Peek(UTCTime) ? UTCTime : GENERALIZED_TIME;
-  return internal::TimeChoice(input, expectedTag, time);
-}
-
-// Parse a DER integer value into value. Empty values, negative values, and
-// zero are rejected. If significantBytes is not null, then it will be set to
-// the number of significant bytes in the value (the length of the value, less
-// the length of any leading padding), which is useful for key size checks.
-inline Result
-PositiveInteger(Reader& input, /*out*/ Input& value,
-                /*optional out*/ Input::size_type* significantBytes = nullptr)
-{
-  return internal::IntegralBytes(
-           input, INTEGER, internal::IntegralValueRestriction::MustBePositive,
-           value, significantBytes);
-}
-
-// This parser will only parse values between 0..127. If this range is
-// increased then callers will need to be changed.
-inline Result
-Integer(Reader& input, /*out*/ uint8_t& value)
-{
-  return internal::IntegralValue(input, INTEGER, value);
-}
-
-// This parser will only parse values between 0..127. If this range is
-// increased then callers will need to be changed. The default value must be
-// -1; defaultValue is only a parameter to make it clear in the calling code
-// what the default value is.
-inline Result
-OptionalInteger(Reader& input, long defaultValue, /*out*/ long& value)
-{
-  // If we need to support a different default value in the future, we need to
-  // test that parsedValue != defaultValue.
-  if (defaultValue != -1) {
-    return Result::FATAL_ERROR_INVALID_ARGS;
-  }
-
-  if (!input.Peek(INTEGER)) {
-    value = defaultValue;
-    return Success;
-  }
-
-  uint8_t parsedValue;
-  Result rv = Integer(input, parsedValue);
-  if (rv != Success) {
-    return rv;
-  }
-  value = parsedValue;
-  return Success;
-}
-
-inline Result
-Null(Reader& input)
-{
-  return ExpectTagAndEmptyValue(input, NULLTag);
-}
-
-template <uint8_t Len>
-Result
-OID(Reader& input, const uint8_t (&expectedOid)[Len])
-{
-  Reader value;
-  Result rv = ExpectTagAndGetValue(input, OIDTag, value);
-  if (rv != Success) {
-    return rv;
-  }
-  if (!value.MatchRest(expectedOid)) {
-    return Result::ERROR_BAD_DER;
-  }
-  return Success;
-}
-
-// PKI-specific types
-
-inline Result
-CertificateSerialNumber(Reader& input, /*out*/ Input& value)
-{
-  // http://tools.ietf.org/html/rfc5280#section-4.1.2.2:
-  //
-  // * "The serial number MUST be a positive integer assigned by the CA to
-  //   each certificate."
-  // * "Certificate users MUST be able to handle serialNumber values up to 20
-  //   octets. Conforming CAs MUST NOT use serialNumber values longer than 20
-  //   octets."
-  // * "Note: Non-conforming CAs may issue certificates with serial numbers
-  //   that are negative or zero.  Certificate users SHOULD be prepared to
-  //   gracefully handle such certificates."
-  return internal::IntegralBytes(
-           input, INTEGER, internal::IntegralValueRestriction::NoRestriction,
-           value);
-}
-
-// x.509 and OCSP both use this same version numbering scheme, though OCSP
-// only supports v1.
-enum class Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3, Uninitialized = 255 };
-
-// X.509 Certificate and OCSP ResponseData both use
-// "[0] EXPLICIT Version DEFAULT v1". Although an explicit encoding of v1 is
-// illegal, we support it because some real-world OCSP responses explicitly
-// encode it.
-Result OptionalVersion(Reader& input, /*out*/ Version& version);
-
-template <typename ExtensionHandler>
-inline Result
-OptionalExtensions(Reader& input, uint8_t tag,
-                   ExtensionHandler extensionHandler)
-{
-  if (!input.Peek(tag)) {
-    return Success;
-  }
-
-  return Nested(input, tag, [extensionHandler](Reader& tagged) {
-    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
-    //
-    // TODO(bug 997994): According to the specification, there should never be
-    // an empty sequence of extensions but we've found OCSP responses that have
-    // that (see bug 991898).
-    return NestedOf(tagged, SEQUENCE, SEQUENCE, EmptyAllowed::Yes,
-                    [extensionHandler](Reader& extension) -> Result {
-      // Extension  ::=  SEQUENCE  {
-      //      extnID      OBJECT IDENTIFIER,
-      //      critical    BOOLEAN DEFAULT FALSE,
-      //      extnValue   OCTET STRING
-      //      }
-      Reader extnID;
-      Result rv = ExpectTagAndGetValue(extension, OIDTag, extnID);
-      if (rv != Success) {
-        return rv;
-      }
-      bool critical;
-      rv = OptionalBoolean(extension, critical);
-      if (rv != Success) {
-        return rv;
-      }
-      Input extnValue;
-      rv = ExpectTagAndGetValue(extension, OCTET_STRING, extnValue);
-      if (rv != Success) {
-        return rv;
-      }
-      bool understood = false;
-      rv = extensionHandler(extnID, extnValue, critical, understood);
-      if (rv != Success) {
-        return rv;
-      }
-      if (critical && !understood) {
-        return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION;
-      }
-      return Success;
-    });
-  });
-}
-
-Result DigestAlgorithmIdentifier(Reader& input,
-                                 /*out*/ DigestAlgorithm& algorithm);
-
-enum class PublicKeyAlgorithm
-{
-  RSA_PKCS1,
-  ECDSA,
-  Uninitialized
-};
-
-Result SignatureAlgorithmIdentifierValue(
-         Reader& input,
-         /*out*/ PublicKeyAlgorithm& publicKeyAlgorithm,
-         /*out*/ DigestAlgorithm& digestAlgorithm);
-
-struct SignedDataWithSignature final
-{
-public:
-  Input data;
-  Input algorithm;
-  Input signature;
-
-  void operator=(const SignedDataWithSignature&) = delete;
-};
-
-// Parses a SEQUENCE into tbs and then parses an AlgorithmIdentifier followed
-// by a BIT STRING into signedData. This handles the commonality between
-// parsing the signed/signature fields of certificates and OCSP responses. In
-// the case of an OCSP response, the caller needs to parse the certs
-// separately.
-//
-// Note that signatureAlgorithm is NOT parsed or validated.
-//
-// Certificate  ::=  SEQUENCE  {
-//        tbsCertificate       TBSCertificate,
-//        signatureAlgorithm   AlgorithmIdentifier,
-//        signatureValue       BIT STRING  }
-//
-// BasicOCSPResponse       ::= SEQUENCE {
-//    tbsResponseData      ResponseData,
-//    signatureAlgorithm   AlgorithmIdentifier,
-//    signature            BIT STRING,
-//    certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
-Result SignedData(Reader& input, /*out*/ Reader& tbs,
-                  /*out*/ SignedDataWithSignature& signedDataWithSignature);
-
-} } } // namespace mozilla::pkix::der
-
-#endif // mozilla_pkix_pkixder_h
deleted file mode 100644
--- a/security/pkix/lib/pkixnames.cpp
+++ /dev/null
@@ -1,2050 +0,0 @@
-/* -*- 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 code is made available to you under your choice of the following sets
- * of licensing terms:
- */
-/* 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/.
- */
-/* Copyright 2014 Mozilla Contributors
- *