summaryrefslogtreecommitdiffstats
path: root/toolkit/components/certviewer/tests
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/certviewer/tests')
-rw-r--r--toolkit/components/certviewer/tests/browser/adjustedCerts.js261
-rw-r--r--toolkit/components/certviewer/tests/browser/browser.toml38
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_aboutcertificateviewer.js81
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_certificateTabLink.js61
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkAuthorityKeyID.js50
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkLongHex.js38
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkMissingCommonName.js50
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkNonEmptyFields.js82
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkNonRepeatedCertTabs.js131
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkNonUndefinedStrings.js49
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkOCSP.js46
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkStandAlonePage.js86
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_checkValiditySection.js57
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_downloadLink.js126
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_handleMultipleCertsURL.js251
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_openTabAndSendCertInfo.js271
-rw-r--r--toolkit/components/certviewer/tests/browser/browser_renderCertToUI.js192
-rw-r--r--toolkit/components/certviewer/tests/browser/dummy_page.html9
-rw-r--r--toolkit/components/certviewer/tests/browser/head.js124
-rw-r--r--toolkit/components/certviewer/tests/chrome/CSoutput.mjs144
-rw-r--r--toolkit/components/certviewer/tests/chrome/chrome.toml13
-rw-r--r--toolkit/components/certviewer/tests/chrome/parseOutput.mjs330
-rw-r--r--toolkit/components/certviewer/tests/chrome/test_adjustCertInformation.html45
-rw-r--r--toolkit/components/certviewer/tests/chrome/test_certDecoder.html39
-rw-r--r--toolkit/components/certviewer/tests/chrome/test_certDecoderFields.html84
-rw-r--r--toolkit/components/certviewer/tests/chrome/test_kebabCaseInAdjustCertInformation.html106
26 files changed, 2764 insertions, 0 deletions
diff --git a/toolkit/components/certviewer/tests/browser/adjustedCerts.js b/toolkit/components/certviewer/tests/browser/adjustedCerts.js
new file mode 100644
index 0000000000..0b0c089a61
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/adjustedCerts.js
@@ -0,0 +1,261 @@
+"use strict";
+
+/*
+To change this file you will have to add a function to download a file in toolkit/components/certviewer/content/certviewer.mjs (e.g: https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server),
+download adjustedCerts (e.g: download("out.txt", JSON.stringify(adjustedCerts)), do it after this line https://searchfox.org/mozilla-central/rev/e3fc8f8970491aef14d3212b2d052942f4d29818/toolkit/components/certviewer/content/certviewer.mjs#428),
+then open Nightly and go to about:certificate?cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D
+open the file, and finally copy and paste it here like
+
+const adjustedCerts = <what you just copied>;
+*/
+
+const adjustedCerts = [
+ {
+ certItems: [
+ {
+ sectionId: "subject-name",
+ sectionItems: [
+ { labelId: "business-category", info: "Private Organization" },
+ { labelId: "inc-country", info: "US" },
+ { labelId: "inc-state-province", info: "Delaware" },
+ { labelId: "serial-number", info: "5157550" },
+ { labelId: "country", info: "US" },
+ { labelId: "state-province", info: "California" },
+ { labelId: "locality", info: "San Francisco" },
+ { labelId: "organization", info: "GitHub, Inc." },
+ { labelId: "common-name", info: "github.com" },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "issuer-name",
+ sectionItems: [
+ { labelId: "country", info: "US" },
+ { labelId: "organization", info: "DigiCert Inc" },
+ { labelId: "organizational-unit", info: "www.digicert.com" },
+ {
+ labelId: "common-name",
+ info: "DigiCert SHA2 Extended Validation Server CA",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "validity",
+ sectionItems: [
+ {
+ labelId: "not-before",
+ info: {
+ local: "5/7/2018, 9:00:00 PM (Brasilia Standard Time)",
+ utc: "Tue, 08 May 2018 00:00:00 GMT",
+ },
+ },
+ {
+ labelId: "not-after",
+ info: {
+ local: "6/3/2020, 9:00:00 AM (Brasilia Standard Time)",
+ utc: "Wed, 03 Jun 2020 12:00:00 GMT",
+ },
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "subject-alt-names",
+ sectionItems: [
+ { labelId: "dns-name", info: "github.com" },
+ { labelId: "dns-name", info: "www.github.com" },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "public-key-info",
+ sectionItems: [
+ { labelId: "algorithm", info: "RSA" },
+ { labelId: "key-size", info: 2048 },
+ { labelId: "exponent", info: 65537 },
+ {
+ labelId: "modulus",
+ info: "C6:3C:AA:F2:3C:97:0C:3A:C1:4F:28:AD:72:70:7D:D3:CE:B9:B5:60:73:A4:74:9B:8A:77:46:FD:7A:98:42:4C:C5:30:19:57:9A:A9:33:0B:E1:5D:4D:10:58:CA:77:99:C3:93:F3:F9:75:90:BC:BF:BB:E0:95:BA:2E:C5:8D:73:61:05:D3:10:84:A8:B3:89:B8:2F:73:8C:F0:2A:6E:BE:EE:AE:83:4B:82:11:B1:61:FD:77:61:DA:9B:1B:9A:23:FF:8C:7E:A2:01:06:DD:D1:7F:53:96:08:C1:5A:FA:E7:C0:CA:C8:44:8C:57:A7:A8:61:5F:66:0D:57:D3:B8:96:AC:B6:4A:9C:C1:EA:E8:FB:96:40:29:F6:15:30:B5:04:B0:CC:05:B6:84:C3:24:59:95:7F:A2:65:90:E5:B0:B3:1A:75:59:C4:3F:31:14:0A:D5:CC:AA:3A:85:05:52:06:32:96:07:61:DF:27:82:0C:F7:85:DB:60:31:F0:09:50:C5:B7:1A:23:E1:B0:7D:02:F5:14:1E:C9:CB:E8:7E:2A:33:04:F6:51:3F:52:98:15:E9:0B:76:47:5C:4D:4A:6B:C5:08:15:AE:F8:D1:57:E9:EA:70:14:FF:C9:45:B9:0C:7C:BC:F4:6D:E6:05:52:F9:8C:80:BB:70:56:91:0F:4B",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "miscellaneous",
+ sectionItems: [
+ {
+ labelId: "serial-number",
+ info: "0A:06:30:42:7F:5B:BC:ED:69:57:39:65:93:B6:45:1F",
+ },
+ {
+ labelId: "signature-algorithm",
+ info: "SHA-256 with RSA Encryption",
+ },
+ { labelId: "version", info: "3" },
+ {
+ labelId: "download",
+ info: "PEM (cert)PEM (chain)",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "fingerprints",
+ sectionItems: [
+ {
+ labelId: "sha-256",
+ info: "31:11:50:0C:4A:66:01:2C:DA:E3:33:EC:3F:CA:1C:9D:DE:45:C9:54:44:0E:7E:E4:13:71:6B:FF:36:63:C0:74",
+ },
+ {
+ labelId: "sha-1",
+ info: "CA:06:F5:6B:25:8B:7A:0D:4F:2B:05:47:09:39:47:86:51:15:19:84",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "basic-constraints",
+ sectionItems: [{ labelId: "certificate-authority", info: false }],
+ Critical: true,
+ },
+ {
+ sectionId: "key-usages",
+ sectionItems: [
+ {
+ labelId: "purposes",
+ info: ["Digital Signature", "Key Encipherment"],
+ },
+ ],
+ Critical: true,
+ },
+ {
+ sectionId: "extended-key-usages",
+ sectionItems: [
+ {
+ labelId: "purposes",
+ info: ["Server Authentication", "Client Authentication"],
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "subject-key-id",
+ sectionItems: [
+ {
+ labelId: "key-id",
+ info: "C9:C2:53:61:66:9D:5F:AB:25:F4:26:CD:0F:38:9A:A8:49:EA:48:A9",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "authority-key-id",
+ sectionItems: [
+ {
+ labelId: "key-id",
+ info: "3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "crl-endpoints",
+ sectionItems: [
+ {
+ labelId: "distribution-point",
+ info: "http://crl3.digicert.com/sha2-ev-server-g2.crl",
+ },
+ {
+ labelId: "distribution-point",
+ info: "http://crl4.digicert.com/sha2-ev-server-g2.crl",
+ },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "authority-info-aia",
+ sectionItems: [
+ { labelId: "location", info: "http://ocsp.digicert.com" },
+ {
+ labelId: "method",
+ info: "Online Certificate Status Protocol (OCSP)",
+ },
+ {
+ labelId: "location",
+ info: "http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt",
+ },
+ { labelId: "method", info: "CA Issuers" },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "certificate-policies",
+ sectionItems: [
+ {
+ labelId: "policy",
+ info: "ANSI Organizational Identifier ( 2.16.840 )",
+ },
+ { labelId: "value", info: "2.16.840.1.114412.2.1" },
+ {
+ labelId: "qualifier",
+ info: "Practices Statement ( 1.3.6.1.5.5.7.2.1 )",
+ },
+ { labelId: "value", info: "https://www.digicert.com/CPS" },
+ { labelId: "policy", info: "Certificate Type ( 2.23.140.1.1 )" },
+ { labelId: "value", info: "Extended Validation" },
+ ],
+ Critical: false,
+ },
+ {
+ sectionId: "embedded-scts",
+ sectionItems: [
+ {
+ labelId: "logid",
+ info: "A4:B9:09:90:B4:18:58:14:87:BB:13:A2:CC:67:70:0A:3C:35:98:04:F9:1B:DF:B8:E3:77:CD:0E:C8:0D:DC:10",
+ },
+ { labelId: "name", info: "Google “Pilot”" },
+ { labelId: "signaturealgorithm", info: "SHA-256 ECDSA" },
+ { labelId: "version", info: 1 },
+ {
+ labelId: "timestamp",
+ info: {
+ local: "5/8/2018, 5:12:39 PM (Brasilia Standard Time)",
+ utc: "Tue, 08 May 2018 20:12:39 GMT",
+ },
+ },
+ {
+ labelId: "logid",
+ info: "56:14:06:9A:2F:D7:C2:EC:D3:F5:E1:BD:44:B2:3E:C7:46:76:B9:BC:99:11:5C:C0:EF:94:98:55:D6:89:D0:DD",
+ },
+ { labelId: "name", info: "DigiCert Server" },
+ { labelId: "signaturealgorithm", info: "SHA-256 ECDSA" },
+ { labelId: "version", info: 1 },
+ {
+ labelId: "timestamp",
+ info: {
+ local: "5/8/2018, 5:12:39 PM (Brasilia Standard Time)",
+ utc: "Tue, 08 May 2018 20:12:39 GMT",
+ },
+ },
+ {
+ labelId: "logid",
+ info: "BB:D9:DF:BC:1F:8A:71:B5:93:94:23:97:AA:92:7B:47:38:57:95:0A:AB:52:E8:1A:90:96:64:36:8E:1E:D1:85",
+ },
+ { labelId: "name", info: "Google “Skydiver”" },
+ { labelId: "signaturealgorithm", info: "SHA-256 ECDSA" },
+ { labelId: "version", info: 1 },
+ {
+ labelId: "timestamp",
+ info: {
+ local: "5/8/2018, 5:12:39 PM (Brasilia Standard Time)",
+ utc: "Tue, 08 May 2018 20:12:39 GMT",
+ },
+ },
+ ],
+ Critical: false,
+ },
+ ],
+ tabName: "github.com",
+ },
+];
diff --git a/toolkit/components/certviewer/tests/browser/browser.toml b/toolkit/components/certviewer/tests/browser/browser.toml
new file mode 100644
index 0000000000..c4fb2be753
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser.toml
@@ -0,0 +1,38 @@
+[DEFAULT]
+support-files = [
+ "head.js",
+ "adjustedCerts.js",
+]
+
+["browser_aboutcertificateviewer.js"]
+
+["browser_certificateTabLink.js"]
+
+["browser_checkAuthorityKeyID.js"]
+
+["browser_checkLongHex.js"]
+
+["browser_checkMissingCommonName.js"]
+
+["browser_checkNonEmptyFields.js"]
+
+["browser_checkNonRepeatedCertTabs.js"]
+
+["browser_checkNonUndefinedStrings.js"]
+
+["browser_checkOCSP.js"]
+skip-if = ["true"] # Bug 1596313
+
+["browser_checkStandAlonePage.js"]
+
+["browser_checkValiditySection.js"]
+
+["browser_downloadLink.js"]
+
+["browser_handleMultipleCertsURL.js"]
+skip-if = ["true"] # Bug 1626853
+
+["browser_openTabAndSendCertInfo.js"]
+support-files = ["dummy_page.html"]
+
+["browser_renderCertToUI.js"]
diff --git a/toolkit/components/certviewer/tests/browser/browser_aboutcertificateviewer.js b/toolkit/components/certviewer/tests/browser/browser_aboutcertificateviewer.js
new file mode 100644
index 0000000000..efd78fc6f5
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_aboutcertificateviewer.js
@@ -0,0 +1,81 @@
+/* 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 validCert =
+ "about:certificate?cert=MIIGMDCCBRigAwIBAgIQCa2oS7Nau6nwv1WyRNIJnzANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFNlcnZlciBDQTAeFw0xOTA2MDYwMDAwMDBaFw0xOTA5MDQxMjAwMDBaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTETMBEGA1UEBxMKTWVubG8gUGFyazEXMBUGA1UEChMORmFjZWJvb2ssIEluYy4xFzAVBgNVBAMMDiouZmFjZWJvb2suY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEALPlfjd8gHkIMDeBOFhRt0e%2B%2F3fdm%2BZdzdM4s1WIHVbYztgmdEy20PUwDCviYKJX4GG%2BT9ivT8kJ%2FvWl1P%2FYqOCA54wggOaMB8GA1UdIwQYMBaAFFFo%2F5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQWBBTsQZVRTuib7KY9w3FfOYsZHvOC9zCBxwYDVR0RBIG%2FMIG8gg4qLmZhY2Vib29rLmNvbYINbWVzc2VuZ2VyLmNvbYILKi5mYmNkbi5uZXSCCCouZmIuY29tghAqLm0uZmFjZWJvb2suY29tggZmYi5jb22CDiouZmFjZWJvb2submV0gg4qLnh4LmZiY2RuLm5ldIIOKi54ei5mYmNkbi5uZXSCDyoubWVzc2VuZ2VyLmNvbYILKi5mYnNieC5jb22CDioueHkuZmJjZG4ubmV0ggxmYWNlYm9vay5jb20wDgYDVR0PAQH%2FBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzYuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABay5CAaUAAAQDAEYwRAIgMwBM6q%2BdBwu2mNtMMjTEwJZZxyoUlHUEYO%2BbfkId%2F9MCIAQ2bxhnxrapYv74fzyoTkt9m%2BELq6%2B43OVpivRVKDKTAHcAdH7agzGtMxCRIZzOJU9CcMK%2F%2FV5CIAjGNzV55hB7zFYAAAFrLkIA%2FAAABAMASDBGAiEA0x1xPWue6RMSE9nbjYBt637CRC86ixrODP%2FEIlI5mCgCIQCHNdqgOlswd0LqaW4QRii2JHN4bnoEj%2FD9j7%2BkqEB7LjANBgkqhkiG9w0BAQsFAAOCAQEAnRdIVNZ850s7IvLgg%2BU9kKxA18kLKVpIF%2FrJHkXTkymvBHKAGOFNfzqF2YxHFhkDMIuoMO2F%2BA1E0Eo8zb1atL6%2FL59broEHTOH6xFmJAlZW0h6mZg8iRJ9Ae0pTN%2FfowaoN9aFVRnVr9ccKhOdqsXYyEZ3Ze39sEwx7Uau9KhzyuJW12Jh3S%2BZJYUdBADeeJNL5ZXSUFIyjgkwSQZPaaWAzSGHZFt3sWhMjdNoBkjRJFlASLDM3m1ZWsKA47vuXvJc%2FDXT35lC1DJmyhYb9qNPR71a1hJ8TS7vUwdDd%2BdEHiJj2wQLV3m7Tn7YvWyJOEyi4n6%2FrPqT44LZmgK7HWw%3D%3D&cert=MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3VyYW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC24C%2FCJAbIbQRf1%2B8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU%2BUDlqUH1VWtMICKq%2FQmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK%2FIHe1NnF9Xt4ZQaJn1itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j%2F018QsIJzJa9buLnqS9UdAn4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I%2B4G3FhahnSMSTeXXkgisdaScus0Xsh5ENWV%2FUyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcftbZvySC%2FzA%2FWiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH%2FAgEAMA4GA1UdDwEB%2FwQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUUWj%2FkK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwdaOpKj4PWUS%2BNa0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk%2FgNHE%2Br1hspZcX30BJZr01lYPf7TMSVcGDiEo%2Bafgv2MW5gxTs14nhr9hctJqvIni5ly%2FD6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zuxICaEnL6VpPX%2F78whQYwvwt%2FTv9XBZ0k7YXDK%2FumdaisLRbvfXknsuvCnQsH6qqF0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY%2B3sAzm2fTYS5yh%2BRp%2FBIAV0AecPUeybQ%3D&cert=MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm%2B9S75S0tMqbf5YE%2Fyc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG%2B%2BMXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx%2BmM0aBhakaHPQNAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH%2FBAQDAgGGMA8GA1UdEwEB%2FwQFMAMBAf8wHQYDVR0OBBYEFLE%2Bw2kD%2BL9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE%2Bw2kD%2BL9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe%2FEW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9%2BMpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2Yzi9RKR%2F5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2%2FS6cCZdkGCevEsXCS%2B0yx5DaMkHJ8HSXPfqIbloEpw8nL%2Be%2FIBcm2PN7EeqJSdnoDfzAIJ9VNep%2BOkuE6N36B9K";
+
+const invalidCert = "about:certificate?cert=MIIH";
+
+const pem_to_der_error = "about:certificate?cert=MIIHQ";
+
+const error_parsing_cert =
+ "about:certificate?cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO11MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D";
+
+async function checkForErrorSection(infoMessage, url, errorMessage, testType) {
+ info(infoMessage);
+
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [{ errorMessage, testType }],
+ async function ({ errorMessage, testType }) {
+ let errorSection;
+
+ if (testType === "invalid") {
+ await ContentTaskUtils.waitForCondition(() => {
+ return (errorSection = content.document
+ .querySelector("certificate-section")
+ .shadowRoot.querySelector("error-section"));
+ }, errorMessage);
+ ok(errorSection, errorMessage);
+ } else if (testType === "valid") {
+ ok(!errorSection, errorMessage);
+ }
+ }
+ );
+ });
+}
+
+add_task(async function test_checkForErrorSection() {
+ let itemsToTest = [
+ {
+ testType: "valid",
+ url: validCert,
+ infoMessage: "Testing for error when a valid certificate is provided.",
+ errorMessage:
+ "Error section should not be visible when URL contains a valid certificate.",
+ },
+ {
+ testType: "invalid",
+ url: invalidCert,
+ infoMessage: "Testing for error when invalid certificate is provided.",
+ errorMessage:
+ "Error section should be visible when certificate is invalid.",
+ },
+ {
+ testType: "invalid",
+ url: pem_to_der_error,
+ infoMessage: "Testing for error when PEM to DIR error occurs.",
+ errorMessage:
+ "Error section should be visible when PEM to DIR error occurs.",
+ },
+ {
+ testType: "invalid",
+ url: error_parsing_cert,
+ infoMessage: "Testing for error when parsing error occurs.",
+ errorMessage:
+ "Error section should be visible when parsing error occurs.",
+ },
+ ];
+
+ for (let i = 0; i < itemsToTest.length; i++) {
+ let item = itemsToTest[i];
+ await checkForErrorSection(
+ item.infoMessage,
+ item.url,
+ item.errorMessage,
+ item.testType
+ );
+ }
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_certificateTabLink.js b/toolkit/components/certviewer/tests/browser/browser_certificateTabLink.js
new file mode 100644
index 0000000000..9c88d2bb03
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_certificateTabLink.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const validCert =
+ "about:certificate?cert=MIIGMDCCBRigAwIBAgIQCa2oS7Nau6nwv1WyRNIJnzANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFNlcnZlciBDQTAeFw0xOTA2MDYwMDAwMDBaFw0xOTA5MDQxMjAwMDBaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTETMBEGA1UEBxMKTWVubG8gUGFyazEXMBUGA1UEChMORmFjZWJvb2ssIEluYy4xFzAVBgNVBAMMDiouZmFjZWJvb2suY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEALPlfjd8gHkIMDeBOFhRt0e%2B%2F3fdm%2BZdzdM4s1WIHVbYztgmdEy20PUwDCviYKJX4GG%2BT9ivT8kJ%2FvWl1P%2FYqOCA54wggOaMB8GA1UdIwQYMBaAFFFo%2F5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQWBBTsQZVRTuib7KY9w3FfOYsZHvOC9zCBxwYDVR0RBIG%2FMIG8gg4qLmZhY2Vib29rLmNvbYINbWVzc2VuZ2VyLmNvbYILKi5mYmNkbi5uZXSCCCouZmIuY29tghAqLm0uZmFjZWJvb2suY29tggZmYi5jb22CDiouZmFjZWJvb2submV0gg4qLnh4LmZiY2RuLm5ldIIOKi54ei5mYmNkbi5uZXSCDyoubWVzc2VuZ2VyLmNvbYILKi5mYnNieC5jb22CDioueHkuZmJjZG4ubmV0ggxmYWNlYm9vay5jb20wDgYDVR0PAQH%2FBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzYuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABay5CAaUAAAQDAEYwRAIgMwBM6q%2BdBwu2mNtMMjTEwJZZxyoUlHUEYO%2BbfkId%2F9MCIAQ2bxhnxrapYv74fzyoTkt9m%2BELq6%2B43OVpivRVKDKTAHcAdH7agzGtMxCRIZzOJU9CcMK%2F%2FV5CIAjGNzV55hB7zFYAAAFrLkIA%2FAAABAMASDBGAiEA0x1xPWue6RMSE9nbjYBt637CRC86ixrODP%2FEIlI5mCgCIQCHNdqgOlswd0LqaW4QRii2JHN4bnoEj%2FD9j7%2BkqEB7LjANBgkqhkiG9w0BAQsFAAOCAQEAnRdIVNZ850s7IvLgg%2BU9kKxA18kLKVpIF%2FrJHkXTkymvBHKAGOFNfzqF2YxHFhkDMIuoMO2F%2BA1E0Eo8zb1atL6%2FL59broEHTOH6xFmJAlZW0h6mZg8iRJ9Ae0pTN%2FfowaoN9aFVRnVr9ccKhOdqsXYyEZ3Ze39sEwx7Uau9KhzyuJW12Jh3S%2BZJYUdBADeeJNL5ZXSUFIyjgkwSQZPaaWAzSGHZFt3sWhMjdNoBkjRJFlASLDM3m1ZWsKA47vuXvJc%2FDXT35lC1DJmyhYb9qNPR71a1hJ8TS7vUwdDd%2BdEHiJj2wQLV3m7Tn7YvWyJOEyi4n6%2FrPqT44LZmgK7HWw%3D%3D&cert=MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3VyYW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC24C%2FCJAbIbQRf1%2B8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU%2BUDlqUH1VWtMICKq%2FQmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK%2FIHe1NnF9Xt4ZQaJn1itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j%2F018QsIJzJa9buLnqS9UdAn4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I%2B4G3FhahnSMSTeXXkgisdaScus0Xsh5ENWV%2FUyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcftbZvySC%2FzA%2FWiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH%2FAgEAMA4GA1UdDwEB%2FwQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUUWj%2FkK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwdaOpKj4PWUS%2BNa0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk%2FgNHE%2Br1hspZcX30BJZr01lYPf7TMSVcGDiEo%2Bafgv2MW5gxTs14nhr9hctJqvIni5ly%2FD6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zuxICaEnL6VpPX%2F78whQYwvwt%2FTv9XBZ0k7YXDK%2FumdaisLRbvfXknsuvCnQsH6qqF0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY%2B3sAzm2fTYS5yh%2BRp%2FBIAV0AecPUeybQ%3D&cert=MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm%2B9S75S0tMqbf5YE%2Fyc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG%2B%2BMXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx%2BmM0aBhakaHPQNAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH%2FBAQDAgGGMA8GA1UdEwEB%2FwQFMAMBAf8wHQYDVR0OBBYEFLE%2Bw2kD%2BL9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE%2Bw2kD%2BL9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe%2FEW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9%2BMpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2Yzi9RKR%2F5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2%2FS6cCZdkGCevEsXCS%2B0yx5DaMkHJ8HSXPfqIbloEpw8nL%2Be%2FIBcm2PN7EeqJSdnoDfzAIJ9VNep%2BOkuE6N36B9K";
+
+add_task(async function test_certificateTabLink() {
+ await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
+ gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, validCert);
+ });
+
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
+ let certificateTabs;
+ await ContentTaskUtils.waitForCondition(() => {
+ certificateTabs = content.document
+ .querySelector("certificate-section")
+ .shadowRoot.querySelectorAll(".certificate-tab");
+ return certificateTabs.length;
+ }, "Found certificate tabs.");
+
+ ok(certificateTabs.length, "Certificate tabs should exist.");
+
+ let issuerNameGroups = content.document
+ .querySelector("certificate-section")
+ .shadowRoot.querySelectorAll(".issuer-name");
+ let issuerNames = [];
+ for (let i = 0; i < issuerNameGroups.length; i++) {
+ issuerNames.push(
+ issuerNameGroups[i].shadowRoot.querySelector(".common-name")
+ );
+ }
+
+ for (let i = 0; i < issuerNames.length; i++) {
+ if (i < issuerNames.length - 1) {
+ issuerNames[i].shadowRoot.querySelector("a").click();
+ await ContentTaskUtils.waitForCondition(() => {
+ return certificateTabs[i + 1].classList.contains("selected");
+ }, "Clicking link should select new tab.");
+ ok(
+ certificateTabs[i + 1].classList.contains("selected"),
+ "Clicking link should select new tab."
+ );
+ } else {
+ await ContentTaskUtils.waitForCondition(() => {
+ return certificateTabs[i].classList.contains("selected");
+ }, "Clicking link should select new tab.");
+ ok(
+ certificateTabs[i].classList.contains("selected"),
+ "Clicking link should select new tab."
+ );
+ ok(
+ !issuerNames[i].shadowRoot.querySelector("a"),
+ "Final tab's issuer name should not be link."
+ );
+ }
+ }
+ });
+ gBrowser.removeCurrentTab(); // closes about:certificate
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkAuthorityKeyID.js b/toolkit/components/certviewer/tests/browser/browser_checkAuthorityKeyID.js
new file mode 100644
index 0000000000..a923f7acb3
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkAuthorityKeyID.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+async function checkAuthorityKeyID(url, expectedKeyId) {
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [expectedKeyId],
+ async function (expectedKeyId) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+ let authorityKeySection =
+ certificateSection.shadowRoot.querySelector(".authority-key-id");
+ let subjectNameSection =
+ certificateSection.shadowRoot.querySelector(".subject-name");
+ if (!expectedKeyId) {
+ Assert.equal(authorityKeySection, null, "authorityKeySection found");
+ Assert.ok(subjectNameSection, "subjectNameSection found");
+ return;
+ }
+ Assert.ok(authorityKeySection, "authorityKeySection found");
+ let item = authorityKeySection.shadowRoot.querySelector("info-item");
+ Assert.ok(item, "item found");
+ let info = item.shadowRoot.querySelector(".info").textContent;
+ Assert.equal(info, expectedKeyId, "Key IDs must be equal");
+ }
+ );
+ });
+}
+
+add_task(async function test() {
+ let tests = [
+ {
+ url: "about:certificate?cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D",
+ expectedKeyId:
+ "3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F",
+ },
+ {
+ url: "about:certificate?cert=MIIGdjCCBF6gAwIBAgIBJjANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJKRTEPMA0GA1UECAwGSmVyc2V5MRUwEwYDVQQKDAx0Z2hvc3QuY28udWsxFTATBgNVBAMMDHRnaG9zdC5jby51azEmMCQGCSqGSIb3DQEJARYXcG9zdG1hc3RlckB0Z2hvc3QuY28udWswHhcNMTkxMTE4MjE1NjAwWhcNMjAxMTE3MjE1NjAwWjBRMQswCQYDVQQGEwJKRTEPMA0GA1UECAwGSmVyc2V5MRUwEwYDVQQKDAx0Z2hvc3QuY28udWsxGjAYBgNVBAMMEW1haWwudGdob3N0LmNvLnVrMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0CS0dR6hyjv4o6s4%2FI2VT43DCfylcaq%2F6%2B5tUn6xMDtf0tYMXPjG%2FGjtlXQk2Jq7wa%2FlRR%2Fzs8c6037BZ7wzu8Wx2i6tvRLZZSlzM2mRHxaRRDYTeHyovanhCFzKqnvi30bxKugQ3lETBK5eP7ppVpcHz58lx%2B%2BFovPOBx6SRaz4EiceUybZwFpKxUJmlhivT2MJTKM5NHF4n27vszM0dyu2qXLzhpy5dgklMEEhdnHFCT%2F9YPN7uLCvzJnCo9N%2FeWf84odJ%2FjTiEKm5NG6SGDuOZ%2FbY9KwQ8nAk26zeTkw%2BMfMXD2Rl76ZFg%2B07bpckSTiaCtLGGhbgLrqEdgNGTpz1Pu3uFjhR4QsfUsDAaSvgns0PT6eSA152cgOtin2SYo%2B4UVjVdM5d%2ByB0JgEIGHmiCRQkDdCD9%2FNZBhrnG2Xwooe64QzD5OjNS8yQSCPvjfivbSk1ulcIGjgxC0z1Ot4hc%2ByuU8aRE0ekIOf5EUEjZfJ%2FnO4EXT3J5en0CYurswJM7miOsVEiO1OIut022T00MoAF%2F%2FWP73qVW3Jbv6X0pzOBYDY3osyje4n6JRqujhPEOR0MNiaZxfz4JFNPAzi0Tq6qORbXbLgGBqPFvKh2KKIMGysfRqLlETI1lpqsHyhMxgllQW9IK33kwK9y0HgluEZvc58dvle8hOS4NK8CAwEAAaOCATQwggEwMAkGA1UdEwQCMAAwHQYDVR0OBBYEFORJOggtlruQ1S6vzucFiAS86CadMIGQBgNVHSMEgYgwgYWheKR2MHQxCzAJBgNVBAYTAkpFMQ8wDQYDVQQIDAZKZXJzZXkxFTATBgNVBAoMDHRnaG9zdC5jby51azEVMBMGA1UEAwwMdGdob3N0LmNvLnVrMSYwJAYJKoZIhvcNAQkBFhdwb3N0bWFzdGVyQHRnaG9zdC5jby51a4IJAMeNizC6cTabMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly93d3cudGdob3N0LmNvLnVrL2NhL2NybC5wZW0wCwYDVR0PBAQDAgP4MBEGCWCGSAGG%2BEIBAQQEAwIE8DAcBgNVHREEFTATghFtYWlsLnRnaG9zdC5jby51azANBgkqhkiG9w0BAQsFAAOCAgEAKZC9pqgU9MPssbNeJhKeGcCoH49BhfhrJNPkWqlJ%2FVbUB32m8p%2F7exaqFEe%2Fk2YwV8ILMA%2FCvQLgeV36Y9rHcWKqaA8lrklhRkK6%2BfYkAkpw37vVbm8qWsTt4OMa0Ajh%2F7QBy%2FUqak8Gaarl3LkJKLKB3Pj%2Bd2BFNxNm5W3TeFia2s%2B5y0O0eKqSQwRPqlQo3qhNQU1fDimTq8yI3fH9AOByWXHePjSc5h45GHxWoXPqQKtuqCINou6pKeZa1KoTCefB2oYJqamkneL2%2B21JhwkSVkGUfseGc2hiROVLejc%2Fgzq7mpUqudOsyN672BwB6W81w6%2FHCt2cZmCTWAAT5E3b6bHqqTTn9O2uljx2zTxao5Xov4L9EZ3hdccsLJGXHYgGDqY33e6Rrf86Jc%2BV%2F4%2FL8vhGf%2B70ASKLkibUuGwFJ0%2BamQHoHnVXLZ5rnbV3ArXOQcsfegTifmEPn7pGyHm7r5%2BkJ2JIh8wCyl5B%2FUxvNwIfAFEiieU3aqRAgbjnezYXwoLoLJBKSRMXdIfZJldduIkoPaeO0zWWaJSMon3qTAeDuboM4EfYG9Ma3UWdznXVkmgiXFo%2Fz6k%2Bg4jNzaQknI8jNHbp9G5K7M9KPcvUja8hjeGG4RIULKDdkauZUe1hX6m3NrzrJLD3MJPD8YTFeAf%2Fe3HCGwl4stKWHg4%3D&cert=MIIFZDCCA0wCCQDHjYswunE2mzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJKRTEPMA0GA1UECAwGSmVyc2V5MRUwEwYDVQQKDAx0Z2hvc3QuY28udWsxFTATBgNVBAMMDHRnaG9zdC5jby51azEmMCQGCSqGSIb3DQEJARYXcG9zdG1hc3RlckB0Z2hvc3QuY28udWswHhcNMTgwNDA4MTIyMjU0WhcNMjMwNDA4MTIyMjU0WjB0MQswCQYDVQQGEwJKRTEPMA0GA1UECAwGSmVyc2V5MRUwEwYDVQQKDAx0Z2hvc3QuY28udWsxFTATBgNVBAMMDHRnaG9zdC5jby51azEmMCQGCSqGSIb3DQEJARYXcG9zdG1hc3RlckB0Z2hvc3QuY28udWswggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCoFbHy44GNOQSymk%2BwAmZmllcAATSM6DrsW7NZgX8vHeP5OAlRaGaOgVmozKcbKSB2KSIvDvY1%2BKEKtfr5meIaeA6r%2BILeUYuNxQomnW3Oy%2B%2B7RFE53pS7R7QIt%2FLVf3k60mdZDLXF1wyFv950noGNrFZfvBvND1%2F88JeC4Gt7dVnJMy9CXOr7V0O%2F7sa5z%2Bvfm2Acufd1RYA3W%2FECbt%2F6z8KV%2FQthAgcYoabQgkmh8AxQ5cG7tBmoEAs%2BNwU%2BR8eMq1f%2B6TBCJiMa07jA1%2BQ663d7YONlk4fTSmvo3lEhXtrR%2BmrkxZAMiAD6NJs3VakcuAED9e1dS3G3%2FmPcNrKsa73aXEC5uvL9y4mKCZLypuSYjlW8cP5JpCG6vtmwL%2FATbcCtwpDwrKLcRWCrZdX0FOJirjWfKL%2BhyIWayQ5u7awdhH430h8rj03fXSMBhtTn73rohSGIANBnqVftvDDPnEQb5p17giaVbJybfA2tdMvJTZg6pEAx9%2B3zHXRECFpWOtaJDjWbmIExPMgiCSFkBPP3MEDVb7VdHKZs0CvBQg6GmpXg9M4OHZylzS6PXXO8qBCtBdKOwdFSZWbeD9E652rkvb5FuQ8laGHcxgMc2YFlVZaqVowXEkVkkld12d4sBipeRpDWNjA2kLfeUmwsXWtugG8c8Jm9IoZY8oeUkwIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCVj6R9C5pE9hkBx7CCr9l4TLoolaEZlKngJHBRRSy5U50MndQ24Jeis2OTxEeYX7DJ%2BOy6QZdaph6FLwALxUWPfQavBcgauKR%2FCdqLQxZc267TMFkRIZvOtHUJ4obJ5qvQAWzNnmRq18b5plznfBfn9b3F2AmHgfsNX6WryQ4geR786VObcUhKTaofcaX%2FE4J9AVzL864fJ%2FDB%2FPSqhYrtskiG6PT9Ngu20ejvgAVk5aJ%2F%2F5Swsjyg6EBl%2BdwJepq2xzI313ZkwCg2pp6oqLDlxf%2Fh585Bsqke39Ax%2B42NWNM14cethcJ7jgyZoEaL3T%2BQ3O%2Bj9XEe5FbvkKtSgMIA6f0FneA4vbF8%2FECPMEi7k3k04gU1gZSR%2FGA63GPEK%2FCLqeh%2BYVgBGKDPinnMEV%2FuBrTUDQFBlDEHlELk7F9o93lxQNs6WOGQSfybfHhySla3nqoYV2phyeZZsJ%2BxMovWWIydJhVN%2F37v0fYTZhnlquGenXHvC5MHrMq2vjUY0Uy637AzXWVNWveNyQmmn9tL4jygELHQu%2Bint4GRybH7rThcslv63D5s4zZza7cITIFjmqZ%2BPrTSVKL%2BlnQLjEMpSdfB86Y2JnMimaOyv%2BbZp1QMB5fYh0PTsjYATi9We%2BDFD42c5H7Su0vFAwCTP11AiKzfbj2oBKVVwwJj3FmkYQ%3D%3D",
+ expectedKeyId: false,
+ },
+ ];
+
+ for (let test of tests) {
+ await checkAuthorityKeyID(test.url, test.expectedKeyId);
+ }
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkLongHex.js b/toolkit/components/certviewer/tests/browser/browser_checkLongHex.js
new file mode 100644
index 0000000000..01b54c083b
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkLongHex.js
@@ -0,0 +1,38 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+async function checkLongHex(url, itemClass) {
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(browser, [itemClass], async function (itemClass) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+ let publicKeyInfoSection =
+ certificateSection.shadowRoot.querySelector(".public-key-info");
+ Assert.ok(publicKeyInfoSection, "publicKeyInfoSection found");
+
+ let item = publicKeyInfoSection.shadowRoot.querySelector(`.${itemClass}`);
+ Assert.ok(item, `item ${itemClass} found`);
+
+ let longHex = item.shadowRoot.querySelector(".long-hex");
+ Assert.ok(longHex, "longHex class name found");
+ });
+ });
+}
+
+add_task(async function test() {
+ let tests = [
+ {
+ url: "about:certificate?cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D",
+ itemClass: "modulus",
+ },
+ {
+ url: "about:certificate?cert=MIIIMTCCBxmgAwIBAgIMFkDF1F0uxNlMfXxqMA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYDVQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hBMjU2IC0gRzIwHhcNMTgxMTA4MjEyMTA0WhcNMTkxMTIyMDc1OTU5WjB5MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEjMCEGA1UEChMaV2lraW1lZGlhIEZvdW5kYXRpb24sIEluYy4xGDAWBgNVBAMMDyoud2lraXBlZGlhLm9yZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGd1rS7GauMxJ15BmViShjVMjwQJNjjw%2BOUhnIaqE5QF%2Fq6c%2FLIvVh4N3473a7J52JcfmlfCrXvDthHzaZNEneKjggWVMIIFkTAOBgNVHQ8BAf8EBAMCA4gwgaAGCCsGAQUFBwEBBIGTMIGQME0GCCsGAQUFBzAChkFodHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc29yZ2FuaXphdGlvbnZhbHNoYTJnMnIxLmNydDA%2FBggrBgEFBQcwAYYzaHR0cDovL29jc3AyLmdsb2JhbHNpZ24uY29tL2dzb3JnYW5pemF0aW9udmFsc2hhMmcyMFYGA1UdIARPME0wQQYJKwYBBAGgMgEUMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMAgGBmeBDAECAjAJBgNVHRMEAjAAMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vZ3MvZ3Nvcmdhbml6YXRpb252YWxzaGEyZzIuY3JsMIICxQYDVR0RBIICvDCCAriCDyoud2lraXBlZGlhLm9yZ4INd2lraW1lZGlhLm9yZ4INbWVkaWF3aWtpLm9yZ4INd2lraWJvb2tzLm9yZ4IMd2lraWRhdGEub3Jnggx3aWtpbmV3cy5vcmeCDXdpa2lxdW90ZS5vcmeCDndpa2lzb3VyY2Uub3Jngg93aWtpdmVyc2l0eS5vcmeCDndpa2l2b3lhZ2Uub3Jngg53aWt0aW9uYXJ5Lm9yZ4IXd2lraW1lZGlhZm91bmRhdGlvbi5vcmeCBncud2lraYISd21mdXNlcmNvbnRlbnQub3JnghEqLm0ud2lraXBlZGlhLm9yZ4IPKi53aWtpbWVkaWEub3JnghEqLm0ud2lraW1lZGlhLm9yZ4IWKi5wbGFuZXQud2lraW1lZGlhLm9yZ4IPKi5tZWRpYXdpa2kub3JnghEqLm0ubWVkaWF3aWtpLm9yZ4IPKi53aWtpYm9va3Mub3JnghEqLm0ud2lraWJvb2tzLm9yZ4IOKi53aWtpZGF0YS5vcmeCECoubS53aWtpZGF0YS5vcmeCDioud2lraW5ld3Mub3JnghAqLm0ud2lraW5ld3Mub3Jngg8qLndpa2lxdW90ZS5vcmeCESoubS53aWtpcXVvdGUub3JnghAqLndpa2lzb3VyY2Uub3JnghIqLm0ud2lraXNvdXJjZS5vcmeCESoud2lraXZlcnNpdHkub3JnghMqLm0ud2lraXZlcnNpdHkub3JnghAqLndpa2l2b3lhZ2Uub3JnghIqLm0ud2lraXZveWFnZS5vcmeCECoud2lrdGlvbmFyeS5vcmeCEioubS53aWt0aW9uYXJ5Lm9yZ4IZKi53aWtpbWVkaWFmb3VuZGF0aW9uLm9yZ4IUKi53bWZ1c2VyY29udGVudC5vcmeCDXdpa2lwZWRpYS5vcmcwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSt4NNfC33t2i98DfZjjYpZGMJsijAfBgNVHSMEGDAWgBSW3mHxvRwWKVMcwMx9O4MAQOYafDCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABZvUzN%2FYAAAQDAEcwRQIgBATdvSzbd5NwGdtkmJ5SEvEPn6A8hgAsk6GSP6hzWcgCIQDKfHQNtObs%2FhHPfLgXsVkcnHIbjlNwmWeiukGtGHZFMgB2AG9Tdqwx8DEZ2JkApFEV%2F3cVHBHZAsEAKQaNsgiaN9kTAAABZvUzN8cAAAQDAEcwRQIgYalEnXtd%2FfPhjq9SXPoSPRhaMmeDs0IMN5o5Y6QTKfUCIQClR1uj%2BB56K4tGh%2Fmws4qugG1qSD9zfvmx8roKik3HHDANBgkqhkiG9w0BAQsFAAOCAQEAUEJyg%2FAZo%2BowG5J%2FLIk8EIDnyOcanmfgvdjMg8KnpBvh8l3Wb4HmOudluJhIeIbCUMwzEzSGqYQQ78n4wtjLaLwaDgL4WzHOVec2k%2BrbfmPT6MUCtdlz1PK5%2FWY9JQyQq6vy%2Btm3a6Wijy6M8U%2FTdrJubK5X03SFfRb0pDuFdr2fnkctLRnyCb1w0XHwGXjEcGm1LY42YKwdvbj3WIqumeSEuG4MZtquW6NURKELSil03G%2FhRHRAHHGx3zXes%2FjJcpH2GPX9eY9B%2BR1oHmCE2QF5Y%2FBh%2BuNA2%2B2Iuj%2F6UJAOw%2FZ%2F8%2BqZcnLWWnK2Dwzc34C%2FAUD%2BWb71oUcr60%2BpPg%3D%3D&cert=MIIEYjCCA0qgAwIBAgILBAAAAAABMYnGRMkwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTEwODAyMTAwMDAwWhcNMjIwODAyMTAwMDAwWjBmMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTE8MDoGA1UEAxMzR2xvYmFsU2lnbiBPcmdhbml6YXRpb24gVmFsaWRhdGlvbiBDQSAtIFNIQTI1NiAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxw5sPyOTf8xwpZ0gww5TP37ATsKYScpH1SPvAzSFdMijAi5GXAt9yYidT4vw%2BJxsjFU127%2Fys%2Br741bnSkbZEyLKNtWbwajjlkOT8gy85vnm6JnIY0h4f1c2aRoZHVrR1H3CnNR%2F4YASrnrqiOpX2MoKCjoSSaJiGXoNJPc367RzknsFI5sStc7rKd%2BkFAK5AaXUppxDZIje%2BH7%2B4%2FUe5f7co6jkZjHZTCXpGLmJWQmu6Z0cbTcPSh41ICjir9QhiwHERa1uK2OrkmthCk0g7XO6fM7%2BFrXbn4Dw1ots2Qh5Sk94ZdqSvL41%2BbPE%2BSeATv%2BWUuYCIOEHc%2BldK72y8QIDAQABo4IBKTCCASUwDgYDVR0PAQH%2FBAQDAgEGMBIGA1UdEwEB%2FwQIMAYBAf8CAQAwHQYDVR0OBBYEFJbeYfG9HBYpUxzAzH07gwBA5hp8MEcGA1UdIARAMD4wPAYEVR0gADA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0L3Jvb3QtcjMuY3JsMD4GCCsGAQUFBwEBBDIwMDAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AyLmdsb2JhbHNpZ24uY29tL3Jvb3RyMzAfBgNVHSMEGDAWgBSP8Et%2FqC5FJK5NUPpjmove4t0bvDANBgkqhkiG9w0BAQsFAAOCAQEAugYpwLQZjCERwJQRnrs91NVDQPafuyULI2i1Gvf6VGTMKxP5IfBEreHoFVjb7v3bok3MGI8Nmm3DawGhMfCNvABAzDlfh2FRbfSV6uoVNT5AhcBi1aE0%2FniqqLJaOfM3Qfuc6D5xSlvr%2BGlYoeDGk3fpumeS62VYkHBzQn2v9CMmeReq%2BqS7meVEb2WB58rrVcj0ticRIXSUvGu3dGIpxM2uR%2FLmQlt4hgVhy5CqeYnfBH6xJnBLjUAfhHvA%2BwfmyLdOkfQ1A%2B3o60EQF0m0YsinLPLhTI8DLPMWN11n8aQ5eUmjwF3MVfkhgA%2F7zuIpalhQ6abX6xwyNrVip8H65g%3D%3D&cert=MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie%2FQV2EcWtiHL8RgJDx7KKnQRfJMsuS%2BFggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ0mpiLx9e%2BpZo34knlTifBtc%2BycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO%2FbLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c%2B9C7v%2FU9AOEGM%2BiCK65TpjoWc4zdQQ4gOsC0p6Hpsk%2BQLjJg6VfLuQSSaGjlOCZgdbKfd%2F%2BRFO%2BuIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH%2FBAQDAgEGMA8GA1UdEwEB%2FwQFMAMBAf8wHQYDVR0OBBYEFI%2FwS3%2BoLkUkrk1Q%2BmOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr%2ByAzv95ZURUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q%2Fc2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj%2B9xTaGdWPoO4zzUhw8lo%2Fs7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj%2B1EbddTKJd%2B82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws%2FzyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9%2BE7gUJTb0o2HLO02JQZR7rkpeDMdmztcpHWD9f",
+ itemClass: "public-value",
+ },
+ ];
+
+ for (let test of tests) {
+ await checkLongHex(test.url, test.itemClass);
+ }
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkMissingCommonName.js b/toolkit/components/certviewer/tests/browser/browser_checkMissingCommonName.js
new file mode 100644
index 0000000000..e26612c1b8
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkMissingCommonName.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function test_check_missing_common_name() {
+ const kURL =
+ "about:certificate?cert=MIIHVDCCBTygAwIBAgIQOBNAgEopyUI1DYLsLmSWejANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ6KGM5pS%2F6ZmiMTUwMwYDVQQDDCzmlL%2FlupzkvLrmnI3lmajmlbjkvY3mhpHorYnnrqHnkIbkuK3lv4MgLSBHMTAeFw0yMDAxMjAwNjExMzBaFw0yMjAxMjAwNjExMzBaMFUxCzAJBgNVBAYTAlRXMQ8wDQYDVQQHDAboh7rngaMxEjAQBgNVBAoMCee4vee1seW6nDEhMB8GA1UEAwwYZW5nbGlzaC5wcmVzaWRlbnQuZ292LnR3MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyxCtEdUsGqr%2FVCNOMpj1TkDzBn6Gs1RBHHERU%2BsJ1q3ri6rJfydTx0rQKUbcGEMyWB2pga4dNSjzxQZ6%2BebP3kctC0H%2F%2BptEnsIOQcyD2yLN5yg8ejx6Y568z3fbU%2FRAVo4q6qGZzlBfzl2AhZMrp3AiNpQZXjLWgNHYZfirDVur7ImSjECq6atLlZ1yn%2B0RC%2FsGsPKalz5iacuxMYIkWeCvm7piA%2FdXPfw%2FVJxbIEkXMSXXxDNGrBZY0wAcmPeDHZxyLDGDOFLV%2Fpics3ZJ4UjFPphwaXuW94K9NKLcfOu7JaYP6JszpBIEiL8GRl8pMdykkKN%2FRkEZ%2F8pE7Tz%2BswIDAQABo4IDGzCCAxcwHwYDVR0jBBgwFoAU1ustnWH%2BK7twiC64B7FZsPSDImowHQYDVR0OBBYEFDxkjGSuIgKbFKTUvadNfX%2B%2BogdCMHUGCCsGAQUFBwEBBGkwZzA1BggrBgEFBQcwAoYpaHR0cDovL2d0bHNjYS5uYXQuZ292LnR3L0NlcnRzL0dUTFNDQS5jcnQwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmd0bHNjYS5uYXQuZ292LnR3L09DU1AwIgYDVR0gBBswGTANBgsrBgEEAYG3I2QAAzAIBgZngQwBAgIwIAYDVR0lAQH%2FBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCMGA1UdEQQcMBqCGGVuZ2xpc2gucHJlc2lkZW50Lmdvdi50dzAgBgNVHQkEGTAXMBUGB2CGdgFkAgExCgYIYIZ2AWQDAwEwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2d0bHNjYS5uYXQuZ292LnR3L2NybC9HVExTQ0EtY29tcGxldGUuY3JsMA4GA1UdDwEB%2FwQEAwIFoDCCAXwGCisGAQQB1nkCBAIEggFsBIIBaAFmAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9%2B443fNDsgN3BAAAAFvwZRvQAAABAMARjBEAiAWcMYq5U%2BiRndzk4q7XRQ10ykv%2FBlaHelk0SMi8LeXmAIgY%2BJUd3bzT5nSTCYQMOAMLGE52UWhnIRgxdWRtcg60uAAdQDuS723dc5guuFCaR%2Br4Z5mow9%2BX7By2IMAxHuJeqj9ywAAAW%2FBlHdGAAAEAwBGMEQCIAM72FPgBC6JzvE%2BEkvdp9g9Lt19fnJ6KfWQYNN%2BMylsAiBezZw%2FDzsg22O4Tr0QGYoY7HsnPzsHzxEJVUJGl8HXZQB2AG9Tdqwx8DEZ2JkApFEV%2F3cVHBHZAsEAKQaNsgiaN9kTAAABb8GUfQAAAAQDAEcwRQIgXVJY0MInclLEtJ1AoMPtjja0tvBD0zPHSAyxIgZ%2B3EECIQDTj7KrkhXuZqKr6sF0hqwr%2BiMiByMi7gNjK4DOqxJ7YjANBgkqhkiG9w0BAQsFAAOCAgEAeOXA%2FpFjaSlenGSQSMDbbSXM%2BL2nM0M1yQ8WxM2mxRfAxzyuH%2FDo1UGDmbvu1e6f%2FdA6Gr%2BAdx2EFia3FqIBrnB9BAymlMgYKq3pW67b83k8r6iF5UcwxISE4LXplY8iV12a59EUCHr0YnVUzK3gLN9ocPyGHnsRdzuowU7WRtZ2tMFAlVT2dEGPqG2ZKsIiCBRummp1vNF3b%2BB5g4Y5Hc7Vw1%2F1LgPMsaSPj5%2Fl4YdLCIO2tWYqnpA0LE8xuRXFSRA0fmlZQKr01N0%2B1ar2QRH6PcRJE3EJbgdnsIGDMithZ4a2COinwCWNkuj6lwB83RvfGOdwJfVv9ricvRpdMOs3HSQnRk0q1IreY42VVmtOGt6MfuCPaIMZtI0unkd3GHmCDcoe64HIu7sjdTCqWAR60JZpQ4oM%2BOpzfBulhf44BDh33zM7lNAlEtVN%2BtszLA2S3CCoDTHpUGWkes%2BzkI4qjG5Nd1eGZT%2FtqqWyRc799ROCEAI5SkgZgowqRgzMhkazdyDANLTbg2Edt4OT7O6zrdLg70JTZMxdJ5%2BAnDMmDr8NCH63URFJe72ZBOH4uAeZuV%2Bhbh9v1%2BF2kFaqVBh2VaRdY%2FHGpnoD%2By1bJ7FI1erKUJFt%2FP4ZEYjACkmT7Gtw8NifvECY3cw3aiAY7AMg2Bnk72ySxvBcXedVMU8%3D&cert=MIIGtjCCBJ6gAwIBAgIRAJltX%2Bmt4Wzcjs2%2F7bFKMpUwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVFcxIzAhBgNVBAoMGkNodW5naHdhIFRlbGVjb20gQ28uLCBMdGQuMS8wLQYDVQQDDCZlUEtJIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0xOTA3MTkwNjQ2NDVaFw0zMTA4MTkwNjQ2NDVaMFgxCzAJBgNVBAYTAlRXMRIwEAYDVQQKDAnooYzmlL%2FpmaIxNTAzBgNVBAMMLOaUv%2BW6nOS8uuacjeWZqOaVuOS9jeaGkeitieeuoeeQhuS4reW%2FgyAtIEcxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwg5R4LGoDj%2BmZIXmcHmRYv501jsSLIm7EoX%2FKAt74uN2yDR436V2EWkFeWhD%2BTS4sx2%2F3JCRW%2BKE%2BIX8NYBKjsWuK9OMY4Gu4FEWJpBu1XCWYjTPKyhHdEhDpxRxv91g3Zk68XgK7j2U5sEzCPx13QjkH7qc%2FMo5BFiro8YsYAfxgCoa%2FrZFEsXyZKXRJeIDw7t%2BiPxVy2cbQ0uNloO9670LGoOVzYVkYABv3IwZo%2BJRtj%2Bj7rLjB7xQKYmfJOA2Jc96yPm6li7zHrIQYfohGPdANmwR9opNNqYOo%2BLtsIYot3%2FcLp9YgAaiGdrAiKrbbEVkYH%2BzKzAHolf5mPBn%2Bh3OElYfygESitWRBp2bwfOGJwAYseTuorQHpyQps1GGcn9vcfnLhvLxa3DMrCAvSJb3SvHCyqahQz0KR0IPcu%2BVLW3icaqlbJausGIGYqp8VSN6FJ0pgmYdbunBLYc1v23VvjmVMl%2BxNJoaSFEUscmSqA4CuYANhkWSANk8HI9rNbvmzuyWhSv7tUXY6UB67mHp4ypGcKYbXrjiKqahv6QLUEb7S8FD71Ds75F2vMeO4O77i6joBs%2FL2E6WZJvSronzJCXL0IwmpYaOAsoFOf0eGVsPBVKn%2Bz4Bq0WA0%2Br7plfWofDbUGmx9Zun%2B%2BrWhoDXrma%2BodubN1Xj1RjlL3sCAwEAAaOCAW4wggFqMB8GA1UdIwQYMBaAFHJbuqpyOO4lkCS1lCL6CYjKiwr7MB0GA1UdDgQWBBTW6y2dYf4ru3CILrgHsVmw9IMiajAOBgNVHQ8BAf8EBAMCAYYwPAYDVR0fBDUwMzAxoC%2BgLYYraHR0cDovL2VjYS5oaW5ldC5uZXQvcmVwb3NpdG9yeS9DUkwyL0NBLmNybDCBggYIKwYBBQUHAQEEdjB0MDsGCCsGAQUFBzAChi9odHRwOi8vZWNhLmhpbmV0Lm5ldC9yZXBvc2l0b3J5L0NlcnRzL2VDQUcyLmNydDA1BggrBgEFBQcwAYYpaHR0cDovL29jc3AuZWNhLmhpbmV0Lm5ldC9PQ1NQL29jc3BHMnNoYTIwEgYDVR0TAQH%2FBAgwBgEB%2FwIBADAiBgNVHSAEGzAZMA0GCysGAQQBgbcjZAADMAgGBmeBDAECAjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggIBAEyrsJ9vUi6nEfwO0vgAoFefXpCRF%2BuDsmG%2F8F6OV9VRnbtzBwazHbxVmaBvDRVofLfoXWr%2BNd8dd3BXVUNxemNrkZa8Hdgdv4s8yFbRs0W6fRTWkhCcc39RpQtSeV7kyxCP1rMTYRSqCA9F%2BFcDMLXJIzZrzl7Tn6guIyqcfZv6sRN7CbbTrYKSc0JX4t26WGFun2zLjzH8kx1TZ457TE4yyjl1oSZdgiWL6Hz7l%2BnbTe6WqPVVm4am2AAmaQaLGncsGLasl7PIHx9Nc4sy7KdOMTc5r0BPCGhAiJ6ueQ6aVd49pra7BDIqFMA7Myy4pXRYfqFnjq9RuROWYiIluzLNUSxlaFtTMUVQnWjJxnlXlBDLX9L4OAxTOvdbtcNNS1GK%2BW1cWiYdTOWF4HTu5pvdUn%2F%2B8yVE4E7MPb0vGuxv3S11QG6JtVPuHkX6BGqRXHo253gY77HZU0g3g9qVs9UaZjWS5UTcqdgLmmOQnH7USaJ9%2F4rXRu%2FP8IWMPG2s6tv1dRVQV5xfq21PQ4y53ytVd0%2B%2Flp0L743%2B1AjnOw0I8t9QxP6c2ti%2Boo43rxM8YE3etVLQBeWsmJc00GOWa%2FXmFACsy8Lkctx0QScAAYwCfB2accfxj9hEX1c6MAeVUVp04YJx4dtjoIFTPI1%2FMFX%2BFkxMq4Fs6k%2BmxSm7tNvv&cert=MIIHZDCCBUygAwIBAgIRAK%2FNjWQsYtZFBn3IV%2F2o8V0wDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCVFcxIzAhBgNVBAoMGkNodW5naHdhIFRlbGVjb20gQ28uLCBMdGQuMSowKAYDVQQLDCFlUEtJIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTUxMTE3MDg1MTM1WhcNMzQxMjIwMDIzMTI3WjBjMQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xLzAtBgNVBAMMJmVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApFkfoC%2FfvuD76dy1if5alwPJOnenjlyv8uMYOfWq3Q9G0mgPV5ynY2DTWM41wqf2iMJPfxso6dCnAMQXTW3iD8UOJiMgq%2Fc6KKJMCgvMjs7mAJpaQA3UUBqb0Q2clPnb7lzQ8YoHzZorQCxJpF1iX6dr3%2B5WCFDzQhhsMbBe5ZxzkrwO0gx9xThXvLtY2yYZAu3jQ4SKTlZr262hMdnMImeWeP93ncxkxTIgau9OMNUkJf2Iea9xGv7VSxsViLwYcKq9rTgKZjBG5YmF1XYkqamz5llgD7SpU8I6nUUa1q7jd17EYjYzLzDEv5XxLTildejRapMuRYdLSqLfv1gnmspiGape1LGASZbdK%2Bxfj5vgnZeI9YQDo6%2BzpXMtQbrlB7dva3H398lar2mZsy%2FIT0LrbGtxZ3jfCqxP10qFAEYa1c24n%2BqVnQ980cYFheYI3ogXgfbVtW7qoRzXYarjWUKJnFl%2BsXxkNN1hIyo5tRCr%2FIapUxrF62rigE5ZkcA4if6zXdb7kenXsH3ZeAjM9SvMK%2BGh1pRzwf5R9Ix9CrWairn12uDJs9iPqoKDjWlTLf0ABBhKoNpU4XmMiet%2F9YLnoLl3Ta75ugI7iHbrfF2zWhPbfCkWa5nRHeRIIaINXgGI6L7xmE0%2BxxZXHF%2FhCG8cTFhDVveAZYxxDqIEZ08CAwEAAaOCAhYwggISMB8GA1UdIwQYMBaAFB4M97Zn8uGSJglFwFU5Lnc%2FQkqiMB0GA1UdDgQWBBRyW7qqcjjuJZAktZQi%2BgmIyosK%2BzAOBgNVHQ8BAf8EBAMCAQYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2VjYS5oaW5ldC5uZXQvcmVwb3NpdG9yeS9DUkxfU0hBMi9DQS5jcmwwgYIGCCsGAQUFBwEBBHYwdDA7BggrBgEFBQcwAoYvaHR0cDovL2VjYS5oaW5ldC5uZXQvcmVwb3NpdG9yeS9DZXJ0cy9lQ0FHMS5jcnQwNQYIKwYBBQUHMAGGKWh0dHA6Ly9vY3NwLmVjYS5oaW5ldC5uZXQvT0NTUC9vY3NwRzFzaGEyMA8GA1UdEwEB%2FwQFMAMBAf8wgecGA1UdIASB3zCB3DANBgsrBgEEAYG3I2QAATANBgsrBgEEAYG3I2QAAjANBgsrBgEEAYG3I2QAAzANBgsrBgEEAYG3I2QABDANBgsrBgEEAYG3I2QACTANBgsrBgEEAYG3I2QAADANBgsrBgEEAYG3I2QEATANBgsrBgEEAYG3I2QEAjANBgsrBgEEAYG3I2QEAzAJBgdghnYBZAABMAkGB2CGdgFkAAIwCQYHYIZ2AWQAAzAJBgdghnYBZAAEMAkGB2CGdgFkAAAwCAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggIBALwy4mxatKA6X%2BUM2IDpnWajNmek00EM4qh5E7eiQY0yZV5Eit9D%2F8q9h0hD77NjVaYPwsOWqWAiVtDAro%2BnWDHfkAG14ptRNBoGjJjzZi%2F%2BOeI2WTc8ZER6C8rAjQ7b%2FRxMzwxfDjRtgCbT2qq01rPiJ%2BqDgyUniDstbyQj08bSo3GJWp6ZsSNDAP26ygODpSgL0Ja806Byk2b4npQevdkmQ0k43S9IU0MeSlWT8hxzluyFlPRl4yuev5le91outdEdpV98KvYcgLAWwW5UcFOM6SRsYTBS2dfSRgKreDnMNdbUHmbAVsb3wLD6WqLoe6LyRNOeXctKPA6%2Be5i%2FJN6NZnqejcMopuS%2BpyWyrNiHlRShGUfTiXrcbT8fbyOswAT8JsX4fWyZYub0kKfFG8hEKQsIxNiyKH4cw6HBih31EYaYS9IEj19NxfHl0KbPm22cpBJoGwkZWgg%2F%2FPflFFHNTdKSalDxPHMKdyZbTBugLtqFVkV%2Bvu1y6WRoGfHwzpa9aQsMWAwLYRnBZnSYzfN9QFZsoHCSDJJVt30Oi6fURJy34%2Bdtvs%2BsQihiN886uYTJ0Cex1R%2BOb9HXCKFrGTumgwD%2Bnitt7hwlB74K9lqrKQrtfgfBFFMG9Tu%2FE%2FOI6JoST2j8KmSN1rpcxoMH3tamxqm3%2BxpLM9HekbBoJ0V2&cert=MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNsIZ5qyNUD9WBpj8zwIuQf5%2FdqIjG3LBXy4P4AakP%2Fh2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKilTza6We%2FCKBk49ZCt0Xvl%2FT29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q%2BRBNGMD%2BXPNjX12ruOzjjK9SXDrkb5wdJfzcq%2BXd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN%2F%2BZ0V0OWQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde%2BS%2FuUWH1%2BETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnaolQ2zepr7BxB4EW%2Fhj8e6DyUadCrlHJhBmd8hh%2BiVBmoKs2pHdmX2Os%2BPYhcZewoozRrSgx4hxyy%2Fvv9haLdnG7t4TY3OZ%2BXkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc%2FQkqiMAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLHClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B01GqZNF5sAFPZn%2FKmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI%2BymBV3QGypzqKOg4ZyYr8dW1P2WT%2BDZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC%2Fgpf36j36%2BuwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2j6%2F7Nu4tCEoduL%2BbXPjqpRugc6bY%2BG7gMwRfaKonh%2B3ZwZCc7b3jajWvY9%2BrGNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS%2FjQ6fbjpKdx2qcgw%2BBRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR%2B2zGp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8%2Fgntsm%2BHbRsZJB%2F9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW%2F2xzQ%2BDhNQ%2BIIX3Sj0rnP0qCglN6oH4EZw%3D";
+
+ await BrowserTestUtils.withNewTab(kURL, async function (browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+
+ let tabs =
+ certificateSection.shadowRoot.querySelector(
+ ".certificate-tabs"
+ ).children;
+
+ Assert.ok(tabs, "Tabs were found");
+ Assert.equal(tabs.length, 4, "There should be 4 tabs");
+ for (let tab of tabs) {
+ Assert.ok(tab.textContent, "Tab should have non-empty label");
+ Assert.notEqual(
+ tab.dataset.l10nId,
+ "certificate-viewer-unknown-group-label"
+ );
+ // If there is another tab after this one, this tab should link to the
+ // next via its issuer's common name or OU, if available.
+ if (tab.nextElementSibling) {
+ tab.click();
+ let infoGroup = certificateSection.shadowRoot.querySelector(
+ ".selected info-group.issuer-name"
+ );
+ Assert.ok(infoGroup, "infoGroup found");
+ let container =
+ infoGroup.shadowRoot.querySelector(".common-name") ||
+ infoGroup.shadowRoot.querySelector(".organizational-unit");
+ Assert.ok(container, "Should find container for link");
+ Assert.ok(
+ container.shadowRoot.querySelector("a"),
+ "There should be a link in the container for " +
+ container.textContent
+ );
+ }
+ }
+ });
+ });
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkNonEmptyFields.js b/toolkit/components/certviewer/tests/browser/browser_checkNonEmptyFields.js
new file mode 100644
index 0000000000..e6c48dc3d1
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkNonEmptyFields.js
@@ -0,0 +1,82 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+async function checkNonEmptyFields(url) {
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+
+ let tabs =
+ certificateSection.shadowRoot.querySelector(
+ ".certificate-tabs"
+ ).children;
+
+ Assert.ok(tabs, "Tabs were found");
+ Assert.greater(tabs.length, 0, "There must at least one tab");
+
+ function clickTabAndCheckSelection(tabID) {
+ let selectedTabBefore = 0;
+
+ for (let i = 0; i < tabs.length; i++) {
+ if (tabs[i].className.includes("selected")) {
+ selectedTabBefore = i;
+ break;
+ }
+ }
+
+ let tabButton = certificateSection.shadowRoot.querySelector(
+ `.certificate-tabs .tab[idnumber="${tabID}"]`
+ );
+ tabButton.click();
+
+ if (tabID !== 0) {
+ Assert.notEqual(
+ selectedTabBefore,
+ tabID,
+ "A new tab should be selected now"
+ );
+ }
+ }
+
+ for (let i = 0; i < tabs.length; i++) {
+ clickTabAndCheckSelection(i);
+
+ let infoGroups =
+ certificateSection.shadowRoot.querySelectorAll("info-group");
+ Assert.ok(infoGroups, "infoGroups found");
+
+ for (let infoGroup of infoGroups) {
+ let infoItems = infoGroup.shadowRoot.querySelectorAll("info-item");
+ Assert.ok(infoItems, "infoItems found");
+
+ for (let infoItem of infoItems) {
+ let item = infoItem.shadowRoot.querySelector(".info");
+ if (item.textContent.length === 0) {
+ await ContentTaskUtils.waitForCondition(
+ () => parseInt(item.textContent.length) > 0,
+ "info-item has not been localized."
+ );
+ }
+ }
+ }
+ }
+ });
+ });
+}
+
+add_task(async function test() {
+ const url1 =
+ "about:certificate?cert=MIIIIDCCBwigAwIBAgIQdFFdOvtZKGMnFerJav62lzANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMSUwIwYDVQQDExxHb29nbGUgSW50ZXJuZXQgQXV0aG9yaXR5IEczMB4XDTE5MDcyOTE4NDQyN1oXDTE5MTAyMTE4MjMwMFowZjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNVBAoMCkdvb2dsZSBMTEMxFTATBgNVBAMMDCouZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOOufVj7d5UF%2FN49KyXmA0Z0rlQPEicHK5CbO122uECXYbWwepNlWlqM7V1GF0vRutC8YyAlxrCsUmOTrpem7NWjggWlMIIFoTATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCB4AwggRqBgNVHREEggRhMIIEXYIMKi5nb29nbGUuY29tgg0qLmFuZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tghIqLmNsb3VkLmdvb2dsZS5jb22CGCouY3Jvd2Rzb3VyY2UuZ29vZ2xlLmNvbYIGKi5nLmNvgg4qLmdjcC5ndnQyLmNvbYIRKi5nY3BjZG4uZ3Z0MS5jb22CCiouZ2dwaHQuY26CFiouZ29vZ2xlLWFuYWx5dGljcy5jb22CCyouZ29vZ2xlLmNhggsqLmdvb2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4qLmdvb2dsZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWCDyouZ29vZ2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20ubXiCDyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5kZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29nbGUuaXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCEiouZ29vZ2xlYWRhcGlzLmNvbYIPKi5nb29nbGVhcGlzLmNughEqLmdvb2dsZWNuYXBwcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xldmlkZW8uY29tggwqLmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CEiouZ3N0YXRpY2NuYXBwcy5jboIKKi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIUKi5tZXRyaWMuZ3N0YXRpYy5jb22CDCoudXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0aW9uLmNvbYIRKi55b3V0dWJla2lkcy5jb22CByoueXQuYmWCCyoueXRpbWcuY29tghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CG2RldmVsb3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2dsZS5jboIEZy5jb4IIZ2dwaHQuY26CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22CD2dvb2dsZWNuYXBwcy5jboISZ29vZ2xlY29tbWVyY2UuY29tghhzb3VyY2UuYW5kcm9pZC5nb29nbGUuY26CCnVyY2hpbi5jb22CCnd3dy5nb28uZ2yCCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb22CD3lvdXR1YmVraWRzLmNvbYIFeXQuYmUwaAYIKwYBBQUHAQEEXDBaMC0GCCsGAQUFBzAChiFodHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFNHSUFHMy5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnBraS5nb29nL0dUU0dJQUczMB0GA1UdDgQWBBRPZJy%2FftYprTgIqQTFvmZIl%2BXaGTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMCEGA1UdIAQaMBgwDAYKKwYBBAHWeQIFAzAIBgZngQwBAgIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5wa2kuZ29vZy9HVFNHSUFHMy5jcmwwDQYJKoZIhvcNAQELBQADggEBADc7%2BG7Np83iC8KU6GYSKizr%2F2VbPPpBjR5EzXIdUpUgxWFQ7Faxd1LVhm22QVlmMKjjYe7JUxnaIa5Zay6pBlMr5Fq%2BHbSTuA63GOt4IW1CvB1zAOaJWfxGXaNX1Xg%2F740qWEDoe95h9Xm%2FfIcFLD86FCUITAenFKBOKdaKoBMGoDBOq7jUdn492oGBYi%2BQtXfNjvcZm0yABGTjQOtH8JzyWKx1NvNLw5gSXYH5Vmj%2FQzRBEED3%2BpIJh6vgKIGEhG%2BhCg4tx4k0nnwoHGnL4a2mcemlRIWRCcjbb%2FBoF%2B05EvQvB6PcurckBaPN8r7wWCxefYViIMnHiMmzPdwZYIA%3D&cert=MIIEXDCCA0SgAwIBAgINAeOpMBz8cgY4P5pTHTANBgkqhkiG9w0BAQsFADBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEyMTUwMDAwNDJaMFQxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3QgU2VydmljZXMxJTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKUkvqHv%2FOJGuo2nIYaNVWXQ5IWi01CXZaz6TIHLGp%2FlOJ%2B600%2F4hbn7vn6AAB3DVzdQOts7G5pH0rJnnOFUAK71G4nzKMfHCGUksW%2Fmona%2BY2emJQ2N%2BaicwJKetPKRSIgAuPOB6Aahh8Hb2XO3h9RUk2T0HNouB2VzxoMXlkyW7XUR5mw6JkLHnA52XDVoRTWkNty5oCINLvGmnRsJ1zouAqYGVQMc%2F7sy%2B%2FEYhALrVJEA8KbtyX%2Br8snwU5C1hUrwaW6MWOARa8qBpNQcWTkaIeoYvy%2FsGIJEmjR0vFEwHdp1cSaWIr6%2F4g72n7OqXwfinu7ZYW97EfoOSQJeAzAgMBAAGjggEzMIIBLzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB%2FwQIMAYBAf8CAQAwHQYDVR0OBBYEFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMB8GA1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd%2FcGYYuMDUGCCsGAQUFBwEBBCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0gBDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAHLeJluRT7bvs26gyAZ8so81trUISd7O45skDUmAge1cnxhG1P2cNmSxbWsoiCt2eux9LSD%2BPAj2LIYRFHW31%2F6xoic1k4tbWXkDCjir37xTTNqRAMPUyFRWSdvt%2BnlPqwnb8Oa2I%2FmaSJukcxDjNSfpDh%2FBd1lZNgdd%2F8cLdsE3%2BwypufJ9uXO1iQpnh9zbuFIwsIONGl1p3A8CgxkqI%2FUAih3JaGOqcpcdaCIzkBaR9uYQ1X4k2Vg5APRLouzVy7a8IVk6wuy6pm%2BT7HT4LY8ibS5FEZlfAFLSW8NwsVz9SBK2Vqn1N0PIMn5xA6NZVc7o835DLAFshEWfC7TIe3g%3D%3D&cert=MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6%2BLm8omUVCxKs%2BIVSbC9N%2FhHD6ErPLv4dfxn%2BG07IwXNb9rfF73OX4YJYJkhD10FPe%2B3t%2Bc4isUoh7SqbKSaZeqKeMWhG8eoLrvozps6yWJQeXSpkqBy%2B0Hne%2Fig%2B1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ%2FgkwpRl4pazq%2Br1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH%2FBAUwAwEB%2FzAdBgNVHQ4EFgQUm%2BIHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0%2FWwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP%2BDTKqttVCL1OmLNIG%2B6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavSot%2B3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h%2Bu%2FN5GJG79G%2BdwfCMNYxdAfvDbbnvRG15RjF%2BCv6pgsH%2F76tuIMRQyV%2BdTZsXjAzlAcmgQWpzU%2FqlULRuJQ%2F7TBj0%2FVLZjmmx6BEP3ojY%2Bx1J96relc8geMJgEtslQIxq%2FH5COEBkEveegeGTLg%3D%3D";
+ const url2 =
+ "about:certificate?cert=MIIDeTCCAmGgAwIBAgIJAPziuikCTox4MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTAeFw0xOTEwMDkyMzQxNTJaFw0yMTEwMDgyMzQxNTJaMGIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2PmzAS2BMTOqytMAPgLaw%2BXLJhgL5XEFdEyt%2FccRLvOmULlA3pmccYYz2QULFRtMWhyefdOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u%2F2CVSndrOfEk0TG23U3AxPxTuW1CrbV8%2Fq71FdIzSOciccfCFHpsKOo3St%2FqbLVytH5aohbcabFXRNsKEqveww9HdFxBIuGa%2BRuT5q0iBikusbpJHAwnnqP7i%2FdAcgCskgjZjFeEU4EFy%2Bb%2Ba1SYQCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaMyMDAwCQYDVR0TBAIwADAjBgNVHREEHDAaggwqLmJhZHNzbC5jb22CCmJhZHNzbC5jb20wDQYJKoZIhvcNAQELBQADggEBAGlwCdbPxflZfYOaukZGCaxYK6gpincX4Lla4Ui2WdeQxE95w7fChXvP3YkE3UYUE7mupZ0eg4ZILr%2FA0e7JQDsgIu%2FSRTUE0domCKgPZ8v99k3Avka4LpLK51jHJJK7EFgo3ca2nldd97GM0MU41xHFk8qaK1tWJkfrrfcGwDJ4GQPIiLlm6i0yHq1Qg1RypAXJy5dTlRXlCLd8ufWhhiwW0W75Va5AEnJuqpQrKwl3KQVewGj67WWRgLfSr%2B4QG1mNvCZb2CkjZWmxkGPuoP40%2Fy7Yu5OFqxP5tAjj4YixCYTWEVA0pmzIzgBg%2BJIe3PdRy27T0asgQW%2FF4TY61Yk%3D";
+ const url3 =
+ "about:certificate?cert=MIIG7jCCBNagAwIBAgIBDzANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQKEwdSb290IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNBIENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRAY2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ8BLPRoZzYLdufujAWGSuzbCtRRcMY%2FpnCujW0r8%2B55jE8Ez64AO7NV1sId6eINm6zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42yfk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz%2BqOqfrU0j36NK2B5jcG8Y0f3%2FJHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN%2FNb5gznZY0dj4kepKwDpUeb%2BagRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE%2F9KTfWgu3YtLq1i6L43qlaegw1SJpfvbi1EinbLDvhG%2BLJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV%2FRRyH9XzQQUxPKZgh%2FTMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivUfslfrejrckzzAeVLIL%2BaplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826YreQQejdIOQpvGQpQsgi3Hia%2F0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAX8wggF7MB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TAPBgNVHRMBAf8EBTADAQH%2FMDQGCWCGSAGG%2BEIBCAQnFiVodHRwOi8vd3d3LmNhY2VydC5vcmcvaW5kZXgucGhwP2lkPTEwMFYGCWCGSAGG%2BEIBDQRJFkdUbyBnZXQgeW91ciBvd24gY2VydGlmaWNhdGUgZm9yIEZSRUUgaGVhZCBvdmVyIHRvIGh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzAxBgNVHR8EKjAoMCagJKAihiBodHRwOi8vY3JsLmNhY2VydC5vcmcvcmV2b2tlLmNybDAzBglghkgBhvhCAQQEJhYkVVJJOmh0dHA6Ly9jcmwuY2FjZXJ0Lm9yZy9yZXZva2UuY3JsMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AuY2FjZXJ0Lm9yZzAfBgNVHSMEGDAWgBQWtTIb1Mfz4OaO873SsDrusjkY0TANBgkqhkiG9w0BAQsFAAOCAgEAR5zXs6IX01JTt7Rq3b%2BbNRUhbO9vGBMggczo7R0qIh1kdhS6WzcrDoO6PkpuRg0L3qM7YQB6pw2V%2BubzF7xl4C0HWltfzPTbzAHdJtjaJQw7QaBlmAYpN2CLB6Jeg8q%2F1Xpgdw%2F%2BIP1GRwdg7xUpReUA482l4MH1kf0W0ad94SuIfNWQHcdLApmno%2FSUh1bpZyeWrMnlhkGNDKMxCCQXQ360TwFHc8dfEAaq5ry6cZzm1oetrkSviE2qofxvv1VFiQ%2B9TX3%2FzkECCsUB%2FEjPM0lxFBmu9T5Ih%2BEqns9ivmrEIQDv9tNyJHuLsDNqbUBal7OoiPZnXk9LH%2Bqb%2BpLf1ofv5noy5vX2a5OKebHe%2B0Ex%2FA7e%2BG%2FHuOjVNqhZ9j5Nispfq9zNyOHGWD8ofj8DHwB50L1Xh5H%2BEbIoga%2FhJCQnRtxWkHP699T1JpLFYwapgplivF4TFv4fqp0nHTKC1x9gGrIgvuYJl1txIKmxXdfJzgscMzqpabhtHOMXOiwQBpWzyJkofF%2Fw55e0LttZDBkEsilV%2FvW0CJsPs3eNaQF%2BiMWscGOkgLFlWsAS3HwyiYLNJo26aqyWPaIdc8E4ck7Sk08WrFrHIK3EHr4n1FZwmLpFAvucKqgl0hr%2B2jypyh5puA3KksHF3CsUzjMUvzxMhykh9zrMxQAHLBVrGwc%3D";
+
+ let urls = [url1, url2, url3];
+
+ await Promise.all(urls.map(checkNonEmptyFields));
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkNonRepeatedCertTabs.js b/toolkit/components/certviewer/tests/browser/browser_checkNonRepeatedCertTabs.js
new file mode 100644
index 0000000000..1e11cc4786
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkNonRepeatedCertTabs.js
@@ -0,0 +1,131 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function checkCertTabs() {
+ let certificatePages = 0;
+ for (let tab of gBrowser.tabs) {
+ let spec = tab.linkedBrowser.documentURI.spec;
+ if (spec.includes("about:certificate")) {
+ certificatePages++;
+ }
+ }
+ Assert.equal(certificatePages, 1, "Do not open repeated certificate pages!");
+}
+
+add_task(async function testBadCert() {
+ info("Testing bad cert");
+
+ let tab = await openErrorPage();
+
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+ for (let i = 0; i < 2; i++) {
+ // try opening two certificates that are the same
+ await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
+ let advancedButton = content.document.getElementById("advancedButton");
+ Assert.ok(advancedButton, "advancedButton found");
+ Assert.equal(
+ advancedButton.hasAttribute("disabled"),
+ false,
+ "advancedButton should be clickable"
+ );
+ advancedButton.click();
+ let viewCertificate = content.document.getElementById("viewCertificate");
+ Assert.ok(viewCertificate, "viewCertificate found");
+ Assert.equal(
+ viewCertificate.hasAttribute("disabled"),
+ false,
+ "viewCertificate should be clickable"
+ );
+
+ viewCertificate.click();
+ });
+ await loaded;
+ }
+ checkCertTabs();
+
+ gBrowser.removeCurrentTab(); // closes about:certificate
+ gBrowser.removeCurrentTab(); // closes https://expired.example.com/
+});
+
+add_task(async function testGoodCert() {
+ info("Testing page info");
+ let url = "https://example.com/";
+
+ info(`Loading ${url}`);
+ await BrowserTestUtils.withNewTab({ gBrowser, url }, async function () {
+ info("Opening pageinfo");
+ let pageInfo = BrowserPageInfo(url, "securityTab", {});
+ await BrowserTestUtils.waitForEvent(pageInfo, "load");
+
+ let securityTab = pageInfo.document.getElementById("securityTab");
+ await TestUtils.waitForCondition(
+ () => BrowserTestUtils.isVisible(securityTab),
+ "Security tab should be visible."
+ );
+ Assert.ok(securityTab, "Security tab is available");
+ let viewCertButton = pageInfo.document.getElementById("security-view-cert");
+ await TestUtils.waitForCondition(
+ () => BrowserTestUtils.isVisible(viewCertButton),
+ "view cert button should be visible."
+ );
+
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+ for (let i = 0; i < 2; i++) {
+ checkAndClickButton(pageInfo.document, "security-view-cert");
+ await loaded;
+ }
+
+ pageInfo.close();
+ checkCertTabs();
+ });
+
+ gBrowser.removeCurrentTab();
+});
+
+add_task(async function testPreferencesCert() {
+ info("Testing preferences cert");
+ let url = "about:preferences#privacy";
+
+ info(`Loading ${url}`);
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url },
+ async function (browser) {
+ checkAndClickButton(browser.contentDocument, "viewCertificatesButton");
+
+ let certDialogLoaded = promiseLoadSubDialog(
+ "chrome://pippki/content/certManager.xhtml"
+ );
+ let dialogWin = await certDialogLoaded;
+ let doc = dialogWin.document;
+ Assert.ok(doc, "doc loaded");
+
+ doc.getElementById("certmanagertabs").selectedTab =
+ doc.getElementById("ca_tab");
+ let treeView = doc.getElementById("ca-tree").view;
+ let selectedCert;
+
+ for (let i = 0; i < treeView.rowCount; i++) {
+ treeView.selection.select(i);
+ dialogWin.getSelectedCerts();
+ let certs = dialogWin.selected_certs;
+ if (certs && certs.length == 1 && certs[0]) {
+ selectedCert = certs[0];
+ break;
+ }
+ }
+ Assert.ok(selectedCert, "A cert should be selected");
+ let viewButton = doc.getElementById("ca_viewButton");
+ Assert.equal(viewButton.disabled, false, "Should enable view button");
+
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+ for (let i = 0; i < 2; i++) {
+ viewButton.click();
+ await loaded;
+ }
+ checkCertTabs();
+ }
+ );
+ gBrowser.removeCurrentTab(); // closes about:certificate
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkNonUndefinedStrings.js b/toolkit/components/certviewer/tests/browser/browser_checkNonUndefinedStrings.js
new file mode 100644
index 0000000000..5e76990592
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkNonUndefinedStrings.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const url =
+ "about:certificate?cert=MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd%2BG7%2Bu6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG%2FvUUWVrsxC2gsbR8WJq%2BcYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI%2BpjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek%2FojvedPWe8dhciHkxOC2qPFZvVFMwg1%2Fo%2Fb80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z%2BlvrSjEgrddemWyGGalqyFp1rXlVM1Tf4%2FIYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c%2ByvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT%2FB9TdQ8eXwebo60%2FMCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH%2FBAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC%2BgLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP%2Fzbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W%2F51l8%2BIxDmV%2B9827%2FVo1HVjb%2FSrVgwbTq%2F16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM%2Fed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql%2F68G5q844kFuC6JPl4LVT9mciD%2BVW6bHUSXD9xifL9DqdJ0Ic0SllTlM%2Boq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc%2Fgjxteskq%2FVl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnBXlRAzZ8%2BOJThUbzK16a2CI3Rg4agKSJk%2BuA47h1%2FImmngpFLRb%2FMvRX6H1oWcUuyH6O7PZdl0YpwTpw1THIuqCGl%2FwpPgyQgcTM%3D&cert=MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8%2B8kTANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANyuWJBNwcQwFZA1W248ghX1LFy949v%2FcUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83nf36QYSvx6%2BM%2FhpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bdKpPDkC55gIDvEwRqFDu1m5K%2BwgdlTvza%2FP96rtxcflUxDOg5B6TXvi%2FTC2rSsd9f%2Fld0Uzs1gN2ujkSYs58O09rg1%2FRrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGXkujNVA075ME%2FOV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6%2Bguqw9ypzAO%2Bsf0%2FRR3w6RbKFfCs%2FmC%2FbdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB%2FwQIMAYBAf8CAQAwDgYDVR0PAQH%2FBAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA%2BAYRyCMWHVLyjnjUY4tCzhxtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEBCwUAA4IBAQAjPt9L0jFCpbZ%2BQlwaRMxp0Wi0XUvgBCFsS%2BJtzLHgl4%2BmUwnNqipl5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq%2FsELfeNqzqPlt%2FyGFUzZgTHbO7Djc1lGA8MXW5dRNJ2Srm8c%2BcftIl7gzbckTB%2B6WohsYFfZcTEDts8Ls%2F3HB40f%2F1LkAtDdC2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPitc%2BLJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz&cert=MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOnTjC3U%2FdDxGkAV53ijSLdhwZAAIEJzs4bg7%2FfzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5BmV%2FSl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C%2FdxC%2F%2FAH2hdmoRBBYMql1GNXRor5H4idq9Joz%2BEkIYIvUX7Q6hL%2BhqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv%2BzbMUZBfHWymeMr%2Fy7vrTC0LUq7dBMtoM1O%2F4gdW7jVg%2FtRvoSSiicNoxBN33shbyTApOB6jtSj1etX%2BjkMOvJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH%2FBAUwAwEB%2FzAdBgNVHQ4EFgQUA95QNVbRTLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK%2Bt1EnE9SsPTfrgT1eXkIoyQY%2FEsrhMAtudXH%2FvTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp%2F2PV5Adg06O%2FnVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp%2BdWOIrWcBAI%2B0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU%2BKrk2U886UAb3LujEV0lsYSEY1QSteDwsOoBrp%2BuvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQkCAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4%3D";
+
+add_task(async function test() {
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+
+ let tabs =
+ certificateSection.shadowRoot.querySelector(
+ ".certificate-tabs"
+ ).children;
+
+ Assert.ok(tabs, "Tabs were found");
+
+ for (let i = 0; i < tabs.length; i++) {
+ let tabButton = certificateSection.shadowRoot.querySelector(
+ `.certificate-tabs .tab[idnumber="${i}"]`
+ );
+ tabButton.click();
+
+ let infoGroups =
+ certificateSection.shadowRoot.querySelectorAll("info-group");
+ Assert.ok(infoGroups, "infoGroups found");
+
+ for (let infoGroup of infoGroups) {
+ let infoItems = infoGroup.shadowRoot.querySelectorAll("info-item");
+ Assert.ok(infoItems, "infoItems found");
+
+ for (let infoItem of infoItems) {
+ let info = infoItem.shadowRoot.children[2].textContent;
+ Assert.equal(
+ info.includes("undefined"),
+ false,
+ "Empty strings shouldn't be rendered"
+ );
+ }
+ }
+ }
+ });
+ });
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkOCSP.js b/toolkit/components/certviewer/tests/browser/browser_checkOCSP.js
new file mode 100644
index 0000000000..b7d51842eb
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkOCSP.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+async function checkOCSP(url, shouldBeRendered) {
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [shouldBeRendered],
+ async function (shouldBeRendered) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+ let OCSPSection =
+ certificateSection.shadowRoot.querySelector(".ocsp-stapling");
+ if (!shouldBeRendered) {
+ Assert.equal(OCSPSection, null, "OCSPSection found");
+ return;
+ }
+ Assert.ok(OCSPSection, "OCSPSection found");
+ let item = OCSPSection.shadowRoot.querySelector("info-item");
+ Assert.ok(item, "item found");
+ let info = item.shadowRoot.querySelector(".info").textContent;
+ Assert.equal(info, "Yes", "OCSP is required");
+ }
+ );
+ });
+}
+
+add_task(async function test() {
+ let tests = [
+ {
+ url: "about:certificate?cert=MIIE1jCCA76gAwIBAgISA8ud4ZkTgHyRgFEI060JNN%2FFMA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTEwMjAwODUzMTFaFw0yMDAxMTgwODUzMTFaMB0xGzAZBgNVBAMTEmRtNHByb2R1Y3Rpb25zLmNvbTB2MBAGByqGSM49AgEGBSuBBAAiA2IABAaBrphEFb0WufNLet5XJDrjo3UYUnEhNJZ5LKbbdaMeRHU%2BamVcM%2B%2Fyddoeq56%2FbeZF0p8oKptxg0TQpeVz4b5ZONe17S6Bp17DN0HLqeX6FXLKyVqRTfoesv7XR1KtW6OCAo8wggKLMA4GA1UdDwEB%2FwQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH%2FBAIwADAdBgNVHQ4EFgQUNXKbW53h63%2Bz%2FBCOyd4pilpoFc8wHwYDVR0jBBgwFoAUqEpqYwR93brm0Tm3pkVl7%2FOo7KEwbwYIKwYBBQUHAQEEYzBhMC4GCCsGAQUFBzABhiJodHRwOi8vb2NzcC5pbnQteDMubGV0c2VuY3J5cHQub3JnMC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDMubGV0c2VuY3J5cHQub3JnLzAzBgNVHREELDAqghQqLmRtNHByb2R1Y3Rpb25zLmNvbYISZG00cHJvZHVjdGlvbnMuY29tMBEGCCsGAQUFBwEYBAUwAwIBBTBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB1ALIeBcyLos2KIE6HZvkruYolIGdr2vpw57JJUy3vi5BeAAABbeiVw3YAAAQDAEYwRAIgHUJgZEK9S5grlRSnDiZMZUWllQ1Ki10T2ldH1XgRfuUCICfKCcvcMas9Wb09athc6kPrD9WxVCi%2FTPfOWVmFv4EdAHYAb1N2rDHwMRnYmQCkURX%2FdxUcEdkCwQApBo2yCJo32RMAAAFt6JXE7wAABAMARzBFAiEAm4lY7Jsj1c%2F%2FzAES61A7hi9jJ5bqQpE1x9KCALQqd4sCIAablaGWv6L3uksVpDH1KDxj1Df9iDPGO2CJSzKjSKdNMA0GCSqGSIb3DQEBCwUAA4IBAQBjP5pR%2Fnj%2FCOZy3Z2LfqN7z%2Fcb87rz0CY7iR5p6PvdvwOs0JPq%2F1pVf4V3JTPmEduP7Z4cYIAoOp2%2BFBE0kZar0zzhp6uXcoBagrlxanG9KvgeWr1hfyJjYbnsteake8Z3vqfjdnlhB5ZFmQudHQh7QAoxtswNbdxjy%2FNwBIR5pKIDxleebVwe%2FneH%2BtokDYSPmH2vsmto0z72VM1KlFjgXC79XDIKMl83R2U%2F1B9wq23EHeFFY38cBUFKEjO67eC9q1Xxsv%2FpYAKrXVkdwwsvHfoY7evFRu%2Fj%2BsS3fWcf8uPrApaoqqJgjxpJ2jHjcXniad47iTffJUmwHqmyeigZ&cert=MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA%2FMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0NlowSjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMTGkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EFq6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan%2FPQeGdxyGkOlZHP%2FuaZ6WA8SMx%2Byk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0Z8h%2FpZq4UmEUEz9l6YKHy9v6Dlb2honzhT%2BXhq%2Bw3Brvaw2VFn3EK6BlspkENnWAa6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB%2FonkxEz0tNvjj%2FPIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0TAQH%2FBAgwBgEB%2FwIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIGCCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNvbTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9kc3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf%2FEFWCFiRAwVAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcCARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwuY3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsFAAOCAQEA3TPXEfNjWDjdGBX7CVW%2Bdla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJouM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg%2BVyOeph4EYpr%2F1wXKtx8%2FwApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so%2FjoWUoHOUgwuX4Po1QYz%2B3dszkDqMp4fklxBwXRsW10KXzPMTZ%2BsOPAveyxindmjkW8lGy%2BQsRlGPfZ%2BG6Z6h7mjem0Y%2BiWlkYcV4PIWL1iwBi8saCbGS5jN2p8M%2BX%2BQ7UNKEkROb3N6KOqkqm57TH2H3eDJAkSnh6%2FDNFu0Qg%3D%3D&cert=MIIDSjCCAjKgAwIBAgIQRK%2BwgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA%2FMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN%2Bv6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi%2BDoM3ZJKuM%2FIUmTrE4Orz5Iy2Xu%2FNMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9UL2AZd%2B3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRyxXtqqzTWMIn%2F5WgTe1QLyNau7Fqckh49ZLOMxt%2B%2FyUFw7BZy1SbsOFU5Q9D8%2FRhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4%2BU9m5%2FwAl0CAwEAAaNCMEAwDwYDVR0TAQH%2FBAUwAwEB%2FzAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62%2BFLkHX%2FxBVghYkQMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or%2BDxz9LwwmglSBd49lZRNI%2BDT69ikugdB%2FOEIKcdBodfpga3csTS7MgROSR6cz8faXbauX%2B5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK%2BrlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir%2Fmd2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL%2BT0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ",
+ shouldBeRendered: true,
+ },
+ {
+ url: "about:certificate?cert=MIIE0DCCBHegAwIBAgIQCP0zdXA01ESx6eTjfitzfzAKBggqhkjOPQQDAjBvMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGTAXBgNVBAoTEENsb3VkRmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkRmxhcmUgSW5jIEVDQyBDQS0yMB4XDTE5MDUwMzAwMDAwMFoXDTIwMDUwMzEyMDAwMFowaDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRkwFwYDVQQDExBzY290dGhlbG1lLmNvLnVrMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYQYIOYOkA0SNAxlrsvTnr7BIOoNmUaBFG2oXXyKfphkc%2F5wXXMU1Ez1%2BpqjFHSwaAtCkgTzTNEEOxkuDicJLqKOCAvowggL2MB8GA1UdIwQYMBaAFD50LR%2FPRXUEfj%2FAooc%2BTEODURPGMB0GA1UdDgQWBBSlm2TM83mhbWzqLL2SZRmdHbh%2FWDAvBgNVHREEKDAmghBzY290dGhlbG1lLmNvLnVrghIqLnNjb3R0aGVsbWUuY28udWswDgYDVR0PAQH%2FBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB5BgNVHR8EcjBwMDagNKAyhjBodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vQ2xvdWRGbGFyZUluY0VDQ0NBMi5jcmwwNqA0oDKGMGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9DbG91ZEZsYXJlSW5jRUNDQ0EyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG%2FWwBATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAECAjB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Nsb3VkRmxhcmVJbmNFQ0NDQS0yLmNydDAMBgNVHRMBAf8EAjAAMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHUA7ku9t3XOYLrhQmkfq%2BGeZqMPfl%2BwctiDAMR7iXqo%2FcsAAAFqfaV7eQAABAMARjBEAiAcD2ch9qAysZxlIFqrYjElyv%2B6fPbwBZ%2BCFSgJW7d4cgIgUnpOdauBy9OXIeQerY0ElxqlPDFo0qTx34NBoPmfyOYAdgBep3P531bA57U2SH3QSeAyepGaDIShEhKEGHWWgXFFWAAAAWp9pXsQAAAEAwBHMEUCIQDlDcpBkwV225tooGiDmWX4bwvpko6nmXnQ8RBeSltUGAIgXUCskAznLKPcqf7e55eEj9xwago28rJZny6stP9NqakwCgYIKoZIzj0EAwIDRwAwRAIfVXERnB1UkKpq73xsv0H3o0SC%2FVGdyuIizTc1HHeP6gIhAKSIp4zfgOLP3l46y2yHzir9PdeCc%2BRGUVg4P4IgAANv&cert=MIIDozCCAougAwIBAgIQD%2FPmFjmqPRoSZfQfizTltjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE1MTAxNDEyMDAwMFoXDTIwMTAwOTEyMDAwMFowbzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMSAwHgYDVQQDExdDbG91ZEZsYXJlIEluYyBFQ0MgQ0EtMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNFW9Jy25DGg9aRSz%2BOaeob%2F8oayXsy1WcwRx07dZP1VnGDjoEvZeFT%2FSFC6ouGhWHWPx2A3RBZNVZns7tQzeiOjggEZMIIBFTASBgNVHRMBAf8ECDAGAQH%2FAgEAMA4GA1UdDwEB%2FwQEAwIBhjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTA6BgNVHR8EMzAxMC%2BgLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vT21uaXJvb3QyMDI1LmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUPnQtH89FdQR%2BP8Cihz5MQ4NRE8YwHwYDVR0jBBgwFoAU5Z1ZMIJHWMys%2BghUNoZ7OrUETfAwDQYJKoZIhvcNAQELBQADggEBADhfp%2F%2F8hfJzMuTVo4mZlmCvMsEDs2Xfvh4DyqXthbKPr0uMc48qjKkADgEkF%2FfsUoV2yOUcecrDF4dQtgQzNp4qnhgXljISr0PMVxje28fYiCWD5coGJTH9vV1IO1EB3SwUx8FgUemVAdiyM1YOR2aNbM2v%2BYXZ6xxHR4g06PD6wqtPaU4JWdRXxszByOPmGcFYOFLi4oOF3iI03D%2Bm968kvOBvwKtoLVLHawVXLEIbLUiHAwyQq0hIqSi%2BNIr7uu30YJkdFXgRqtltU39pKLy3ayB2f6BVA3F59WensKAKF1eyAKmtz%2F9njD4m5ackvMJvEOiJxnCl0h%2BA7Q0%2FJxM%3D&cert=MIIDdzCCAl%2BgAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN%2BhXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnnc%2BgRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9%2FlSEy%2FCG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD%2BtqYF%2FLTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f%2FxXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v%2Fyejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1BE3wMBIGA1UdEwEB%2FwQIMAYBAf8CAQMwDgYDVR0PAQH%2FBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF%2BvaKSm2eT929hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE%2FszKN%2BOMY3EU%2Ft3WgxjkzSswF07r51XgdIGn9w%2FxZchMB5hbgF%2FX%2B%2BZRGjD8ACtPhSNzkE1akxehi%2FoCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h%2B3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5%2BNauQrz4wlHrQMz2nZQ%2F1%2FI6eYs9HRCwBXbsdtTLSR9I4LtD%2Bgdwyah617jzV%2FOeBHRnDJELqYzmp",
+ shouldBeRendered: false,
+ },
+ ];
+
+ for (let test of tests) {
+ await checkOCSP(test.url, test.shouldBeRendered);
+ }
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkStandAlonePage.js b/toolkit/components/certviewer/tests/browser/browser_checkStandAlonePage.js
new file mode 100644
index 0000000000..02d8fdc250
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkStandAlonePage.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TYPE_CA = 1;
+const TYPE_USER = 2;
+const TYPE_EMAIL = 4;
+const TYPE_SERVER = 8;
+
+add_task(async function test_dbItemDisplayed() {
+ await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
+ gBrowser.selectedTab = BrowserTestUtils.addTab(
+ gBrowser,
+ "about:certificate"
+ );
+ });
+
+ let categories = [
+ {
+ type: TYPE_CA,
+ tabName: "Authorities",
+ id: "ca",
+ },
+ {
+ type: TYPE_USER,
+ tabName: "Your Certificates",
+ id: "mine",
+ },
+ {
+ type: TYPE_EMAIL,
+ tabName: "People",
+ id: "people",
+ },
+ {
+ type: TYPE_SERVER,
+ tabName: "Servers",
+ id: "servers",
+ },
+ ];
+
+ let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
+ Ci.nsIX509CertDB
+ );
+ Assert.ok(certdb, "certdb not null");
+ let certcache = certdb.getCerts();
+ Assert.ok(certcache, "certcache not null");
+
+ for (let cert of certcache) {
+ let category = categories.find(({ type }) => type & cert.certType);
+
+ await SpecialPowers.spawn(
+ gBrowser.selectedBrowser,
+ [cert.displayName, category],
+ async function (displayName, category) {
+ let aboutCertificateSection = await ContentTaskUtils.waitForCondition(
+ () => {
+ return content.document.querySelector("about-certificate-section");
+ },
+ "Found aboutCertificateSection."
+ );
+
+ let tab = aboutCertificateSection.shadowRoot.querySelector(
+ `.certificate-tabs #certificate-viewer-tab-${category.id}`
+ );
+ Assert.ok(tab, `${category.tabName} tab should exist.`);
+ tab.click();
+
+ let certificateItems = aboutCertificateSection.shadowRoot.querySelector(
+ `.info-groups #certificate-viewer-tab-${category.id}`
+ );
+
+ let listItems =
+ certificateItems.shadowRoot.querySelectorAll("list-item");
+
+ let item = Array.from(listItems).find(
+ i =>
+ i.shadowRoot.querySelector(".item-name").textContent == displayName
+ );
+ Assert.ok(item, `${displayName} should be listed`);
+ }
+ );
+ }
+
+ gBrowser.removeCurrentTab(); // closes about:certificate
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_checkValiditySection.js b/toolkit/components/certviewer/tests/browser/browser_checkValiditySection.js
new file mode 100644
index 0000000000..10e82be94a
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_checkValiditySection.js
@@ -0,0 +1,57 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const github_url =
+ "about:certificate?cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D";
+const mozilla_url =
+ "about:certificate?cert=MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd%2BG7%2Bu6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG%2FvUUWVrsxC2gsbR8WJq%2BcYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI%2BpjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek%2FojvedPWe8dhciHkxOC2qPFZvVFMwg1%2Fo%2Fb80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z%2BlvrSjEgrddemWyGGalqyFp1rXlVM1Tf4%2FIYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c%2ByvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT%2FB9TdQ8eXwebo60%2FMCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH%2FBAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC%2BgLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP%2Fzbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W%2F51l8%2BIxDmV%2B9827%2FVo1HVjb%2FSrVgwbTq%2F16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM%2Fed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql%2F68G5q844kFuC6JPl4LVT9mciD%2BVW6bHUSXD9xifL9DqdJ0Ic0SllTlM%2Boq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc%2Fgjxteskq%2FVl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnBXlRAzZ8%2BOJThUbzK16a2CI3Rg4agKSJk%2BuA47h1%2FImmngpFLRb%2FMvRX6H1oWcUuyH6O7PZdl0YpwTpw1THIuqCGl%2FwpPgyQgcTM%3D";
+const youtube_url =
+ "about:certificate?cert=MIIIIDCCBwigAwIBAgIQGk0sGNQUuaOL9Rii2XQ4yjANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMSUwIwYDVQQDExxHb29nbGUgSW50ZXJuZXQgQXV0aG9yaXR5IEczMB4XDTE5MDYxODA4MjE1OFoXDTE5MDkxMDA4MTUwMFowZjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNVBAoMCkdvb2dsZSBMTEMxFTATBgNVBAMMDCouZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMRScn8kk6qy3LHVktWZWxm%2FMq4kowlEdxQH40wijThZ%2B%2F5Jrqh6UlWnWuiulNorHH2DEW4OkSKreFoYze7w8O6jggWlMIIFoTATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCB4AwggRqBgNVHREEggRhMIIEXYIMKi5nb29nbGUuY29tgg0qLmFuZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tghIqLmNsb3VkLmdvb2dsZS5jb22CGCouY3Jvd2Rzb3VyY2UuZ29vZ2xlLmNvbYIGKi5nLmNvgg4qLmdjcC5ndnQyLmNvbYIRKi5nY3BjZG4uZ3Z0MS5jb22CCiouZ2dwaHQuY26CFiouZ29vZ2xlLWFuYWx5dGljcy5jb22CCyouZ29vZ2xlLmNhggsqLmdvb2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4qLmdvb2dsZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWCDyouZ29vZ2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20ubXiCDyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5kZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29nbGUuaXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCEiouZ29vZ2xlYWRhcGlzLmNvbYIPKi5nb29nbGVhcGlzLmNughEqLmdvb2dsZWNuYXBwcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xldmlkZW8uY29tggwqLmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CEiouZ3N0YXRpY2NuYXBwcy5jboIKKi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIUKi5tZXRyaWMuZ3N0YXRpYy5jb22CDCoudXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0aW9uLmNvbYIRKi55b3V0dWJla2lkcy5jb22CByoueXQuYmWCCyoueXRpbWcuY29tghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CG2RldmVsb3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2dsZS5jboIEZy5jb4IIZ2dwaHQuY26CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22CD2dvb2dsZWNuYXBwcy5jboISZ29vZ2xlY29tbWVyY2UuY29tghhzb3VyY2UuYW5kcm9pZC5nb29nbGUuY26CCnVyY2hpbi5jb22CCnd3dy5nb28uZ2yCCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb22CD3lvdXR1YmVraWRzLmNvbYIFeXQuYmUwaAYIKwYBBQUHAQEEXDBaMC0GCCsGAQUFBzAChiFodHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFNHSUFHMy5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnBraS5nb29nL0dUU0dJQUczMB0GA1UdDgQWBBT8E5DiGEc7xHswBMF5K5EmFzx6fDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMCEGA1UdIAQaMBgwDAYKKwYBBAHWeQIFAzAIBgZngQwBAgIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5wa2kuZ29vZy9HVFNHSUFHMy5jcmwwDQYJKoZIhvcNAQELBQADggEBAGrWCimTdP8%2B6qCqNh1Xza9Wlm%2FGDVb%2BKp0PHUZaNDMThFQQqGn2XVi7ZkhqsxTtMw88Nrl97Bi1OsnNPlabhDwxtRyWkNkLdpFxebRz73CsjyoB3cboH%2FZ8sU9LLwXe%2FIJgMkvT7fznKtKSweWV%2BmAYG%2F3KzaIyLrowYpyOsWaYytPJK7ypuk6yOPxuQcQnelotWpuHUBR3mo3FIW56BPCy20KwqwvWoZe27BNxO%2F11Ym%2FPnric2fWXwgmHdkvVqqssUMFs%2BmG2tS%2FpqnR5yZdQL60xOgDq70mVWYgQT4yUTm7i8qvugvNnuSIjjsbelHgbC8f5%2Fx%2Bo2pEyw%2FDYyKw%3D";
+
+async function checValiditySection(url) {
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+
+ let validitySection = certificateSection.shadowRoot.querySelector(
+ "info-group.validity"
+ );
+ Assert.ok(validitySection, "validitySection found");
+
+ let infoItems = validitySection.shadowRoot.querySelectorAll("info-item");
+ Assert.ok(infoItems, "infoItems found");
+ Assert.equal(
+ infoItems.length,
+ 2,
+ "There must be render just one date for Not Before and one for Not After"
+ );
+
+ for (let infoItem of infoItems) {
+ let label = infoItem.shadowRoot
+ .querySelector("label")
+ .getAttribute("data-l10n-id");
+
+ Assert.notEqual(label, "", "Label shouldn't be empty");
+
+ let infoElem = infoItem.shadowRoot.querySelector(".info");
+ let title = infoElem.textContent;
+ Assert.equal(
+ title.includes("GMT"),
+ true,
+ "UTC timezone should be displayed in the label"
+ );
+ }
+ });
+ });
+}
+
+add_task(async function test() {
+ let input = [github_url, mozilla_url, youtube_url];
+ for (let url of input) {
+ await checValiditySection(url);
+ }
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_downloadLink.js b/toolkit/components/certviewer/tests/browser/browser_downloadLink.js
new file mode 100644
index 0000000000..5b7b587733
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_downloadLink.js
@@ -0,0 +1,126 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const validCert =
+ "about:certificate?cert=MIIGMDCCBRigAwIBAgIQCa2oS7Nau6nwv1WyRNIJnzANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFNlcnZlciBDQTAeFw0xOTA2MDYwMDAwMDBaFw0xOTA5MDQxMjAwMDBaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTETMBEGA1UEBxMKTWVubG8gUGFyazEXMBUGA1UEChMORmFjZWJvb2ssIEluYy4xFzAVBgNVBAMMDiouZmFjZWJvb2suY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEALPlfjd8gHkIMDeBOFhRt0e%2B%2F3fdm%2BZdzdM4s1WIHVbYztgmdEy20PUwDCviYKJX4GG%2BT9ivT8kJ%2FvWl1P%2FYqOCA54wggOaMB8GA1UdIwQYMBaAFFFo%2F5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQWBBTsQZVRTuib7KY9w3FfOYsZHvOC9zCBxwYDVR0RBIG%2FMIG8gg4qLmZhY2Vib29rLmNvbYINbWVzc2VuZ2VyLmNvbYILKi5mYmNkbi5uZXSCCCouZmIuY29tghAqLm0uZmFjZWJvb2suY29tggZmYi5jb22CDiouZmFjZWJvb2submV0gg4qLnh4LmZiY2RuLm5ldIIOKi54ei5mYmNkbi5uZXSCDyoubWVzc2VuZ2VyLmNvbYILKi5mYnNieC5jb22CDioueHkuZmJjZG4ubmV0ggxmYWNlYm9vay5jb20wDgYDVR0PAQH%2FBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzYuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABay5CAaUAAAQDAEYwRAIgMwBM6q%2BdBwu2mNtMMjTEwJZZxyoUlHUEYO%2BbfkId%2F9MCIAQ2bxhnxrapYv74fzyoTkt9m%2BELq6%2B43OVpivRVKDKTAHcAdH7agzGtMxCRIZzOJU9CcMK%2F%2FV5CIAjGNzV55hB7zFYAAAFrLkIA%2FAAABAMASDBGAiEA0x1xPWue6RMSE9nbjYBt637CRC86ixrODP%2FEIlI5mCgCIQCHNdqgOlswd0LqaW4QRii2JHN4bnoEj%2FD9j7%2BkqEB7LjANBgkqhkiG9w0BAQsFAAOCAQEAnRdIVNZ850s7IvLgg%2BU9kKxA18kLKVpIF%2FrJHkXTkymvBHKAGOFNfzqF2YxHFhkDMIuoMO2F%2BA1E0Eo8zb1atL6%2FL59broEHTOH6xFmJAlZW0h6mZg8iRJ9Ae0pTN%2FfowaoN9aFVRnVr9ccKhOdqsXYyEZ3Ze39sEwx7Uau9KhzyuJW12Jh3S%2BZJYUdBADeeJNL5ZXSUFIyjgkwSQZPaaWAzSGHZFt3sWhMjdNoBkjRJFlASLDM3m1ZWsKA47vuXvJc%2FDXT35lC1DJmyhYb9qNPR71a1hJ8TS7vUwdDd%2BdEHiJj2wQLV3m7Tn7YvWyJOEyi4n6%2FrPqT44LZmgK7HWw%3D%3D&cert=MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3VyYW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC24C%2FCJAbIbQRf1%2B8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU%2BUDlqUH1VWtMICKq%2FQmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK%2FIHe1NnF9Xt4ZQaJn1itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j%2F018QsIJzJa9buLnqS9UdAn4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I%2B4G3FhahnSMSTeXXkgisdaScus0Xsh5ENWV%2FUyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcftbZvySC%2FzA%2FWiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH%2FAgEAMA4GA1UdDwEB%2FwQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUUWj%2FkK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwdaOpKj4PWUS%2BNa0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk%2FgNHE%2Br1hspZcX30BJZr01lYPf7TMSVcGDiEo%2Bafgv2MW5gxTs14nhr9hctJqvIni5ly%2FD6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zuxICaEnL6VpPX%2F78whQYwvwt%2FTv9XBZ0k7YXDK%2FumdaisLRbvfXknsuvCnQsH6qqF0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY%2B3sAzm2fTYS5yh%2BRp%2FBIAV0AecPUeybQ%3D&cert=MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm%2B9S75S0tMqbf5YE%2Fyc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG%2B%2BMXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx%2BmM0aBhakaHPQNAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH%2FBAQDAgGGMA8GA1UdEwEB%2FwQFMAMBAf8wHQYDVR0OBBYEFLE%2Bw2kD%2BL9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE%2Bw2kD%2BL9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe%2FEW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9%2BMpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2Yzi9RKR%2F5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2%2FS6cCZdkGCevEsXCS%2B0yx5DaMkHJ8HSXPfqIbloEpw8nL%2Be%2FIBcm2PN7EeqJSdnoDfzAIJ9VNep%2BOkuE6N36B9K";
+
+add_task(async function test_checkForErrorSection() {
+ await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
+ gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, validCert);
+ });
+
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
+ let infoGroups;
+ let downloadLinkContainers = [];
+
+ await ContentTaskUtils.waitForCondition(() => {
+ infoGroups = content.document
+ .querySelector("certificate-section")
+ .shadowRoot.querySelectorAll(".miscellaneous");
+ for (let i = 0; i < infoGroups.length; i++) {
+ downloadLinkContainers.push(
+ infoGroups[i].shadowRoot
+ .querySelector(".download")
+ .shadowRoot.querySelector(".info")
+ );
+ }
+ return downloadLinkContainers.length;
+ }, "Found download info items.");
+
+ ok(downloadLinkContainers.length, "Download info items should exist.");
+
+ let certTabs = content.document
+ .querySelector("certificate-section")
+ .shadowRoot.querySelectorAll(".certificate-tab");
+
+ await ContentTaskUtils.waitForCondition(
+ () => certTabs.length,
+ "Certificate tabs should exist."
+ );
+
+ let url = new URL(content.document.documentURI);
+ let certs = url.searchParams.getAll("cert");
+ let certChain = [];
+ for (let i = 0; i < certs.length; i++) {
+ certChain.push(
+ `-----BEGIN CERTIFICATE-----\r\n${certs[i]}\r\n-----END CERTIFICATE-----\r\n`
+ );
+ }
+ certChain = certChain.join("").replace(/(\r\n|\n|\r)/gm, "");
+
+ for (let i = 0; i < certTabs.length; i++) {
+ let downloadLink =
+ downloadLinkContainers[i].querySelector(".download-link");
+
+ let downloadChainLink = downloadLinkContainers[i].querySelector(
+ ".download-link-chain"
+ );
+
+ let cert = certs[i];
+ cert = `-----BEGIN CERTIFICATE-----\r\n${cert}\r\n-----END CERTIFICATE-----\r\n`;
+ cert = cert.replace(/(\r\n|\n|\r)/gm, "");
+
+ let linkCert = downloadLink.getAttribute("href");
+ linkCert = linkCert.replace("data:,", "");
+ linkCert = decodeURI(linkCert);
+ let certLineLength = Math.max(
+ ...linkCert.split(/\r\n|\n|\r/m).map(x => x.length)
+ );
+ linkCert = linkCert.replace(/(\r\n|\n|\r)/gm, "");
+
+ let downloadChainCert = downloadChainLink.getAttribute("href");
+ downloadChainCert = downloadChainCert.replace("data:,", "");
+ downloadChainCert = decodeURI(downloadChainCert);
+ let chainLineLength = Math.max(
+ ...downloadChainCert.split(/\r\n|\n|\r/m).map(x => x.length)
+ );
+ downloadChainCert = downloadChainCert.replace(/(\r\n|\n|\r)/gm, "");
+
+ Assert.lessOrEqual(
+ certLineLength,
+ 64,
+ "PEM cert line length should be capped to 64"
+ );
+ Assert.lessOrEqual(
+ chainLineLength,
+ 64,
+ "PEM chain line length should be capped to 64"
+ );
+
+ Assert.equal(
+ cert,
+ linkCert,
+ "Download link href should be equal to URL cert."
+ );
+
+ Assert.equal(
+ certChain,
+ downloadChainCert,
+ "Download chain link href should be equal to URL cert."
+ );
+
+ await content.document.l10n.translateElements([
+ downloadChainLink,
+ downloadLink,
+ ]);
+
+ Assert.equal(
+ downloadLinkContainers[i].textContent,
+ "PEM (cert)PEM (chain)",
+ "Download should contain links to PEM cert and PEM chain."
+ );
+
+ if (certTabs[i + 1]) {
+ certTabs[i + 1].click();
+
+ await ContentTaskUtils.waitForCondition(
+ () => certTabs[i + 1].classList.contains("selected"),
+ "Cert tab should be selected"
+ );
+ }
+ }
+ });
+ gBrowser.removeCurrentTab(); // closes about:certificate
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_handleMultipleCertsURL.js b/toolkit/components/certviewer/tests/browser/browser_handleMultipleCertsURL.js
new file mode 100644
index 0000000000..b0199cce83
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_handleMultipleCertsURL.js
@@ -0,0 +1,251 @@
+// valids
+const multipleCerts1 =
+ "about:certificate?cert=MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd%2BG7%2Bu6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG%2FvUUWVrsxC2gsbR8WJq%2BcYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI%2BpjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek%2FojvedPWe8dhciHkxOC2qPFZvVFMwg1%2Fo%2Fb80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z%2BlvrSjEgrddemWyGGalqyFp1rXlVM1Tf4%2FIYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c%2ByvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT%2FB9TdQ8eXwebo60%2FMCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH%2FBAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC%2BgLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP%2Fzbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W%2F51l8%2BIxDmV%2B9827%2FVo1HVjb%2FSrVgwbTq%2F16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM%2Fed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql%2F68G5q844kFuC6JPl4LVT9mciD%2BVW6bHUSXD9xifL9DqdJ0Ic0SllTlM%2Boq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc%2Fgjxteskq%2FVl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnBXlRAzZ8%2BOJThUbzK16a2CI3Rg4agKSJk%2BuA47h1%2FImmngpFLRb%2FMvRX6H1oWcUuyH6O7PZdl0YpwTpw1THIuqCGl%2FwpPgyQgcTM%3D&cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D";
+const multipleCerts2 =
+ "about:certificate?cert=MIIIIDCCBwigAwIBAgIQGk0sGNQUuaOL9Rii2XQ4yjANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMSUwIwYDVQQDExxHb29nbGUgSW50ZXJuZXQgQXV0aG9yaXR5IEczMB4XDTE5MDYxODA4MjE1OFoXDTE5MDkxMDA4MTUwMFowZjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNVBAoMCkdvb2dsZSBMTEMxFTATBgNVBAMMDCouZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMRScn8kk6qy3LHVktWZWxm%2FMq4kowlEdxQH40wijThZ%2B%2F5Jrqh6UlWnWuiulNorHH2DEW4OkSKreFoYze7w8O6jggWlMIIFoTATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCB4AwggRqBgNVHREEggRhMIIEXYIMKi5nb29nbGUuY29tgg0qLmFuZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tghIqLmNsb3VkLmdvb2dsZS5jb22CGCouY3Jvd2Rzb3VyY2UuZ29vZ2xlLmNvbYIGKi5nLmNvgg4qLmdjcC5ndnQyLmNvbYIRKi5nY3BjZG4uZ3Z0MS5jb22CCiouZ2dwaHQuY26CFiouZ29vZ2xlLWFuYWx5dGljcy5jb22CCyouZ29vZ2xlLmNhggsqLmdvb2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4qLmdvb2dsZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWCDyouZ29vZ2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20ubXiCDyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5kZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29nbGUuaXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCEiouZ29vZ2xlYWRhcGlzLmNvbYIPKi5nb29nbGVhcGlzLmNughEqLmdvb2dsZWNuYXBwcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xldmlkZW8uY29tggwqLmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CEiouZ3N0YXRpY2NuYXBwcy5jboIKKi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIUKi5tZXRyaWMuZ3N0YXRpYy5jb22CDCoudXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0aW9uLmNvbYIRKi55b3V0dWJla2lkcy5jb22CByoueXQuYmWCCyoueXRpbWcuY29tghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CG2RldmVsb3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2dsZS5jboIEZy5jb4IIZ2dwaHQuY26CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22CD2dvb2dsZWNuYXBwcy5jboISZ29vZ2xlY29tbWVyY2UuY29tghhzb3VyY2UuYW5kcm9pZC5nb29nbGUuY26CCnVyY2hpbi5jb22CCnd3dy5nb28uZ2yCCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb22CD3lvdXR1YmVraWRzLmNvbYIFeXQuYmUwaAYIKwYBBQUHAQEEXDBaMC0GCCsGAQUFBzAChiFodHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFNHSUFHMy5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnBraS5nb29nL0dUU0dJQUczMB0GA1UdDgQWBBT8E5DiGEc7xHswBMF5K5EmFzx6fDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMCEGA1UdIAQaMBgwDAYKKwYBBAHWeQIFAzAIBgZngQwBAgIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5wa2kuZ29vZy9HVFNHSUFHMy5jcmwwDQYJKoZIhvcNAQELBQADggEBAGrWCimTdP8%2B6qCqNh1Xza9Wlm%2FGDVb%2BKp0PHUZaNDMThFQQqGn2XVi7ZkhqsxTtMw88Nrl97Bi1OsnNPlabhDwxtRyWkNkLdpFxebRz73CsjyoB3cboH%2FZ8sU9LLwXe%2FIJgMkvT7fznKtKSweWV%2BmAYG%2F3KzaIyLrowYpyOsWaYytPJK7ypuk6yOPxuQcQnelotWpuHUBR3mo3FIW56BPCy20KwqwvWoZe27BNxO%2F11Ym%2FPnric2fWXwgmHdkvVqqssUMFs%2BmG2tS%2FpqnR5yZdQL60xOgDq70mVWYgQT4yUTm7i8qvugvNnuSIjjsbelHgbC8f5%2Fx%2Bo2pEyw%2FDYyKw%3D&cert=MIIGcTCCBVmgAwIBAgIQCHx760AsIFydVjey10GPXTANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFNlcnZlciBDQTAeFw0xOTA1MjQwMDAwMDBaFw0yMDA1MjMxMjAwMDBaMHkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRYwFAYDVQQKEw1Ud2l0dGVyLCBJbmMuMQ0wCwYDVQQLEwRhdGxhMRYwFAYDVQQDDA0qLnR3aXR0ZXIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4IL8Mo0RIfgZmVhwMiaq30EfjJzcB1dalwHZb2K6P6LtmEpLs%2Bnqm1FCdfZgKO3u4CAbd5Oc2EaZB5KjhOcEo6GjhGKcLS430y%2FXhqWo6dDWWYal1Ulu7CCvNLir0Q5aQ2m8EJuafK%2BqwxSBCGXiWeT4HXqabyU34i70bQbgBSjvffaHr27HVrD4hxq0DspKTIpf0fc4%2B%2Fs%2FTTbxEmX7FbVgmu3Y3rTpeNXegL2Lp5nrGp1drWpcM6g8PlrlhcWujdD2Sb0BpIO0dFNCmvOwDspKt8Ih7t0Sw3Q7u0EGEGJLt%2BgY7nrBoRm1G0DSBd0Ih4coHzfgoGBPy11atynvLwIDAQABo4IC%2FDCCAvgwHwYDVR0jBBgwFoAUUWj%2FkK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFNFZBVr1ptzC%2FiUkvSIQ8QAGfB5jMCUGA1UdEQQeMByCDSoudHdpdHRlci5jb22CC3R3aXR0ZXIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItaGEtc2VydmVyLWc2LmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItaGEtc2VydmVyLWc2LmNybDBMBgNVHSAERTBDMDcGCWCGSAGG%2FWwBATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAECAjCBgwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJIaWdoQXNzdXJhbmNlU2VydmVyQ0EuY3J0MAwGA1UdEwEB%2FwQCMAAwggEFBgorBgEEAdZ5AgQCBIH2BIHzAPEAdgDuS723dc5guuFCaR%2Br4Z5mow9%2BX7By2IMAxHuJeqj9ywAAAWrrCDXmAAAEAwBHMEUCIQCSwzRMoifj1DjYLJuMOH%2BZ6coX83bWIgWgWynLUED87wIgFKdipP9ycAE8S9apXJxKQyp0RoA%2Ftca5%2BWHQE5VlF68AdwCHdb%2FnWXz4jEOZX73zbv9WjUdWNv9KtWDBtOr%2FXqCDDwAAAWrrCDakAAAEAwBIMEYCIQCcmFOfp58BDMFZZS%2FRVl2uiY94RcTozBrcmtkpoWhgkgIhAN%2BX3ODViV4HnN2ZpZ383mFaEHIjKACRdWTRL%2BcYA43lMA0GCSqGSIb3DQEBCwUAA4IBAQB8LQLmUzevGtdw%2FXVL8aFrotloF3zsUPb2Q7CONLzlMGrmfv%2BNKDXN9xqPLLzmX4MddOjfpbVcDX1mJkuvuYNhh5AQrsaxcfEgfMcqPOdELA1mHPfk8H5a8Tvno1nF9wQWqkCQjLedjKReivmDOGfs1%2Fl%2FDnrprc0v4f28cWvN7YkJsdqfEGLbJ6SKsAxNbtNn%2Ffi6LxnemjLbcTrZYps11Ex55PtDNc200ejqpbpzHolgAew4KUzsyElaYSvDwkLMdmfwYSI9wgcPmrPBfZ0N12TAfmJJbE%2FkZc0jIOi92A%2FVgZLKvQrxadnBqPzAR%2F2SrZMT5joWa5sHpwl9fg5Z";
+
+// both invalids
+const errorCerts1 = "about:certificate?cert=aa&cert=bb&cert=abc";
+// one invalid and other valid
+const errorCerts2 =
+ "about:certificate?cert=aa&cert=MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd%2BG7%2Bu6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG%2FvUUWVrsxC2gsbR8WJq%2BcYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI%2BpjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek%2FojvedPWe8dhciHkxOC2qPFZvVFMwg1%2Fo%2Fb80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z%2BlvrSjEgrddemWyGGalqyFp1rXlVM1Tf4%2FIYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c%2ByvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT%2FB9TdQ8eXwebo60%2FMCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH%2FBAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC%2BgLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH%2FBAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE%2BRvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP%2Fzbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W%2F51l8%2BIxDmV%2B9827%2FVo1HVjb%2FSrVgwbTq%2F16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM%2Fed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql%2F68G5q844kFuC6JPl4LVT9mciD%2BVW6bHUSXD9xifL9DqdJ0Ic0SllTlM%2Boq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc%2Fgjxteskq%2FVl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnBXlRAzZ8%2BOJThUbzK16a2CI3Rg4agKSJk%2BuA47h1%2FImmngpFLRb%2FMvRX6H1oWcUuyH6O7PZdl0YpwTpw1THIuqCGl%2FwpPgyQgcTM%3D";
+
+async function checkSubjectName(inputPage, subjectsNameInfo) {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: inputPage,
+ },
+ async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [subjectsNameInfo],
+ async function (subjectsNameInfoExpected) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(
+ () => {
+ return content.document.querySelector("certificate-section");
+ },
+ "Certificate section found"
+ );
+
+ async function selectTab(tabName, index) {
+ let tabs =
+ certificateSection.shadowRoot.querySelector(".certificate-tabs");
+
+ let tab = tabs.querySelector(`.tab[idnumber="${index}"]`);
+ Assert.ok(tab, `Tab at index ${index} found`);
+ Assert.equal(
+ tab.innerText,
+ tabName,
+ `Tab name should be ${tabName}`
+ );
+
+ tab.click();
+ }
+
+ function checkSelectedTab(sectionItemsExpected, index) {
+ let infoGroup = certificateSection.shadowRoot.querySelector(
+ `#panel${index} info-group`
+ );
+ Assert.ok(infoGroup, "infoGroup found");
+
+ let sectionTitle =
+ infoGroup.shadowRoot.querySelector(".info-group-title").innerText;
+ Assert.equal(
+ sectionTitle,
+ "Subject Name",
+ "Subject Name must be the selected item"
+ );
+
+ let infoItems = infoGroup.shadowRoot.querySelectorAll("info-item");
+ Assert.equal(
+ infoItems.length,
+ sectionItemsExpected.length,
+ "sectionItems must be the same length"
+ );
+ }
+
+ for (let i = 0; i < subjectsNameInfoExpected.length; i++) {
+ await selectTab(subjectsNameInfoExpected[i].tabName, i);
+ checkSelectedTab(subjectsNameInfoExpected[i].sectionItems, i);
+ }
+ }
+ );
+ }
+ );
+}
+
+async function checkTabsName(inputPage, tabsNames) {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: inputPage,
+ },
+ async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [tabsNames],
+ async function (expectedTabsNames) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(
+ () => {
+ return content.document.querySelector("certificate-section");
+ },
+ "Certificate section found"
+ );
+
+ let tabsSection =
+ certificateSection.shadowRoot.querySelector(".certificate-tabs");
+ Assert.ok(tabsSection, "Tabs section found");
+
+ let tabs = tabsSection.children;
+ Assert.equal(
+ tabs.length,
+ expectedTabsNames.length,
+ `There must be ${expectedTabsNames.length} tabs`
+ );
+
+ for (let i = 0; i < expectedTabsNames.length; i++) {
+ Assert.equal(
+ tabs[i].innerText,
+ expectedTabsNames[i],
+ "Tab name must be equal to expected tab name"
+ );
+ if (i === 0) {
+ Assert.ok(
+ tabs[i].className.includes("selected"),
+ "First tab must be selected"
+ );
+ } else {
+ Assert.equal(
+ tabs[i].className.includes("selected"),
+ false,
+ "Just the first tab must be selected"
+ );
+ }
+ }
+ }
+ );
+ }
+ );
+}
+
+async function checkDOM(inputPage, errorExpected) {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: inputPage,
+ },
+ async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [errorExpected],
+ async function (errorExpected) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(
+ () => {
+ return content.document.querySelector("certificate-section");
+ },
+ "Certificate section found"
+ );
+
+ let errorSection =
+ certificateSection.shadowRoot.querySelector("error-section");
+
+ if (errorExpected) {
+ // should render error page
+ Assert.ok(errorSection, "Error section found");
+ } else {
+ // should render page with certificate info
+ Assert.equal(errorSection, null, "Error section was not found");
+ }
+ }
+ );
+ }
+ );
+}
+
+add_task(async function runTests() {
+ let inputs = [
+ {
+ url: multipleCerts1,
+ tabsNames: ["www.mozilla.org", "github.com"],
+ errorPageExpected: false,
+ subjectNameInfo: [
+ {
+ tabName: "www.mozilla.org",
+ sectionTitle: "Subject Name",
+ sectionItems: [
+ { label: "Country", info: "US" },
+ { label: "State / Province", info: "California" },
+ { label: "Locality", info: "Mountain View" },
+ { label: "Organization", info: "Mozilla Corporation" },
+ { label: "Organizational Unit", info: "WebOps" },
+ { label: "Common Name", info: "www.mozilla.org" },
+ ],
+ },
+ {
+ tabName: "github.com",
+ sectionTitle: "Subject Name",
+ sectionItems: [
+ { label: "Business Category", info: "Private Organization" },
+ { label: "Inc. Country", info: "US" },
+ { label: "Inc. State / Province", info: "Delaware" },
+ { label: "Serial Number", info: "5157550" },
+ { label: "Country", info: "US" },
+ { label: "State / Province", info: "California" },
+ { label: "Locality", info: "San Francisco" },
+ { label: "Organization", info: "GitHub, Inc." },
+ { label: "Common Name", info: "github.com" },
+ ],
+ },
+ ],
+ },
+ {
+ url: multipleCerts2,
+ tabsNames: ["*.google.com", "*.twitter.com"],
+ errorPageExpected: false,
+ subjectNameInfo: [
+ {
+ tabName: "*.google.com",
+ sectionTitle: "Subject Name",
+ sectionItems: [
+ { label: "Country", info: "US" },
+ { label: "State / Province", info: "California" },
+ { label: "Locality", info: "Mountain View" },
+ { label: "Organization", info: "Google LLC" },
+ { label: "Common Name", info: "*.google.com" },
+ ],
+ },
+ {
+ tabName: "*.twitter.com",
+ sectionTitle: "Subject Name",
+ sectionItems: [
+ { label: "Country", info: "US" },
+ { label: "State / Province", info: "California" },
+ { label: "Locality", info: "San Francisco" },
+ { label: "Organization", info: "Twitter, Inc." },
+ { label: "Organizational Unit", info: "atla" },
+ { label: "Common Name", info: "*.twitter.com" },
+ ],
+ },
+ ],
+ },
+ {
+ url: errorCerts1,
+ tabsNames: [],
+ errorPageExpected: true,
+ },
+ {
+ url: errorCerts2,
+ tabsNames: [],
+ errorPageExpected: true,
+ },
+ ];
+
+ for (let input of inputs) {
+ await checkDOM(input.url, input.errorPageExpected);
+ if (!input.errorPageExpected) {
+ await checkTabsName(input.url, input.tabsNames);
+ await checkSubjectName(input.url, input.subjectNameInfo);
+ }
+ }
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_openTabAndSendCertInfo.js b/toolkit/components/certviewer/tests/browser/browser_openTabAndSendCertInfo.js
new file mode 100644
index 0000000000..c6307f529a
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_openTabAndSendCertInfo.js
@@ -0,0 +1,271 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TEST_CERT_BASE64 =
+ "MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd+G7+u6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG/vUUWVrsxC2gsbR8WJq+cYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI+pjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek/ojvedPWe8dhciHkxOC2qPFZvVFMwg1/o/b80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z+lvrSjEgrddemWyGGalqyFp1rXlVM1Tf4/IYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c+yvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT/B9TdQ8eXwebo60/MCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP/zbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM/ed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql/68G5q844kFuC6JPl4LVT9mciD+VW6bHUSXD9xifL9DqdJ0Ic0SllTlM+oq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc/gjxteskq/Vl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnBXlRAzZ8+OJThUbzK16a2CI3Rg4agKSJk+uA47h1/ImmngpFLRb/MvRX6H1oWcUuyH6O7PZdl0YpwTpw1THIuqCGl/wpPgyQgcTM=";
+
+function checkSpec(spec) {
+ Assert.ok(
+ spec.startsWith("about:certificate"),
+ "about:certificate was opened"
+ );
+
+ let newUrl = new URL(spec);
+ let certEncoded = newUrl.searchParams.get("cert");
+ let certDecoded = decodeURIComponent(certEncoded);
+ Assert.equal(
+ btoa(atob(certDecoded)),
+ certDecoded,
+ "We received an base64 string"
+ );
+}
+
+function checksCertTab(tabsCount) {
+ Assert.equal(gBrowser.tabs.length, tabsCount + 1, "New tab was opened");
+ let spec = gBrowser.tabs[tabsCount].linkedBrowser.documentURI.spec;
+ checkSpec(spec);
+}
+
+async function checkCertChain(browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let certificateTabs;
+ await ContentTaskUtils.waitForCondition(() => {
+ let certificateSection = content.document.querySelector(
+ "certificate-section"
+ );
+ if (!certificateSection) {
+ return false;
+ }
+ certificateTabs =
+ certificateSection.shadowRoot.querySelectorAll(".certificate-tab");
+ return certificateTabs.length;
+ }, "Found certificate tabs.");
+
+ Assert.greaterOrEqual(
+ certificateTabs.length,
+ 1,
+ "Certificate chain tabs shown"
+ );
+ });
+}
+
+// taken from https://searchfox.org/mozilla-central/rev/7ed8e2d3d1d7a1464ba42763a33fd2e60efcaedc/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js#47
+function openCertDownloadDialog(cert) {
+ let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
+ Ci.nsIWritablePropertyBag2
+ );
+ let win = window.openDialog(
+ "chrome://pippki/content/downloadcert.xhtml",
+ "",
+ "",
+ cert,
+ returnVals
+ );
+ return new Promise((resolve, reject) => {
+ win.addEventListener(
+ "load",
+ function () {
+ executeSoon(() => resolve([win]));
+ },
+ { once: true }
+ );
+ });
+}
+
+add_task(async function openFromPopUp() {
+ info("Testing openFromPopUp");
+
+ const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
+ Ci.nsIX509CertDB
+ );
+ let cert = certdb.constructX509FromBase64(TEST_CERT_BASE64);
+
+ let [win] = await openCertDownloadDialog(cert);
+ let viewCertButton = win.document.getElementById("viewC-button");
+ let newWinOpened = BrowserTestUtils.waitForNewWindow();
+ viewCertButton.click();
+
+ let topWin = await newWinOpened;
+ let browser = topWin.gBrowser.selectedBrowser;
+
+ // We're racing against messages sent up from the content process that
+ // loads about:certificate. It may or may not have had the opportunity
+ // to tell the parent that it had loaded the page yet. If not, we wait
+ // for the page to load.
+ //
+ // Note that we can't use the URL parameter for
+ // BrowserTestUtils.waitForNewWindow, since we need to use a function
+ // to choose the right URL.
+ if (!browser.currentURI.spec.startsWith("about:certificate")) {
+ await BrowserTestUtils.browserLoaded(browser, false, spec =>
+ spec.startsWith("about:certificate")
+ );
+ }
+
+ let spec = browser.currentURI.spec;
+ checkSpec(spec);
+
+ await checkCertChain(browser);
+
+ await BrowserTestUtils.closeWindow(topWin); // closes about:certificate
+ win.document.getElementById("download_cert").cancelDialog();
+ await BrowserTestUtils.windowClosed(win);
+});
+
+add_task(async function testBadCert() {
+ info("Testing bad cert");
+
+ let tab = await openErrorPage();
+
+ let tabsCount = gBrowser.tabs.length;
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+
+ await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
+ let advancedButton = content.document.getElementById("advancedButton");
+ Assert.ok(advancedButton, "advancedButton found");
+ Assert.equal(
+ advancedButton.hasAttribute("disabled"),
+ false,
+ "advancedButton should be clickable"
+ );
+ advancedButton.click();
+ let viewCertificate = content.document.getElementById("viewCertificate");
+ Assert.ok(viewCertificate, "viewCertificate found");
+ Assert.equal(
+ viewCertificate.hasAttribute("disabled"),
+ false,
+ "viewCertificate should be clickable"
+ );
+
+ viewCertificate.click();
+ });
+ await loaded;
+ checksCertTab(tabsCount);
+ await checkCertChain(gBrowser.selectedBrowser);
+
+ gBrowser.removeCurrentTab(); // closes about:certificate
+ gBrowser.removeCurrentTab(); // closes https://expired.example.com/
+});
+
+add_task(async function testBadCertIframe() {
+ info("Testing bad cert in an iframe");
+
+ let tab = await openErrorPage(true);
+
+ let tabsCount = gBrowser.tabs.length;
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+
+ await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
+ let doc = content.document.querySelector("iframe").contentDocument;
+ let advancedButton = doc.getElementById("advancedButton");
+ Assert.ok(advancedButton, "advancedButton found");
+ Assert.equal(
+ advancedButton.hasAttribute("disabled"),
+ false,
+ "advancedButton should be clickable"
+ );
+ advancedButton.click();
+ let viewCertificate = doc.getElementById("viewCertificate");
+ Assert.ok(viewCertificate, "viewCertificate found");
+ Assert.equal(
+ viewCertificate.hasAttribute("disabled"),
+ false,
+ "viewCertificate should be clickable"
+ );
+
+ viewCertificate.click();
+ });
+ await loaded;
+ checksCertTab(tabsCount);
+ await checkCertChain(gBrowser.selectedBrowser);
+
+ gBrowser.removeCurrentTab(); // closes about:certificate
+ gBrowser.removeCurrentTab(); // closes https://expired.example.com/
+});
+
+add_task(async function testGoodCert() {
+ info("Testing page info");
+ let url = "https://example.com/";
+
+ let tabsCount = gBrowser.tabs.length;
+
+ info(`Loading ${url}`);
+ await BrowserTestUtils.withNewTab({ gBrowser, url }, async function () {
+ info("Opening pageinfo");
+ let pageInfo = BrowserPageInfo(url, "securityTab", {});
+ await BrowserTestUtils.waitForEvent(pageInfo, "load");
+
+ let securityTab = pageInfo.document.getElementById("securityTab");
+ await TestUtils.waitForCondition(
+ () => BrowserTestUtils.isVisible(securityTab),
+ "Security tab should be visible."
+ );
+ Assert.ok(securityTab, "Security tab is available");
+ let viewCertButton = pageInfo.document.getElementById("security-view-cert");
+ await TestUtils.waitForCondition(
+ () => BrowserTestUtils.isVisible(viewCertButton),
+ "view cert button should be visible."
+ );
+
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+ checkAndClickButton(pageInfo.document, "security-view-cert");
+ await loaded;
+
+ await checkCertChain(gBrowser.selectedBrowser);
+ pageInfo.close();
+ });
+ checksCertTab(tabsCount);
+
+ gBrowser.removeCurrentTab(); // closes about:certificate
+});
+
+add_task(async function testPreferencesCert() {
+ info("Testing preferences cert");
+ let url = "about:preferences#privacy";
+
+ let tabsCount;
+
+ info(`Loading ${url}`);
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url },
+ async function (browser) {
+ tabsCount = gBrowser.tabs.length;
+ checkAndClickButton(browser.contentDocument, "viewCertificatesButton");
+
+ let certDialogLoaded = promiseLoadSubDialog(
+ "chrome://pippki/content/certManager.xhtml"
+ );
+ let dialogWin = await certDialogLoaded;
+ let doc = dialogWin.document;
+ Assert.ok(doc, "doc loaded");
+
+ doc.getElementById("certmanagertabs").selectedTab =
+ doc.getElementById("mine_tab");
+ let treeView = doc.getElementById("user-tree").view;
+ let selectedCert;
+ // See https://searchfox.org/mozilla-central/rev/40ef22080910c2e2c27d9e2120642376b1d8b8b2/browser/components/preferences/in-content/tests/browser_cert_export.js#41
+ for (let i = 0; i < treeView.rowCount; i++) {
+ treeView.selection.select(i);
+ dialogWin.getSelectedCerts();
+ let certs = dialogWin.selected_certs;
+ if (certs && certs[0]) {
+ selectedCert = certs[0];
+ break;
+ }
+ }
+ Assert.ok(selectedCert, "A cert should be selected");
+ let viewButton = doc.getElementById("mine_viewButton");
+ Assert.equal(viewButton.disabled, false, "Should enable view button");
+
+ let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
+ viewButton.click();
+ await loaded;
+
+ checksCertTab(tabsCount);
+ await checkCertChain(gBrowser.selectedBrowser);
+ }
+ );
+ gBrowser.removeCurrentTab(); // closes about:certificate
+});
diff --git a/toolkit/components/certviewer/tests/browser/browser_renderCertToUI.js b/toolkit/components/certviewer/tests/browser/browser_renderCertToUI.js
new file mode 100644
index 0000000000..0ecb93f176
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/browser_renderCertToUI.js
@@ -0,0 +1,192 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const url =
+ "about:certificate?cert=MIIHQjCCBiqgAwIBAgIQCgYwQn9bvO1pVzllk7ZFHzANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MDUwODAwMDAwMFoXDTIwMDYwMzEyMDAwMFowgccxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQFEwc1MTU3NTUwMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjyq8jyXDDrBTyitcnB90865tWBzpHSbindG%2FXqYQkzFMBlXmqkzC%2BFdTRBYyneZw5Pz%2BXWQvL%2B74JW6LsWNc2EF0xCEqLOJuC9zjPAqbr7uroNLghGxYf13YdqbG5oj%2F4x%2BogEG3dF%2FU5YIwVr658DKyESMV6eoYV9mDVfTuJastkqcwero%2B5ZAKfYVMLUEsMwFtoTDJFmVf6JlkOWwsxp1WcQ%2FMRQK1cyqOoUFUgYylgdh3yeCDPeF22Ax8AlQxbcaI%2BGwfQL1FB7Jy%2Bh%2BKjME9lE%2FUpgV6Qt2R1xNSmvFCBWu%2BNFX6epwFP%2FJRbkMfLz0beYFUvmMgLtwVpEPSwIDAQABo4IDeTCCA3UwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFMnCU2FmnV%2BrJfQmzQ84mqhJ6kipMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1UdDwEB%2FwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG%2FWwCATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWNBYm0KAAAEAwBHMEUCIQDRZp38cTWsWH2GdBpe%2FuPTWnsu%2Fm4BEC2%2BdIcvSykZYgIgCP5gGv6yzaazxBK2NwGdmmyuEFNSg2pARbMJlUFgU5UAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWNBYm0tAAAEAwBHMEUCIQCi7omUvYLm0b2LobtEeRAYnlIo7n6JxbYdrtYdmPUWJQIgVgw1AZ51vK9ENinBg22FPxb82TvNDO05T17hxXRC2IYAdgC72d%2B8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWNBYm3fAAAEAwBHMEUCIQChzdTKUU2N%2BXcqcK0OJYrN8EYynloVxho4yPk6Dq3EPgIgdNH5u8rC3UcslQV4B9o0a0w204omDREGKTVuEpxGeOQwDQYJKoZIhvcNAQELBQADggEBAHAPWpanWOW%2Fip2oJ5grAH8mqQfaunuCVE%2Bvac%2B88lkDK%2FLVdFgl2B6kIHZiYClzKtfczG93hWvKbST4NRNHP9LiaQqdNC17e5vNHnXVUGw%2ByxyjMLGqkgepOnZ2Rb14kcTOGp4i5AuJuuaMwXmCo7jUwPwfLe1NUlVBKqg6LK0Hcq4K0sZnxE8HFxiZ92WpV2AVWjRMEc%2F2z2shNoDvxvFUYyY1Oe67xINkmyQKc%2BygSBZzyLnXSFVWmHr3u5dcaaQGGAR42v6Ydr4iL38Hd4dOiBma%2BFXsXBIqWUjbST4VXmdaol7uzFMojA4zkxQDZAvF5XgJlAFadfySna%2Fteik%3D";
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/certviewer/tests/browser/adjustedCerts.js",
+ this
+);
+
+add_task(async function test() {
+ Assert.ok(adjustedCerts, "adjustedCerts found");
+
+ let tabName = adjustedCerts[0].tabName;
+ let certItems = adjustedCerts[0].certItems;
+
+ await BrowserTestUtils.withNewTab(url, async function (browser) {
+ await SpecialPowers.spawn(
+ browser,
+ [[certItems, tabName]],
+ async function ([adjustedCerts, expectedTabName]) {
+ let certificateSection = await ContentTaskUtils.waitForCondition(() => {
+ return content.document.querySelector("certificate-section");
+ }, "Certificate section found");
+
+ let infoGroups =
+ certificateSection.shadowRoot.querySelectorAll("info-group");
+ Assert.ok(infoGroups, "infoGroups found");
+ Assert.equal(
+ infoGroups.length,
+ adjustedCerts.length,
+ "infoGroups must have the same length of adjustedCerts"
+ );
+
+ let tabName =
+ certificateSection.shadowRoot.querySelector(
+ ".tab[idnumber='0']"
+ ).textContent;
+ Assert.equal(tabName, expectedTabName, "Tab name should be the same");
+
+ function getElementByAttribute(source, property, target) {
+ for (let elem of source) {
+ if (elem.hasOwnProperty(property) && elem[property] === target) {
+ return elem;
+ }
+ }
+ return null;
+ }
+
+ function checkBooleans(got, expected) {
+ info(
+ "If adjustedCertElments returned true, this value should be Yes, otherwise it should be No"
+ );
+ let gotBool;
+ if (got === "Yes") {
+ gotBool = true;
+ } else if (got === "No") {
+ gotBool = false;
+ } else {
+ gotBool = null;
+ }
+ Assert.equal(
+ gotBool,
+ expected,
+ `Expected ${expected}, got ${gotBool}`
+ );
+ }
+
+ for (let infoGroup of infoGroups) {
+ let sectionId = infoGroup.shadowRoot
+ .querySelector(".info-group-title")
+ .getAttribute("data-l10n-id")
+ .replace("certificate-viewer-", "");
+
+ let adjustedCertsElem = getElementByAttribute(
+ adjustedCerts,
+ "sectionId",
+ sectionId
+ );
+ Assert.ok(adjustedCertsElem, "The element exists in adjustedCerts");
+
+ let infoItems = infoGroup.shadowRoot.querySelectorAll("info-item");
+ Assert.equal(
+ infoItems.length,
+ adjustedCertsElem.sectionItems.length,
+ "sectionItems must be the same length"
+ );
+
+ let i = 0;
+ // Message ID mappings
+ let stringMapping = {
+ signaturealgorithm: "signature-algorithm",
+ };
+ for (let infoItem of infoItems) {
+ let infoItemLabel = infoItem.shadowRoot
+ .querySelector("label")
+ .getAttribute("data-l10n-id");
+ let infoElem = infoItem.shadowRoot.querySelector(".info");
+ let infoItemInfo = infoElem.textContent;
+ let adjustedCertsElemLabel =
+ adjustedCertsElem.sectionItems[i].labelId;
+ let adjustedCertsElemInfo = adjustedCertsElem.sectionItems[i].info;
+
+ if (adjustedCertsElemLabel == null) {
+ adjustedCertsElemLabel = "";
+ }
+ adjustedCertsElemLabel = adjustedCertsElemLabel
+ .replace(/\s+/g, "-")
+ .replace(/\./g, "")
+ .replace(/\//g, "")
+ .replace(/--/g, "-")
+ .toLowerCase();
+ adjustedCertsElemLabel =
+ stringMapping[adjustedCertsElemLabel] || adjustedCertsElemLabel;
+
+ if (adjustedCertsElemInfo == null) {
+ adjustedCertsElemInfo = "";
+ }
+ if (typeof adjustedCertsElemInfo === "boolean") {
+ checkBooleans(infoItemInfo, adjustedCertsElemInfo);
+ continue;
+ }
+
+ if (
+ adjustedCertsElemLabel === "timestamp" ||
+ adjustedCertsElemLabel === "not-after" ||
+ adjustedCertsElemLabel === "not-before"
+ ) {
+ Assert.equal(
+ infoElem.textContent,
+ adjustedCertsElemInfo.utc,
+ "Timestamps must be equal"
+ );
+ i++;
+ continue;
+ }
+ if (adjustedCertsElemLabel === "download") {
+ Assert.equal(infoElem.children.length, 2, "Should have 2 links.");
+ for (let kid of infoElem.children) {
+ Assert.equal(
+ kid.localName,
+ "a",
+ "Should get a cert/chain link."
+ );
+ Assert.ok(
+ kid.download.endsWith("pem"),
+ "Link `download` attribute should point to pem file."
+ );
+ Assert.ok(
+ kid.dataset.l10nId.includes("pem"),
+ "Link should be labeled"
+ );
+ Assert.equal(
+ kid.dataset.l10nId.includes("chain"),
+ kid.download.includes("chain"),
+ "Download label and filename should match"
+ );
+ }
+ // Remaining tests in browser_downloadLink.js
+
+ i++;
+ continue;
+ }
+
+ if (Array.isArray(adjustedCertsElemInfo)) {
+ // there is a case where we have a boolean
+ adjustedCertsElemInfo = adjustedCertsElemInfo
+ .toString()
+ .replace(/,/g, ", ");
+ }
+
+ Assert.ok(
+ infoItemLabel.includes(adjustedCertsElemLabel),
+ "data-l10n-id must contain the original label"
+ );
+
+ Assert.equal(
+ infoItemInfo,
+ adjustedCertsElemInfo,
+ "Info must be equal"
+ );
+
+ i++;
+ }
+ }
+ }
+ );
+ });
+});
diff --git a/toolkit/components/certviewer/tests/browser/dummy_page.html b/toolkit/components/certviewer/tests/browser/dummy_page.html
new file mode 100644
index 0000000000..1a87e28408
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/dummy_page.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Dummy test page</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
+</head>
+<body>
+<p>Dummy test page</p>
+</body>
+</html>
diff --git a/toolkit/components/certviewer/tests/browser/head.js b/toolkit/components/certviewer/tests/browser/head.js
new file mode 100644
index 0000000000..2a28444f9b
--- /dev/null
+++ b/toolkit/components/certviewer/tests/browser/head.js
@@ -0,0 +1,124 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function checkAndClickButton(document, id) {
+ let button = document.getElementById(id);
+ Assert.ok(button, `${id} button found`);
+ Assert.equal(
+ button.hasAttribute("disabled"),
+ false,
+ "button should be clickable"
+ );
+ button.click();
+}
+
+function is_element_visible(aElement, aMsg) {
+ isnot(aElement, null, "Element should not be null, when checking visibility");
+ Assert.ok(!BrowserTestUtils.isHidden(aElement), aMsg);
+}
+
+// Extracted from https://searchfox.org/mozilla-central/rev/40ef22080910c2e2c27d9e2120642376b1d8b8b2/browser/components/preferences/in-content/tests/head.js#41
+function promiseLoadSubDialog(aURL) {
+ return new Promise((resolve, reject) => {
+ content.gSubDialog._dialogStack.addEventListener(
+ "dialogopen",
+ function dialogopen(aEvent) {
+ if (
+ aEvent.detail.dialog._frame.contentWindow.location == "about:blank"
+ ) {
+ return;
+ }
+ content.gSubDialog._dialogStack.removeEventListener(
+ "dialogopen",
+ dialogopen
+ );
+
+ Assert.equal(
+ aEvent.detail.dialog._frame.contentWindow.location.toString(),
+ aURL,
+ "Check the proper URL is loaded"
+ );
+
+ // Check visibility
+ is_element_visible(aEvent.detail.dialog._overlay, "Overlay is visible");
+
+ // Check that stylesheets were injected
+ let expectedStyleSheetURLs =
+ aEvent.detail.dialog._injectedStyleSheets.slice(0);
+ for (let styleSheet of aEvent.detail.dialog._frame.contentDocument
+ .styleSheets) {
+ let i = expectedStyleSheetURLs.indexOf(styleSheet.href);
+ if (i >= 0) {
+ info("found " + styleSheet.href);
+ expectedStyleSheetURLs.splice(i, 1);
+ }
+ }
+ Assert.equal(
+ expectedStyleSheetURLs.length,
+ 0,
+ "All expectedStyleSheetURLs should have been found"
+ );
+
+ // Wait for the next event tick to make sure the remaining part of the
+ // testcase runs after the dialog gets ready for input.
+ executeSoon(() => resolve(aEvent.detail.dialog._frame.contentWindow));
+ }
+ );
+ });
+}
+
+function injectErrorPageFrame(tab, src) {
+ return SpecialPowers.spawn(
+ tab.linkedBrowser,
+ [{ frameSrc: src }],
+ async function ({ frameSrc }) {
+ let loaded = ContentTaskUtils.waitForEvent(
+ content.wrappedJSObject,
+ "DOMFrameContentLoaded"
+ );
+ let iframe = content.document.createElement("iframe");
+ iframe.src = frameSrc;
+ content.document.body.appendChild(iframe);
+ await loaded;
+ // We will have race conditions when accessing the frame content after setting a src,
+ // so we can't wait for AboutNetErrorLoad. Let's wait for the certerror class to
+ // appear instead (which should happen at the same time as AboutNetErrorLoad).
+ await ContentTaskUtils.waitForCondition(() =>
+ iframe.contentDocument.body.classList.contains("certerror")
+ );
+ }
+ );
+}
+
+async function openErrorPage(useFrame = false) {
+ let src = "https://expired.example.com/";
+ let dummyPage =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "https://example.com"
+ ) + "dummy_page.html";
+
+ let tab;
+ if (useFrame) {
+ info("Loading cert error page in an iframe");
+ tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, dummyPage);
+ await injectErrorPageFrame(tab, src);
+ } else {
+ let certErrorLoaded;
+ tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ () => {
+ gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, src);
+ let browser = gBrowser.selectedBrowser;
+ certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
+ },
+ false
+ );
+ info("Loading and waiting for the cert error");
+ await certErrorLoaded;
+ }
+
+ return tab;
+}
diff --git a/toolkit/components/certviewer/tests/chrome/CSoutput.mjs b/toolkit/components/certviewer/tests/chrome/CSoutput.mjs
new file mode 100644
index 0000000000..d90026353e
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/CSoutput.mjs
@@ -0,0 +1,144 @@
+export const certOutputCS = [
+ {
+ ext: {
+ aia: {
+ descriptions: [
+ {
+ location: "http://ocsp.digicert.com",
+ method: "Online Certificate Status Protocol (OCSP)",
+ },
+ {
+ location:
+ "http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt",
+ method: "CA Issuers",
+ },
+ ],
+ critical: false,
+ },
+ aKID: {
+ critical: false,
+ id: "0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2",
+ },
+ basicConstraints: { cA: false, critical: true },
+ crlPoints: {
+ critical: false,
+ points: [
+ "http://crl3.digicert.com/ssca-sha2-g6.crl",
+ "http://crl4.digicert.com/ssca-sha2-g6.crl",
+ ],
+ },
+ cp: {
+ critical: false,
+ policies: [
+ {
+ id: "2.16.840",
+ name: "ANSI Organizational Identifier",
+ qualifiers: [
+ {
+ qualifierId: "1.3.6.1.5.5.7.2.1",
+ qualifierName: "Practices Statement",
+ qualifierValue: "https://www.digicert.com/CPS",
+ },
+ ],
+ value: "2.16.840.1.114412.1.1",
+ },
+ {
+ id: "2.23.140.1.2.2",
+ name: "Certificate Type",
+ value: "Organization Validation",
+ },
+ ],
+ },
+ eKeyUsages: {
+ critical: false,
+ purposes: ["Server Authentication", "Client Authentication"],
+ },
+ keyUsages: {
+ critical: true,
+ purposes: ["Digital Signature", "Key Encipherment"],
+ },
+ msCrypto: { exists: false },
+ ocspStaple: { critical: false, required: false },
+ scts: {
+ critical: false,
+ timestamps: [
+ {
+ logId:
+ "A4:B9:09:90:B4:18:58:14:87:BB:13:A2:CC:67:70:0A:3C:35:98:04:F9:1B:DF:B8:E3:77:CD:0E:C8:0D:DC:10",
+ name: "Google “Pilot”",
+ signatureAlgorithm: "SHA-256 ECDSA",
+ timestamp: "11/5/2018, 8:55:28 PM (Brasilia Standard Time)",
+ timestampUTC: "Mon, 05 Nov 2018 22:55:28 GMT",
+ version: 1,
+ },
+ {
+ logId:
+ "87:75:BF:E7:59:7C:F8:8C:43:99:5F:BD:F3:6E:FF:56:8D:47:56:36:FF:4A:B5:60:C1:B4:EA:FF:5E:A0:83:0F",
+ name: "DigiCert Server 2",
+ signatureAlgorithm: "SHA-256 ECDSA",
+ timestamp: "11/5/2018, 8:55:28 PM (Brasilia Standard Time)",
+ timestampUTC: "Mon, 05 Nov 2018 22:55:28 GMT",
+ version: 1,
+ },
+ ],
+ },
+ sKID: {
+ critical: false,
+ id: "DA:52:BD:21:9C:37:65:53:FC:1F:53:75:0F:1E:5F:07:9B:A3:AD:3F",
+ },
+ san: {
+ altNames: [
+ ["DNS Name", "www.mozilla.org"],
+ ["DNS Name", "mozilla.org"],
+ ],
+ critical: false,
+ },
+ },
+ files: {
+ pem: "-----BEGIN%20CERTIFICATE-----%0D%0AMIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd+G7+u6kDANBgkqhkiG9w0BAQsFADBN%0D%0AMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E%0D%0AaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcN%0D%0AMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju%0D%0AaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29y%0D%0AcG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEu%0D%0Ab3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7Q%0D%0AjmXlUOBcLFRyw5LG/vUUWVrsxC2gsbR8WJq+cYoYBpoNVStKrO4U2rBh1GEbccvT%0D%0A6qKOQI+pjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek/ojve%0D%0AdPWe8dhciHkxOC2qPFZvVFMwg1/o/b80147BwZQmzB18mnHsmcyKlpsCN8pxw86u%0D%0Aao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z+lvrSjEgrddemWyGGalqy%0D%0AFp1rXlVM1Tf4/IYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c+yvaYJ%0D%0AKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG%0D%0A2eIwHQYDVR0OBBYEFNpSvSGcN2VT/B9TdQ8eXwebo60/MCcGA1UdEQQgMB6CD3d3%0D%0Ady5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud%0D%0AJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRw%0D%0AOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0%0D%0AcDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUw%0D%0AQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNl%0D%0AcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzAB%0D%0AhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9j%0D%0AYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5j%0D%0AcnQwDAYDVR0TAQH/BAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0%0D%0AGFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMS%0D%0AH1JdG6NASHWTwD0mlP/zbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz%0D%0A1NQ9cq8Az1KnMKRuaFAlAHUAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16g%0D%0Agw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18%0D%0ASfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcN%0D%0AAQELBQADggEBAKLJAFO3wuaP5MM/ed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT%0D%0A9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql/68G5q844kFuC6JPl4LVT9mciD+VW6b%0D%0AHUSXD9xifL9DqdJ0Ic0SllTlM+oq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc/gjx%0D%0Ateskq/Vl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnB%0D%0AXlRAzZ8+OJThUbzK16a2CI3Rg4agKSJk+uA47h1/ImmngpFLRb/MvRX6H1oWcUuy%0D%0AH6O7PZdl0YpwTpw1THIuqCGl/wpPgyQgcTM=%0D%0A-----END%20CERTIFICATE-----%0D%0A",
+ },
+ fingerprint: {
+ sha1: "0E:95:79:81:17:5C:51:D2:76:05:AC:8E:C4:61:71:61:97:29:ED:61",
+ sha256:
+ "30:23:CB:EC:1B:A8:C2:D9:E7:45:05:D5:4A:E2:0F:73:E1:51:C4:2D:46:59:CE:B4:EE:E6:51:7B:9E:CB:84:7B",
+ },
+ issuer: {
+ cn: "DigiCert SHA2 Secure Server CA",
+ dn: "c=US, o=DigiCert Inc, cn=DigiCert SHA2 Secure Server CA",
+ entries: [
+ ["Country", "US"],
+ ["Organization", "DigiCert Inc"],
+ ["Common Name", "DigiCert SHA2 Secure Server CA"],
+ ],
+ },
+ notBefore: "11/4/2018, 10:00:00 PM (Brasilia Standard Time)",
+ notBeforeUTC: "Mon, 05 Nov 2018 00:00:00 GMT",
+ notAfter: "11/13/2019, 10:00:00 AM (Brasilia Standard Time)",
+ notAfterUTC: "Wed, 13 Nov 2019 12:00:00 GMT",
+ subject: {
+ cn: "www.mozilla.org",
+ dn: "c=US, s=California, l=Mountain View, o=Mozilla Corporation, ou=WebOps, cn=www.mozilla.org",
+ entries: [
+ ["Country", "US"],
+ ["State / Province", "California"],
+ ["Locality", "Mountain View"],
+ ["Organization", "Mozilla Corporation"],
+ ["Organizational Unit", "WebOps"],
+ ["Common Name", "www.mozilla.org"],
+ ],
+ },
+ serialNumber: "0C:97:6E:3E:42:38:F4:20:D6:3D:DF:86:EF:EB:BA:90",
+ signature: {
+ name: "SHA-256 with RSA Encryption",
+ type: "1.2.840.113549.1.1.11",
+ },
+ subjectPublicKeyInfo: {
+ e: 65537,
+ kty: "RSA",
+ n: "B8:AA:EE:CA:69:24:9A:4A:82:26:1E:D0:8E:65:E5:50:E0:5C:2C:54:72:C3:92:C6:FE:F5:14:59:5A:EC:C4:2D:A0:B1:B4:7C:58:9A:BE:71:8A:18:06:9A:0D:55:2B:4A:AC:EE:14:DA:B0:61:D4:61:1B:71:CB:D3:EA:A2:8E:40:8F:A9:8E:30:F1:C7:D7:26:45:DB:9B:19:31:A9:F0:BD:0C:17:5A:21:56:F8:48:BD:82:EE:98:E1:28:44:30:CF:53:83:EF:18:98:C6:85:E9:3F:A2:3B:DE:74:F5:9E:F1:D8:5C:88:79:31:38:2D:AA:3C:56:6F:54:53:30:83:5F:E8:FD:BF:34:D7:8E:C1:C1:94:26:CC:1D:7C:9A:71:EC:99:CC:8A:96:9B:02:37:CA:71:C3:CE:AE:6A:8F:48:BA:7F:20:65:0A:EC:96:55:BA:E2:B4:D9:95:14:79:EA:91:DD:01:CB:86:02:86:63:61:9C:70:4B:D6:7E:96:FA:D2:8C:48:2B:75:D7:A6:5B:21:86:6A:5A:B2:16:9D:6B:5E:55:4C:D5:37:F8:FC:86:16:01:05:D3:81:35:0D:DF:4D:EE:DF:13:23:B2:CE:D0:2B:B7:94:0E:C0:02:47:18:96:3C:B5:BD:5D:00:DD:D5:CF:B2:BD:A6:09:2B:38:09:DB",
+ keysize: 2048,
+ },
+ unsupportedExtensions: [],
+ version: "3",
+ },
+];
diff --git a/toolkit/components/certviewer/tests/chrome/chrome.toml b/toolkit/components/certviewer/tests/chrome/chrome.toml
new file mode 100644
index 0000000000..2afba193c0
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/chrome.toml
@@ -0,0 +1,13 @@
+[DEFAULT]
+scheme = "https"
+
+["test_adjustCertInformation.html"]
+support-files = ["parseOutput.mjs"]
+
+["test_certDecoder.html"]
+
+["test_certDecoderFields.html"]
+support-files = ["CSoutput.mjs"]
+
+["test_kebabCaseInAdjustCertInformation.html"]
+support-files = ["parseOutput.mjs"]
diff --git a/toolkit/components/certviewer/tests/chrome/parseOutput.mjs b/toolkit/components/certviewer/tests/chrome/parseOutput.mjs
new file mode 100644
index 0000000000..947801145e
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/parseOutput.mjs
@@ -0,0 +1,330 @@
+export const parseOutput = [
+ {
+ ext: {
+ aia: {
+ descriptions: [
+ {
+ location: "http://ocsp.digicert.com",
+ method: "Online Certificate Status Protocol (OCSP)",
+ },
+ {
+ location:
+ "http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt",
+ method: "CA Issuers",
+ },
+ ],
+ critical: false,
+ },
+ aKID: {
+ critical: false,
+ id: "3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F",
+ },
+ basicConstraints: { cA: false, critical: true },
+ crlPoints: {
+ critical: false,
+ points: [
+ "http://crl3.digicert.com/sha2-ev-server-g2.crl",
+ "http://crl4.digicert.com/sha2-ev-server-g2.crl",
+ ],
+ },
+ cp: {
+ critical: false,
+ policies: [
+ {
+ id: "2.16.840",
+ name: "ANSI Organizational Identifier",
+ qualifiers: [
+ {
+ id: "1.3.6.1.5.5.7.2.1",
+ name: "Practices Statement",
+ value: "https://www.digicert.com/CPS",
+ },
+ ],
+ value: "2.16.840.1.114412.2.1",
+ },
+ {
+ id: "2.23.140.1.1",
+ name: "Certificate Type",
+ value: "Extended Validation",
+ },
+ ],
+ },
+ eKeyUsages: {
+ critical: false,
+ purposes: ["Server Authentication", "Client Authentication"],
+ },
+ keyUsages: {
+ critical: true,
+ purposes: ["Digital Signature", "Key Encipherment"],
+ },
+ msCrypto: { exists: false },
+ ocspStaple: { critical: false, required: false },
+ scts: {
+ critical: false,
+ timestamps: [
+ {
+ logId:
+ "A4:B9:09:90:B4:18:58:14:87:BB:13:A2:CC:67:70:0A:3C:35:98:04:F9:1B:DF:B8:E3:77:CD:0E:C8:0D:DC:10",
+ name: "Google “Pilot”",
+ signatureAlgorithm: "SHA-256 ECDSA",
+ timestamp: "11/7/2018, 7:50:01 PM (Brasilia Standard Time)",
+ timestampUTC: "Wed, 07 Nov 2018 21:50:01 GMT",
+ version: 1,
+ },
+ {
+ logId:
+ "87:75:BF:E7:59:7C:F8:8C:43:99:5F:BD:F3:6E:FF:56:8D:47:56:36:FF:4A:B5:60:C1:B4:EA:FF:5E:A0:83:0F",
+ name: "DigiCert Server 2",
+ signatureAlgorithm: "SHA-256 ECDSA",
+ timestamp: "11/7/2018, 7:50:01 PM (Brasilia Standard Time)",
+ timestampUTC: "Wed, 07 Nov 2018 21:50:01 GMT",
+ version: 1,
+ },
+ {
+ logId:
+ "EE:4B:BD:B7:75:CE:60:BA:E1:42:69:1F:AB:E1:9E:66:A3:0F:7E:5F:B0:72:D8:83:00:C4:7B:89:7A:A8:FD:CB",
+ name: "Google “Rocketeer”",
+ signatureAlgorithm: "SHA-256 ECDSA",
+ timestamp: "11/7/2018, 7:50:01 PM (Brasilia Standard Time)",
+ timestampUTC: "Wed, 07 Nov 2018 21:50:01 GMT",
+ version: 1,
+ },
+ ],
+ },
+ sKID: {
+ critical: false,
+ id: "6C:B0:43:56:FE:3D:E8:12:EC:D9:12:F5:63:D5:C4:CA:07:AF:B0:76",
+ },
+ san: {
+ altNames: [
+ ["DNS Name", "www.digicert.com"],
+ ["DNS Name", "admin.digicert.com"],
+ ["DNS Name", "digicert.com"],
+ ["DNS Name", "content.digicert.com"],
+ ["DNS Name", "login.digicert.com"],
+ ["DNS Name", "api.digicert.com"],
+ ["DNS Name", "ws.digicert.com"],
+ ["DNS Name", "www.origin.digicert.com"],
+ ],
+ critical: false,
+ },
+ },
+ files: {
+ pem: "-----BEGIN%20CERTIFICATE-----%0D%0AMIIIzDCCB7SgAwIBAgIQDrbqtBjIc9jzwDHc3d8YsDANBgkqhkiG9w0BAQsFADB1%0D%0AMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3%0D%0Ad3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk%0D%0AIFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE4MTEwNzAwMDAwMFoXDTIwMTExMzEy%0D%0AMDAwMFowgc8xHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB%0D%0ABAGCNzwCAQMTAlVTMRUwEwYLKwYBBAGCNzwCAQITBFV0YWgxFTATBgNVBAUTDDUy%0D%0AOTk1MzctMDE0MjELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcT%0D%0ABExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMQwwCgYDVQQLEwNTUkUxGTAX%0D%0ABgNVBAMTEHd3dy5kaWdpY2VydC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw%0D%0AggIKAoICAQDOn4XKOTAwt/aYabScEF1QOyVj0OVo1NmlyizWNZWyPg0pi53ggUoE%0D%0A98CeNUkz+6scEYqWNY6l3qKB56pJJIqNQmo9NoWO8k2G/jTIjFFGqNWYIq23i4+H%0D%0AqaXi1/H/aWFgazk1qkyyAOQQA/p56bG9m5Ok/IBM/BZnLqVJLGJOx9ihgG1dI9Dr%0D%0A6vap+8QaPRau3t9sEd2cxe4Ix7gLdaYG3vxsYf3BycKTSKtyrbkX1Qy0dsSxy+GC%0D%0AM2ETxE1gMa7vRomQ/ZoZo8Ib55kFp6lIT6UOOkkdyiJdpWPXIZZlsZR5wkegWDsJ%0D%0AP7Xv7nE0WMkY1+05iNYtrzZRhhlnBw2AoMGNI+tsBXLQKeZfWFmU30bhkzX99pmv%0D%0AIYJ3f1fQGLao44nQEjdknIvpm0HMgvagYCnQVnnhJStzyYz324flWLPSp57OQeNM%0D%0Atr6O5W0HdWyhUZU+D4R6wObYQMZ5biYjRhtAQjMg8EVQEfZzEdr0WGO5JRHLHyot%0D%0A8tErXM9DiF5cCbzfcjeuoik2SHW+vbuPagMiHTM9+3lr0oRO+ZWwcM7fJvn1JfR2%0D%0APDLAaI3QUv7OLhSH32UfQsk+1ICq05m2HwSxiAviDRl5De66MEZDdvu03sUAQTHv%0D%0AWnw0Mr7Jgbjtn0DeUKLYwsRWg+spqoFTJHWGbb9RIb+3lxev7nIqOQIDAQABo4ID%0D%0A+zCCA/cwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYE%0D%0AFGywQ1b+PegS7NkS9WPVxMoHr7B2MIGlBgNVHREEgZ0wgZqCEHd3dy5kaWdpY2Vy%0D%0AdC5jb22CEmFkbWluLmRpZ2ljZXJ0LmNvbYIMZGlnaWNlcnQuY29tghRjb250ZW50%0D%0ALmRpZ2ljZXJ0LmNvbYISbG9naW4uZGlnaWNlcnQuY29tghBhcGkuZGlnaWNlcnQu%0D%0AY29tgg93cy5kaWdpY2VydC5jb22CF3d3dy5vcmlnaW4uZGlnaWNlcnQuY29tMA4G%0D%0AA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYD%0D%0AVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYt%0D%0Ac2VydmVyLWcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3No%0D%0AYTItZXYtc2VydmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgG%0D%0ACCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEB%0D%0AMIGIBggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj%0D%0AZXJ0LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t%0D%0AL0RpZ2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNV%0D%0AHRMBAf8EAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdQCkuQmQtBhYFIe7%0D%0AE6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWbwJ1QeAAAEAwBGMEQCIAzNFnn0UQyL%0D%0A5ZkwA7BX2JiQkjCk9QZrNHR9S1So7l8LAiAzoHDpWV5Dq5iM5NU86nJwqB1qsjZt%0D%0Aa4fWlvNKs0S+eQB3AId1v+dZfPiMQ5lfvfNu/1aNR1Y2/0q1YMG06v9eoIMPAAAB%0D%0AZvAnVbMAAAQDAEgwRgIhAOr0s3YbgyIs7dytmC1s5ClugVmo+r+W6ZKqRpphsIjT%0D%0AAiEAqgzFns9X9+SKwTSz0h1epijxrnWH+qZ815QgaJVd83UAdwDuS723dc5guuFC%0D%0AaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAWbwJ1RAAAAEAwBIMEYCIQCsFv4KXmNK%0D%0A+POADrfs37hcjApxSuiK14+tN5wFGby6QQIhANa+RvbVx1nYk13IyLCBiCMENLEV%0D%0A9urcBZfprZN+ZsrlMA0GCSqGSIb3DQEBCwUAA4IBAQB+tQhW07rk6eb2L2Ir+Wwq%0D%0Al5ZJaoaZq3zwoG8vPMFTZbcWPYsSVI5KuXELdB1QnmPbHebTJuI/gjfD65vf7C3N%0D%0ABjgLoXui39mwN4UNTBCc2Ls8s8/aVfTZGPCNNwynCEsY9h0HRobI8kiVPvU0kyBJ%0D%0AO3p3msqR7W2lAIWciJWmoPQkEFh7u84/oc7Pz2SSE6tqMW9lZmyBqjSuBufRJn1g%0D%0ACTdp/5DZdQWTNL6L5GSsRoXQnarsVtFVriqOjWf5R4O4z6LQznlbBQCMUR3geUNq%0D%0A0vSblnmgav0+L9HK97wqtONu1CrJ9/Q2JwoxFAs/zps/nh9oJU2ToK9lzl/38gpo%0D%0A-----END%20CERTIFICATE-----%0D%0A",
+ },
+ fingerprint: {
+ sha1: "8E:43:B7:D0:84:FD:B2:6C:08:9E:D3:F1:10:0C:D2:1D:D4:AD:C6:DF",
+ sha256:
+ "37:BF:44:A9:28:03:8A:22:AE:0C:E3:2D:96:3C:36:F5:D2:2D:37:99:D6:B2:63:CB:9C:1D:45:D1:CF:FE:B0:69",
+ },
+ issuer: {
+ cn: "DigiCert SHA2 Extended Validation Server CA",
+ dn: "c=US, o=DigiCert Inc, ou=www.digicert.com, cn=DigiCert SHA2 Extended Validation Server CA",
+ entries: [
+ ["Country", "US"],
+ ["Organization", "DigiCert Inc"],
+ ["Organizational Unit", "www.digicert.com"],
+ ["Common Name", "DigiCert SHA2 Extended Validation Server CA"],
+ ],
+ },
+ notBefore: "11/6/2018, 10:00:00 PM (Brasilia Standard Time)",
+ notBeforeUTC: "Wed, 07 Nov 2018 00:00:00 GMT",
+ notAfter: "11/13/2020, 9:00:00 AM (Brasilia Standard Time)",
+ notAfterUTC: "Fri, 13 Nov 2020 12:00:00 GMT",
+ subject: {
+ cn: "www.digicert.com",
+ dn: "OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=US, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, serialNumber=5299537-0142, c=US, s=Utah, l=Lehi, o=DigiCert, Inc., ou=SRE, cn=www.digicert.com",
+ entries: [
+ ["Business Category", "Private Organization"],
+ ["Inc. Country", "US"],
+ ["Inc. State / Province", "Utah"],
+ ["Serial Number", "5299537-0142"],
+ ["Country", "US"],
+ ["State / Province", "Utah"],
+ ["Locality", "Lehi"],
+ ["Organization", "DigiCert, Inc."],
+ ["Organizational Unit", "SRE"],
+ ["Common Name", "www.digicert.com"],
+ ],
+ },
+ serialNumber: "0E:B6:EA:B4:18:C8:73:D8:F3:C0:31:DC:DD:DF:18:B0",
+ signature: {
+ name: "SHA-256 with RSA Encryption",
+ type: "1.2.840.113549.1.1.11",
+ },
+ subjectPublicKeyInfo: {
+ e: 65537,
+ kty: "RSA",
+ n: "CE:9F:85:CA:39:30:30:B7:F6:98:69:B4:9C:10:5D:50:3B:25:63:D0:E5:68:D4:D9:A5:CA:2C:D6:35:95:B2:3E:0D:29:8B:9D:E0:81:4A:04:F7:C0:9E:35:49:33:FB:AB:1C:11:8A:96:35:8E:A5:DE:A2:81:E7:AA:49:24:8A:8D:42:6A:3D:36:85:8E:F2:4D:86:FE:34:C8:8C:51:46:A8:D5:98:22:AD:B7:8B:8F:87:A9:A5:E2:D7:F1:FF:69:61:60:6B:39:35:AA:4C:B2:00:E4:10:03:FA:79:E9:B1:BD:9B:93:A4:FC:80:4C:FC:16:67:2E:A5:49:2C:62:4E:C7:D8:A1:80:6D:5D:23:D0:EB:EA:F6:A9:FB:C4:1A:3D:16:AE:DE:DF:6C:11:DD:9C:C5:EE:08:C7:B8:0B:75:A6:06:DE:FC:6C:61:FD:C1:C9:C2:93:48:AB:72:AD:B9:17:D5:0C:B4:76:C4:B1:CB:E1:82:33:61:13:C4:4D:60:31:AE:EF:46:89:90:FD:9A:19:A3:C2:1B:E7:99:05:A7:A9:48:4F:A5:0E:3A:49:1D:CA:22:5D:A5:63:D7:21:96:65:B1:94:79:C2:47:A0:58:3B:09:3F:B5:EF:EE:71:34:58:C9:18:D7:ED:39:88:D6:2D:AF:36:51:86:19:67:07:0D:80:A0:C1:8D:23:EB:6C:05:72:D0:29:E6:5F:58:59:94:DF:46:E1:93:35:FD:F6:99:AF:21:82:77:7F:57:D0:18:B6:A8:E3:89:D0:12:37:64:9C:8B:E9:9B:41:CC:82:F6:A0:60:29:D0:56:79:E1:25:2B:73:C9:8C:F7:DB:87:E5:58:B3:D2:A7:9E:CE:41:E3:4C:B6:BE:8E:E5:6D:07:75:6C:A1:51:95:3E:0F:84:7A:C0:E6:D8:40:C6:79:6E:26:23:46:1B:40:42:33:20:F0:45:50:11:F6:73:11:DA:F4:58:63:B9:25:11:CB:1F:2A:2D:F2:D1:2B:5C:CF:43:88:5E:5C:09:BC:DF:72:37:AE:A2:29:36:48:75:BE:BD:BB:8F:6A:03:22:1D:33:3D:FB:79:6B:D2:84:4E:F9:95:B0:70:CE:DF:26:F9:F5:25:F4:76:3C:32:C0:68:8D:D0:52:FE:CE:2E:14:87:DF:65:1F:42:C9:3E:D4:80:AA:D3:99:B6:1F:04:B1:88:0B:E2:0D:19:79:0D:EE:BA:30:46:43:76:FB:B4:DE:C5:00:41:31:EF:5A:7C:34:32:BE:C9:81:B8:ED:9F:40:DE:50:A2:D8:C2:C4:56:83:EB:29:AA:81:53:24:75:86:6D:BF:51:21:BF:B7:97:17:AF:EE:72:2A:39",
+ keysize: 4096,
+ },
+ unsupportedExtensions: [],
+ version: "3",
+ },
+ {
+ ext: {
+ aia: {
+ descriptions: [
+ {
+ location: "http://ocsp.digicert.com",
+ method: "Online Certificate Status Protocol (OCSP)",
+ },
+ ],
+ critical: false,
+ },
+ aKID: {
+ critical: false,
+ id: "B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3",
+ },
+ basicConstraints: { cA: true, critical: true },
+ crlPoints: {
+ critical: false,
+ points: ["http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl"],
+ },
+ cp: {
+ critical: false,
+ policies: [
+ {
+ id: "2.5.29.32.0",
+ qualifiers: [
+ {
+ id: "1.3.6.1.5.5.7.2.1",
+ name: "Practices Statement",
+ value: "https://www.digicert.com/CPS",
+ },
+ ],
+ },
+ ],
+ },
+ eKeyUsages: {
+ critical: false,
+ purposes: ["Server Authentication", "Client Authentication"],
+ },
+ keyUsages: {
+ critical: true,
+ purposes: ["Digital Signature", "Certificate Signing", "CRL Signing"],
+ },
+ msCrypto: { exists: false },
+ ocspStaple: { critical: false, required: false },
+ scts: { critical: false, timestamps: [] },
+ sKID: {
+ critical: false,
+ id: "3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F",
+ },
+ san: { altNames: [], critical: false },
+ },
+ files: {
+ pem: "-----BEGIN%20CERTIFICATE-----%0D%0AMIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs%0D%0AMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3%0D%0Ad3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j%0D%0AZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL%0D%0AMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3%0D%0ALmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW%0D%0AYWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC%0D%0AggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY%0D%0AuD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/%0D%0ALhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy%0D%0A/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh%0D%0AcJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k%0D%0A8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB%0D%0AAf8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF%0D%0ABQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp%0D%0AZ2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy%0D%0AdC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2%0D%0AMDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j%0D%0Ab20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW%0D%0AgBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh%0D%0AhgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg%0D%0A4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa%0D%0A2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs%0D%0A1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1%0D%0AoVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn%0D%0A8TUoE6smftX3eg==%0D%0A-----END%20CERTIFICATE-----%0D%0A",
+ },
+ fingerprint: {
+ sha1: "7E:2F:3A:4F:8F:E8:FA:8A:57:30:AE:CA:02:96:96:63:7E:98:6F:3F",
+ sha256:
+ "40:3E:06:2A:26:53:05:91:13:28:5B:AF:80:A0:D4:AE:42:2C:84:8C:9F:78:FA:D0:1F:C9:4B:C5:B8:7F:EF:1A",
+ },
+ issuer: {
+ cn: "DigiCert High Assurance EV Root CA",
+ dn: "c=US, o=DigiCert Inc, ou=www.digicert.com, cn=DigiCert High Assurance EV Root CA",
+ entries: [
+ ["Country", "US"],
+ ["Organization", "DigiCert Inc"],
+ ["Organizational Unit", "www.digicert.com"],
+ ["Common Name", "DigiCert High Assurance EV Root CA"],
+ ],
+ },
+ notBefore: "10/22/2013, 10:00:00 AM (Brasilia Standard Time)",
+ notBeforeUTC: "Tue, 22 Oct 2013 12:00:00 GMT",
+ notAfter: "10/22/2028, 9:00:00 AM (Brasilia Standard Time)",
+ notAfterUTC: "Sun, 22 Oct 2028 12:00:00 GMT",
+ subject: {
+ cn: "DigiCert SHA2 Extended Validation Server CA",
+ dn: "c=US, o=DigiCert Inc, ou=www.digicert.com, cn=DigiCert SHA2 Extended Validation Server CA",
+ entries: [
+ ["Country", "US"],
+ ["Organization", "DigiCert Inc"],
+ ["Organizational Unit", "www.digicert.com"],
+ ["Common Name", "DigiCert SHA2 Extended Validation Server CA"],
+ ],
+ },
+ serialNumber: "0C:79:A9:44:B0:8C:11:95:20:92:61:5F:E2:6B:1D:83",
+ signature: {
+ name: "SHA-256 with RSA Encryption",
+ type: "1.2.840.113549.1.1.11",
+ },
+ subjectPublicKeyInfo: {
+ e: 65537,
+ kty: "RSA",
+ n: "D7:53:A4:04:51:F8:99:A6:16:48:4B:67:27:AA:93:49:D0:39:ED:0C:B0:B0:00:87:F1:67:28:86:85:8C:8E:63:DA:BC:B1:40:38:E2:D3:F5:EC:A5:05:18:B8:3D:3E:C5:99:17:32:EC:18:8C:FA:F1:0C:A6:64:21:85:CB:07:10:34:B0:52:88:2B:1F:68:9B:D2:B1:8F:12:B0:B3:D2:E7:88:1F:1F:EF:38:77:54:53:5F:80:79:3F:2E:1A:AA:A8:1E:4B:2B:0D:AB:B7:63:B9:35:B7:7D:14:BC:59:4B:DF:51:4A:D2:A1:E2:0C:E2:90:82:87:6A:AE:EA:D7:64:D6:98:55:E8:FD:AF:1A:50:6C:54:BC:11:F2:FD:4A:F2:9D:BB:7F:0E:F4:D5:BE:8E:16:89:12:55:D8:C0:71:34:EE:F6:DC:2D:EC:C4:87:25:86:8D:D8:21:E4:B0:4D:0C:89:DC:39:26:17:DD:F6:D7:94:85:D8:04:21:70:9D:6F:6F:FF:5C:BA:19:E1:45:CB:56:57:28:7E:1C:0D:41:57:AA:B7:B8:27:BB:B1:E4:FA:2A:EF:21:23:75:1A:AD:2D:9B:86:35:8C:9C:77:B5:73:AD:D8:94:2D:E4:F3:0C:9D:EE:C1:4E:62:7E:17:C0:71:9E:2C:DE:F1:F9:10:28:19:33",
+ keysize: 2048,
+ },
+ unsupportedExtensions: [],
+ version: "3",
+ },
+ {
+ ext: {
+ aia: { critical: false },
+ aKID: {
+ critical: false,
+ id: "B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3",
+ },
+ basicConstraints: { cA: true, critical: true },
+ cp: { critical: false },
+ keyUsages: {
+ critical: true,
+ purposes: ["Digital Signature", "Certificate Signing", "CRL Signing"],
+ },
+ msCrypto: { exists: false },
+ ocspStaple: { critical: false, required: false },
+ scts: { critical: false, timestamps: [] },
+ sKID: {
+ critical: false,
+ id: "B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3",
+ },
+ san: { altNames: [], critical: false },
+ },
+ files: {
+ pem: "-----BEGIN%20CERTIFICATE-----%0D%0AMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs%0D%0AMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3%0D%0Ad3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j%0D%0AZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL%0D%0AMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3%0D%0ALmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug%0D%0ARVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm%0D%0A+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW%0D%0APNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM%0D%0AxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB%0D%0AIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3%0D%0AhzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg%0D%0AEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF%0D%0AMAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA%0D%0AFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec%0D%0AnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z%0D%0AeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF%0D%0AhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2%0D%0AYzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe%0D%0AvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep%0D%0A+OkuE6N36B9K%0D%0A-----END%20CERTIFICATE-----%0D%0A",
+ },
+ fingerprint: {
+ sha1: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
+ sha256:
+ "74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF",
+ },
+ issuer: {
+ cn: "DigiCert High Assurance EV Root CA",
+ dn: "c=US, o=DigiCert Inc, ou=www.digicert.com, cn=DigiCert High Assurance EV Root CA",
+ entries: [
+ ["Country", "US"],
+ ["Organization", "DigiCert Inc"],
+ ["Organizational Unit", "www.digicert.com"],
+ ["Common Name", "DigiCert High Assurance EV Root CA"],
+ ],
+ },
+ notBefore: "11/9/2006, 10:00:00 PM (Brasilia Standard Time)",
+ notBeforeUTC: "Fri, 10 Nov 2006 00:00:00 GMT",
+ notAfter: "11/9/2031, 9:00:00 PM (Brasilia Standard Time)",
+ notAfterUTC: "Mon, 10 Nov 2031 00:00:00 GMT",
+ subject: {
+ cn: "DigiCert High Assurance EV Root CA",
+ dn: "c=US, o=DigiCert Inc, ou=www.digicert.com, cn=DigiCert High Assurance EV Root CA",
+ entries: [
+ ["Country", "US"],
+ ["Organization", "DigiCert Inc"],
+ ["Organizational Unit", "www.digicert.com"],
+ ["Common Name", "DigiCert High Assurance EV Root CA"],
+ ],
+ },
+ serialNumber: "02:AC:5C:26:6A:0B:40:9B:8F:0B:79:F2:AE:46:25:77",
+ signature: {
+ name: "SHA-1 with RSA Encryption",
+ type: "1.2.840.113549.1.1.5",
+ },
+ subjectPublicKeyInfo: {
+ e: 65537,
+ kty: "RSA",
+ n: "C6:CC:E5:73:E6:FB:D4:BB:E5:2D:2D:32:A6:DF:E5:81:3F:C9:CD:25:49:B6:71:2A:C3:D5:94:34:67:A2:0A:1C:B0:5F:69:A6:40:B1:C4:B7:B2:8F:D0:98:A4:A9:41:59:3A:D3:DC:94:D6:3C:DB:74:38:A4:4A:CC:4D:25:82:F7:4A:A5:53:12:38:EE:F3:49:6D:71:91:7E:63:B6:AB:A6:5F:C3:A4:84:F8:4F:62:51:BE:F8:C5:EC:DB:38:92:E3:06:E5:08:91:0C:C4:28:41:55:FB:CB:5A:89:15:7E:71:E8:35:BF:4D:72:09:3D:BE:3A:38:50:5B:77:31:1B:8D:B3:C7:24:45:9A:A7:AC:6D:00:14:5A:04:B7:BA:13:EB:51:0A:98:41:41:22:4E:65:61:87:81:41:50:A6:79:5C:89:DE:19:4A:57:D5:2E:E6:5D:1C:53:2C:7E:98:CD:1A:06:16:A4:68:73:D0:34:04:13:5C:A1:71:D3:5A:7C:55:DB:5E:64:E1:37:87:30:56:04:E5:11:B4:29:80:12:F1:79:39:88:A2:02:11:7C:27:66:B7:88:B7:78:F2:CA:0A:A8:38:AB:0A:64:C2:BF:66:5D:95:84:C1:A1:25:1E:87:5D:1A:50:0B:20:12:CC:41:BB:6E:0B:51:38:B8:4B:CB",
+ keysize: 2048,
+ },
+ unsupportedExtensions: [],
+ version: "3",
+ },
+];
diff --git a/toolkit/components/certviewer/tests/chrome/test_adjustCertInformation.html b/toolkit/components/certviewer/tests/chrome/test_adjustCertInformation.html
new file mode 100644
index 0000000000..ddd4c8a0b3
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/test_adjustCertInformation.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>certviewer adjustCertInformation test</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+ </head>
+<body>
+ <script type="module">
+ function hasNullElements(obj) {
+ for (let key of Object.keys(obj)) {
+ if (obj[key] == null) return false;
+ if (typeof(obj[key]) === 'object') {
+ if (hasNullElements(obj[key]) === false) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ async function doTest() {
+ const { adjustCertInformation } = await import("chrome://global/content/certviewer/certviewer.mjs");
+ const { parseOutput } = await import("./parseOutput.mjs");
+
+ ok(adjustCertInformation, "adjustCertInformation should be available in this context");
+ ok(parseOutput, "parseOutput should be available in this context");
+ is(typeof(parseOutput), 'object', "parseOutput must be an object");
+
+ for (let cert of parseOutput) {
+ let adjustedCerts = adjustCertInformation(cert);
+ let result = hasNullElements(adjustedCerts.certItems);
+ ok(result, "adjustCertInformation function shouldn't return null elements");
+ }
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ doTest();
+
+ </script>
+</body>
+</html>
diff --git a/toolkit/components/certviewer/tests/chrome/test_certDecoder.html b/toolkit/components/certviewer/tests/chrome/test_certDecoder.html
new file mode 100644
index 0000000000..67ad083242
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/test_certDecoder.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>certviewer parse test</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+ </head>
+<body>
+ <script type="module">
+ // inputPEM is the same input to CS extension (https://github.com/april/certainly-something)
+ const inputPEM = "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";
+ const certOutputCS = "-----BEGIN%20CERTIFICATE-----%0D%0AMIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd+G7+u6kDANBgkqhkiG9w0BAQsFADBN%0D%0AMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E%0D%0AaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcN%0D%0AMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju%0D%0AaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29y%0D%0AcG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEu%0D%0Ab3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7Q%0D%0AjmXlUOBcLFRyw5LG/vUUWVrsxC2gsbR8WJq+cYoYBpoNVStKrO4U2rBh1GEbccvT%0D%0A6qKOQI+pjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek/ojve%0D%0AdPWe8dhciHkxOC2qPFZvVFMwg1/o/b80147BwZQmzB18mnHsmcyKlpsCN8pxw86u%0D%0Aao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z+lvrSjEgrddemWyGGalqy%0D%0AFp1rXlVM1Tf4/IYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c+yvaYJ%0D%0AKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG%0D%0A2eIwHQYDVR0OBBYEFNpSvSGcN2VT/B9TdQ8eXwebo60/MCcGA1UdEQQgMB6CD3d3%0D%0Ady5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud%0D%0AJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRw%0D%0AOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0%0D%0AcDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUw%0D%0AQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNl%0D%0AcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzAB%0D%0AhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9j%0D%0AYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5j%0D%0AcnQwDAYDVR0TAQH/BAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0%0D%0AGFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMS%0D%0AH1JdG6NASHWTwD0mlP/zbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz%0D%0A1NQ9cq8Az1KnMKRuaFAlAHUAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16g%0D%0Agw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18%0D%0ASfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcN%0D%0AAQELBQADggEBAKLJAFO3wuaP5MM/ed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT%0D%0A9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql/68G5q844kFuC6JPl4LVT9mciD+VW6b%0D%0AHUSXD9xifL9DqdJ0Ic0SllTlM+oq5aAeOxUQGXhXIqj6fSQv9fQN6mXxQIoc/gjx%0D%0Ateskq/Vl8YmY1FIZP9Bh7g27kxZ9GAAGQtjTL03RzKAuSg6yeImYVdQWasc7UPnB%0D%0AXlRAzZ8+OJThUbzK16a2CI3Rg4agKSJk+uA47h1/ImmngpFLRb/MvRX6H1oWcUuy%0D%0AH6O7PZdl0YpwTpw1THIuqCGl/wpPgyQgcTM=%0D%0A-----END%20CERTIFICATE-----%0D%0A";
+
+
+ async function doTest() {
+ const { parse, pemToDER } = await import("chrome://global/content/certviewer/certDecoder.mjs");
+
+ ok(parse, "parse should be available in this context");
+ ok(pemToDER, "pemToDER should be available in this context");
+
+ let input = inputPEM.trim()
+ .replace(/\r|\n|\0/g, "")
+ .split()
+ .filter(v => v.startsWith("MII"))[0];
+
+ let certDER = pemToDER(input);
+ let cert = await parse(certDER);
+ ok(cert, "There should be a result");
+ is(cert.files.pem, certOutputCS, "certificates output must be the same");
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ doTest();
+
+ </script>
+</body>
+</html>
diff --git a/toolkit/components/certviewer/tests/chrome/test_certDecoderFields.html b/toolkit/components/certviewer/tests/chrome/test_certDecoderFields.html
new file mode 100644
index 0000000000..1f54cced4b
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/test_certDecoderFields.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>certviewer parse test</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+ </head>
+<body>
+ <script type="module">
+ // inputPEM is the same input to CS extension (https://github.com/april/certainly-something)
+ const inputPEM = "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";
+ const inputPEMerror1 = "MIIGRjCCBS6gAwIBAgIQDJduPkI49CDWPd+G7+u6kDANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMTA1MDAwMDAwWhcNMTkxMTEzMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xDzANBgNVBAsTBldlYk9wczEYMBYGA1UEAxMPd3d3Lm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKruymkkmkqCJh7QjmXlUOBcLFRyw5LG/vUUWVrsxC2gsbR8WJq+cYoYBpoNVStKrO4U2rBh1GEbccvT6qKOQI+pjjDxx9cmRdubGTGp8L0MF1ohVvhIvYLumOEoRDDPU4PvGJjGhek/ojvedPWe8dhciHkxOC2qPFZvVFMwg1/o/b80147BwZQmzB18mnHsmcyKlpsCN8pxw86uao9Iun8gZQrsllW64rTZlRR56pHdAcuGAoZjYZxwS9Z+lvrSjEgrddemWyGGalqyFp1rXlVM1Tf4/IYWAQXTgTUN303u3xMjss7QK7eUDsACRxiWPLW9XQDd1c+yvaYJKzgJ2wIDAQABo4IC6TCCAuUwHwYDVR0jBBgwFoAUD4BhHIIxYdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFNpSvSGcN2VT/B9TdQ8eXwebo60/MCcGA1UdEQQgMB6CD3d3dy5tb3ppbGxhLm9yZ4ILbW96aWxsYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABZuYWiHwAAAQDAEYwRAIgZnMSH1JdG6NASHWTwD0mlP/zbr0hzP263c02Ym0DU64CIEe4QHJDP47j0b6oTFu6RrZz1NQ9cq8Az1KnMKRuaFAlAHUAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFm5haJAgAABAMARjBEAiAxGLXkUaOAkZhXNeNR3pWyahZeKmSaMXadgu18SfK1ZAIgKtwu5eGxK76rgaszLCZ9edBIjuU0DKorzPUuxUXFY0QwDQYJKoZIhvcNAQELBQADggEBAKLJAFO3wuaP5MM/ed1lhk5Uc2aDokhcM7XyvdhEKSHbgPhcgMoT9YIVoPa70gNC6KHcwoXu0g8wt7X6Vm1ql/68G5q844kFuC6JPl4LVT9mciD+VW6bHUSXD9xifL9D";
+ const inputPEMerror2 = "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";
+
+ async function run(input, expected) {
+ const { parse, pemToDER } = await import("chrome://global/content/certviewer/certDecoder.mjs");
+
+ ok(parse, "parse should be available in this context");
+ ok(pemToDER, "pemToDER should be available in this context");
+
+ let certDER;
+ try {
+ certDER = pemToDER(input);
+ } catch (err) {
+ is("error", expected, "OK, error found when executing pemToDER function");
+ return;
+ }
+ ok(certDER, "pemToDER returned a non null value");
+
+ let cert;
+ try {
+ cert = await parse(certDER);
+ } catch (err) {
+ is("error", expected, "OK, error found when executing parse function");
+ return;
+ }
+ ok(cert, "Parse function returned an Object");
+
+ // "Because the representation of JS Date objects will vary depending on the timezone,
+ // we don't consider them in the test. Instead we test their corresponding UTC values (e.g notAfterUTC)."
+ cert.notAfter = "";
+ expected.notAfter = "";
+
+ cert.notBefore = "";
+ expected.notBefore = "";
+
+ cert.ext.scts.timestamps = cert.ext.scts.timestamps.map(elem => elem.timestamp = "");
+ expected.ext.scts.timestamps = expected.ext.scts.timestamps.map(elem => elem.timestamp = "");
+
+ is(JSON.stringify(cert), JSON.stringify(expected), "All the fields in CS must be equal to our output");
+ }
+
+ async function doTest() {
+ const { certOutputCS } = await import("./CSoutput.mjs");
+
+ ok(certOutputCS, "certOutputCS should be available in this context");
+ is(typeof(certOutputCS), 'object', "certOutputCS must be an object");
+
+ let inputs = [
+ inputPEM,
+ inputPEMerror1,
+ inputPEMerror2
+ ];
+
+ let expected = [
+ certOutputCS[0],
+ "error",
+ "error"
+ ];
+
+ for (let i = 0; i < inputs.length; i++) {
+ await run(inputs[i], expected[i]);
+ }
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ doTest();
+
+ </script>
+</body>
+</html>
diff --git a/toolkit/components/certviewer/tests/chrome/test_kebabCaseInAdjustCertInformation.html b/toolkit/components/certviewer/tests/chrome/test_kebabCaseInAdjustCertInformation.html
new file mode 100644
index 0000000000..b9f7b98d89
--- /dev/null
+++ b/toolkit/components/certviewer/tests/chrome/test_kebabCaseInAdjustCertInformation.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>certviewer adjustCertInformation test</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+ </head>
+<body>
+ <script type="module">
+ function isKebabCase(str) {
+ if (str === "") return true;
+ return /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(str);
+ }
+
+ function validateIsKebabCase() {
+ let tests = [
+ {
+ input: "",
+ expected: true
+ },
+ {
+ input: "A",
+ expected: false
+ },
+ {
+ input: "Ab",
+ expected: false
+ },
+ {
+ input: "Ab-ad",
+ expected: false
+ },
+ {
+ input: "ad-Az",
+ expected: false
+ },
+ {
+ input: "ad- z",
+ expected: false
+ },
+ {
+ input: "ad-z ",
+ expected: false
+ },
+ {
+ input: "ad z",
+ expected: false
+ },
+ {
+ input: "ad--fz",
+ expected: false
+ },
+ {
+ input: "-a-b-c",
+ expected: false
+ },
+ {
+ input: "ad-fz",
+ expected: true
+ },
+ {
+ input: "ad",
+ expected: true
+ },
+ {
+ input: "a-b-c",
+ expected: true
+ },
+ ];
+
+ for (let test of tests) {
+ let result = isKebabCase(test.input);
+ is(result, test.expected, `${test.input} should${test.expected === false ? "n't" : ""} be a kebab-case string`);
+ }
+ }
+
+ async function doTest() {
+ const { adjustCertInformation } = await import("chrome://global/content/certviewer/certviewer.mjs");
+ const { parseOutput } = await import("./parseOutput.mjs");
+
+ ok(adjustCertInformation, "adjustCertInformation should be available in this context");
+ ok(parseOutput, "parseOutput should be available in this context");
+ is(typeof(parseOutput), 'object', "parseOutput must be an object");
+
+ validateIsKebabCase();
+
+ for (let cert of parseOutput) {
+ let adjustedCerts = adjustCertInformation(cert);
+ adjustedCerts.certItems.forEach(item => {
+ ok(isKebabCase(item.sectionId), `${item.sectionId} should be a valid kebab-case string`);
+ item.sectionItems.forEach(element => {
+ ok(isKebabCase(element.label), `${element.label} should be a valid kebab-case string`);
+ });
+ });
+ }
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ doTest();
+
+ </script>
+</body>
+</html>