dumpGoogleRoots.js (3058B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 "use strict"; 5 6 // This file is a helper script that generates the list of certificates that 7 // make up the preloaded pinset for Google properties. 8 // 9 // How to run this file: 10 // 1. [obtain firefox source code] 11 // 2. [build/obtain firefox binaries] 12 // 3. run `[path to]/firefox -xpcshell dumpGoogleRoots.js' 13 // 4. [paste the output into the appropriate section in 14 // security/manager/tools/PreloadedHPKPins.json] 15 16 Services.prefs.setBoolPref("network.process.enabled", false); 17 Services.prefs.setBoolPref("network.xhr.block_sync_system_requests", false); 18 19 function downloadRoots() { 20 let req = new XMLHttpRequest(); 21 req.open("GET", "https://pki.google.com/roots.pem", false); 22 try { 23 req.send(); 24 } catch (e) { 25 throw new Error("ERROR: problem downloading Google Root PEMs: " + e); 26 } 27 28 if (req.status != 200) { 29 throw new Error( 30 "ERROR: problem downloading Google Root PEMs. Status: " + req.status 31 ); 32 } 33 34 let pem = req.responseText; 35 let roots = []; 36 let currentPEM = ""; 37 let readingRoot = false; 38 let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( 39 Ci.nsIX509CertDB 40 ); 41 for (let line of pem.split(/[\r\n]/)) { 42 if (line == "-----END CERTIFICATE-----") { 43 if (currentPEM) { 44 roots.push(certDB.constructX509FromBase64(currentPEM)); 45 } 46 currentPEM = ""; 47 readingRoot = false; 48 continue; 49 } 50 if (readingRoot) { 51 currentPEM += line; 52 } 53 if (line == "-----BEGIN CERTIFICATE-----") { 54 readingRoot = true; 55 } 56 } 57 return roots; 58 } 59 60 function makeFormattedNickname(cert, knownNicknames) { 61 if (cert.displayName in knownNicknames) { 62 return `"${cert.displayName}"`; 63 } 64 // Otherwise, this isn't a built-in and we have to comment it out. 65 return `// "${cert.displayName}"`; 66 } 67 68 function gatherKnownNicknames() { 69 let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( 70 Ci.nsIX509CertDB 71 ); 72 let nicknames = {}; 73 for (let cert of certDB.getCerts()) { 74 nicknames[cert.displayName] = true; 75 } 76 return nicknames; 77 } 78 79 var knownNicknames = gatherKnownNicknames(); 80 var roots = downloadRoots(); 81 var rootNicknames = []; 82 for (var root of roots) { 83 rootNicknames.push(makeFormattedNickname(root, knownNicknames)); 84 } 85 rootNicknames.sort(function (rootA, rootB) { 86 let rootALowercase = rootA.toLowerCase().replace(/(^[^"]*")|"/g, ""); 87 let rootBLowercase = rootB.toLowerCase().replace(/(^[^"]*")|"/g, ""); 88 if (rootALowercase < rootBLowercase) { 89 return -1; 90 } 91 if (rootALowercase > rootBLowercase) { 92 return 1; 93 } 94 return 0; 95 }); 96 dump(" {\n"); 97 dump(' "name": "google_root_pems",\n'); 98 dump(' "sha256_hashes": [\n'); 99 var first = true; 100 for (var nickname of rootNicknames) { 101 if (!first) { 102 dump(",\n"); 103 } 104 first = false; 105 dump(" " + nickname); 106 } 107 dump("\n"); 108 dump(" ]\n"); 109 dump(" }\n");