bug 1232766 - update the preloaded pinset for Google domains r?rbarnes
Also includes a script for making this process faster in the future.
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -46,16 +46,20 @@ static const char kBaltimore_CyberTrust_
/* COMODO Certification Authority */
static const char kCOMODO_Certification_AuthorityFingerprint[] =
"AG1751Vd2CAmRCxPGieoDomhmJy4ezREjtIZTBgZbV4=";
/* COMODO ECC Certification Authority */
static const char kCOMODO_ECC_Certification_AuthorityFingerprint[] =
"58qRu/uxh4gFezqAcERupSkRYBlBAvfcw7mEjGPLnNU=";
+/* COMODO RSA Certification Authority */
+static const char kCOMODO_RSA_Certification_AuthorityFingerprint[] =
+ "grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=";
+
/* Comodo AAA Services root */
static const char kComodo_AAA_Services_rootFingerprint[] =
"vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=";
/* Comodo Secure Services root */
static const char kComodo_Secure_Services_rootFingerprint[] =
"RpHL/ehKa2BS3b4VK7DCFq4lqG5XR4E9vA8UfzOFcL4=";
@@ -66,24 +70,44 @@ static const char kComodo_Trusted_Servic
/* Cybertrust Global Root */
static const char kCybertrust_Global_RootFingerprint[] =
"foeCwVDOOVL4AuY2AjpdPpW7XWjjPoWtsroXgSXOvxU=";
/* DigiCert Assured ID Root CA */
static const char kDigiCert_Assured_ID_Root_CAFingerprint[] =
"I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o=";
+/* DigiCert Assured ID Root G2 */
+static const char kDigiCert_Assured_ID_Root_G2Fingerprint[] =
+ "8ca6Zwz8iOTfUpc8rkIPCgid1HQUT+WAbEIAZOFZEik=";
+
+/* DigiCert Assured ID Root G3 */
+static const char kDigiCert_Assured_ID_Root_G3Fingerprint[] =
+ "Fe7TOVlLME+M+Ee0dzcdjW/sYfTbKwGvWJ58U7Ncrkw=";
+
/* DigiCert Global Root CA */
static const char kDigiCert_Global_Root_CAFingerprint[] =
"r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
+/* DigiCert Global Root G2 */
+static const char kDigiCert_Global_Root_G2Fingerprint[] =
+ "i7WTqTvh0OioIruIfFR4kMPnBqrS2rdiVPl/s2uC/CY=";
+
+/* DigiCert Global Root G3 */
+static const char kDigiCert_Global_Root_G3Fingerprint[] =
+ "uUwZgwDOxcBXrQcntwu+kYFpkiVkOaezL0WYEZ3anJc=";
+
/* DigiCert High Assurance EV Root CA */
static const char kDigiCert_High_Assurance_EV_Root_CAFingerprint[] =
"WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
+/* DigiCert Trusted Root G4 */
+static const char kDigiCert_Trusted_Root_G4Fingerprint[] =
+ "Wd8xe/qfTwq3ylFNd3IpaqLHZbh2ZNCLluVzmeNkcpw=";
+
/* End Entity Test Cert */
static const char kEnd_Entity_Test_CertFingerprint[] =
"VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=";
/* Entrust Root Certification Authority */
static const char kEntrust_Root_Certification_AuthorityFingerprint[] =
"bb+uANN7nNc/j7R95lkXrwDg3d9C286sIMF8AnXuIJU=";
@@ -98,24 +122,16 @@ static const char kEntrust_Root_Certific
/* Entrust.net Premium 2048 Secure Server CA */
static const char kEntrust_net_Premium_2048_Secure_Server_CAFingerprint[] =
"HqPF5D7WbC2imDpCpKebHpBnhs6fG1hiFBmgBGOofTg=";
/* Equifax Secure CA */
static const char kEquifax_Secure_CAFingerprint[] =
"/1aAzXOlcD2gSBegdf1GJQanNQbEuBoVg+9UlHjSZHY=";
-/* Equifax Secure Global eBusiness CA */
-static const char kEquifax_Secure_Global_eBusiness_CAFingerprint[] =
- "pvH5v4oKndwID7SbHvw9GhwsMtwOE2pbAMlzFvKj3BE=";
-
-/* Equifax Secure eBusiness CA 1 */
-static const char kEquifax_Secure_eBusiness_CA_1Fingerprint[] =
- "JsGNxu6m9jL2drzrodjCtINS8pwtX82oeOCdy4Mt1uU=";
-
/* FacebookBackup */
static const char kFacebookBackupFingerprint[] =
"q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ=";
/* GOOGLE_PIN_DigiCertECCSecureServerCA */
static const char kGOOGLE_PIN_DigiCertECCSecureServerCAFingerprint[] =
"PZXN3lRAy+8tBKk2Ox6F7jIlnzr2Yzmwqc3JnyfXoCw=";
@@ -186,16 +202,24 @@ static const char kGeoTrust_Primary_Cert
/* GeoTrust Universal CA */
static const char kGeoTrust_Universal_CAFingerprint[] =
"lpkiXF3lLlbN0y3y6W0c/qWqPKC7Us2JM8I7XCdEOCA=";
/* GeoTrust Universal CA 2 */
static const char kGeoTrust_Universal_CA_2Fingerprint[] =
"fKoDRlEkWQxgHlZ+UhSOlSwM/+iQAFMP4NlbbVDqrkE=";
+/* GlobalSign ECC Root CA - R4 */
+static const char kGlobalSign_ECC_Root_CA___R4Fingerprint[] =
+ "CLOmM1/OXvSPjw5UOYbAf9GKOxImEp9hhku9W90fHMk=";
+
+/* GlobalSign ECC Root CA - R5 */
+static const char kGlobalSign_ECC_Root_CA___R5Fingerprint[] =
+ "fg6tdrtoGdwvVFEahDVPboswe53YIFjqbABPAdndpd8=";
+
/* GlobalSign Root CA */
static const char kGlobalSign_Root_CAFingerprint[] =
"K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q=";
/* GlobalSign Root CA - R2 */
static const char kGlobalSign_Root_CA___R2Fingerprint[] =
"iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0=";
@@ -210,52 +234,32 @@ static const char kGo_Daddy_Class_2_CAFi
/* Go Daddy Root Certificate Authority - G2 */
static const char kGo_Daddy_Root_Certificate_Authority___G2Fingerprint[] =
"Ko8tivDrEjiY90yGasP6ZpBU4jwXvHqVvQI0GS3GNdA=";
/* GoogleBackup2048 */
static const char kGoogleBackup2048Fingerprint[] =
"IPMbDAjLVSGntGO3WP53X/zilCVndez5YJ2+vJvhJsA=";
-/* Network Solutions Certificate Authority */
-static const char kNetwork_Solutions_Certificate_AuthorityFingerprint[] =
- "MtGA7THJNVieydu7ciEjuIO1/C3BD5/KOpXXfhv8tTQ=";
-
/* SpiderOak2 */
static const char kSpiderOak2Fingerprint[] =
"7Y3UnxbffL8aFPXsOJBpGasgpDmngpIhAxGKdQRklQQ=";
/* SpiderOak3 */
static const char kSpiderOak3Fingerprint[] =
"LkER54vOdlygpTsbYvlpMq1CE/lDAG1AP9xmdtwvV2A=";
/* Starfield Class 2 CA */
static const char kStarfield_Class_2_CAFingerprint[] =
"FfFKxFycfaIz00eRZOgTf+Ne4POK6FgYPwhBDqgqxLQ=";
/* Starfield Root Certificate Authority - G2 */
static const char kStarfield_Root_Certificate_Authority___G2Fingerprint[] =
"gI1os/q0iEpflxrOfRBVDXqVoWN3Tz7Dav/7IT++THQ=";
-/* Starfield Services Root Certificate Authority - G2 */
-static const char kStarfield_Services_Root_Certificate_Authority___G2Fingerprint[] =
- "KwccWaCgrnaw6tsrrSO61FgLacNgG2MMLq8GE6+oP5I=";
-
-/* StartCom Certification Authority */
-static const char kStartCom_Certification_AuthorityFingerprint[] =
- "5C8kvU039KouVrl52D0eZSGf4Onjo4Khs8tmyTlV3nU=";
-
-/* StartCom Certification Authority G2 */
-static const char kStartCom_Certification_Authority_G2Fingerprint[] =
- "FSg5faISiQqDCwuVpZlozvI0dzd531GBzxD6ZHU0u2U=";
-
-/* TC TrustCenter Class 3 CA II */
-static const char kTC_TrustCenter_Class_3_CA_IIFingerprint[] =
- "k5KuIUmSSt435kXbof9L3dzaKykbYJdmnSr6XHo3Jhk=";
-
/* TestSPKI */
static const char kTestSPKIFingerprint[] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
/* Tor1 */
static const char kTor1Fingerprint[] =
"bYz9JTDk89X3qu3fgswG+lBQso5vI0N1f0Rx4go4nLo=";
@@ -266,16 +270,24 @@ static const char kTor2Fingerprint[] =
/* Tor3 */
static const char kTor3Fingerprint[] =
"CleC1qwUR8JPgH1nXvSe2VHxDe5/KfNs96EusbfSOfo=";
/* Twitter1 */
static const char kTwitter1Fingerprint[] =
"vU9M48LzD/CF34wE5PPf4nBwRyosy06X21J0ap8yS5s=";
+/* USERTrust ECC Certification Authority */
+static const char kUSERTrust_ECC_Certification_AuthorityFingerprint[] =
+ "ICGRfpgmOUXIWcQ/HXPLQTkFPEFPoDyjvH7ohhQpjzs=";
+
+/* USERTrust RSA Certification Authority */
+static const char kUSERTrust_RSA_Certification_AuthorityFingerprint[] =
+ "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=";
+
/* UTN USERFirst Email Root CA */
static const char kUTN_USERFirst_Email_Root_CAFingerprint[] =
"Laj56jRU0hFGRko/nQKNxMf7tXscUsc8KwVyovWZotM=";
/* UTN USERFirst Hardware Root CA */
static const char kUTN_USERFirst_Hardware_Root_CAFingerprint[] =
"TUDnr0MEoJ3of7+YliBMBVFB4/gJsv5zO7IxD9+YoWI=";
@@ -306,32 +318,24 @@ static const char kVerisign_Class_1_Publ
/* Verisign Class 2 Public Primary Certification Authority - G2 */
static const char kVerisign_Class_2_Public_Primary_Certification_Authority___G2Fingerprint[] =
"2oALgLKofTmeZvoZ1y/fSZg7R9jPMix8eVA6DH4o/q8=";
/* Verisign Class 2 Public Primary Certification Authority - G3 */
static const char kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint[] =
"cAajgxHlj7GTSEIzIYIQxmEloOSoJq7VOaxWHfv72QM=";
-/* Verisign Class 3 Public Primary Certification Authority */
-static const char kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint[] =
- "sRJBQqWhpaKIGcc1NA7/jJ4vgWj+47oYfyU7waOS1+I=";
-
/* Verisign Class 3 Public Primary Certification Authority - G2 */
static const char kVerisign_Class_3_Public_Primary_Certification_Authority___G2Fingerprint[] =
"AjyBzOjnxk+pQtPBUEhwfTXZu1uH9PVExb8bxWQ68vo=";
/* Verisign Class 3 Public Primary Certification Authority - G3 */
static const char kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint[] =
"SVqWumuteCQHvVIaALrOZXuzVVVeS7f4FGxxu6V+es4=";
-/* XRamp Global CA Root */
-static const char kXRamp_Global_CA_RootFingerprint[] =
- "BRz5+pXkDpuD7a7aaWH2Fox4ecRmAXJHnN1RqwPOpis=";
-
/* YahooBackup1 */
static const char kYahooBackup1Fingerprint[] =
"2fRAUXyxl4A1/XHrKNBmc8bTkzA7y4FB/GLJuNAzCqY=";
/* YahooBackup2 */
static const char kYahooBackup2Fingerprint[] =
"dolnbtzEBnELx/9lOEQ22e6OZO/QNb6VSSX2XHA3E7A=";
@@ -356,69 +360,69 @@ struct StaticFingerprints {
struct StaticPinset {
const StaticFingerprints* sha1;
const StaticFingerprints* sha256;
};
/* PreloadedHPKPins.json pinsets */
static const char* kPinset_google_root_pems_sha256_Data[] = {
kEquifax_Secure_CAFingerprint,
+ kEntrust_Root_Certification_Authority___EC1Fingerprint,
kComodo_Trusted_Services_rootFingerprint,
kCOMODO_ECC_Certification_AuthorityFingerprint,
- kStartCom_Certification_AuthorityFingerprint,
- kStartCom_Certification_AuthorityFingerprint,
+ kDigiCert_Assured_ID_Root_G2Fingerprint,
kCOMODO_Certification_AuthorityFingerprint,
- kVerisign_Class_3_Public_Primary_Certification_Authority___G2Fingerprint,
- kXRamp_Global_CA_RootFingerprint,
kAddTrust_Low_Value_Services_RootFingerprint,
+ kGlobalSign_ECC_Root_CA___R4Fingerprint,
kGeoTrust_Global_CA_2Fingerprint,
- kStartCom_Certification_Authority_G2Fingerprint,
+ kDigiCert_Assured_ID_Root_G3Fingerprint,
kStarfield_Class_2_CAFingerprint,
kthawte_Primary_Root_CA___G3Fingerprint,
kthawte_Primary_Root_CAFingerprint,
kEntrust_net_Premium_2048_Secure_Server_CAFingerprint,
kDigiCert_Assured_ID_Root_CAFingerprint,
+ kUSERTrust_ECC_Certification_AuthorityFingerprint,
kVeriSign_Class_3_Public_Primary_Certification_Authority___G5Fingerprint,
- kEquifax_Secure_eBusiness_CA_1Fingerprint,
kGlobalSign_Root_CAFingerprint,
kGo_Daddy_Root_Certificate_Authority___G2Fingerprint,
- kStarfield_Services_Root_Certificate_Authority___G2Fingerprint,
kAffirmTrust_Premium_ECCFingerprint,
- kNetwork_Solutions_Certificate_AuthorityFingerprint,
kAddTrust_Public_Services_RootFingerprint,
kComodo_Secure_Services_rootFingerprint,
kGeoTrust_Primary_Certification_AuthorityFingerprint,
kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
kUTN_USERFirst_Hardware_Root_CAFingerprint,
kVeriSign_Class_3_Public_Primary_Certification_Authority___G4Fingerprint,
kGo_Daddy_Class_2_CAFingerprint,
+ kDigiCert_Trusted_Root_G4Fingerprint,
kDigiCert_High_Assurance_EV_Root_CAFingerprint,
kBaltimore_CyberTrust_RootFingerprint,
kthawte_Primary_Root_CA___G2Fingerprint,
kAffirmTrust_CommercialFingerprint,
kEntrust_Root_Certification_AuthorityFingerprint,
kGlobalSign_Root_CA___R3Fingerprint,
+ kEntrust_Root_Certification_Authority___G2Fingerprint,
kGeoTrust_Universal_CA_2Fingerprint,
+ kGlobalSign_ECC_Root_CA___R5Fingerprint,
kCybertrust_Global_RootFingerprint,
kStarfield_Root_Certificate_Authority___G2Fingerprint,
+ kCOMODO_RSA_Certification_AuthorityFingerprint,
kGeoTrust_Global_CAFingerprint,
+ kDigiCert_Global_Root_G2Fingerprint,
kGlobalSign_Root_CA___R2Fingerprint,
- kTC_TrustCenter_Class_3_CA_IIFingerprint,
kAffirmTrust_NetworkingFingerprint,
kAddTrust_External_RootFingerprint,
kVeriSign_Universal_Root_Certification_AuthorityFingerprint,
kGeoTrust_Universal_CAFingerprint,
- kEquifax_Secure_Global_eBusiness_CAFingerprint,
kGeoTrust_Primary_Certification_Authority___G3Fingerprint,
kDigiCert_Global_Root_CAFingerprint,
- kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint,
- kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint,
+ kDigiCert_Global_Root_G3Fingerprint,
kGeoTrust_Primary_Certification_Authority___G2Fingerprint,
kComodo_AAA_Services_rootFingerprint,
kAffirmTrust_PremiumFingerprint,
+ kUSERTrust_RSA_Certification_AuthorityFingerprint,
kAddTrust_Qualified_Certificates_RootFingerprint,
};
static const StaticFingerprints kPinset_google_root_pems_sha256 = {
sizeof(kPinset_google_root_pems_sha256_Data) / sizeof(const char*),
kPinset_google_root_pems_sha256_Data
};
static const StaticPinset kPinset_google_root_pems = {
@@ -1171,9 +1175,9 @@ static const TransportSecurityPreload kP
{ "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
{ "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
};
// Pinning Preload List Length = 450;
static const int32_t kUnknownId = -1;
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1460202914164000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1460495519231000);
--- a/security/manager/tools/PreloadedHPKPins.json
+++ b/security/manager/tools/PreloadedHPKPins.json
@@ -125,76 +125,63 @@
"AddTrust External Root",
"AddTrust Low-Value Services Root",
"AddTrust Public Services Root",
"AddTrust Qualified Certificates Root",
"AffirmTrust Commercial",
"AffirmTrust Networking",
"AffirmTrust Premium",
"AffirmTrust Premium ECC",
- // "America Online Root Certification Authority 1",
- // "America Online Root Certification Authority 2",
"Baltimore CyberTrust Root",
"Comodo AAA Services root",
"COMODO Certification Authority",
"COMODO ECC Certification Authority",
+ "COMODO RSA Certification Authority",
"Comodo Secure Services root",
"Comodo Trusted Services root",
"Cybertrust Global Root",
"DigiCert Assured ID Root CA",
+ "DigiCert Assured ID Root G2",
+ "DigiCert Assured ID Root G3",
"DigiCert Global Root CA",
+ "DigiCert Global Root G2",
+ "DigiCert Global Root G3",
"DigiCert High Assurance EV Root CA",
- "Entrust.net Premium 2048 Secure Server CA",
- // "Entrust.net Secure Server CA",
+ "DigiCert Trusted Root G4",
"Entrust Root Certification Authority",
+ "Entrust Root Certification Authority - EC1",
+ "Entrust Root Certification Authority - G2",
+ "Entrust.net Premium 2048 Secure Server CA",
"Equifax Secure CA",
- "Equifax Secure eBusiness CA 1",
- // "Equifax Secure eBusiness CA 2",
- "Equifax Secure Global eBusiness CA",
"GeoTrust Global CA",
"GeoTrust Global CA 2",
"GeoTrust Primary Certification Authority",
"GeoTrust Primary Certification Authority - G2",
"GeoTrust Primary Certification Authority - G3",
"GeoTrust Universal CA",
"GeoTrust Universal CA 2",
+ "GlobalSign ECC Root CA - R4",
+ "GlobalSign ECC Root CA - R5",
"GlobalSign Root CA",
"GlobalSign Root CA - R2",
"GlobalSign Root CA - R3",
"Go Daddy Class 2 CA",
"Go Daddy Root Certificate Authority - G2",
- // "GTE CyberTrust Global Root",
- "Network Solutions Certificate Authority",
- // "RSA Root Certificate 1",
"Starfield Class 2 CA",
"Starfield Root Certificate Authority - G2",
- "Starfield Services Root Certificate Authority - G2",
- "StartCom Certification Authority",
- "StartCom Certification Authority",
- "StartCom Certification Authority G2",
- "TC TrustCenter Class 3 CA II",
- // "TC TrustCenter Universal CA III",
- // "Thawte Premium Server CA",
"thawte Primary Root CA",
"thawte Primary Root CA - G2",
"thawte Primary Root CA - G3",
- // "Thawte Server CA",
- // "UTN DATACorp SGC Root CA",
+ "USERTrust ECC Certification Authority",
+ "USERTrust RSA Certification Authority",
"UTN USERFirst Hardware Root CA",
- // "ValiCert Class 1 VA",
- // "ValiCert Class 2 VA",
- "Verisign Class 3 Public Primary Certification Authority",
- "Verisign Class 3 Public Primary Certification Authority",
- "Verisign Class 3 Public Primary Certification Authority - G2",
"Verisign Class 3 Public Primary Certification Authority - G3",
"VeriSign Class 3 Public Primary Certification Authority - G4",
"VeriSign Class 3 Public Primary Certification Authority - G5",
- // "Verisign Class 4 Public Primary Certification Authority - G3",
- "VeriSign Universal Root Certification Authority",
- "XRamp Global CA Root"
+ "VeriSign Universal Root Certification Authority"
]
}
],
"entries": [
// Only domains that are operationally crucial to Firefox can have per-host
// telemetry reporting (the "id") field
{ "name": "addons.mozilla.org", "include_subdomains": true,
new file mode 100644
--- /dev/null
+++ b/security/manager/tools/dumpGoogleRoots.js
@@ -0,0 +1,89 @@
+/* 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/. */
+
+// 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]
+
+// <https://developer.mozilla.org/en/XPConnect/xpcshell/HOWTO>
+// <https://bugzilla.mozilla.org/show_bug.cgi?id=546628>
+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 "ERROR: problem downloading Google Root PEMs: " + e;
+ }
+
+ if (req.status != 200) {
+ throw "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;
+}
+
+var roots = downloadRoots();
+var rootNicknames = [];
+for (var root of roots) {
+ rootNicknames.push(root.nickname.substring("Builtin Object Token:".length));
+}
+rootNicknames.sort(function(rootA, rootB) {
+ let rootALowercase = rootA.toLowerCase();
+ let rootBLowercase = rootB.toLowerCase();
+ 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");