summaryrefslogtreecommitdiffstats
path: root/security/manager/tools/dumpGoogleRoots.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/tools/dumpGoogleRoots.js')
-rw-r--r--security/manager/tools/dumpGoogleRoots.js106
1 files changed, 106 insertions, 0 deletions
diff --git a/security/manager/tools/dumpGoogleRoots.js b/security/manager/tools/dumpGoogleRoots.js
new file mode 100644
index 000000000..2daa20434
--- /dev/null
+++ b/security/manager/tools/dumpGoogleRoots.js
@@ -0,0 +1,106 @@
+/* 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";
+
+// This file is a helper script that generates the list of certificates that
+// make up the preloaded pinset for Google properties.
+//
+// How to run this file:
+// 1. [obtain firefox source code]
+// 2. [build/obtain firefox binaries]
+// 3. run `[path to]/run-mozilla.sh [path to]/xpcshell dumpGoogleRoots.js'
+// 4. [paste the output into the appropriate section in
+// security/manager/tools/PreloadedHPKPins.json]
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function downloadRoots() {
+ let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+ .createInstance(Ci.nsIXMLHttpRequest);
+ req.open("GET", "https://pki.google.com/roots.pem", false);
+ try {
+ req.send();
+ }
+ catch (e) {
+ throw new Error("ERROR: problem downloading Google Root PEMs: " + e);
+ }
+
+ if (req.status != 200) {
+ throw new Error("ERROR: problem downloading Google Root PEMs. Status: " +
+ req.status);
+ }
+
+ let pem = req.responseText;
+ let roots = [];
+ let currentPEM = "";
+ let readingRoot = false;
+ let certDB = Cc["@mozilla.org/security/x509certdb;1"]
+ .getService(Ci.nsIX509CertDB);
+ for (let line of pem.split(/[\r\n]/)) {
+ if (line == "-----END CERTIFICATE-----") {
+ if (currentPEM) {
+ roots.push(certDB.constructX509FromBase64(currentPEM));
+ }
+ currentPEM = "";
+ readingRoot = false;
+ continue;
+ }
+ if (readingRoot) {
+ currentPEM += line;
+ }
+ if (line == "-----BEGIN CERTIFICATE-----") {
+ readingRoot = true;
+ }
+ }
+ return roots;
+}
+
+function makeFormattedNickname(cert) {
+ if (cert.nickname.startsWith("Builtin Object Token:")) {
+ return `"${cert.nickname.substring("Builtin Object Token:".length)}"`;
+ }
+ // Otherwise, this isn't a built-in and we have to comment it out.
+ if (cert.commonName) {
+ return `// "${cert.commonName}"`;
+ }
+ if (cert.organizationalUnit) {
+ return `// "${cert.organizationalUnit}"`;
+ }
+ if (cert.organization) {
+ return `// "${cert.organization}"`;
+ }
+ throw new Error(`couldn't make nickname for ${cert.subjectName}`);
+}
+
+var roots = downloadRoots();
+var rootNicknames = [];
+for (var root of roots) {
+ rootNicknames.push(makeFormattedNickname(root));
+}
+rootNicknames.sort(function(rootA, rootB) {
+ let rootALowercase = rootA.toLowerCase().replace(/(^[^"]*")|"/g, "");
+ let rootBLowercase = rootB.toLowerCase().replace(/(^[^"]*")|"/g, "");
+ if (rootALowercase < rootBLowercase) {
+ return -1;
+ }
+ if (rootALowercase > rootBLowercase) {
+ return 1;
+ }
+ return 0;
+});
+dump(" {\n");
+dump(" \"name\": \"google_root_pems\",\n");
+dump(" \"sha256_hashes\": [\n");
+var first = true;
+for (var nickname of rootNicknames) {
+ if (!first) {
+ dump(",\n");
+ }
+ first = false;
+ dump(" " + nickname);
+}
+dump("\n");
+dump(" ]\n");
+dump(" }\n");