commit d43da37916a3a4a8f9fb540f31a736afae1d32b6
parent 5ab9b6db2133ea9e0680853a547d7e1bc4854e4e
Author: John M. Schanck <jschanck@mozilla.com>
Date: Tue, 21 Oct 2025 21:41:51 +0000
Bug 1993621 - display certificate transparency log names in certviewer. r=keeler,fluent-reviewers,bolsson
Differential Revision: https://phabricator.services.mozilla.com/D268234
Diffstat:
9 files changed, 337 insertions(+), 118 deletions(-)
diff --git a/taskcluster/docker/periodic-updates/scripts/getCTKnownLogs.py b/taskcluster/docker/periodic-updates/scripts/getCTKnownLogs.py
@@ -16,6 +16,7 @@ See more information at https://certificate.transparency.dev/google/
import argparse
import base64
import datetime
+import hashlib
import json
import os.path
import ssl
@@ -95,6 +96,18 @@ $operators
"""
+LOG_NAME_TABLE_TEMPLATE = """\
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* This file was automatically generated by $prog. */
+
+// prettier-ignore
+export const logNameTable = $logNameTable
+"""
+
+
def get_timestamp(time_str):
"""
Convert a time string such as "2017-01-01T00:00:00Z" to an integer
@@ -256,6 +269,22 @@ def generate_cpp_header_file(json_data, out_file):
)
+def generate_log_name_table_file(json_data, out_file):
+ """Generate an mjs file that defines a map from log["log_id"] to log["description"] for each of the known logs."""
+ entries = {}
+ for operator in json_data["operators"]:
+ for log in operator.get("logs", []):
+ entries[log["log_id"]] = log.get("description", "")
+ for log in operator.get("tiled_logs", []):
+ entries[log["log_id"]] = log.get("description", "")
+ logNameTable = json.dumps(entries, indent=2, sort_keys=True)
+ out_file.write(
+ Template(LOG_NAME_TABLE_TEMPLATE).substitute(
+ prog=os.path.basename(sys.argv[0]), logNameTable=logNameTable
+ )
+ )
+
+
def patch_in_test_logs(json_data):
"""Insert Mozilla-specific test log data."""
max_id = len(json_data["operators"])
@@ -347,6 +376,22 @@ def patch_in_test_logs(json_data):
}
],
}
+
+ def add_log_id(log):
+ log["log_id"] = base64.b64encode(
+ hashlib.sha256(base64.b64decode(log["key"])).digest()
+ ).decode("utf-8")
+
+ def add_log_ids(operator):
+ for log in operator.get("tiled_logs", []):
+ add_log_id(log)
+ for log in operator.get("logs", []):
+ add_log_id(log)
+
+ add_log_ids(mozilla_test_operator_1)
+ add_log_ids(mozilla_test_operator_2)
+ add_log_ids(mozilla_test_operator_3)
+
json_data["operators"].append(mozilla_test_operator_1)
json_data["operators"].append(mozilla_test_operator_2)
json_data["operators"].append(mozilla_test_operator_3)
@@ -404,10 +449,14 @@ def run(args):
json_data = json.loads(json_text)
patch_in_test_logs(json_data)
- print("Writing output: ", args.out)
+ print("Writing cpp header output: ", args.out)
with open(args.out, "w") as out_file:
generate_cpp_header_file(json_data, out_file)
+ print("Writing log name table output: ", args.log_name_table_out)
+ with open(args.log_name_table_out, "w") as out_file:
+ generate_log_name_table_file(json_data, out_file)
+
print("Done.")
@@ -456,6 +505,19 @@ def parse_arguments_and_run():
help="write the known CT logs JSON data to the specified file when downloading it from the given url (default: %(default)s)",
)
arg_parser.add_argument(
+ "--log-name-table-out",
+ default=mozpath.join(
+ buildconfig.topsrcdir,
+ "toolkit",
+ "components",
+ "certviewer",
+ "content",
+ "components",
+ "logNameTable.mjs",
+ ),
+ help="path and filename of the log name table to be generated (default: %(default)s)",
+ )
+ arg_parser.add_argument(
"--out",
default=mozpath.join(buildconfig.topsrcdir, "security", "ct", "CTKnownLogs.h"),
help="path and filename of the header file to be generated (default: %(default)s)",
diff --git a/toolkit/components/certviewer/content/certviewer.mjs b/toolkit/components/certviewer/content/certviewer.mjs
@@ -2,7 +2,7 @@
* 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/. */
-import { normalizeToKebabCase } from "./components/utils.mjs";
+import { normalizeToKebabCase, getLogName } from "./components/utils.mjs";
import {
parse,
pemToDER,
@@ -393,15 +393,19 @@ export const adjustCertInformation = cert => {
for (let key of Object.keys(entry)) {
if (key.includes("timestamp")) {
timestamps[key.includes("UTC") ? "utc" : "local"] = entry[key];
- } else {
- let isHex = false;
- if (key == "logId") {
- isHex = true;
+ continue;
+ }
+ let isHex = false;
+ if (key == "logId") {
+ isHex = true;
+ let logName = getLogName(entry[key]);
+ if (logName) {
+ items.push(createEntryItem("log-name", logName, false));
}
- items.push(
- createEntryItem(normalizeToKebabCase(key), entry[key], isHex)
- );
}
+ items.push(
+ createEntryItem(normalizeToKebabCase(key), entry[key], isHex)
+ );
}
items.push(createEntryItem("timestamp", timestamps));
});
@@ -413,6 +417,20 @@ export const adjustCertInformation = cert => {
getElementByPathOrFalse(cert, "ext.scts.critical")
);
+ // Uncomment the following to generate the expected test results in
+ // toolkit/components/certviewer/tests/browser/adjustedCerts.js
+ //
+ // function download(filename, text) {
+ // var element = document.createElement('a');
+ // element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
+ // element.setAttribute('download', filename);
+ // element.style.display = 'none';
+ // document.body.appendChild(element);
+ // element.click();
+ // document.body.removeChild(element);
+ // }
+ // download("out.txt",JSON.stringify({certItems, tabName}));
+
return {
certItems,
tabName,
diff --git a/toolkit/components/certviewer/content/components/logNameTable.mjs b/toolkit/components/certviewer/content/components/logNameTable.mjs
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* This file was automatically generated by getCTKnownLogs.py. */
+
+// prettier-ignore
+export const logNameTable = {
+ "+3xjpo0eBq3Qg4ibuNQyHLJFROv2/mlyKRkuOD5ebiM=": "IPng Networks 'Halloumi2025h2'",
+ "0W6ppWgHfmY1oD83pd28A6U8QRIU1IgY9ekxsyPLlQQ=": "Sectigo 'Elephant2026h1'",
+ "0vxlL6X5tzi4N1X6XrFfC0UlP06Po7m2T9TeVmLRhwg=": "Bogus RFC6962 log to avoid breaking misbehaving CT libraries",
+ "1219ENGn9XfCx+lf1wC/+YLJM1pl4dCzAXMXwMjFaXc=": "Google 'Argon2026h2' log",
+ "1d5V7roItgyf/BjFE75qYLoARga8WVuWu0T2LMV9Ofo=": "Geomys 'Tuscolo2027h2'",
+ "1tWNqdAXU/NqSqDHV0kCr+vH3CzTjNn3ZMgMiRkenwI=": "Google 'Argon2027h1'",
+ "2AlVO5RPev/IFhlvlE+Fq7D4/F6HVSYPFdEucrtFSxQ=": "Google 'Xenon2026h2' log",
+ "3dzKNJXX4RYF55Uy+sef+D0cUN/bADoUEnYKLKy7yCo=": "Google 'Xenon2025h2' log",
+ "4yON8o2iiOCq4Kzw+pDJhfC2v/XSpSewAfwcRFjEtug=": "Let's Encrypt 'Willow2026h1'",
+ "5NAXdhyRORG+9HOWrNjSRljCT7WTtRvqxVknYuiFPBU=": "Let's Encrypt 'Willow2025h2d'",
+ "5eNiR9ku9K2jhYO1NZHbcp/C8ArktnRRdNPd/GqiU4g=": "Let's Encrypt 'Sycamore2027h2'",
+ "5tIxY0B3jMEQQQbXcbnOwdJA9paEhvu6hzId/R43jlA=": "DigiCert Nessie2025 Log",
+ "6Mz6YX3GS9LYtKJsKw/1dnHx5n3gb4uVYfJVLXuUA5o=": "Mozilla Test RSA Log 4",
+ "750EQi4gtDIQJ1TfUtJRRgJ/hEwH/YZeySLub86fe7w=": "Geomys 'Tuscolo2025h2'",
+ "7TxL1ugGwqSiAFfbyyTiOAHfUS/txIbFcA8g3bc+P+A=": "DigiCert 'Wyvern2025h2' Log",
+ "7drrgVxjITRJtHvlB3kFq9DZMUfCesUUazvFjkPptsc=": "TrustAsia 'HETU2027'",
+ "A4AqwmL24F4D+Lxve5hRMk/Xaj31t1lRdeIi+46b1fY=": "Sectigo 'Tiger2027h2'",
+ "ABpdGhwtk3W2SFV4+C9xoa5u7zl9KXyK4xV7yt7hoB4=": "DigiCert 'Wyvern2027h1'",
+ "CRV/Yy1Gx/dtlSZUk7wPALOVrF2zorJr+wQ9ukrGOJM=": "IPng Networks 'Halloumi2027h2'",
+ "DR28iUTp9QBVQtctPhRMzEMIKrbqHpTf1wZlfS6G8wE=": "Sectigo 'Elephant2025h2'",
+ "DeHyMCvTDcFAYhIJ6lUu/Ed0fLHX6TDvDkIetH5OqjQ=": "Let's Encrypt 'Oak2025h2'",
+ "DleUvPOuqT4zGyyZB7P3kN+bwj1xMiXdIaklrGHFTiE=": "Google 'Argon2026h1' log",
+ "EvFONL1TckyEBhnDjz96E/jntWKHiJxtMAWE6+WGJjo=": "Google 'Argon2025h2' log",
+ "FoMtq/CpJQ8P8DqlRf/Iv8gj0IdL9gQpJ/jnHzMT9fo=": "Sectigo 'Tiger2026h1'",
+ "GYbUxyiqb/66A294Kk0BkarOLXIxD67OXXBBLSVMx9Q=": "Let's Encrypt 'Oak2026h1'",
+ "GgT/SdBUHUCv9qDDv/HYxGcvTuzuI0BomGsXQC7ciX0=": "Sectigo 'Sabre2025h2'",
+ "Gouda43XkdHNBUnttgNV1ga2T60w23H+eI8Px8j7xLE=": "IPng Networks 'Gouda2027h1'",
+ "GoudaUpXmMiZoMqIvfSPwLRWYMzDYA0fcfRp/8fRrKM=": "IPng Networks 'Gouda2026h1'",
+ "GoudaVNi2GSSp7niI2BuNOzp4xC6NPuTBXhdKc5XV+s=": "IPng Networks 'Gouda2027h2'",
+ "GoudanQ8ze1gH3O9MJcIHbyuxKYTnJKwtUDDE3sg7AU=": "IPng Networks 'Gouda2025h2'",
+ "Goudaw/+v4G0eTnG0jEKhtbRAtTwRuIYLJ3jX14mJe8=": "IPng Networks 'Gouda2026h2'",
+ "H1bRq5RwSkHdP+r99GmTVTAsFDG/5hNGCJ//rnldzC8=": "Sectigo 'Sabre2026h2'",
+ "H7D4qS2K3aEhd2wF4qouFbrLxitlOTaVV2qqtS4R0R0=": "DigiCert 'sphinx2027h2'",
+ "HJ9oLOn68EVpUPgbloqH3dsyENhM5siy44JSSsTPWZ8=": "Sectigo 'Tiger2027h1'",
+ "JS+Uwisp6W6fQRpyBytpXFtS/5epDSVAu/zcUexN7gs=": "Sectigo 'Mammoth2026h1'",
+ "Jbfv3qETAZPtkweXcKoyKiZiDeNayKp8dRl94LGp4GU=": "TrustAsia 'log2026b'",
+ "KCyL3YEP+QkSCs4W1uDsIBvqgqOkrxnZ7/tZ6D/cQmg=": "TrustAsia Log2025b",
+ "KOKBOP2DIUXpqdaqdTdtg3eohRKzwH9yQUgh3L3pjGY=": "TrustAsia Log2025a",
+ "KrgwRDO5FN7S8x5CB/JRwXo3oJJoUtkIAgb4Xlc5Fio=": "Mozilla Test EC Log",
+ "LtakTeuPDIZGZ3acTt0EH4QjZ1X6OqymNNCTXfzVmnA=": "Bogus placeholder log to unbreak misbehaving CT libraries",
+ "MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI=": "Mozilla Test RSA Log 2",
+ "N6oHzCFvLm2RnHCdJNj3MbAPKxR8YhzAkaX6GoTYFt0=": "DigiCert 'Wyvern2027h2'",
+ "RMK9DOkUDmSlyUoBkwpaobs1lw4A7hEWiWgqHETXtWY=": "Google 'Xenon2027h1'",
+ "ROgi/CurDpLu0On61pZkYCd20Bdg4IkFCckjobA/w38=": "IPng Networks 'Halloumi2027h1'",
+ "Rq+GPTs+5Z+ld96oJF02sNntIqIj9GF3QSKUUu6VUF8=": "Geomys 'Tuscolo2026h2'",
+ "RqI5Z8YNtkaHxm89+ZmUdpOmphEghFfVVefj0KHZtkY=": "DigiCert 'sphinx2027h1'",
+ "SZybad4dfOz8Nt7Nh2SmuFuvCoeAGdFVUvvp6ynd+MM=": "DigiCert 'Sphinx2026h1'",
+ "TGPcmOWcHauI9h6KPd6uj6tEozd7X5uUw/uhnPzBviY=": "Cloudflare 'Nimbus2027'",
+ "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=": "Mozilla Test RSA Log 1",
+ "VmzVo3a+g9/jQrZ1xJwjJJinabrDgsurSaOHfZqzLQE=": "Sectigo 'Sabre2026h1'",
+ "W/beU/H7+sSaGFl0aUWhpqconV5wpg9IRQ5Ya7mucrg=": "Let's Encrypt 'Sycamore2025h2d'",
+ "WW5sM4aUsllyolbIoOjdkEp26Ag92oc7AQg4KBQ87lk=": "Geomys 'Tuscolo2027h1'",
+ "XKV30pt/i69Bntjsq/tty67DhTcC1XRvF02tPJNKqWo=": "Sectigo 'Tiger2025h2'",
+ "YEyar3p/d18B1Ab8kg3ImesLHH34yVIb+voXdzuXi8k=": "Sectigo 'Elephant2027h1'",
+ "ZBHEbKQS7KeJHKICLgC8q08oB9QeNSer6v7VA8l9zfA=": "DigiCert 'Wyvern2026h1'",
+ "bP5QGUOoXqkWvFLRM+TcyR7xQRx9JYQg0XOAnhgY6zo=": "Let's Encrypt 'Sycamore2026h2'",
+ "cX6V88I4im2x44RJPTHhWqliCHYtQgDgBQzQZ7WmYeI=": "Geomys 'Tuscolo2026h1'",
+ "dNudWPfUfp39eHoWKpkcGM9pjafHKZGMmhiwRQ26RLw=": "TrustAsia 'log2026a'",
+ "fVkeEuF4KnscYWd8Xv340IdcFKBOlZ65Ay/ZDowuebg=": "DigiCert Yeti2025 Log",
+ "fz035/iSPY5xZb6w0+q+5yoivkbAy4TEFtTkuYJky8I=": "IPng Networks 'Halloumi2026h1'",
+ "jspHC6zeavOiBrCkeoS3Rv4fxr+VPiXmm07kAkjzxug=": "Let's Encrypt 'Sycamore2027h1'",
+ "lE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdg=": "DigiCert 'Sphinx2026h2'",
+ "lLHBirDQV8R74KwEDh8svI3DdXJ7yVHyClJhJoY7pzw=": "Sectigo 'Mammoth2026h2'",
+ "lpdkv1VYl633Q4doNwhCd+nwOtX2pPM2bkakPw/KqcY=": "Google 'Xenon2026h1' log",
+ "okkM3NuOM6QAMhdg1tTVGiA2GR6nfZaL4mqKAPb///c=": "Sectigo 'Elephant2027h2'",
+ "ooEAGHNOF24dR+CVQPOBulRml81jqENQcW64CU7a8Q0=": "Let's Encrypt 'Willow2027h1'",
+ "pELFBklgYVSPD9TqnPt6LSZFTYepfy/fRVn2J086hFQ=": "DigiCert 'Sphinx2025h2' Log",
+ "pcl4kl1XRheChw3YiWYLXFVki30AQPLsB2hR0YhpGfc=": "Let's Encrypt 'Sycamore2026h1'",
+ "ppWirZJtb5lujvxJAUJX2LvwRqfWJYm4jcLXh2x45S8=": "Let's Encrypt 'Willow2027h2'",
+ "qCbL4wrGNRJGUz/gZfFPGdluGQgTxB3ZbXkAsxI8VSc=": "Let's Encrypt 'Willow2026h2'",
+ "r2eIO1ewTt2Pptl+9i6o64EKx3Fg8CReVdYML+eFhzo=": "Sectigo 'Elephant2026h2'",
+ "rKswcGzr7IQx9BPS9JFfER5CJEOx8qaMTzwrO6ceAsM=": "Let's Encrypt 'Oak2026h2'",
+ "rxgaKNaMo+CpikycZ6sJ+Lu8IrquvLE4o6Gd0/m2Aw0=": "Sectigo 'Mammoth2025h2'",
+ "wjF+V0UZo0XufzjespBB68fCIVoiv3/Vta12mtkOUs0=": "DigiCert 'Wyvern2026h2'",
+ "yKPEf8ezrbk1awE/anoSbeM6TkOlxkb5l605dZkdz5o=": "Sectigo 'Tiger2026h2'",
+ "yzj3FYl8hKFEX1vB3fvJbvKaWc1HCmkFhbDLFMMUWOc=": "Cloudflare 'Nimbus2026'",
+ "zPsPaoVxCWX+lZtTzumyfCLphVwNl422qX5UwP5MDbA=": "Cloudflare 'Nimbus2025'"
+}
diff --git a/toolkit/components/certviewer/content/components/utils.mjs b/toolkit/components/certviewer/content/components/utils.mjs
@@ -2,6 +2,8 @@
* 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/. */
+import { logNameTable } from "./logNameTable.mjs";
+
export const normalizeToKebabCase = string => {
let kebabString = string
// Turn all dots into dashes
@@ -25,6 +27,18 @@ export const b64ToPEM = string => {
return `-----BEGIN CERTIFICATE-----\r\n${wrapped}\r\n-----END CERTIFICATE-----\r\n`;
};
+export const getLogName = hexLogId => {
+ let base64LogId = btoa(
+ hexLogId
+ .match(/\w{2}/g)
+ .map(function (a) {
+ return String.fromCharCode(parseInt(a, 16));
+ })
+ .join("")
+ );
+ return logNameTable[base64LogId];
+};
+
export const hexToIpv6Repr = ipAddressHex => {
let chunks = ipAddressHex
.match(/.{4}/g)
diff --git a/toolkit/components/certviewer/tests/browser/adjustedCerts.js b/toolkit/components/certviewer/tests/browser/adjustedCerts.js
@@ -1,12 +1,42 @@
"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
+To change this file you will have to add a function to download a file in toolkit/components/certviewer/content/certviewer.mjs.
+Add the following after this line https://searchfox.org/firefox-main/rev/50a34d25155fd70628ee69c7d68a2509c0e3445d/toolkit/components/certviewer/content/certviewer.mjs#414:
-const adjustedCerts = <what you just copied>;
+function download(filename, text) {
+ var element = document.createElement('a');
+ element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
+ element.setAttribute('download', filename);
+
+ element.style.display = 'none';
+ document.body.appendChild(element);
+
+ element.click();
+
+ document.body.removeChild(element);
+}
+
+// Start file download.
+download("out.txt",JSON.stringify({certItems, tabName}));
+
+Build Nightly and then open the test certificate in about:certificate.
+
+You can use the following bash script to get the correct URL:
+
+```
+function urlencode() {
+ python3 -c 'import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=sys.argv[2]))' "$1" "$urlencode_safe"
+}
+
+function pemurl() {
+ echo "about:certificate?cert=$(urlencode $(openssl x509 -in $1 -outform der | base64 -w 0))"
+}
+
+pemurl toolkit/components/certviewer/tests/browser/example.com.pem
+```
+
+Finally, paste the output here and update the URL in browser_renderCertToUI.js.
*/
const adjustedCerts = [
@@ -15,27 +45,21 @@ const adjustedCerts = [
{
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" },
+ {
+ labelId: "common-name",
+ info: "Certviewer Test Subject",
+ isHex: false,
+ },
],
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",
+ info: "Certviewer Test Issuer",
+ isHex: false,
},
],
Critical: false,
@@ -46,16 +70,18 @@ const adjustedCerts = [
{
labelId: "not-before",
info: {
- local: "5/7/2018, 9:00:00 PM (Brasilia Standard Time)",
- utc: "Tue, 08 May 2018 00:00:00 GMT",
+ local: "12/31/2019, 4:00:00 PM (Pacific Daylight Time)",
+ utc: "Wed, 01 Jan 2020 00:00:00 GMT",
},
+ isHex: false,
},
{
labelId: "not-after",
info: {
- local: "6/3/2020, 9:00:00 AM (Brasilia Standard Time)",
- utc: "Wed, 03 Jun 2020 12:00:00 GMT",
+ local: "12/31/2048, 4:00:00 PM (Pacific Daylight Time)",
+ utc: "Fri, 01 Jan 2049 00:00:00 GMT",
},
+ isHex: false,
},
],
Critical: false,
@@ -63,20 +89,20 @@ const adjustedCerts = [
{
sectionId: "subject-alt-names",
sectionItems: [
- { labelId: "dns-name", info: "github.com" },
- { labelId: "dns-name", info: "www.github.com" },
+ { labelId: "dns-name", info: "example.com", isHex: false },
],
Critical: false,
},
{
sectionId: "public-key-info",
sectionItems: [
- { labelId: "algorithm", info: "RSA" },
- { labelId: "key-size", info: 2048 },
- { labelId: "exponent", info: 65537 },
+ { labelId: "algorithm", info: "RSA", isHex: false },
+ { labelId: "key-size", info: 2048, isHex: false },
+ { labelId: "exponent", info: 65537, isHex: false },
{
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",
+ info: "BA:88:51:A8:44:8E:16:D6:41:FD:6E:B6:88:06:36:10:3D:3C:13:D9:EA:E4:35:4A:B4:EC:F5:68:57:6C:24:7B:C1:C7:25:A8:E0:D8:1F:BD:B1:9C:06:9B:6E:1A:86:F2:6B:E2:AF:5A:75:6B:6A:64:71:08:7A:A5:5A:A7:45:87:F7:1C:D5:24:9C:02:7E:CD:43:FC:1E:69:D0:38:20:29:93:AB:20:C3:49:E4:DB:B9:4C:C2:6B:6C:0E:ED:15:82:0F:F1:7E:AD:69:1A:B1:D3:02:3A:8B:2A:41:EE:A7:70:E0:0F:0D:8D:FD:66:0B:2B:B0:24:92:A4:7D:B9:88:61:79:90:B1:57:90:3D:D2:3B:C5:E0:B8:48:1F:A8:37:D3:88:43:EF:27:16:D8:55:B7:66:5A:AA:7E:02:90:2F:3A:7B:10:80:06:24:CC:1C:6C:97:AD:96:61:5B:B7:E2:96:12:C0:75:31:A3:0C:91:DD:B4:CA:F7:FC:AD:1D:25:D3:09:EF:B9:17:0E:A7:68:E1:B3:7B:2F:22:6F:69:E3:B4:8A:95:61:1D:EE:26:D6:25:9D:AB:91:08:4E:36:CB:1C:24:04:2C:BF:16:8B:2F:E5:F1:8F:99:17:31:B8:B3:FE:49:23:FA:72:51:C4:31:D5:03:AC:DA:18:0A:35:ED:8D",
+ isHex: true,
},
],
Critical: false,
@@ -86,16 +112,19 @@ const adjustedCerts = [
sectionItems: [
{
labelId: "serial-number",
- info: "0A:06:30:42:7F:5B:BC:ED:69:57:39:65:93:B6:45:1F",
+ info: "29:7F:CF:B0:CB:3D:C9:C0:10:48:10:9B:31:73:50:26:D0:39:02:6E",
+ isHex: true,
},
{
labelId: "signature-algorithm",
info: "SHA-256 with RSA Encryption",
+ isHex: false,
},
- { labelId: "version", info: "3" },
+ { labelId: "version", info: "3", isHex: false },
{
labelId: "download",
- info: "PEM (cert)PEM (chain)",
+ info: "-----BEGIN%20CERTIFICATE-----%0D%0AMIIEsDCCA5igAwIBAgIUKX/PsMs9ycAQSBCbMXNQJtA5Am4wDQYJKoZIhvcNAQEL%0D%0ABQAwITEfMB0GA1UEAwwWQ2VydHZpZXdlciBUZXN0IElzc3VlcjAiGA8yMDIwMDEw%0D%0AMTAwMDAwMFoYDzIwNDkwMTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdDZXJ0dmlld2Vy%0D%0AIFRlc3QgU3ViamVjdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI%0D%0AUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi%0D%0Ar1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x%0D%0Afq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD%0D%0A7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv%0D%0AuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj%0D%0A+nJRxDHVA6zaGAo17Y0CAwEAAaOCAdkwggHVMDIGCCsGAQUFBwEBBCYwJDAiBggr%0D%0ABgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzAPBgNVHRMBAf8EBTADAQH/%0D%0AMCgGA1UdIAQhMB8wBwYFZ4EMAQEwFAYSKwYBBAHrSYUahRqFGgGDdAkBMBMGA1Ud%0D%0AJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIBhjAWBgNVHREEDzANggtleGFt%0D%0AcGxlLmNvbTCCASUGCisGAQQB1nkCBAIEggEVBIIBEQEPAHUAKrgwRDO5FN7S8x5C%0D%0AB/JRwXo3oJJoUtkIAgb4Xlc5FioAAAGUHyl8AAAABAMARjBEAiBcdVGfExFQzV2K%0D%0A3iCjvAYwkf+yc3VfMWTs/ctCgApw5gIgRafynpUWWNFU5IGinUAH9iDXVEOW7Zgm%0D%0AkZtwCwQThQ8AlgDNeRdNGEsWeEl3r8cOu4yKezTP7Z+7GD6Lprh70wkA0gAAAZQf%0D%0AKXwAAAAEAwBnMGUCMQDtBic+oWg6VLTYGkN0hEiWPOY+voEXA+zXPXLwolQGWdTs%0D%0ARUboVudeZVW3k6n3APMCMH8jluFThKPCL0BhJLvmN49NV3jvCO3wSUSUPneJciRV%0D%0Atv0otIlh5ng8PqFrFBHo+DANBgkqhkiG9w0BAQsFAAOCAQEAW8qizE6SMno2irSW%0D%0AQEGznA7xLXqVWFM5rW/6SA9uynXIGaaoKtkkWQy4qa7RI7vgACCwyoBJCr3Y7ypn%0D%0AeKJUB+fTD0QIA5HH3ohz/UqI5SdezUCUQVd8lscdSEIvcyV35Gw5r3EAL+cFRk4U%0D%0AgeFewGwYCW61YPS72NzHGLfLA6/NpiZJongsqaYFb98fvk0DIFnmiyIcWfqO7n/p%0D%0ANAbh1wvkGhQ1qWKH6jZs2XC7RueaZuo88XCJTqIWs87p0LqUrkfrBNizVSGouCn9%0D%0AeuoUC1ngwOKeSzAuPR4k3OGOD3V6bBQ5EI7gAIv1hqyBvHFC1mvCEKv0qJHlycrR%0D%0ARPNIug==%0D%0A-----END%20CERTIFICATE-----%0D%0A",
+ isHex: false,
},
],
Critical: false,
@@ -105,18 +134,22 @@ const adjustedCerts = [
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",
+ info: "2C:E6:D4:35:4E:7B:89:B6:50:C5:D9:F1:A5:40:99:68:93:3B:4E:9A:4C:70:12:ED:07:E4:B0:C0:40:AE:28:9C",
+ isHex: true,
},
{
labelId: "sha-1",
- info: "CA:06:F5:6B:25:8B:7A:0D:4F:2B:05:47:09:39:47:86:51:15:19:84",
+ info: "D6:97:4A:BD:7A:B6:36:31:23:78:B1:66:0F:C5:96:AE:DE:F0:BE:16",
+ isHex: true,
},
],
Critical: false,
},
{
sectionId: "basic-constraints",
- sectionItems: [{ labelId: "certificate-authority", info: false }],
+ sectionItems: [
+ { labelId: "certificate-authority", info: true, isHex: false },
+ ],
Critical: true,
},
{
@@ -124,7 +157,8 @@ const adjustedCerts = [
sectionItems: [
{
labelId: "purposes",
- info: ["Digital Signature", "Key Encipherment"],
+ info: ["Digital Signature", "Certificate Signing", "CRL Signing"],
+ isHex: false,
},
],
Critical: true,
@@ -134,41 +168,8 @@ const adjustedCerts = [
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",
+ info: ["Server Authentication"],
+ isHex: false,
},
],
Critical: false,
@@ -176,16 +177,12 @@ const adjustedCerts = [
{
sectionId: "authority-info-aia",
sectionItems: [
- { labelId: "location", info: "http://ocsp.digicert.com" },
+ { labelId: "location", info: "http://localhost:8888/", isHex: false },
{
labelId: "method",
info: "Online Certificate Status Protocol (OCSP)",
+ isHex: false,
},
- {
- labelId: "location",
- info: "http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt",
- },
- { labelId: "method", info: "CA Issuers" },
],
Critical: false,
},
@@ -194,68 +191,69 @@ const adjustedCerts = [
sectionItems: [
{
labelId: "policy",
- info: "ANSI Organizational Identifier ( 2.16.840 )",
+ info: "Certificate Type ( 2.23.140.1.1 )",
+ isHex: false,
+ },
+ { labelId: "value", info: "Extended Validation", isHex: false },
+ {
+ labelId: "policy",
+ info: "Statement Identifier ( 1.3.6.1.4.1 )",
+ isHex: false,
},
- { 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: "1.3.6.1.4.1.13769.666.666.666.1.500.9.1",
+ isHex: false,
},
- { 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: "log-name", info: "Mozilla Test EC Log", isHex: false },
{
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",
- },
+ info: "2A:B8:30:44:33:B9:14:DE:D2:F3:1E:42:07:F2:51:C1:7A:37:A0:92:68:52:D9:08:02:06:F8:5E:57:39:16:2A",
+ isHex: true,
},
{
- 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: "signaturealgorithm",
+ info: "SHA-256 ECDSA",
+ isHex: false,
},
- { labelId: "name", info: "DigiCert Server" },
- { labelId: "signaturealgorithm", info: "SHA-256 ECDSA" },
- { labelId: "version", info: 1 },
+ { labelId: "version", info: 1, isHex: false },
{
labelId: "timestamp",
info: {
- local: "5/8/2018, 5:12:39 PM (Brasilia Standard Time)",
- utc: "Tue, 08 May 2018 20:12:39 GMT",
+ local: "12/31/2024, 4:00:00 PM (Pacific Daylight Time)",
+ utc: "Wed, 01 Jan 2025 00:00:00 GMT",
},
+ isHex: false,
},
{
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",
+ info: "CD:79:17:4D:18:4B:16:78:49:77:AF:C7:0E:BB:8C:8A:7B:34:CF:ED:9F:BB:18:3E:8B:A6:B8:7B:D3:09:00:D2",
+ isHex: true,
+ },
+ {
+ labelId: "signaturealgorithm",
+ info: "SHA-256 ECDSA",
+ isHex: false,
},
- { labelId: "name", info: "Google “Skydiver”" },
- { labelId: "signaturealgorithm", info: "SHA-256 ECDSA" },
- { labelId: "version", info: 1 },
+ { labelId: "version", info: 1, isHex: false },
{
labelId: "timestamp",
info: {
- local: "5/8/2018, 5:12:39 PM (Brasilia Standard Time)",
- utc: "Tue, 08 May 2018 20:12:39 GMT",
+ local: "12/31/2024, 4:00:00 PM (Pacific Daylight Time)",
+ utc: "Wed, 01 Jan 2025 00:00:00 GMT",
},
+ isHex: false,
},
],
Critical: false,
},
],
- tabName: "github.com",
+ tabName: "Certviewer Test Subject",
},
];
diff --git a/toolkit/components/certviewer/tests/browser/browser_renderCertToUI.js b/toolkit/components/certviewer/tests/browser/browser_renderCertToUI.js
@@ -4,7 +4,7 @@
"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";
+ "about:certificate?cert=MIIEsDCCA5igAwIBAgIUKX%2FPsMs9ycAQSBCbMXNQJtA5Am4wDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWQ2VydHZpZXdlciBUZXN0IElzc3VlcjAiGA8yMDIwMDEwMTAwMDAwMFoYDzIwNDkwMTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdDZXJ0dmlld2VyIFRlc3QgU3ViamVjdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ%2BzUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg%2Fxfq1pGrHTAjqLKkHup3DgDw2N%2FWYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt%2BKWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL%2BXxj5kXMbiz%2Fkkj%2BnJRxDHVA6zaGAo17Y0CAwEAAaOCAdkwggHVMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzAPBgNVHRMBAf8EBTADAQH%2FMCgGA1UdIAQhMB8wBwYFZ4EMAQEwFAYSKwYBBAHrSYUahRqFGgGDdAkBMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB%2FwQEAwIBhjAWBgNVHREEDzANggtleGFtcGxlLmNvbTCCASUGCisGAQQB1nkCBAIEggEVBIIBEQEPAHUAKrgwRDO5FN7S8x5CB%2FJRwXo3oJJoUtkIAgb4Xlc5FioAAAGUHyl8AAAABAMARjBEAiBcdVGfExFQzV2K3iCjvAYwkf%2Byc3VfMWTs%2FctCgApw5gIgRafynpUWWNFU5IGinUAH9iDXVEOW7ZgmkZtwCwQThQ8AlgDNeRdNGEsWeEl3r8cOu4yKezTP7Z%2B7GD6Lprh70wkA0gAAAZQfKXwAAAAEAwBnMGUCMQDtBic%2BoWg6VLTYGkN0hEiWPOY%2BvoEXA%2BzXPXLwolQGWdTsRUboVudeZVW3k6n3APMCMH8jluFThKPCL0BhJLvmN49NV3jvCO3wSUSUPneJciRVtv0otIlh5ng8PqFrFBHo%2BDANBgkqhkiG9w0BAQsFAAOCAQEAW8qizE6SMno2irSWQEGznA7xLXqVWFM5rW%2F6SA9uynXIGaaoKtkkWQy4qa7RI7vgACCwyoBJCr3Y7ypneKJUB%2BfTD0QIA5HH3ohz%2FUqI5SdezUCUQVd8lscdSEIvcyV35Gw5r3EAL%2BcFRk4UgeFewGwYCW61YPS72NzHGLfLA6%2FNpiZJongsqaYFb98fvk0DIFnmiyIcWfqO7n%2FpNAbh1wvkGhQ1qWKH6jZs2XC7RueaZuo88XCJTqIWs87p0LqUrkfrBNizVSGouCn9euoUC1ngwOKeSzAuPR4k3OGOD3V6bBQ5EI7gAIv1hqyBvHFC1mvCEKv0qJHlycrRRPNIug%3D%3D";
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/toolkit/components/certviewer/tests/browser/adjustedCerts.js",
diff --git a/toolkit/components/certviewer/tests/browser/example.com.pem b/toolkit/components/certviewer/tests/browser/example.com.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEsDCCA5igAwIBAgIUKX/PsMs9ycAQSBCbMXNQJtA5Am4wDQYJKoZIhvcNAQEL
+BQAwITEfMB0GA1UEAwwWQ2VydHZpZXdlciBUZXN0IElzc3VlcjAiGA8yMDIwMDEw
+MTAwMDAwMFoYDzIwNDkwMTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdDZXJ0dmlld2Vy
+IFRlc3QgU3ViamVjdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI
+UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi
+r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x
+fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD
+7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv
+uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj
++nJRxDHVA6zaGAo17Y0CAwEAAaOCAdkwggHVMDIGCCsGAQUFBwEBBCYwJDAiBggr
+BgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzAPBgNVHRMBAf8EBTADAQH/
+MCgGA1UdIAQhMB8wBwYFZ4EMAQEwFAYSKwYBBAHrSYUahRqFGgGDdAkBMBMGA1Ud
+JQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIBhjAWBgNVHREEDzANggtleGFt
+cGxlLmNvbTCCASUGCisGAQQB1nkCBAIEggEVBIIBEQEPAHUAKrgwRDO5FN7S8x5C
+B/JRwXo3oJJoUtkIAgb4Xlc5FioAAAGUHyl8AAAABAMARjBEAiBcdVGfExFQzV2K
+3iCjvAYwkf+yc3VfMWTs/ctCgApw5gIgRafynpUWWNFU5IGinUAH9iDXVEOW7Zgm
+kZtwCwQThQ8AlgDNeRdNGEsWeEl3r8cOu4yKezTP7Z+7GD6Lprh70wkA0gAAAZQf
+KXwAAAAEAwBnMGUCMQDtBic+oWg6VLTYGkN0hEiWPOY+voEXA+zXPXLwolQGWdTs
+RUboVudeZVW3k6n3APMCMH8jluFThKPCL0BhJLvmN49NV3jvCO3wSUSUPneJciRV
+tv0otIlh5ng8PqFrFBHo+DANBgkqhkiG9w0BAQsFAAOCAQEAW8qizE6SMno2irSW
+QEGznA7xLXqVWFM5rW/6SA9uynXIGaaoKtkkWQy4qa7RI7vgACCwyoBJCr3Y7ypn
+eKJUB+fTD0QIA5HH3ohz/UqI5SdezUCUQVd8lscdSEIvcyV35Gw5r3EAL+cFRk4U
+geFewGwYCW61YPS72NzHGLfLA6/NpiZJongsqaYFb98fvk0DIFnmiyIcWfqO7n/p
+NAbh1wvkGhQ1qWKH6jZs2XC7RueaZuo88XCJTqIWs87p0LqUrkfrBNizVSGouCn9
+euoUC1ngwOKeSzAuPR4k3OGOD3V6bBQ5EI7gAIv1hqyBvHFC1mvCEKv0qJHlycrR
+RPNIug==
+-----END CERTIFICATE-----
diff --git a/toolkit/components/certviewer/tests/browser/example.com.pem.certspec b/toolkit/components/certviewer/tests/browser/example.com.pem.certspec
@@ -0,0 +1,10 @@
+issuer:Certviewer Test Issuer
+subject:Certviewer Test Subject
+validity:20200101-20490101
+extension:authorityInformationAccess:http://localhost:8888/
+extension:basicConstraints[critical]:cA,
+extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1
+extension:embeddedSCTList:secp256r1:20250101,secp384r1:20250101
+extension:extKeyUsage:serverAuth
+extension:keyUsage[critical]:digitalSignature,keyCertSign,cRLSign
+extension:subjectAlternativeName:example.com
diff --git a/toolkit/locales/en-US/toolkit/about/certviewer.ftl b/toolkit/locales/en-US/toolkit/about/certviewer.ftl
@@ -36,6 +36,9 @@ certificate-viewer-key-size = Key Size
certificate-viewer-inc-locality = Inc. Locality
certificate-viewer-locality = Locality
certificate-viewer-location = Location
+# Log is a noun meaning a record of events.
+certificate-viewer-log-name = Log Name
+# Log is a noun meaning a record of events.
certificate-viewer-logid = Log ID
certificate-viewer-method = Method
certificate-viewer-modulus = Modulus