summaryrefslogtreecommitdiff
path: root/system/security/manager/tools
diff options
context:
space:
mode:
Diffstat (limited to 'system/security/manager/tools')
-rw-r--r--system/security/manager/tools/.eslintrc.js9
-rw-r--r--system/security/manager/tools/KnownRootHashes.json949
-rw-r--r--system/security/manager/tools/dumpGoogleRoots.js106
-rw-r--r--system/security/manager/tools/genRootCAHashes.js255
-rw-r--r--system/security/manager/tools/makeCNNICHashes.js282
5 files changed, 1601 insertions, 0 deletions
diff --git a/system/security/manager/tools/.eslintrc.js b/system/security/manager/tools/.eslintrc.js
new file mode 100644
index 000000000..49de9eadd
--- /dev/null
+++ b/system/security/manager/tools/.eslintrc.js
@@ -0,0 +1,9 @@
+"use strict";
+
+module.exports = { // eslint-disable-line no-undef
+ "globals": {
+ // JS files in this folder are commonly xpcshell scripts where |arguments|
+ // is defined in the global scope.
+ "arguments": false
+ }
+};
diff --git a/system/security/manager/tools/KnownRootHashes.json b/system/security/manager/tools/KnownRootHashes.json
new file mode 100644
index 000000000..81adeb653
--- /dev/null
+++ b/system/security/manager/tools/KnownRootHashes.json
@@ -0,0 +1,949 @@
+// 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 is an automatically generated file. It's used to maintain state for
+// runs of genRootCAHashes.js; you should never need to manually edit it
+//***************************************************************************
+
+{
+ "roots": [
+ {
+ "label": "GTE_CyberTrust_Global_Root",
+ "binNumber": 1,
+ "sha256Fingerprint": "pTElGI0hEKqWSwLHt8baMgMXCJTl+3H/+2Zn1eaBCjY="
+ },
+ {
+ "label": "Thawte_Server_CA",
+ "binNumber": 2,
+ "sha256Fingerprint": "tEELc+Lm6spH+8Qvj6QBivQ4HcVM+qhEUEYe7QlFTek="
+ },
+ {
+ "label": "Thawte_Premium_Server_CA",
+ "binNumber": 3,
+ "sha256Fingerprint": "q3A2NlxxVKopwsKfXUGRFjsWKiIlARNX1W0H/6e8H3I="
+ },
+ {
+ "label": "OU_Equifax_Secure_Certificate_Authority_O_Equifax_C_US",
+ "binNumber": 4,
+ "sha256Fingerprint": "CCl6QEfbojaAxzHbbjF2U8p4SOG+vToLAXmnB/ks8Xg="
+ },
+ {
+ "label": "OU_VeriSign_Trust_Network_OU___c__1998_VeriSign__Inc____For_authorized_use_only__OU_Class_3_Public_Primary_Certification_Authority___G2_O__VeriSign__Inc___C_US",
+ "binNumber": 5,
+ "sha256Fingerprint": "g848Eiloilk9SF+BlzwPkZVDHto3zF42Qw55x6iIY4s="
+ },
+ {
+ "label": "GlobalSign_Root_CA",
+ "binNumber": 6,
+ "sha256Fingerprint": "69QQQOS7PsdCyeOB0x7ypBpItmhclufO88HfbNQzHJk="
+ },
+ {
+ "label": "GlobalSign",
+ "binNumber": 7,
+ "sha256Fingerprint": "ykLdQXRf0LgeuQI2LPnYv3Gdob0bHvyUb1tMmfQsG54="
+ },
+ {
+ "label": "VeriSign_Class_3_Public_Primary_Certification_Authority___G3",
+ "binNumber": 8,
+ "sha256Fingerprint": "6wTPXrHzmvp2LyuxIPKWy6Ugwbl9sViVZbgcuaF7ckQ="
+ },
+ {
+ "label": "VeriSign_Class_4_Public_Primary_Certification_Authority___G3",
+ "binNumber": 9,
+ "sha256Fingerprint": "44k2DQ/brrPSUFhLRzAxTiIvOcFWoCAUTo2WBWF5FQY="
+ },
+ {
+ "label": "Entrust_net_Certification_Authority__2048_",
+ "binNumber": 10,
+ "sha256Fingerprint": "bcRxcuAcvLC/YlgNiV/iuKya1PhzgB4MELnIN9IesXc="
+ },
+ {
+ "label": "Baltimore_CyberTrust_Root",
+ "binNumber": 11,
+ "sha256Fingerprint": "Fq9XqfZ2sKsSYJWqXrre8iqzERnWRKyVzUuT2/Pyaus="
+ },
+ {
+ "label": "Equifax_Secure_Global_eBusiness_CA_1",
+ "binNumber": 12,
+ "sha256Fingerprint": "Xwti6rXjU+plIWUWWPu2U1n0QygKSvvRBNd9EPnwTAc="
+ },
+ {
+ "label": "Equifax_Secure_eBusiness_CA_1",
+ "binNumber": 13,
+ "sha256Fingerprint": "z1b/RqShhhCd2WWEte61ilEMQnWw5flPQLuuhl4Z9nM="
+ },
+ {
+ "label": "AddTrust_Class_1_CA_Root",
+ "binNumber": 14,
+ "sha256Fingerprint": "jHIJJ5rATideFtB/07d16AFUtZaARuMfUt0ldmMk6ac="
+ },
+ {
+ "label": "AddTrust_External_CA_Root",
+ "binNumber": 15,
+ "sha256Fingerprint": "aH+kUTgieP/wyLEfjUPVdmccbrK86rQT+4PZZdBtL/I="
+ },
+ {
+ "label": "AddTrust_Public_CA_Root",
+ "binNumber": 16,
+ "sha256Fingerprint": "B5HKB0myB4Kq08fXvQzfyUhYNYQ+steZYAnOQ6tsaSc="
+ },
+ {
+ "label": "AddTrust_Qualified_CA_Root",
+ "binNumber": 17,
+ "sha256Fingerprint": "gJUhCAXbS7w1XkQo2P1uws3jq1+5eplCmI649NzQYBY="
+ },
+ {
+ "label": "Entrust_Root_Certification_Authority",
+ "binNumber": 18,
+ "sha256Fingerprint": "c8F2Q08bxtWt9FsOducnKHyN5XYWwebmFBorLLx9jkw="
+ },
+ {
+ "label": "OU_RSA_Security_2048_V3_O_RSA_Security_Inc",
+ "binNumber": 19,
+ "sha256Fingerprint": "r4tnYqHlKCKBYaldXFWe4mYnj3XXnoMBiaUDUGq9a0w="
+ },
+ {
+ "label": "GeoTrust_Global_CA",
+ "binNumber": 20,
+ "sha256Fingerprint": "/4VqLSUdzYjTZlb0UBJnmM+rqt5AeZxyLeTStds2pzo="
+ },
+ {
+ "label": "GeoTrust_Global_CA_2",
+ "binNumber": 21,
+ "sha256Fingerprint": "yi2CoIZ3By+KtnZP8DVnbP4+XjJeASFy3z+SCW23m4U="
+ },
+ {
+ "label": "GeoTrust_Universal_CA",
+ "binNumber": 22,
+ "sha256Fingerprint": "oEWbn2OyJVn1+l1MbbP59y/xk0IDNXjwc78dG0bLuRI="
+ },
+ {
+ "label": "GeoTrust_Universal_CA_2",
+ "binNumber": 23,
+ "sha256Fingerprint": "oCNPO8hSfKVijuyBrV1piV2laA3JHRy4R38z+Hi5Wws="
+ },
+ {
+ "label": "America_Online_Root_Certification_Authority_1",
+ "binNumber": 24,
+ "sha256Fingerprint": "d0BzEsY6FT1bwAtOUXWc39rCN9wqM7Z5RumOm/poCuM="
+ },
+ {
+ "label": "America_Online_Root_Certification_Authority_2",
+ "binNumber": 25,
+ "sha256Fingerprint": "fTtGWmAU5SbAr/zuISfSMRcnrYEcJoQtAGrzcwbMgL0="
+ },
+ {
+ "label": "Visa_eCommerce_Root",
+ "binNumber": 26,
+ "sha256Fingerprint": "afrJvVX7CseNU7vuXPHVl5if0KqrIKJRUb3xcz7n0SI="
+ },
+ {
+ "label": "Certum_CA",
+ "binNumber": 27,
+ "sha256Fingerprint": "2OD+vB2y440AlA830n1BNE2ZPnNLmdVlbZd41NgUNiQ="
+ },
+ {
+ "label": "AAA_Certificate_Services",
+ "binNumber": 28,
+ "sha256Fingerprint": "16eg+11+JzHXcelITrze9x1fDD4KKUh4K8g+4OppnvQ="
+ },
+ {
+ "label": "Secure_Certificate_Services",
+ "binNumber": 29,
+ "sha256Fingerprint": "vYHOO09lkdEaZ7X8ekf97yVSG/mqThi5498uNKeAO+g="
+ },
+ {
+ "label": "Trusted_Certificate_Services",
+ "binNumber": 30,
+ "sha256Fingerprint": "PwblVoHUlvW+Fp61OJ+fK4/2HhcI32iBckhJzV0ny2k="
+ },
+ {
+ "label": "QuoVadis_Root_Certification_Authority",
+ "binNumber": 31,
+ "sha256Fingerprint": "pF7eO7vwnIrhXHLvwHJo1pOiHJlv1R5nygeUYP1tiHM="
+ },
+ {
+ "label": "QuoVadis_Root_CA_2",
+ "binNumber": 32,
+ "sha256Fingerprint": "haDdfdcgrbf/Bfg9VCsgncf/RSj31nexg4n+peXEnoY="
+ },
+ {
+ "label": "QuoVadis_Root_CA_3",
+ "binNumber": 33,
+ "sha256Fingerprint": "GPH8fyBd+K3d63/gB91X4683WpxNjXNUa/Tx/tHhjTU="
+ },
+ {
+ "label": "OU_Security_Communication_RootCA1_O_SECOM_Trust_net_C_JP",
+ "binNumber": 34,
+ "sha256Fingerprint": "515y7Z9WDuxutIAAc6Q/w60ZGVo5IoIBeJWXSpkCa2w="
+ },
+ {
+ "label": "Sonera_Class2_CA",
+ "binNumber": 35,
+ "sha256Fingerprint": "eQi0AxTBOBALUY0HNYB/+/z4UYoAlTNxBbo4axU92Sc="
+ },
+ {
+ "label": "Staat_der_Nederlanden_Root_CA",
+ "binNumber": 36,
+ "sha256Fingerprint": "1B2CnowWWYIq+T/OYr/83iZPyE6LlQxf8nXQUjVGlaM="
+ },
+ {
+ "label": "UTN___DATACorp_SGC",
+ "binNumber": 37,
+ "sha256Fingerprint": "hfsvkd0SJ1oBRbY2U0+EAkrWi2m47ohoT/cRN1gFs0g="
+ },
+ {
+ "label": "UTN_USERFirst_Hardware",
+ "binNumber": 38,
+ "sha256Fingerprint": "bqVHQdAEZn7tG0gWY0qjp55uS5aVD4J52vyNm9iBITc="
+ },
+ {
+ "label": "Chambers_of_Commerce_Root",
+ "binNumber": 39,
+ "sha256Fingerprint": "DCWKEqVnSu8l8oun3Prs7qNI5UHm9cxO5jtxs2FgasM="
+ },
+ {
+ "label": "Global_Chambersign_Root",
+ "binNumber": 40,
+ "sha256Fingerprint": "7zy0F/yOv2+Xh2yeTs453h6l/mSRQdECi30RwLIpjO0="
+ },
+ {
+ "label": "NetLock_Kozjegyzoi__Class_A__Tanusitvanykiado",
+ "binNumber": 41,
+ "sha256Fingerprint": "fxLNX35eKQ7H2FF51bcsIKW+dQj/21v4GrloSn/J9mc="
+ },
+ {
+ "label": "XRamp_Global_Certification_Authority",
+ "binNumber": 42,
+ "sha256Fingerprint": "zs3ckFCZ2NrfxbHSCbc3y+LBjPssEMD/C88NMob8GqI="
+ },
+ {
+ "label": "OU_Go_Daddy_Class_2_Certification_Authority_O__The_Go_Daddy_Group__Inc___C_US",
+ "binNumber": 43,
+ "sha256Fingerprint": "w4Rr8kuek8pkJ0wOxnwezF4CT/ys0tdAGTUOgf5UauQ="
+ },
+ {
+ "label": "OU_Starfield_Class_2_Certification_Authority_O__Starfield_Technologies__Inc___C_US",
+ "binNumber": 44,
+ "sha256Fingerprint": "FGX6IFOXuHb6pvCplY5VkOQPzH+qT7fCyGd1Iftftlg="
+ },
+ {
+ "label": "StartCom_Certification_Authority",
+ "binNumber": 45,
+ "sha256Fingerprint": "x2apvvLUBxyGOjGqSSDoE7LRmGCMt7fP4hFDuDbfCeo="
+ },
+ {
+ "label": "O_Government_Root_Certification_Authority_C_TW",
+ "binNumber": 46,
+ "sha256Fingerprint": "dgApXu/oW54f1iTbdgYqqq5ZgYpU0ndM1MCywBEx4bM="
+ },
+ {
+ "label": "Swisscom_Root_CA_1",
+ "binNumber": 47,
+ "sha256Fingerprint": "IdsgEjZguy7UGCBdoR7nqFpl4rxuVbWvfniZyKJm2S4="
+ },
+ {
+ "label": "DigiCert_Assured_ID_Root_CA",
+ "binNumber": 48,
+ "sha256Fingerprint": "PpCZtQFej0hsALzqnREe5yH6ujVaibzx32lWHj3GMlw="
+ },
+ {
+ "label": "DigiCert_Global_Root_CA",
+ "binNumber": 49,
+ "sha256Fingerprint": "Q0ig6URMeMsmXgWNXolEtNhPlmK9Jtslf4k0pEPHAWE="
+ },
+ {
+ "label": "DigiCert_High_Assurance_EV_Root_CA",
+ "binNumber": 50,
+ "sha256Fingerprint": "dDHl9MPBzkaQd08LYeBUQIg7qaAe0Aumq9eAbtOxGM8="
+ },
+ {
+ "label": "Class_2_Primary_CA",
+ "binNumber": 51,
+ "sha256Fingerprint": "D5k8iu+Xuq9WhxQO1ZrRghu0r6zwqppYtdV6M4o6+8s="
+ },
+ {
+ "label": "DST_Root_CA_X3",
+ "binNumber": 52,
+ "sha256Fingerprint": "BocmAzGnJAPZCfEF5pvPDTLhvSST/8bZIG0RvNZ3Bzk="
+ },
+ {
+ "label": "DST_ACES_CA_X6",
+ "binNumber": 53,
+ "sha256Fingerprint": "dnyVWnZBLImvaI6QoccPVWz9a2Al2+oQQW1+toMfjEA="
+ },
+ {
+ "label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
+ "binNumber": 54,
+ "sha256Fingerprint": "RATjO14UDc+ZgFH9/IAox8gWFcXuc3sRG1iCM6m1NaA="
+ },
+ {
+ "label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
+ "binNumber": 55,
+ "sha256Fingerprint": "xHDPVH4jArl3+yndcaiae2wfYHd7Ayn1YBfzKL9Pa+Y="
+ },
+ {
+ "label": "SwissSign_Gold_CA___G2",
+ "binNumber": 56,
+ "sha256Fingerprint": "Yt0L6bn1ChY+oPjnXAU7HspX6lXIaI9kfGiB8sg1e5U="
+ },
+ {
+ "label": "SwissSign_Silver_CA___G2",
+ "binNumber": 57,
+ "sha256Fingerprint": "vmxNoru5ulm285OXaDdCRsPABZk/qY8CDR3tvtSKgdU="
+ },
+ {
+ "label": "GeoTrust_Primary_Certification_Authority",
+ "binNumber": 58,
+ "sha256Fingerprint": "N9UQBsUS6qtiZCHx7IySAT/F+CrpjuUz60YZuN600Gw="
+ },
+ {
+ "label": "thawte_Primary_Root_CA",
+ "binNumber": 59,
+ "sha256Fingerprint": "jXIvganBE8B5HfE2opZtsmyVCpcdtGtBmfTqVLeL+58="
+ },
+ {
+ "label": "VeriSign_Class_3_Public_Primary_Certification_Authority___G5",
+ "binNumber": 60,
+ "sha256Fingerprint": "ms+rfkPI2IDQayYqlN7u5LRlmYnD0Mrxm69kBeQat98="
+ },
+ {
+ "label": "SecureTrust_CA",
+ "binNumber": 61,
+ "sha256Fingerprint": "8cG1CuWiDdgDDsn2vCSCPdNntSVXWbTnG2H86fc3XXM="
+ },
+ {
+ "label": "Secure_Global_CA",
+ "binNumber": 62,
+ "sha256Fingerprint": "QgD1BDrIWQ67Un0gntFQMCn7y9QcobUG7CfxWt59rGk="
+ },
+ {
+ "label": "COMODO_Certification_Authority",
+ "binNumber": 63,
+ "sha256Fingerprint": "DCzWPfeAb6OZ7egJEWtXW/h5ifBlGPmAjIYFAxeLr2Y="
+ },
+ {
+ "label": "Network_Solutions_Certificate_Authority",
+ "binNumber": 64,
+ "sha256Fingerprint": "FfC6AKOsevOsiEwHKxARoHe9d8CX9AFksvhZir2Dhgw="
+ },
+ {
+ "label": "WellsSecure_Public_Root_Certificate_Authority",
+ "binNumber": 65,
+ "sha256Fingerprint": "pxJyrqqjz+hyf3+znw+z0eVCbpBgsG7m8T6aPFgzzUM="
+ },
+ {
+ "label": "COMODO_ECC_Certification_Authority",
+ "binNumber": 66,
+ "sha256Fingerprint": "F5OSegYUVJeJrc4vjzT38LZtDzrjo7hNIewV27pPrcc="
+ },
+ {
+ "label": "IGC_A",
+ "binNumber": 67,
+ "sha256Fingerprint": "ub6nhgqWLqNhHauXq22j4hwQaLl9VVde0OESecEciTI="
+ },
+ {
+ "label": "OU_Security_Communication_EV_RootCA1_O__SECOM_Trust_Systems_CO__LTD___C_JP",
+ "binNumber": 68,
+ "sha256Fingerprint": "oi26aB6XN24tOX1yiq46m2KWuf26YLwuEfZH8sZ1+zc="
+ },
+ {
+ "label": "OISTE_WISeKey_Global_Root_GA_CA",
+ "binNumber": 69,
+ "sha256Fingerprint": "Qckjhmq0yta3rVeAgVguAgeXpsvfT/94zoOWs4k31/U="
+ },
+ {
+ "label": "Microsec_e_Szigno_Root_CA",
+ "binNumber": 70,
+ "sha256Fingerprint": "Mno9dhq63qA065mEBidcsaR3bv2uL99tAWjqHE9VZ9A="
+ },
+ {
+ "label": "Certigna",
+ "binNumber": 71,
+ "sha256Fingerprint": "47ai2y7XzkiEL3rFMkHHtx1UFEv7QMEfPx0LQvXuoS0="
+ },
+ {
+ "label": "TC_TrustCenter_Class_2_CA_II",
+ "binNumber": 72,
+ "sha256Fingerprint": "5rj4dmSF+Aeuf42sFnBGHwfAoT7vOh/3F1ONerrTkbQ="
+ },
+ {
+ "label": "TC_TrustCenter_Class_3_CA_II",
+ "binNumber": 73,
+ "sha256Fingerprint": "jaCE/Pmc4Hci+JsyBZOYBvpcuBHhyBP2oQjH0zazQI4="
+ },
+ {
+ "label": "TC_TrustCenter_Universal_CA_I",
+ "binNumber": 74,
+ "sha256Fingerprint": "6/PAKoeJsft9URmV1mO3KQbZE84NXhBWiop34lhhZ+c="
+ },
+ {
+ "label": "Deutsche_Telekom_Root_CA_2",
+ "binNumber": 75,
+ "sha256Fingerprint": "thkaUNDDl399qZvNqshqIn2uuWeexwujsMnZInHBcNM="
+ },
+ {
+ "label": "ComSign_Secured_CA",
+ "binNumber": 76,
+ "sha256Fingerprint": "UHlBx0RgoLRwhiINTpkyVyq10bW7y4mAqxyxdlGoRNI="
+ },
+ {
+ "label": "Cybertrust_Global_Root",
+ "binNumber": 77,
+ "sha256Fingerprint": "lgrfAGPpY1Z1DCll3QoIZ9oLnL1ud3FK6vsjSas5PaM="
+ },
+ {
+ "label": "OU_ePKI_Root_Certification_Authority_O__Chunghwa_Telecom_Co___Ltd___C_TW",
+ "binNumber": 78,
+ "sha256Fingerprint": "wKb03GOiS/3PVO8qaggqCnLeNYA+L/X/Unrl2HIG39U="
+ },
+ {
+ "label": "T_B_TAK_UEKAE_K_k_Sertifika_Hizmet_Sa_lay_c_s____S_r_m_3",
+ "binNumber": 79,
+ "sha256Fingerprint": "5Mc0MNeltQkl30M3Cg0hbpp5udbbg3Ogxp6xzDHHxSo="
+ },
+ {
+ "label": "Buypass_Class_2_CA_1",
+ "binNumber": 80,
+ "sha256Fingerprint": "D06c3SZLAlVQ0XCAY0AhT+lENMmwL2l+xxD8X+r7Xjg="
+ },
+ {
+ "label": "Buypass_Class_3_CA_1",
+ "binNumber": 81,
+ "sha256Fingerprint": "t7ErFx+CHaqZDND+UIexKESLqOUYT4TFHgK1yPuWKyQ="
+ },
+ {
+ "label": "EBG_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
+ "binNumber": 82,
+ "sha256Fingerprint": "Na5b3dj3rmNc/7pWgqjwC5X0hGLHEI7poOUpKwdKr7I="
+ },
+ {
+ "label": "OU_certSIGN_ROOT_CA_O_certSIGN_C_RO",
+ "binNumber": 83,
+ "sha256Fingerprint": "6qlixPpKa6/r5BUZbTUczYiNT1Pz+orm18RmqU5gQrs="
+ },
+ {
+ "label": "CNNIC_ROOT",
+ "binNumber": 84,
+ "sha256Fingerprint": "4oOTdz2oRaZ58ggMx/tEo7ehw3kst+t3Kf3Lao2Zrqc="
+ },
+ {
+ "label": "OU_ApplicationCA_O_Japanese_Government_C_JP",
+ "binNumber": 85,
+ "sha256Fingerprint": "LUdDfeF5USFaEvPFjlHHKaWAJu8fzApfs9ncAS9gDRk="
+ },
+ {
+ "label": "GeoTrust_Primary_Certification_Authority___G3",
+ "binNumber": 86,
+ "sha256Fingerprint": "tHi4EiUN+HhjXCqn7H0VXqpiXugpFuLNKUNhiGzR+9Q="
+ },
+ {
+ "label": "thawte_Primary_Root_CA___G2",
+ "binNumber": 87,
+ "sha256Fingerprint": "pDENUK8YpkRxkDcqhq+vi5Uf+0Mdg38eVoi0WXHtFVc="
+ },
+ {
+ "label": "thawte_Primary_Root_CA___G3",
+ "binNumber": 88,
+ "sha256Fingerprint": "SwP0WAetcPIb/Cyuccn95GBMBkz1/7aGuuXbqtf900w="
+ },
+ {
+ "label": "GeoTrust_Primary_Certification_Authority___G2",
+ "binNumber": 89,
+ "sha256Fingerprint": "Xtt6xDuCoGqHYejXvkl56/JhH33Xm/kcHGtWaiGe12Y="
+ },
+ {
+ "label": "VeriSign_Universal_Root_Certification_Authority",
+ "binNumber": 90,
+ "sha256Fingerprint": "I5lWESelcSXejO/qYQ3fL6B4tcgGf06CgpC/uGDoSzw="
+ },
+ {
+ "label": "VeriSign_Class_3_Public_Primary_Certification_Authority___G4",
+ "binNumber": 91,
+ "sha256Fingerprint": "ad3X6pC7V8k+E13IXqb81UgLYDI5vcRU/HWLKibPf3k="
+ },
+ {
+ "label": "NetLock_Arany__Class_Gold__F_tan_s_tv_ny",
+ "binNumber": 92,
+ "sha256Fingerprint": "bGHaw6Le8DFQa+A20qb+QBmU+9E9+cjUZlmSdMRG7Jg="
+ },
+ {
+ "label": "Staat_der_Nederlanden_Root_CA___G2",
+ "binNumber": 93,
+ "sha256Fingerprint": "ZoyDlH2mO3JL7OF0PDGg5q7Q247Fsxvjd7t4T5G2cW8="
+ },
+ {
+ "label": "CA_Disig",
+ "binNumber": 94,
+ "sha256Fingerprint": "kr9RGavsytCxMy3E4dBfunW1Z5BE7gyibpMfdE8vM88="
+ },
+ {
+ "label": "Juur_SK",
+ "binNumber": 95,
+ "sha256Fingerprint": "7MPpw0B1A77gkaqVL0E0j/iLqoY7ImS++sgHkBV06Tk="
+ },
+ {
+ "label": "Hongkong_Post_Root_CA_1",
+ "binNumber": 96,
+ "sha256Fingerprint": "+eZ9M2xRACrAVMYyAi1m3aLn4//xCtBh7THYu7QQz7I="
+ },
+ {
+ "label": "SecureSign_RootCA11",
+ "binNumber": 97,
+ "sha256Fingerprint": "vw/u+546WBrV+enbdYmYV0PSYQhcTTFPb11yWapCFhI="
+ },
+ {
+ "label": "ACEDICOM_Root",
+ "binNumber": 98,
+ "sha256Fingerprint": "A5UPtJpTHz4ZkZQjmN+p4Ooy17oc3ZvIXbV+2UALQ0o="
+ },
+ {
+ "label": "Microsec_e_Szigno_Root_CA_2009",
+ "binNumber": 99,
+ "sha256Fingerprint": "PF+B/qX6uCxkv6Lq7K/N6OB3/IYgp8rlNxY9827b83g="
+ },
+ {
+ "label": "e_Guven_Kok_Elektronik_Sertifika_Hizmet_Saglayicisi",
+ "binNumber": 100,
+ "sha256Fingerprint": "5gkHhGWkGXgMtqxMHAv7RlPZ2cxus5Rut/PWmZe61Zg="
+ },
+ {
+ "label": "GlobalSign",
+ "binNumber": 101,
+ "sha256Fingerprint": "y7Ui17fxJ61qAROGW98c1BAufQdZr2NafPRyDcljxTs="
+ },
+ {
+ "label": "Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068",
+ "binNumber": 102,
+ "sha256Fingerprint": "BASAKL8fKGTUj5rU2DKUNmqCiFZVPzsUMD+QFH9dQO8="
+ },
+ {
+ "label": "Izenpe_com",
+ "binNumber": 103,
+ "sha256Fingerprint": "JTDMjpgyFQK62W+bH7obCZ4tKZ4PRUi7kU82O8DUUx8="
+ },
+ {
+ "label": "Chambers_of_Commerce_Root___2008",
+ "binNumber": 104,
+ "sha256Fingerprint": "Bj5K+sSR39My8wibhULpRhfYk9f+lE4Qp5N+4p2Wk8A="
+ },
+ {
+ "label": "Global_Chambersign_Root___2008",
+ "binNumber": 105,
+ "sha256Fingerprint": "E2M1Q5M0p2mAFqDTJN5yKE4HnXtSILuPvXR4Fu6+uso="
+ },
+ {
+ "label": "Go_Daddy_Root_Certificate_Authority___G2",
+ "binNumber": 106,
+ "sha256Fingerprint": "RRQLMkfrnMjFtPDXtTCR9zKSCJ5uWmPidJ3TrKkZjto="
+ },
+ {
+ "label": "Starfield_Root_Certificate_Authority___G2",
+ "binNumber": 107,
+ "sha256Fingerprint": "LOHLC/nS+eECmT++IVFSw7LdDKveHGjlMZuDkVTbt/U="
+ },
+ {
+ "label": "Starfield_Services_Root_Certificate_Authority___G2",
+ "binNumber": 108,
+ "sha256Fingerprint": "Vo1pBaLIhwikswJRkO3P7bGXSmBqE8blKQ/LKuY+2rU="
+ },
+ {
+ "label": "AffirmTrust_Commercial",
+ "binNumber": 109,
+ "sha256Fingerprint": "A3arHVTF+YA85LLiAaDufu97V7Y26Kk8m41IYMlvX6c="
+ },
+ {
+ "label": "AffirmTrust_Networking",
+ "binNumber": 110,
+ "sha256Fingerprint": "CoHsWpKXd/FFkErzjV1Qn2a14sWPzbUxBYsOF/PwtBs="
+ },
+ {
+ "label": "AffirmTrust_Premium",
+ "binNumber": 111,
+ "sha256Fingerprint": "cKc/fzdrYAdCSJBFNLEUgtW/DmmOzEmN9SV36/LpO5o="
+ },
+ {
+ "label": "AffirmTrust_Premium_ECC",
+ "binNumber": 112,
+ "sha256Fingerprint": "vXH99tqX5M9i0WR63SWBsH15rfg5frTsupxehIiCFCM="
+ },
+ {
+ "label": "Certum_Trusted_Network_CA",
+ "binNumber": 113,
+ "sha256Fingerprint": "XFhGjVX1jkl+dDmC0rUAELbRZTdKz4On1KMtt2jEQI4="
+ },
+ {
+ "label": "Certinomis___Autorit__Racine",
+ "binNumber": 114,
+ "sha256Fingerprint": "/L/iiGIG9ysnWTyLBwKX4S12ntEO15MHBagJjv/BTRc="
+ },
+ {
+ "label": "Root_CA_Generalitat_Valenciana",
+ "binNumber": 115,
+ "sha256Fingerprint": "jE7f0ENI8yKWnn4ppM1NygBGVQYcFuGwdkIu80KtYw4="
+ },
+ {
+ "label": "A_Trust_nQual_03",
+ "binNumber": 116,
+ "sha256Fingerprint": "eTy/RVm5/eOKsi3xaGn2mIGuFMSwE5rHiKeKGvzKAvs="
+ },
+ {
+ "label": "TWCA_Root_Certification_Authority",
+ "binNumber": 117,
+ "sha256Fingerprint": "v9iP4RAcQa4+gBv4vlY1Dum60aa5vVFe3FxtW4cRrEQ="
+ },
+ {
+ "label": "OU_Security_Communication_RootCA2_O__SECOM_Trust_Systems_CO__LTD___C_JP",
+ "binNumber": 118,
+ "sha256Fingerprint": "UTss7LgQ1M3l3YU5Gt/Gwt1g2Hu3NtK1IUhKpHoOvvY="
+ },
+ {
+ "label": "EC_ACC",
+ "binNumber": 119,
+ "sha256Fingerprint": "iEl/AWAvMVQkauKMTVrvEPHYfrt2Ym9K4Lf5W6eWh5k="
+ },
+ {
+ "label": "Hellenic_Academic_and_Research_Institutions_RootCA_2011",
+ "binNumber": 120,
+ "sha256Fingerprint": "vBBPFaSL5wncpUKn4dS5328FRSfoAuqpLVlURCWK/nE="
+ },
+ {
+ "label": "Actalis_Authentication_Root_CA",
+ "binNumber": 121,
+ "sha256Fingerprint": "VZJghOyWOmS5biq+Ac4LqGpk+/68x6q1r8FVs3/XYGY="
+ },
+ {
+ "label": "OU_Trustis_FPS_Root_CA_O_Trustis_Limited_C_GB",
+ "binNumber": 122,
+ "sha256Fingerprint": "wbSCmaulII/pYwrOVcpooD7aWlGciAKg06Zzvo+OVX0="
+ },
+ {
+ "label": "StartCom_Certification_Authority",
+ "binNumber": 123,
+ "sha256Fingerprint": "4XiQ7gmj+/T0i5xBShfWN7elBkfpvHUjInJ/zBdCqRE="
+ },
+ {
+ "label": "StartCom_Certification_Authority_G2",
+ "binNumber": 124,
+ "sha256Fingerprint": "x7plZ96Tp5iuH6p5HnEtN4+uH5PEOX/qRBu3y+b9WZU="
+ },
+ {
+ "label": "Buypass_Class_2_Root_CA",
+ "binNumber": 125,
+ "sha256Fingerprint": "mhFAJRl8W7ldlOY9Vc1DeQhHtkayPN8RraSgDv8V+0g="
+ },
+ {
+ "label": "Buypass_Class_3_Root_CA",
+ "binNumber": 126,
+ "sha256Fingerprint": "7ffrvKJ6KjhNOHt9QBDGZuLttIQ+TCm0rh1bkzLmsk0="
+ },
+ {
+ "label": "T_TeleSec_GlobalRoot_Class_3",
+ "binNumber": 127,
+ "sha256Fingerprint": "/XPa0xxkT/G0O+8MzdqWcQuc2Ydeyn4xcHrz6W1SK70="
+ },
+ {
+ "label": "EE_Certification_Centre_Root_CA",
+ "binNumber": 128,
+ "sha256Fingerprint": "PoS6Q0KQhRbndXPAmS8JecoITkaFaB/xlcy6iiKbinY="
+ },
+ {
+ "label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_",
+ "binNumber": 129,
+ "sha256Fingerprint": "l4zZZvL6oHunqpUA2cAunXfyza2mrWunSvS5HGZZPFA="
+ },
+ {
+ "label": "D_TRUST_Root_Class_3_CA_2_2009",
+ "binNumber": 130,
+ "sha256Fingerprint": "SeekQqzw6mKHBQBUtSVktlDk9J5C40jWqjjgOelXscE="
+ },
+ {
+ "label": "D_TRUST_Root_Class_3_CA_2_EV_2009",
+ "binNumber": 131,
+ "sha256Fingerprint": "7sVJa5iM6YYluTQJLuwpCL7QsPMWwtRzDITq8fPTSIE="
+ },
+ {
+ "label": "PSCProcert",
+ "binNumber": 132,
+ "sha256Fingerprint": "PPw8FNH2hP8X44xDykQMALln7JM+i/4GTKHXLJDyrbA="
+ },
+ {
+ "label": "China_Internet_Network_Information_Center_EV_Certificates_Root",
+ "binNumber": 133,
+ "sha256Fingerprint": "HAHG9Nuy/vwiVYsryjJWP0mESs/DK3vksP9Zn56Mevc="
+ },
+ {
+ "label": "Swisscom_Root_CA_2",
+ "binNumber": 134,
+ "sha256Fingerprint": "8JsSLHEU9KCb1OpPSpnVWLRuTCXNgRQNKcBWE5FMOEE="
+ },
+ {
+ "label": "Swisscom_Root_EV_CA_2",
+ "binNumber": 135,
+ "sha256Fingerprint": "2V/qPKTu3OdM1251/G0f9ixEHw+ovHfwNLGeXbJYAV0="
+ },
+ {
+ "label": "CA_Disig_Root_R1",
+ "binNumber": 136,
+ "sha256Fingerprint": "+W8j9MPnnAd6RpiNWvWQBnag8DnLZF3RdUmyFsgkQM4="
+ },
+ {
+ "label": "CA_Disig_Root_R2",
+ "binNumber": 137,
+ "sha256Fingerprint": "4j1KA217cOn1lbFCIHnSuR7fux+2UaBjPqqKncX4BwM="
+ },
+ {
+ "label": "ACCVRAIZ1",
+ "binNumber": 138,
+ "sha256Fingerprint": "mm7AEuGn2p2+NBlNR4rXwNsYIvsHHfEpgUlu0QQ4QRM="
+ },
+ {
+ "label": "TWCA_Global_Root_CA",
+ "binNumber": 139,
+ "sha256Fingerprint": "WXaQB/doXQ/NUIcvn5XVdVpbK0V9gfNpK2EKmGcvDhs="
+ },
+ {
+ "label": "TeliaSonera_Root_CA_v1",
+ "binNumber": 140,
+ "sha256Fingerprint": "3Wk2/iH48HfBI6GlIcEiJPciVbc+A6cmBpPooksPo4k="
+ },
+ {
+ "label": "E_Tugra_Certification_Authority",
+ "binNumber": 141,
+ "sha256Fingerprint": "sL/VK7DX2b2Sv11NwT2iVcAsVC83g2XqiTkR9V5V8jw="
+ },
+ {
+ "label": "T_TeleSec_GlobalRoot_Class_2",
+ "binNumber": 142,
+ "sha256Fingerprint": "keL1eI1YEOunulhzfeFUio7KzQFFmLwLFD4EGxcFJVI="
+ },
+ {
+ "label": "Atos_TrustedRoot_2011",
+ "binNumber": 143,
+ "sha256Fingerprint": "81a+okS3qR6zXVPKmteGSs4Bji011fj5bd9opvQapHQ="
+ },
+ {
+ "label": "QuoVadis_Root_CA_1_G3",
+ "binNumber": 144,
+ "sha256Fingerprint": "ioZv0bJ2tX5XjpIcZYKKK+1Y6fLyiAVBNLfx9L/JzHQ="
+ },
+ {
+ "label": "QuoVadis_Root_CA_2_G3",
+ "binNumber": 145,
+ "sha256Fingerprint": "j+T7Cvk6TQ1n2wvrsj43xxvzJdy83SQOoE2vWLR+GEA="
+ },
+ {
+ "label": "QuoVadis_Root_CA_3_G3",
+ "binNumber": 146,
+ "sha256Fingerprint": "iO+B3iAusBhFLkP4ZHJc6l+9H8LZ0gVzBwnF2LhpD0Y="
+ },
+ {
+ "label": "DigiCert_Assured_ID_Root_G2",
+ "binNumber": 147,
+ "sha256Fingerprint": "fQXrtoIzn4yUUe4JTuv++nlToRTtsvRJSUUvq30vwYU="
+ },
+ {
+ "label": "DigiCert_Assured_ID_Root_G3",
+ "binNumber": 148,
+ "sha256Fingerprint": "fjfLi0xHCQyrNlUbpvRduEBoD7oWapUtsQBxf0MFP8I="
+ },
+ {
+ "label": "DigiCert_Global_Root_G2",
+ "binNumber": 149,
+ "sha256Fingerprint": "yzzLt2Ax5eATj43TmiP53kf/w15DwRRM6ifUalqxy18="
+ },
+ {
+ "label": "DigiCert_Global_Root_G3",
+ "binNumber": 150,
+ "sha256Fingerprint": "Ma1mSPgQQTjHOPOepDIBMzk+OhjMAilu+Xwqye9nMdA="
+ },
+ {
+ "label": "DigiCert_Trusted_Root_G4",
+ "binNumber": 151,
+ "sha256Fingerprint": "VS973PGnr55s5nIBf08Sq/dyQMeOdhrCA9HZ0grImYg="
+ },
+ {
+ "label": "Certification_Authority_of_WoSign",
+ "binNumber": 152,
+ "sha256Fingerprint": "SyLVpq7JnzzbeapewGg4R5zV7LpxZPfyLcHWX2PYVwg="
+ },
+ {
+ "label": "CA______",
+ "binNumber": 153,
+ "sha256Fingerprint": "1vA0vZSqIz8Cl+ykJFsoOXPkR6pZDzEMd/SP34MRIlQ="
+ },
+ {
+ "label": "COMODO_RSA_Certification_Authority",
+ "binNumber": 154,
+ "sha256Fingerprint": "UvDhxOWOxikpG2AxfwdGcbhdfqgNWwcnNGNTSzK0AjQ="
+ },
+ {
+ "label": "USERTrust_RSA_Certification_Authority",
+ "binNumber": 155,
+ "sha256Fingerprint": "55PJsC/YqhPiHDEiisywgRlkO3SciYlksXRtRsPUy9I="
+ },
+ {
+ "label": "USERTrust_ECC_Certification_Authority",
+ "binNumber": 156,
+ "sha256Fingerprint": "T/Rg1Uuchtq/vPxXEuBADSvtP7xNT72qhuBq3NKprXo="
+ },
+ {
+ "label": "GlobalSign",
+ "binNumber": 157,
+ "sha256Fingerprint": "vslJEcKVVnbbbApVCYbXbjugBWZ8RCyXYrT7t3PeIow="
+ },
+ {
+ "label": "GlobalSign",
+ "binNumber": 158,
+ "sha256Fingerprint": "F5+8FIo90A/STqE0WMxDv6f1nIGC14OlE/br7BAMiSQ="
+ },
+ {
+ "label": "Staat_der_Nederlanden_Root_CA___G3",
+ "binNumber": 159,
+ "sha256Fingerprint": "PE+wuVq4swAy9DK4b1Nf4XLBhdD9OYZYN882GH+m9Cg="
+ },
+ {
+ "label": "Staat_der_Nederlanden_EV_Root_CA",
+ "binNumber": 160,
+ "sha256Fingerprint": "TSSRQUz+lWdG7Ezvps9vcuKKEylDL52KkHrEy12twVo="
+ },
+ {
+ "label": "IdenTrust_Commercial_Root_CA_1",
+ "binNumber": 161,
+ "sha256Fingerprint": "XVZJm+TS4IvPytCKPjhyPVBQO95waUjkL1VgMBnlKK4="
+ },
+ {
+ "label": "IdenTrust_Public_Sector_Root_CA_1",
+ "binNumber": 162,
+ "sha256Fingerprint": "MNCJWppEiiYgkWNVItH1IBC1hnrK4Sx475WP1PQ4ny8="
+ },
+ {
+ "label": "Entrust_Root_Certification_Authority___G2",
+ "binNumber": 163,
+ "sha256Fingerprint": "Q99XdLA+f+9f5A2TGnvt8bsua0JzjE5tOEEQPTqn8zk="
+ },
+ {
+ "label": "Entrust_Root_Certification_Authority___EC1",
+ "binNumber": 164,
+ "sha256Fingerprint": "Au0OsowU2kUWXFZnkXANZFHX+1bwsqsdO46wcOVu3/U="
+ },
+ {
+ "label": "CFCA_EV_ROOT",
+ "binNumber": 165,
+ "sha256Fingerprint": "XMPXjk4dXkVUegTmhz5k+Qz5U20czC74APNVxMX9cP0="
+ },
+ {
+ "label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s__H5",
+ "binNumber": 166,
+ "sha256Fingerprint": "STUbkDREwYXM3FxpPSTYVVyyCNaoFBMHaZ9K8GMZnXg="
+ },
+ {
+ "label": "T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s__H6",
+ "binNumber": 167,
+ "sha256Fingerprint": "jeeGVeG+f3hHgAuT9pTSHTaMwG4DPn+rBLteuZ2mtwA="
+ },
+ {
+ "label": "Certinomis___Root_CA",
+ "binNumber": 168,
+ "sha256Fingerprint": "Kpn1vBF0tzy7HWIIhOAcNOUcyzl42hJfDjMmiIO/QVg="
+ },
+ {
+ "label": "OISTE_WISeKey_Global_Root_GB_CA",
+ "binNumber": 169,
+ "sha256Fingerprint": "a5wI6G6w92fPrWXNmLYhSeVJSmf1hF570e0Bnye4a9Y="
+ },
+ {
+ "label": "Certification_Authority_of_WoSign_G2",
+ "binNumber": 170,
+ "sha256Fingerprint": "1Ielb4OwdILoXpYzlMHswsnlHQkD7pRrAsMBWB7ZnhY="
+ },
+ {
+ "label": "CA_WoSign_ECC_Root",
+ "binNumber": 171,
+ "sha256Fingerprint": "i0XaHAb3kesMq/Jr5Yj1+yMWXC5hS/iFVi0NzlCymwI="
+ },
+ {
+ "label": "SZAFIR_ROOT_CA2",
+ "binNumber": 172,
+ "sha256Fingerprint": "oTOdMygaC1blV9PTKxzn+TZ+sJS9X6cqflAEyN7Xyv4="
+ },
+ {
+ "label": "Certum_Trusted_Network_CA_2",
+ "binNumber": 173,
+ "sha256Fingerprint": "tnby7drod1zTbLD2PNHUYDlh9J5iZboBOi8DB7bQuAQ="
+ },
+ {
+ "label": "Hellenic_Academic_and_Research_Institutions_RootCA_2015",
+ "binNumber": 174,
+ "sha256Fingerprint": "oECSmgLOU7Ss9PL/xpgc5ElvdV5tRf4LKmkrzVJSPzY="
+ },
+ {
+ "label": "Hellenic_Academic_and_Research_Institutions_ECC_RootCA_2015",
+ "binNumber": 175,
+ "sha256Fingerprint": "RLVFqool5lpzyhXcJ/w20kwcuZU6BmU5sRWC3Eh7SDM="
+ },
+ {
+ "label": "Certplus_Root_CA_G1",
+ "binNumber": 176,
+ "sha256Fingerprint": "FSpAK/zfLNVIBU0idbOcf8o+wJeAeLDw6nblYabHQz4="
+ },
+ {
+ "label": "Certplus_Root_CA_G2",
+ "binNumber": 177,
+ "sha256Fingerprint": "bMBQQeZEXnRpbEz7yfgPVDt+q7tEtM5veHxqmXHELxc="
+ },
+ {
+ "label": "OpenTrust_Root_CA_G1",
+ "binNumber": 178,
+ "sha256Fingerprint": "VsdxKNmMGNkbTP3/vCXukQPUdY6iq62CapDzRX1GDrQ="
+ },
+ {
+ "label": "OpenTrust_Root_CA_G2",
+ "binNumber": 179,
+ "sha256Fingerprint": "J5lYKf5qdRXBv+hI+cR2HbFsIlkpJXv0DQiU8p6ouvI="
+ },
+ {
+ "label": "OpenTrust_Root_CA_G3",
+ "binNumber": 180,
+ "sha256Fingerprint": "t8NiMXBugQeMNny4lhmPHjII3ZJpSd2PVwmkEPdbYpI="
+ },
+ {
+ "label": "ISRG_Root_X1",
+ "binNumber": 181,
+ "sha256Fingerprint": "lrzsBiZJdvN0YHeazyjFp8/oo8Cq4RqP/O4FwL3fCMY="
+ },
+ {
+ "label": "OU_AC_RAIZ_FNMT_RCM_O_FNMT_RCM_C_ES",
+ "binNumber": 182,
+ "sha256Fingerprint": "68VXDCkBjE1nsaoSe68S9wO0YR68F7fatVc4lBebk/o="
+ },
+ {
+ "label": "Amazon_Root_CA_1",
+ "binNumber": 183,
+ "sha256Fingerprint": "js3miE89h7ESW6Maw/yxPXAW3n9XzJBP4cuXxq6YGW4="
+ },
+ {
+ "label": "Amazon_Root_CA_2",
+ "binNumber": 184,
+ "sha256Fingerprint": "G6WyqoxlQBqClgEY+AvsT2IwTYPOxHE6GcOcAR6kbbQ="
+ },
+ {
+ "label": "Amazon_Root_CA_3",
+ "binNumber": 185,
+ "sha256Fingerprint": "GM5s/nvxTmCy40e43+hoyzHQLrs62icVafUDQ7Rts6Q="
+ },
+ {
+ "label": "Amazon_Root_CA_4",
+ "binNumber": 186,
+ "sha256Fingerprint": "410oQZ7QICXPppA4zWI5YkWNpcaV+96jwisL+yWJcJI="
+ },
+ {
+ "label": "LuxTrust_Global_Root_2",
+ "binNumber": 187,
+ "sha256Fingerprint": "VEVfcSnCCxRHxBj5lxaPJMWPxQI79dpb4utuHdiQLtU="
+ }
+ ],
+ "maxBin": 187
+} \ No newline at end of file
diff --git a/system/security/manager/tools/dumpGoogleRoots.js b/system/security/manager/tools/dumpGoogleRoots.js
new file mode 100644
index 000000000..2daa20434
--- /dev/null
+++ b/system/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");
diff --git a/system/security/manager/tools/genRootCAHashes.js b/system/security/manager/tools/genRootCAHashes.js
new file mode 100644
index 000000000..0d6f1df48
--- /dev/null
+++ b/system/security/manager/tools/genRootCAHashes.js
@@ -0,0 +1,255 @@
+/* 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";
+
+// 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 genRootCAHashes.js \
+// [absolute path to]/RootHashes.inc'
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+
+const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
+const CertDb = Components.classes[nsX509CertDB].getService(Ci.nsIX509CertDB);
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/FileUtils.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+const { CommonUtils } = Cu.import("resource://services-common/utils.js", {});
+
+const FILENAME_OUTPUT = "RootHashes.inc";
+const FILENAME_TRUST_ANCHORS = "KnownRootHashes.json";
+const ROOT_NOT_ASSIGNED = -1;
+
+const JSON_HEADER = "// This Source Code Form is subject to the terms of the Mozilla Public\n" +
+"// License, v. 2.0. If a copy of the MPL was not distributed with this\n" +
+"// file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n" +
+"//\n" +
+"//***************************************************************************\n" +
+"// This is an automatically generated file. It's used to maintain state for\n" +
+"// runs of genRootCAHashes.js; you should never need to manually edit it\n" +
+"//***************************************************************************\n" +
+"\n";
+
+const FILE_HEADER = "/* This Source Code Form is subject to the terms of the Mozilla Public\n" +
+" * License, v. 2.0. If a copy of the MPL was not distributed with this\n" +
+" * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n" +
+"\n" +
+"/*****************************************************************************/\n" +
+"/* This is an automatically generated file. If you're not */\n" +
+"/* RootCertificateTelemetryUtils.cpp, you shouldn't be #including it. */\n" +
+"/*****************************************************************************/\n" +
+"\n" +
+"#define HASH_LEN 32\n";
+
+const FP_PREAMBLE = "struct CertAuthorityHash {\n" +
+" const uint8_t hash[HASH_LEN];\n" +
+" const int32_t binNumber;\n" +
+"};\n\n" +
+"static const struct CertAuthorityHash ROOT_TABLE[] = {\n";
+
+const FP_POSTAMBLE = "};\n";
+
+// Helper
+function writeString(fos, string) {
+ fos.write(string, string.length);
+}
+
+// Remove all colons from a string
+function stripColons(hexString) {
+ return hexString.replace(/:/g, '');
+}
+
+// Expect an array of bytes and make it C-formatted
+function hexSlice(bytes, start, end) {
+ let ret = "";
+ for (let i = start; i < end; i++) {
+ let hex = (0 + bytes.charCodeAt(i).toString(16)).slice(-2).toUpperCase();
+ ret += "0x" + hex;
+ if (i < end - 1) {
+ ret += ", ";
+ }
+ }
+ return ret;
+}
+
+function stripComments(buf) {
+ let lines = buf.split("\n");
+ let entryRegex = /^\s*\/\//;
+ let data = "";
+ for (let i = 0; i < lines.length; i++) {
+ let match = entryRegex.exec(lines[i]);
+ if (!match) {
+ data = data + lines[i];
+ }
+ }
+ return data;
+}
+
+
+// Load the trust anchors JSON object from disk
+function loadTrustAnchors(file) {
+ if (file.exists()) {
+ let stream = Cc["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Ci.nsIFileInputStream);
+ stream.init(file, -1, 0, 0);
+ let buf = NetUtil.readInputStreamToString(stream, stream.available());
+ return JSON.parse(stripComments(buf));
+ }
+ // If there's no input file, bootstrap.
+ return { roots: [], maxBin: 0 };
+}
+
+// Saves our persistence file so that we don't lose track of the mapping
+// between bin numbers and the CA-hashes, even as CAs come and go.
+function writeTrustAnchors(file) {
+ let fos = FileUtils.openSafeFileOutputStream(file);
+
+ let serializedData = JSON.stringify(gTrustAnchors, null, ' ');
+ fos.write(JSON_HEADER, JSON_HEADER.length);
+ fos.write(serializedData, serializedData.length);
+
+ FileUtils.closeSafeFileOutputStream(fos);
+}
+
+
+// Write the C++ header file
+function writeRootHashes(fos) {
+ try {
+ writeString(fos, FILE_HEADER);
+
+ // Output the sorted gTrustAnchors
+ writeString(fos, FP_PREAMBLE);
+ gTrustAnchors.roots.forEach(function(fp) {
+ let fpBytes = atob(fp.sha256Fingerprint);
+
+ writeString(fos, " {\n");
+ writeString(fos, " /* " + fp.label + " */\n");
+ writeString(fos, " { " + hexSlice(fpBytes, 0, 16) + ",\n");
+ writeString(fos, " " + hexSlice(fpBytes, 16, 32) + " },\n");
+ writeString(fos, " " + fp.binNumber + " /* Bin Number */\n");
+
+ writeString(fos, " },\n");
+ });
+ writeString(fos, FP_POSTAMBLE);
+
+ writeString(fos, "\n");
+
+ }
+ catch (e) {
+ dump("ERROR: problem writing output: " + e + "\n");
+ }
+}
+
+// Scan our list (linearly) for the given fingerprint string
+function findTrustAnchorByFingerprint(sha256Fingerprint) {
+ for (let i = 0; i < gTrustAnchors.roots.length; i++) {
+ if (sha256Fingerprint == gTrustAnchors.roots[i].sha256Fingerprint) {
+ return i;
+ }
+ }
+ return ROOT_NOT_ASSIGNED;
+}
+
+// Get a clean label for a given certificate; usually the common name.
+function getLabelForCert(cert) {
+ let label = cert.commonName;
+
+ if (label.length < 5) {
+ label = cert.subjectName;
+ }
+
+ // replace non-ascii characters
+ label = label.replace(/[^[:ascii:]]/g, "_");
+ // replace non-word characters
+ label = label.replace(/[^A-Za-z0-9]/g, "_");
+ return label;
+}
+
+// Fill in the gTrustAnchors list with trust anchors from the database.
+function insertTrustAnchorsFromDatabase() {
+ // We only want CA certs for SSL
+ const CERT_TYPE = Ci.nsIX509Cert.CA_CERT;
+ const TRUST_TYPE = Ci.nsIX509CertDB.TRUSTED_SSL;
+
+ // Iterate through the whole Cert DB
+ let enumerator = CertDb.getCerts().getEnumerator();
+ while (enumerator.hasMoreElements()) {
+ let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
+
+ // Find the certificate in our existing list. Do it here because we need to check if
+ // it's untrusted too.
+
+ // If this is a trusted cert
+ if (CertDb.isCertTrusted(cert, CERT_TYPE, TRUST_TYPE)) {
+ // Base64 encode the hex string
+ let binaryFingerprint = CommonUtils.hexToBytes(stripColons(cert.sha256Fingerprint));
+ let encodedFingerprint = btoa(binaryFingerprint);
+
+ // Scan to see if this is already in the database.
+ if (findTrustAnchorByFingerprint(encodedFingerprint) == ROOT_NOT_ASSIGNED) {
+
+ // Let's get a usable name; some old certs do not have CN= filled out
+ let label = getLabelForCert(cert);
+
+ // Add to list
+ gTrustAnchors.maxBin += 1;
+ gTrustAnchors.roots.push(
+ {
+ "label": label,
+ "binNumber": gTrustAnchors.maxBin,
+ "sha256Fingerprint": encodedFingerprint
+ });
+ }
+ }
+ }
+}
+
+//
+// PRIMARY LOGIC
+//
+
+if (arguments.length != 1) {
+ throw new Error("Usage: genRootCAHashes.js " +
+ "<absolute path to current RootHashes.inc>");
+}
+
+var trustAnchorsFile = FileUtils.getFile("CurWorkD", [FILENAME_TRUST_ANCHORS]);
+// let rootHashesFile = FileUtils.getFile("CurWorkD", arguments[0]);
+var rootHashesFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+rootHashesFile.initWithPath(arguments[0]);
+
+// Open the known hashes file; this is to ensure stable bin numbers.
+var gTrustAnchors = loadTrustAnchors(trustAnchorsFile);
+
+// Collect all certificate entries
+insertTrustAnchorsFromDatabase();
+
+// Update known hashes before we sort
+writeTrustAnchors(trustAnchorsFile);
+
+// Sort all trust anchors before writing, as AccumulateRootCA.cpp
+// will perform binary searches
+gTrustAnchors.roots.sort(function(a, b) {
+ // We need to work from the binary values, not the base64 values.
+ let aBin = atob(a.sha256Fingerprint);
+ let bBin = atob(b.sha256Fingerprint);
+
+ if (aBin < bBin) {
+ return -1;
+ }
+ if (aBin > bBin) {
+ return 1;
+ }
+ return 0;
+});
+
+// Write the output file.
+var rootHashesFileOutputStream = FileUtils.openSafeFileOutputStream(rootHashesFile);
+writeRootHashes(rootHashesFileOutputStream);
+FileUtils.closeSafeFileOutputStream(rootHashesFileOutputStream);
diff --git a/system/security/manager/tools/makeCNNICHashes.js b/system/security/manager/tools/makeCNNICHashes.js
new file mode 100644
index 000000000..1b558949e
--- /dev/null
+++ b/system/security/manager/tools/makeCNNICHashes.js
@@ -0,0 +1,282 @@
+/* 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";
+
+// How to run this file:
+// 1. [obtain CNNIC-issued certificates to be whitelisted]
+// 2. [obtain firefox source code]
+// 3. [build/obtain firefox binaries]
+// 4. run `[path to]/run-mozilla.sh [path to]/xpcshell makeCNNICHashes.js \
+// [path to]/intermediatesFile
+// [path to]/certlist'
+// Where |intermediatesFile| is a file containing PEM encoded intermediate
+// certificates that the certificates in |certlist| may be issued by.
+// where certlist is a file containing a list of paths to certificates to
+// be included in the whitelist
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+var gCertDB = Cc["@mozilla.org/security/x509certdb;1"]
+ .getService(Ci.nsIX509CertDB);
+
+var { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
+var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
+const HEADER = "// This Source Code Form is subject to the terms of the Mozilla Public\n" +
+"// License, v. 2.0. If a copy of the MPL was not distributed with this\n" +
+"// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n" +
+"//\n" +
+"//***************************************************************************\n" +
+"// This file was automatically generated by makeCNNICHashes.js. It shouldn't\n" +
+"// need to be manually edited.\n" +
+"//***************************************************************************\n" +
+"\n";
+
+const PREAMBLE = "#define CNNIC_WHITELIST_HASH_LEN 32\n\n" +
+"struct WhitelistedCNNICHash {\n" +
+" const uint8_t hash[CNNIC_WHITELIST_HASH_LEN];\n" +
+"};\n\n" +
+"static const struct WhitelistedCNNICHash WhitelistedCNNICHashes[] = {\n";
+
+const POSTAMBLE = "};\n";
+
+function writeString(fos, string) {
+ fos.write(string, string.length);
+}
+
+// fingerprint is in the form "00:11:22:..."
+function hexSlice(fingerprint, start, end) {
+ let hexBytes = fingerprint.split(":");
+ let ret = "";
+ for (let i = start; i < end; i++) {
+ let hex = hexBytes[i];
+ ret += "0x" + hex;
+ if (i < end - 1) {
+ ret += ", ";
+ }
+ }
+ return ret;
+}
+
+// Write the C++ header file
+function writeHashes(certs, lastValidTime, fos) {
+ writeString(fos, HEADER);
+ writeString(fos, `// This file may be removed after ${new Date(lastValidTime)}\n\n`);
+ writeString(fos, PREAMBLE);
+
+ certs.forEach(function(cert) {
+ writeString(fos, " {\n");
+ writeString(fos, " { " + hexSlice(cert.sha256Fingerprint, 0, 16) + ",\n");
+ writeString(fos, " " + hexSlice(cert.sha256Fingerprint, 16, 32) + " },\n");
+
+ writeString(fos, " },\n");
+ });
+ writeString(fos, POSTAMBLE);
+}
+
+function readFileContents(file) {
+ let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Ci.nsIFileInputStream);
+ fstream.init(file, -1, 0, 0);
+ let data = NetUtil.readInputStreamToString(fstream, fstream.available());
+ fstream.close();
+ return data;
+}
+
+function relativePathToFile(path) {
+ let currentDirectory = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties)
+ .get("CurWorkD", Ci.nsILocalFile);
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(currentDirectory.path + "/" + path);
+ return file;
+}
+
+function pathToFile(path) {
+ let file = relativePathToFile(path);
+ if (!file.exists()) {
+ // Fall back to trying absolute path
+ file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(path);
+ }
+ return file;
+}
+
+// punt on dealing with leap-years
+const sixYearsInMilliseconds = 6 * 366 * 24 * 60 * 60 * 1000;
+
+function loadCertificates(certFile, currentWhitelist) {
+ let nowInMilliseconds = (new Date()).getTime();
+ // months are 0-indexed, so April is month 3 :(
+ let april1InMilliseconds = (new Date(2015, 3, 1)).getTime();
+ let latestNotAfter = nowInMilliseconds;
+ let certs = [];
+ let certMap = {};
+ let invalidCerts = [];
+ let paths = readFileContents(certFile).split("\n");
+ for (let path of paths) {
+ if (!path) {
+ continue;
+ }
+ let certData = readFileContents(pathToFile(path));
+ let cert = null;
+ try {
+ cert = gCertDB.constructX509FromBase64(certData);
+ } catch (e) {}
+ if (!cert) {
+ cert = gCertDB.constructX509(certData, certData.length);
+ }
+ // Don't add multiple copies of any particular certificate.
+ if (cert.sha256Fingerprint in certMap) {
+ continue;
+ }
+ certMap[cert.sha256Fingerprint] = true;
+ // If we can't verify the certificate, don't include it. Unfortunately, if
+ // a CNNIC-issued certificate wasn't previously on the whitelist but it
+ // otherwise verifies successfully, verifyCertNow will return
+ // SEC_ERROR_REVOKED_CERTIFICATE, so we count that as verifying
+ // successfully. If the certificate is later revoked by CNNIC, the user
+ // will see that when they attempt to connect to a site using it and we do
+ // normal revocation checking.
+ let errorCode = gCertDB.verifyCertNow(cert, 2 /* SSL Server */,
+ Ci.nsIX509CertDB.LOCAL_ONLY, null,
+ {}, {});
+ if (errorCode != 0 &&
+ errorCode != -8180 /* SEC_ERROR_REVOKED_CERTIFICATE */) {
+ continue;
+ }
+ let durationMilliseconds = (cert.validity.notAfter - cert.validity.notBefore) / 1000;
+ let notBeforeMilliseconds = cert.validity.notBefore / 1000;
+ let notAfterMilliseconds = cert.validity.notAfter / 1000;
+ // Only consider certificates that were issued before 1 April 2015, haven't
+ // expired, and have a validity period shorter than 6 years (there is a
+ // delegated OCSP responder certificate with a validity period of 6 years
+ // that should be on the whitelist).
+ // Also only consider certificates that were already on the whitelist.
+ if (notBeforeMilliseconds < april1InMilliseconds &&
+ notAfterMilliseconds > nowInMilliseconds &&
+ durationMilliseconds < sixYearsInMilliseconds &&
+ currentWhitelist[cert.sha256Fingerprint]) {
+ certs.push(cert);
+ if (notAfterMilliseconds > latestNotAfter) {
+ latestNotAfter = notAfterMilliseconds;
+ }
+ }
+ if (durationMilliseconds >= sixYearsInMilliseconds) {
+ invalidCerts.push(cert);
+ }
+ }
+ return { certs: certs,
+ lastValidTime: latestNotAfter,
+ invalidCerts: invalidCerts };
+}
+
+// Expects something like "00:11:22:...", returns a string of bytes.
+function hexToBinaryString(hexString) {
+ let hexBytes = hexString.split(":");
+ let result = "";
+ for (let hexByte of hexBytes) {
+ result += String.fromCharCode(parseInt(hexByte, 16));
+ }
+ return result;
+}
+
+function compareCertificatesByHash(certA, certB) {
+ let aBin = hexToBinaryString(certA.sha256Fingerprint);
+ let bBin = hexToBinaryString(certB.sha256Fingerprint);
+
+ if (aBin < bBin) {
+ return -1;
+ }
+ if (aBin > bBin) {
+ return 1;
+ }
+ return 0;
+}
+
+function certToPEM(cert) {
+ let der = cert.getRawDER({});
+ let derString = '';
+ for (let i = 0; i < der.length; i++) {
+ derString += String.fromCharCode(der[i]);
+ }
+ let base64Lines = btoa(derString).replace(/(.{64})/g, "$1\n");
+ let output = "-----BEGIN CERTIFICATE-----\n";
+ for (let line of base64Lines.split("\n")) {
+ if (line.length > 0) {
+ output += line + "\n";
+ }
+ }
+ output += "-----END CERTIFICATE-----";
+ return output;
+}
+
+function loadIntermediates(intermediatesFile) {
+ let pem = readFileContents(intermediatesFile);
+ let intermediates = [];
+ let currentPEM = "";
+ for (let line of pem.split("\r\n")) {
+ if (line == "-----END CERTIFICATE-----") {
+ if (currentPEM) {
+ intermediates.push(gCertDB.constructX509FromBase64(currentPEM));
+ }
+ currentPEM = "";
+ continue;
+ }
+ if (line != "-----BEGIN CERTIFICATE-----") {
+ currentPEM += line;
+ }
+ }
+ return intermediates;
+}
+
+function readCurrentWhitelist(currentWhitelistFile) {
+ let contents = readFileContents(currentWhitelistFile).replace(/[\r\n ]/g, "");
+ let split = contents.split(/((?:0x[0-9A-F][0-9A-F],){31}0x[0-9A-F][0-9A-F])/);
+ // The hashes will be every odd-indexed element of the array.
+ let currentWhitelist = {};
+ for (let i = 1; i < split.length && i < split.length - 1; i += 2) {
+ let hash = split[i].replace(/0x/g, "").replace(/,/g, ":");
+ currentWhitelist[hash] = true;
+ }
+ return currentWhitelist;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+if (arguments.length != 3) {
+ throw new Error("Usage: makeCNNICHashes.js <PEM intermediates file> " +
+ "<path to list of certificates> <path to current whitelist file>");
+}
+
+Services.prefs.setIntPref("security.OCSP.enabled", 0);
+var intermediatesFile = pathToFile(arguments[0]);
+var intermediates = loadIntermediates(intermediatesFile);
+var certFile = pathToFile(arguments[1]);
+var currentWhitelistFile = pathToFile(arguments[2]);
+var currentWhitelist = readCurrentWhitelist(currentWhitelistFile);
+var { certs, lastValidTime, invalidCerts } = loadCertificates(certFile, currentWhitelist);
+
+dump("The following certificates were not included due to overlong validity periods:\n");
+for (let cert of invalidCerts) {
+ dump(certToPEM(cert) + "\n");
+}
+
+// Sort the key hashes to allow for binary search.
+certs.sort(compareCertificatesByHash);
+
+// Write the output file.
+var outFile = relativePathToFile("CNNICHashWhitelist.inc");
+if (!outFile.exists()) {
+ outFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
+}
+var outStream = Cc["@mozilla.org/network/file-output-stream;1"]
+ .createInstance(Ci.nsIFileOutputStream);
+outStream.init(outFile, -1, 0, 0);
+writeHashes(certs, lastValidTime, outStream);
+outStream.close();