Bug 1688703 - reuse certviewer utility files in devtools r=johannh,ochameau

Differential Revision: https://phabricator.services.mozilla.com/D106340
This commit is contained in:
Dana Keeler 2021-04-21 17:48:21 +00:00
parent 22a9c1397e
commit 241c47c8cc
33 changed files with 1554 additions and 1449 deletions

View File

@ -4,8 +4,22 @@
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
import { parse } from "chrome://global/content/certviewer/certDecoder.js"; import "chrome://global/content/certviewer/pvutils_bundle.js";
import { pemToDER } from "chrome://global/content/certviewer/utils.js"; import "chrome://global/content/certviewer/asn1js_bundle.js";
import "chrome://global/content/certviewer/pkijs_bundle.js";
import "chrome://global/content/certviewer/certDecoder.js";
const { Integer, fromBER } = globalThis.asn1js.asn1js;
const { Certificate } = globalThis.pkijs.pkijs;
const { fromBase64, stringToArrayBuffer } = globalThis.pvutils.pvutils;
const { parse, pemToDER } = globalThis.certDecoderInitializer(
Integer,
fromBER,
Certificate,
fromBase64,
stringToArrayBuffer,
crypto
);
const formatter = new Intl.DateTimeFormat("default"); const formatter = new Intl.DateTimeFormat("default");

View File

@ -209,8 +209,5 @@
</div> </div>
</body> </body>
<script src="chrome://browser/content/certerror/aboutNetErrorCodes.js"/> <script src="chrome://browser/content/certerror/aboutNetErrorCodes.js"/>
<script src="chrome://global/content/certviewer/pvutils_bundle.js"></script>
<script src="chrome://global/content/certviewer/asn1js_bundle.js"></script>
<script src="chrome://global/content/certviewer/pkijs_bundle.js"></script>
<script type="module" src="chrome://browser/content/certerror/aboutNetError.js"/> <script type="module" src="chrome://browser/content/certerror/aboutNetError.js"/>
</html> </html>

View File

@ -27,6 +27,9 @@ var gExceptionPaths = [
// These resources are referenced using relative paths from html files. // These resources are referenced using relative paths from html files.
"resource://payments/", "resource://payments/",
// These chrome resources are referenced using relative paths from JS files.
"chrome://global/content/certviewer/components/",
// https://github.com/mozilla/activity-stream/issues/3053 // https://github.com/mozilla/activity-stream/issues/3053
"chrome://activity-stream/content/data/content/tippytop/images/", "chrome://activity-stream/content/data/content/tippytop/images/",
"chrome://activity-stream/content/data/content/tippytop/favicons/", "chrome://activity-stream/content/data/content/tippytop/favicons/",

View File

@ -13,11 +13,6 @@ loader.lazyRequireGetter(
"NetworkHelper", "NetworkHelper",
"devtools/shared/webconsole/network-helper" "devtools/shared/webconsole/network-helper"
); );
loader.lazyRequireGetter(
this,
"DevToolsUtils",
"devtools/shared/DevToolsUtils"
);
loader.lazyRequireGetter( loader.lazyRequireGetter(
this, this,
"CacheEntry", "CacheEntry",
@ -227,7 +222,7 @@ NetworkResponseListener.prototype = {
} }
this.request = request; this.request = request;
this._getSecurityInfo(); this._onSecurityInfo = this._getSecurityInfo();
this._findOpenResponse(); this._findOpenResponse();
// We need to track the offset for the onDataAvailable calls where // We need to track the offset for the onDataAvailable calls where
// we pass the data from our pipe to the converter. // we pass the data from our pipe to the converter.
@ -316,7 +311,7 @@ NetworkResponseListener.prototype = {
/** /**
* Parse security state of this request and report it to the client. * Parse security state of this request and report it to the client.
*/ */
_getSecurityInfo: DevToolsUtils.makeInfallible(function() { _getSecurityInfo: async function() {
// Many properties of the securityInfo (e.g., the server certificate or HPKP // Many properties of the securityInfo (e.g., the server certificate or HPKP
// status) are not available in the content process and can't be even touched safely, // status) are not available in the content process and can't be even touched safely,
// because their C++ getters trigger assertions. This function is called in content // because their C++ getters trigger assertions. This function is called in content
@ -333,8 +328,10 @@ NetworkResponseListener.prototype = {
if (secinfo) { if (secinfo) {
secinfo.QueryInterface(Ci.nsITransportSecurityInfo); secinfo.QueryInterface(Ci.nsITransportSecurityInfo);
} }
const info = NetworkHelper.parseSecurityInfo(secinfo, this.httpActivity); const info = await NetworkHelper.parseSecurityInfo(
secinfo,
this.httpActivity
);
let isRacing = false; let isRacing = false;
try { try {
const channel = this.httpActivity.channel; const channel = this.httpActivity.channel;
@ -347,7 +344,7 @@ NetworkResponseListener.prototype = {
} }
this.httpActivity.owner.addSecurityInfo(info, isRacing); this.httpActivity.owner.addSecurityInfo(info, isRacing);
}), },
/** /**
* Fetches cache information from CacheEntry * Fetches cache information from CacheEntry
@ -479,6 +476,15 @@ NetworkResponseListener.prototype = {
* from the cache. * from the cache.
*/ */
_onComplete: function(data) { _onComplete: function(data) {
// Make sure all the security and response content info are sent
this._getResponseContent(data);
this._onSecurityInfo.then(() => this._destroy());
},
/**
* Create the response object and send it to the client.
*/
_getResponseContent: function(data) {
const response = { const response = {
mimeType: "", mimeType: "",
text: data || "", text: data || "",
@ -534,7 +540,9 @@ NetworkResponseListener.prototype = {
blockedReason: reason, blockedReason: reason,
blockingExtension: id, blockingExtension: id,
}); });
},
_destroy: function() {
this._wrappedNotificationCallbacks = null; this._wrappedNotificationCallbacks = null;
this.httpActivity = null; this.httpActivity = null;
this.sink = null; this.sink = null;

View File

@ -208,7 +208,8 @@ class NetworkEventWatcher {
!types.includes("requestHeaders") || !types.includes("requestHeaders") ||
!types.includes("requestCookies") || !types.includes("requestCookies") ||
!types.includes("eventTimings") || !types.includes("eventTimings") ||
!types.includes("responseContent") !types.includes("responseContent") ||
!types.includes("securityInfo")
) { ) {
return; return;
} }

View File

@ -48,6 +48,7 @@ const debuggerSandbox = Cu.Sandbox(systemPrincipal, {
"btoa", "btoa",
"Blob", "Blob",
"ChromeUtils", "ChromeUtils",
"crypto",
"CSS", "CSS",
"CSSRule", "CSSRule",
"DOMParser", "DOMParser",
@ -70,6 +71,7 @@ const {
btoa, btoa,
Blob, Blob,
ChromeUtils, ChromeUtils,
crypto,
CSS, CSS,
CSSRule, CSSRule,
DOMParser, DOMParser,
@ -247,6 +249,7 @@ exports.globals = {
btoa, btoa,
BrowsingContext, BrowsingContext,
console, console,
crypto,
CSS, CSS,
CSSRule, CSSRule,
DOMParser, DOMParser,

View File

@ -130,7 +130,8 @@ module.exports = async function({
!types.includes("requestHeaders") || !types.includes("requestHeaders") ||
!types.includes("requestCookies") || !types.includes("requestCookies") ||
!types.includes("eventTimings") || !types.includes("eventTimings") ||
!types.includes("responseContent") !types.includes("responseContent") ||
!types.includes("securityInfo")
) { ) {
return; return;
} }

View File

@ -62,11 +62,40 @@
"use strict"; "use strict";
const { components, Cc, Ci } = require("chrome"); const { components, Cc, Ci, Cu } = require("chrome");
loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm"); loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
const DevToolsUtils = require("devtools/shared/DevToolsUtils"); const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const Services = require("Services"); const Services = require("Services");
loader.lazyGetter(this, "certDecoder", () => {
const { asn1js } = Cu.import(
"chrome://global/content/certviewer/asn1js_bundle.js"
);
const { pkijs } = Cu.import(
"chrome://global/content/certviewer/pkijs_bundle.js"
);
const { pvutils } = Cu.import(
"chrome://global/content/certviewer/pvutils_bundle.js"
);
const { Integer, fromBER } = asn1js.asn1js;
const { Certificate } = pkijs.pkijs;
const { fromBase64, stringToArrayBuffer } = pvutils.pvutils;
const { certDecoderInitializer } = Cu.import(
"chrome://global/content/certviewer/certDecoder.js"
);
const { parse, pemToDER } = certDecoderInitializer(
Integer,
fromBER,
Certificate,
fromBase64,
stringToArrayBuffer,
crypto
);
return { parse, pemToDER };
});
// The cache used in the `nsIURL` function. // The cache used in the `nsIURL` function.
const gNSURLStore = new Map(); const gNSURLStore = new Map();
@ -552,7 +581,7 @@ var NetworkHelper = {
* - weaknessReasons: list of reasons that cause the request to be * - weaknessReasons: list of reasons that cause the request to be
* considered weak. See getReasonsForWeakness. * considered weak. See getReasonsForWeakness.
*/ */
parseSecurityInfo: function(securityInfo, httpActivity) { parseSecurityInfo: async function(securityInfo, httpActivity) {
const info = { const info = {
state: "insecure", state: "insecure",
}; };
@ -646,7 +675,7 @@ var NetworkHelper = {
); );
// Certificate. // Certificate.
info.cert = this.parseCertificateInfo(securityInfo.serverCert); info.cert = await this.parseCertificateInfo(securityInfo.serverCert);
// Certificate transparency status. // Certificate transparency status.
info.certificateTransparency = securityInfo.certificateTransparencyStatus; info.certificateTransparency = securityInfo.certificateTransparencyStatus;
@ -703,29 +732,47 @@ var NetworkHelper = {
* fingerprint: { sha1, sha256 } * fingerprint: { sha1, sha256 }
* } * }
*/ */
parseCertificateInfo: function(cert) { parseCertificateInfo: async function(cert) {
function getDNComponent(dn, componentType) {
for (const [type, value] of dn.entries) {
if (type == componentType) {
return value;
}
}
return undefined;
}
const info = {}; const info = {};
if (cert) { if (cert) {
const parsedCert = await certDecoder.parse(
certDecoder.pemToDER(cert.getBase64DERString())
);
info.subject = { info.subject = {
commonName: cert.commonName, commonName: getDNComponent(parsedCert.subject, "Common Name"),
organization: cert.organization, organization: getDNComponent(parsedCert.subject, "Organization"),
organizationalUnit: cert.organizationalUnit, organizationalUnit: getDNComponent(
parsedCert.subject,
"Organizational Unit"
),
}; };
info.issuer = { info.issuer = {
commonName: cert.issuerCommonName, commonName: getDNComponent(parsedCert.issuer, "Common Name"),
organization: cert.issuerOrganization, organization: getDNComponent(parsedCert.issuer, "Organization"),
organizationUnit: cert.issuerOrganizationUnit, organizationUnit: getDNComponent(
parsedCert.issuer,
"Organizational Unit"
),
}; };
info.validity = { info.validity = {
start: cert.validity.notBeforeLocalDay, start: parsedCert.notBeforeUTC,
end: cert.validity.notAfterLocalDay, end: parsedCert.notAfterUTC,
}; };
info.fingerprint = { info.fingerprint = {
sha1: cert.sha1Fingerprint, sha1: parsedCert.fingerprint.sha1,
sha256: cert.sha256Fingerprint, sha256: parsedCert.fingerprint.sha256,
}; };
} else { } else {
DevToolsUtils.reportException( DevToolsUtils.reportException(

View File

@ -17,80 +17,76 @@ Object.defineProperty(this, "NetworkHelper", {
}); });
const DUMMY_CERT = { const DUMMY_CERT = {
commonName: "cn", getBase64DERString: function() {
organization: "o", // This is the base64-encoded contents of the "DigiCert ECC Secure Server CA"
organizationalUnit: "ou", // intermediate certificate as issued by "DigiCert Global Root CA". It was
issuerCommonName: "issuerCN", // chosen as a test certificate because it has an issuer common name,
issuerOrganization: "issuerO", // organization, and organizational unit that are somewhat distinct from
issuerOrganizationUnit: "issuerOU", // its subject common name and organization name.
sha256Fingerprint: "qwertyuiopoiuytrewq", return "MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBTZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6gLGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/AbuiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/63qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoBUEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQdEa8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc=";
sha1Fingerprint: "qwertyuiop",
validity: {
notBeforeLocalDay: "yesterday",
notAfterLocalDay: "tomorrow",
}, },
}; };
function run_test() { add_task(async function run_test() {
info("Testing NetworkHelper.parseCertificateInfo."); info("Testing NetworkHelper.parseCertificateInfo.");
const result = NetworkHelper.parseCertificateInfo(DUMMY_CERT); const result = await NetworkHelper.parseCertificateInfo(DUMMY_CERT);
// Subject // Subject
equal( equal(
result.subject.commonName, result.subject.commonName,
DUMMY_CERT.commonName, "DigiCert ECC Secure Server CA",
"Common name is correct." "Common name is correct."
); );
equal( equal(
result.subject.organization, result.subject.organization,
DUMMY_CERT.organization, "DigiCert Inc",
"Organization is correct." "Organization is correct."
); );
equal( equal(
result.subject.organizationUnit, result.subject.organizationUnit,
DUMMY_CERT.organizationUnit, undefined,
"Organizational unit is correct." "Organizational unit is correct."
); );
// Issuer // Issuer
equal( equal(
result.issuer.commonName, result.issuer.commonName,
DUMMY_CERT.issuerCommonName, "DigiCert Global Root CA",
"Common name of the issuer is correct." "Common name of the issuer is correct."
); );
equal( equal(
result.issuer.organization, result.issuer.organization,
DUMMY_CERT.issuerOrganization, "DigiCert Inc",
"Organization of the issuer is correct." "Organization of the issuer is correct."
); );
equal( equal(
result.issuer.organizationUnit, result.issuer.organizationUnit,
DUMMY_CERT.issuerOrganizationUnit, "www.digicert.com",
"Organizational unit of the issuer is correct." "Organizational unit of the issuer is correct."
); );
// Validity // Validity
equal( equal(
result.validity.start, result.validity.start,
DUMMY_CERT.validity.notBeforeLocalDay, "Fri, 08 Mar 2013 12:00:00 GMT",
"Start of the validity period is correct." "Start of the validity period is correct."
); );
equal( equal(
result.validity.end, result.validity.end,
DUMMY_CERT.validity.notAfterLocalDay, "Wed, 08 Mar 2023 12:00:00 GMT",
"End of the validity period is correct." "End of the validity period is correct."
); );
// Fingerprints // Fingerprints
equal( equal(
result.fingerprint.sha1, result.fingerprint.sha1,
DUMMY_CERT.sha1Fingerprint, "56:EE:7C:27:06:83:16:2D:83:BA:EA:CC:79:0E:22:47:1A:DA:AB:E8",
"Certificate SHA1 fingerprint is correct." "Certificate SHA1 fingerprint is correct."
); );
equal( equal(
result.fingerprint.sha256, result.fingerprint.sha256,
DUMMY_CERT.sha256Fingerprint, "45:84:46:BA:75:D9:32:E9:14:F2:3C:2B:57:B7:D1:92:ED:DB:C2:18:1D:95:8E:11:81:AD:52:51:74:7A:1E:E8",
"Certificate SHA256 fingerprint is correct." "Certificate SHA256 fingerprint is correct."
); );
} });

View File

@ -17,17 +17,10 @@ Object.defineProperty(this, "NetworkHelper", {
const wpl = Ci.nsIWebProgressListener; const wpl = Ci.nsIWebProgressListener;
const MockCertificate = { const MockCertificate = {
commonName: "cn", getBase64DERString: function() {
organization: "o", // This is the same test certificate as in
organizationalUnit: "ou", // test_security-info-certificate.js for consistency.
issuerCommonName: "issuerCN", return "MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBTZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6gLGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/AbuiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/63qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoBUEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQdEa8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc=";
issuerOrganization: "issuerO",
issuerOrganizationUnit: "issuerOU",
sha256Fingerprint: "qwertyuiopoiuytrewq",
sha1Fingerprint: "qwertyuiop",
validity: {
notBeforeLocalDay: "yesterday",
notAfterLocalDay: "tomorrow",
}, },
}; };
@ -43,8 +36,8 @@ const MockSecurityInfo = {
serverCert: MockCertificate, serverCert: MockCertificate,
}; };
function run_test() { add_task(async function run_test() {
const result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); const result = await NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
equal(result.state, "secure", "State is correct."); equal(result.state, "secure", "State is correct.");
@ -58,10 +51,10 @@ function run_test() {
deepEqual( deepEqual(
result.cert, result.cert,
NetworkHelper.parseCertificateInfo(MockCertificate), await NetworkHelper.parseCertificateInfo(MockCertificate),
"Certificate information is correct." "Certificate information is correct."
); );
equal(result.hpkp, false, "HPKP is false when URI is not available."); equal(result.hpkp, false, "HPKP is false when URI is not available.");
equal(result.hsts, false, "HSTS is false when URI is not available."); equal(result.hsts, false, "HSTS is false when URI is not available.");
} });

View File

@ -29,19 +29,19 @@ const MockSecurityInfo = {
cipherName: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", cipherName: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
}; };
function run_test() { add_task(async function run_test() {
test_nullSecurityInfo(); await test_nullSecurityInfo();
test_insecureSecurityInfoWithNSSError(); await test_insecureSecurityInfoWithNSSError();
test_insecureSecurityInfoWithoutNSSError(); await test_insecureSecurityInfoWithoutNSSError();
test_brokenSecurityInfo(); await test_brokenSecurityInfo();
test_secureSecurityInfo(); await test_secureSecurityInfo();
} });
/** /**
* Test that undefined security information is returns "insecure". * Test that undefined security information is returns "insecure".
*/ */
function test_nullSecurityInfo() { async function test_nullSecurityInfo() {
const result = NetworkHelper.parseSecurityInfo(null, {}); const result = await NetworkHelper.parseSecurityInfo(null, {});
equal( equal(
result.state, result.state,
"insecure", "insecure",
@ -52,13 +52,13 @@ function test_nullSecurityInfo() {
/** /**
* Test that STATE_IS_INSECURE with NSSError returns "broken" * Test that STATE_IS_INSECURE with NSSError returns "broken"
*/ */
function test_insecureSecurityInfoWithNSSError() { async function test_insecureSecurityInfoWithNSSError() {
MockSecurityInfo.securityState = wpl.STATE_IS_INSECURE; MockSecurityInfo.securityState = wpl.STATE_IS_INSECURE;
// Taken from security/manager/ssl/tests/unit/head_psm.js. // Taken from security/manager/ssl/tests/unit/head_psm.js.
MockSecurityInfo.errorCode = -8180; MockSecurityInfo.errorCode = -8180;
const result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); const result = await NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
equal( equal(
result.state, result.state,
"broken", "broken",
@ -72,10 +72,10 @@ function test_insecureSecurityInfoWithNSSError() {
/** /**
* Test that STATE_IS_INSECURE without NSSError returns "insecure" * Test that STATE_IS_INSECURE without NSSError returns "insecure"
*/ */
function test_insecureSecurityInfoWithoutNSSError() { async function test_insecureSecurityInfoWithoutNSSError() {
MockSecurityInfo.securityState = wpl.STATE_IS_INSECURE; MockSecurityInfo.securityState = wpl.STATE_IS_INSECURE;
const result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); const result = await NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
equal( equal(
result.state, result.state,
"insecure", "insecure",
@ -87,10 +87,10 @@ function test_insecureSecurityInfoWithoutNSSError() {
/** /**
* Test that STATE_IS_SECURE returns "secure" * Test that STATE_IS_SECURE returns "secure"
*/ */
function test_secureSecurityInfo() { async function test_secureSecurityInfo() {
MockSecurityInfo.securityState = wpl.STATE_IS_SECURE; MockSecurityInfo.securityState = wpl.STATE_IS_SECURE;
const result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); const result = await NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
equal( equal(
result.state, result.state,
"secure", "secure",
@ -101,10 +101,10 @@ function test_secureSecurityInfo() {
/** /**
* Test that STATE_IS_BROKEN returns "weak" * Test that STATE_IS_BROKEN returns "weak"
*/ */
function test_brokenSecurityInfo() { async function test_brokenSecurityInfo() {
MockSecurityInfo.securityState = wpl.STATE_IS_BROKEN; MockSecurityInfo.securityState = wpl.STATE_IS_BROKEN;
const result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); const result = await NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
equal( equal(
result.state, result.state,
"weak", "weak",

View File

@ -28,7 +28,11 @@ const MockSecurityInfo = {
// TLS_VERSION_1_2 // TLS_VERSION_1_2
protocolVersion: 3, protocolVersion: 3,
serverCert: { serverCert: {
validity: {}, getBase64DERString: function() {
// This is the same test certificate as in
// test_security-info-certificate.js for consistency.
return "MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBTZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6gLGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/AbuiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/63qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoBUEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQdEa8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc=";
},
}, },
}; };
@ -37,11 +41,11 @@ const MockHttpInfo = {
private: false, private: false,
}; };
function run_test() { add_task(async function run_test() {
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1); Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1);
const result = NetworkHelper.parseSecurityInfo( const result = await NetworkHelper.parseSecurityInfo(
MockSecurityInfo, MockSecurityInfo,
MockHttpInfo MockHttpInfo
); );
equal(result.hpkp, true, "Static HPKP detected."); equal(result.hpkp, true, "Static HPKP detected.");
} });

View File

@ -0,0 +1,19 @@
#!/bin/bash
# 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 https://mozilla.org/MPL/2.0/.
# Helper script to bundle the given library and amend it to be loadable in more
# contexts.
WHICH="${1}"
# Run the browserify command
./node_modules/browserify/bin/cmd.js "$WHICH".js --standalone "$WHICH" -o ./vendor/"$WHICH"_bundle.js
# Amend 'this' in the first line to 'globalThis'
sed -e '1s/{g=this}/{g=globalThis}/' -i "" ./vendor/"$WHICH"_bundle.js
# Append code to export the library
echo "var $WHICH = globalThis.$WHICH;" >> ./vendor/"$WHICH"_bundle.js
echo "var EXPORTED_SYMBOLS = [\"$WHICH\"];" >> ./vendor/"$WHICH"_bundle.js

File diff suppressed because it is too large Load Diff

View File

@ -10,23 +10,9 @@
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; object-src 'none'" /> <meta http-equiv="Content-Security-Policy" content="default-src chrome:; object-src 'none'" />
<link rel="localization" href="toolkit/about/certviewer.ftl"> <link rel="localization" href="toolkit/about/certviewer.ftl">
<link rel="localization" href="branding/brand.ftl"> <link rel="localization" href="branding/brand.ftl">
<script defer="defer" src="chrome://global/content/certviewer/pvutils_bundle.js"></script> <script type="module" src="chrome://global/content/certviewer/certviewer.js"></script>
<script defer="defer" src="chrome://global/content/certviewer/asn1js_bundle.js"></script> <script type="module" src="chrome://global/content/certviewer/components/certificate-section.js"></script>
<script defer="defer" src="chrome://global/content/certviewer/pkijs_bundle.js"></script> <script type="module" src="chrome://global/content/certviewer/components/about-certificate-section.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/ctlognames.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/strings.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/utils.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/certDecoder.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/certviewer.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/list-item.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/info-group.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/info-group-container.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/info-item.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/certificate-tabs-section.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/certificate-section.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/error-section.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/about-certificate-section.js"></script>
<script defer="defer" type="module" src="chrome://global/content/certviewer/components/about-certificate-items.js"></script>
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css"> <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" href="chrome://global/content/certviewer/certviewer.css"> <link rel="stylesheet" href="chrome://global/content/certviewer/certviewer.css">
<title id="certTitle">about:certificate</title> <title id="certTitle">about:certificate</title>

View File

@ -6,8 +6,24 @@
"use strict"; "use strict";
import { parse } from "./certDecoder.js"; import { normalizeToKebabCase } from "./components/utils.js";
import { pemToDER, normalizeToKebabCase } from "./utils.js";
import "chrome://global/content/certviewer/pvutils_bundle.js";
import "chrome://global/content/certviewer/asn1js_bundle.js";
import "chrome://global/content/certviewer/pkijs_bundle.js";
import "chrome://global/content/certviewer/certDecoder.js";
const { Integer, fromBER } = globalThis.asn1js.asn1js;
const { Certificate } = globalThis.pkijs.pkijs;
const { fromBase64, stringToArrayBuffer } = globalThis.pvutils.pvutils;
const { parse, pemToDER } = globalThis.certDecoderInitializer(
Integer,
fromBER,
Certificate,
fromBase64,
stringToArrayBuffer,
crypto
);
document.addEventListener("DOMContentLoaded", async e => { document.addEventListener("DOMContentLoaded", async e => {
let url = new URL(document.URL); let url = new URL(document.URL);

View File

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { normalizeToKebabCase } from "../utils.js"; import { normalizeToKebabCase } from "./utils.js";
import { updateSelectedItem } from "../certviewer.js"; import { updateSelectedItem } from "../certviewer.js";
export class CertificateTabsSection extends HTMLElement { export class CertificateTabsSection extends HTMLElement {

View File

@ -4,7 +4,7 @@
import { InfoItem } from "./info-item.js"; import { InfoItem } from "./info-item.js";
import { updateSelectedItem } from "../certviewer.js"; import { updateSelectedItem } from "../certviewer.js";
import { normalizeToKebabCase } from "../utils.js"; import { normalizeToKebabCase } from "./utils.js";
export class InfoGroup extends HTMLElement { export class InfoGroup extends HTMLElement {
constructor(item, final) { constructor(item, final) {

View File

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { b64ToPEM, normalizeToKebabCase } from "../utils.js"; import { b64ToPEM, normalizeToKebabCase } from "./utils.js";
export class InfoItem extends HTMLElement { export class InfoItem extends HTMLElement {
constructor(item) { constructor(item) {

View File

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { normalizeToKebabCase } from "../utils.js"; import { normalizeToKebabCase } from "./utils.js";
export class ListItem extends HTMLElement { export class ListItem extends HTMLElement {
constructor(item) { constructor(item) {

View File

@ -0,0 +1,26 @@
/* 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/. */
export const normalizeToKebabCase = string => {
let kebabString = string
// Turn all dots into dashes
.replace(/\./g, "-")
// Turn whitespace into dashes
.replace(/\s+/g, "-")
// Remove all non-characters or numbers
.replace(/[^a-z0-9\-]/gi, "")
// De-dupe dashes
.replace(/--/g, "-")
// Remove trailing and leading dashes
.replace(/^-/g, "")
.replace(/-$/g, "")
.toLowerCase();
return kebabString;
};
export const b64ToPEM = string => {
let wrapped = string.match(/.{1,64}/g).join("\r\n");
return `-----BEGIN CERTIFICATE-----\r\n${wrapped}\r\n-----END CERTIFICATE-----\r\n`;
};

View File

@ -1,170 +0,0 @@
/* 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/. */
export const ctLogNames = {
"9606c02c690033aa1d145f59c6e2648d0549f0df96aab8db915a70d8ecf390a5":
"Akamai CT",
"39376f545f7b4607f59742d768cd5d2437bf3473b6534a4834bcf72e681c83c9":
"Alpha CT",
a577ac9ced7548dd8f025b67a241089df86e0f476ec203c2ecbedb185f282638: "CNNIC CT",
cdb5179b7fc1c046feea31136a3f8f002e6182faf8896fecc8b2f5b5ab604900: "Certly.IO",
"1fbc36e002ede97f40199e86b3573b8a4217d80187746ad0da03a06054d20df4":
"Cloudflare “Nimbus2017”",
db74afeecb29ecb1feca3e716d2ce5b9aabb36f7847183c75d9d4f37b61fbf64:
"Cloudflare “Nimbus2018”",
"747eda8331ad331091219cce254f4270c2bffd5e422008c6373579e6107bcc56":
"Cloudflare “Nimbus2019”",
"5ea773f9df56c0e7b536487dd049e0327a919a0c84a112128418759681714558":
"Cloudflare “Nimbus2020”",
"4494652eb0eeceafc44007d8a8fe28c0dae682bed8cb31b53fd33396b5b681a8":
"Cloudflare “Nimbus2021”",
"41c8cab1df22464a10c6a13a0942875e4e318b1b03ebeb4bc768f090629606f6":
"Cloudflare “Nimbus2022”",
"7a328c54d8b72db620ea38e0521ee98416703213854d3bd22bc13a57a352eb52":
"Cloudflare “Nimbus2023”",
"6ff141b5647e4222f7ef052cefae7c21fd608e27d2af5a6e9f4b8a37d6633ee5":
"DigiCert Nessie2018",
fe446108b1d01ab78a62ccfeab6ab2b2babff3abdad80a4d8b30df2d0008830c:
"DigiCert Nessie2019",
c652a0ec48ceb3fcab170992c43a87413309e80065a26252401ba3362a17c565:
"DigiCert Nessie2020",
eec095ee8d72640f92e3c3b91bc712a3696a097b4b6a1a1438e647b2cbedc5f9:
"DigiCert Nessie2021",
"51a3b0f5fd01799c566db837788f0ca47acc1b27cbf79e88429a0dfed48b05e5":
"DigiCert Nessie2022",
b3737707e18450f86386d605a9dc11094a792db1670c0b87dcf0030e7936a59a:
"DigiCert Nessie2023",
"5614069a2fd7c2ecd3f5e1bd44b23ec74676b9bc99115cc0ef949855d689d0dd":
"DigiCert Server",
"8775bfe7597cf88c43995fbdf36eff568d475636ff4ab560c1b4eaff5ea0830f":
"DigiCert Server 2",
c1164ae0a772d2d4392dc80ac10770d4f0c49bde991a4840c1fa075164f63360:
"DigiCert Yeti2018",
e2694bae26e8e94009e8861bb63b83d43ee7fe7488fba48f2893019dddf1dbfe:
"DigiCert Yeti2019",
f095a459f200d18240102d2f93888ead4bfe1d47e399e1d034a6b0a8aa8eb273:
"DigiCert Yeti2020",
"5cdc4392fee6ab4544b15e9ad456e61037fbd5fa47dca17394b25ee6f6c70eca":
"DigiCert Yeti2021",
"2245450759552456963fa12ff1f76d86e0232663adc04b7f5dc6835c6ee20f02":
"DigiCert Yeti2022",
"35cf191bbfb16c57bf0fad4c6d42cbbbb627202651ea3fe12aefa803c33bd64c":
"DigiCert Yeti2023",
"717ea7420975be84a2723553f1777c26dd51af4e102144094d9019b462fb6668": "GDCA 1",
"14308d90ccd030135005c01ca526d81e84e87624e39b6248e08f724aea3bb42a": "GDCA 2",
c9cf890a21109c666cc17a3ed065c930d0e0135a9feba85af14210b8072421aa:
"GDCA CT #1",
"924a30f909336ff435d6993a10ac75a2c641728e7fc2d659ae6188ffad40ce01":
"GDCA CT #2",
fad4c97cc49ee2f8ac85c5ea5cea09d0220dbbf4e49c6b50662ff868f86b8c28:
"Google “Argon2017”",
a4501269055a15545e6211ab37bc103f62ae5576a45e4b1714453e1b22106a25:
"Google “Argon2018”",
"63f2dbcde83bcc2ccf0b728427576b33a48d61778fbd75a638b1c768544bd88d":
"Google “Argon2019”",
b21e05cc8ba2cd8a204e8766f92bb98a2520676bdafa70e7b249532def8b905e:
"Google “Argon2020”",
f65c942fd1773022145418083094568ee34d131933bfdf0c2f200bcc4ef164e3:
"Google “Argon2021”",
"2979bef09e393921f056739f63a577e5be577d9c600af8f94d5d265c255dc784":
"Google “Argon2022”",
"68f698f81f6482be3a8ceeb9281d4cfc71515d6793d444d10a67acbb4f4ffbc4":
"Google “Aviator”",
c3bf03a7e1ca8841c607bae3ff4270fca5ec45b186ebbe4e2cf3fc778630f5f6:
"Google “Crucible”",
"1d024b8eb1498b344dfd87ea3efc0996f7506f235d1d497061a4773c439c25fb":
"Google “Daedalus”",
"293c519654c83965baaa50fc5807d4b76fbf587a2972dca4c30cf4e54547f478":
"Google “Icarus”",
a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377cd0ec80ddc10:
"Google “Pilot”",
ee4bbdb775ce60bae142691fabe19e66a30f7e5fb072d88300c47b897aa8fdcb:
"Google “Rocketeer”",
bbd9dfbc1f8a71b593942397aa927b473857950aab52e81a909664368e1ed185:
"Google “Skydiver”",
"52eb4b225ec896974850675f23e43bc1d021e3214ce52ecd5fa87c203cdfca03":
"Google “Solera2018”",
"0b760e9a8b9a682f88985b15e947501a56446bba8830785c3842994386450c00":
"Google “Solera2019”",
"1fc72ce5a1b799f400c359bff96ca3913548e8644220610952e9ba1774f7bac7":
"Google “Solera2020”",
a3c99845e80ab7ce00157b3742df0207dd272b2b602ecf98ee2c12db9c5ae7e7:
"Google “Solera2021”",
"697aafca1a6b536fae21205046debad7e0eaea13d2432e6e9d8fb379f2b9aaf3":
"Google “Solera2022”",
a899d8780c9290aaf462f31880ccfbd52451e970d0fbf591ef75b0d99b645681:
"Google “Submariner”",
b0cc83e5a5f97d6baf7c09cc284904872ac7e88b132c6350b7c6fd26e16c6c77:
"Google “Testtube”",
b10cd559a6d67846811f7df9a51532739ac48d703bea0323da5d38755bc0ad4e:
"Google “Xenon2018”",
"084114980071532c16190460bcfc47fdc2653afa292c72b37ff863ae29ccc9f0":
"Google “Xenon2019”",
"07b75c1be57d68fff1b0c61d2315c7bae6577c5794b76aeebc613a1a69d3a21c":
"Google “Xenon2020”",
"7d3ef2f88fff88556824c2c0ca9e5289792bc50e78097f2e6a9768997e22f0d7":
"Google “Xenon2021”",
"46a555eb75fa912030b5a28969f4f37d112c4174befd49b885abf2fc70fe6d47":
"Google “Xenon2022”",
"7461b4a09cfb3d41d75159575b2e7649a445a8d27709b0cc564a6482b7eb41a3": "Izenpe",
"8941449c70742e06b9fc9ce7b116ba0024aa36d59af44f0204404f00f7ea8566":
"Izenpe “Argi”",
"296afa2d568bca0d2ea844956ae9721fc35fa355ecda99693aafd458a71aefdd":
"Let“s Encrypt ”Clicky”",
"537b69a3564335a9c04904e39593b2c298eb8d7a6e83023635c627248cd6b440":
"Nordu “flimsy”",
aae70b7f3cb8d566c86c2f16979c9f445f69ab0eb4535589b2f77a030104f3cd:
"Nordu “plausible”",
e0127629e90496564e3d0147984498aa48f8adb16600eb7902a1ef9909906273:
"PuChuangSiDa CT",
cf55e28923497c340d5206d05353aeb25834b52f1f8dc9526809f212efdd7ca6:
"SHECA CT 1",
"32dc59c2d4c41968d56e14bc61ac8f0e45db39faf3c155aa4252f5001fa0c623":
"SHECA CT 2",
db76fdadac65e7d09508886e2159bd8b90352f5fead3e3dc5e22eb350acc7b98:
"Sectigo (Comodo) “Dodo” CT",
"6f5376ac31f03119d89900a45115ff77151c11d902c10029068db2089a37d913":
"Sectigo (Comodo) “Mammoth” CT",
"5581d4c2169036014aea0b9b573c53f0c0e43878702508172fa3aa1d0713d30c":
"Sectigo (Comodo) “Sabre” CT",
"34bb6ad6c3df9c03eea8a499ff7891486c9d5e5cac92d01f7bfd1bce19db48ef":
"StartCom",
ddeb1d2b7a0d4fa6208b81ad8168707e2e8e9d01d55c888d3d11c4cdb6ecbecc: "Symantec",
a7ce4a4e6207e0addee5fdaa4b1f86768767b5d002a55d47310e7e670a95eab2:
"Symantec Deneb",
"15970488d7b997a05beb52512adee8d2e8b4a3165264121a9fabfbd5f85ad93f":
"Symantec “Sirius”",
bc78e1dfc5f63c684649334da10fa15f0979692009c081b4f3f6917f3ed9b8a5:
"Symantec “Vega”",
b0b784bc81c0ddc47544e883f05985bb9077d134d8ab88b2b2e533980b8e508b:
"Up In The Air “Behind the Sofa”",
ac3b9aed7fa9674757159e6d7d575672f9d98100941e9bdeffeca1313b75782d: "Venafi",
"03019df3fd85a69a8ebd1facc6da9ba73e469774fe77f579fc5a08b8328c1d6b":
"Venafi Gen2 CT",
"41b2dc2e89e63ce4af1ba7bb29bf68c6dee6f9f1cc047e30dffae3b3ba259263": "WoSign",
"63d0006026dde10bb0601f452446965ee2b6ea2cd4fbc95ac866a550af9075b7":
"WoSign 2",
"9e4ff73dc3ce220b69217c899e468076abf8d78636d5ccfc85a31a75628ba88b":
"WoSign CT #1",
"659b3350f43b12cc5ea5ab4ec765d3fde6c88243777778e72003f9eb2b8c3129":
"Let's Encrypt Oak 2019",
e712f2b0377e1a62fb8ec90c6184f1ea7b37cb561d11265bf3e0f34bf241546e:
"Let's Encrypt Oak 2020",
"9420bc1e8ed58d6c88731f828b222c0dd1da4d5e6c4f943d61db4e2f584da2c2":
"Let's Encrypt Oak 2021",
dfa55eab68824f1f6cadeeb85f4e3e5aeacda212a46a5e8e3b12c020445c2a73:
"Let's Encrypt Oak 2022",
b73efb24df9c4dba75f239c5ba58f46c5dfc42cf7a9f35c49e1d098125edb499:
"Let's Encrypt Oak 2023",
"849f5f7f58d2bf7b54ecbd74611cea45c49c98f1d6481bc6f69e8c174f24f3cf":
"Let's Encrypt Testflume 2019",
c63f2218c37d56a6aa06b596da8e53d4d7156d1e9bac8e44d2202de64d69d9dc:
"Let's Encrypt Testflume 2020",
"03edf1da9776b6f38c341e39ed9d707a7570369cf9844f327fe9e14138361b60":
"Let's Encrypt Testflume 2021",
"2327efda352510dbc019ef491ae3ff1cc5a479bce37878360ee318cffb64f8c8":
"Let's Encrypt Testflume 2022",
"5534b7ab5a6ac3a7cbeba65487b2a2d71b48f650fa17c5197c97a0cb2076f3c6":
"Let's Encrypt Testflume 2023",
};

View File

@ -3,9 +3,9 @@
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"scripts": { "scripts": {
"build-pvutils": "./node_modules/browserify/bin/cmd.js pvutils.js --standalone pvutils -o ./vendor/pvutils_bundle.js", "build-pvutils": "./bundle.sh pvutils",
"build-asn1js": "./node_modules/browserify/bin/cmd.js asn1js.js --standalone asn1js -o ./vendor/asn1js_bundle.js", "build-asn1js": "./bundle.sh asn1js",
"build-pkijs": "./node_modules/browserify/bin/cmd.js pkijs.js --standalone pkijs -o ./vendor/pkijs_bundle.js", "build-pkijs": "./bundle.sh pkijs",
"build": "npm run build-pvutils && npm run build-asn1js && npm run build-pkijs" "build": "npm run build-pvutils && npm run build-asn1js && npm run build-pkijs"
}, },
"license": "MPL-2.0", "license": "MPL-2.0",

View File

@ -1,505 +0,0 @@
/* 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/. */
export const strings = {
ux: {
upload: "Upload Certificate",
},
names: {
// Directory Pilot Attributes
"0.9.2342.19200300.100.1.1": {
short: "uid",
long: "User ID",
},
"0.9.2342.19200300.100.1.25": {
short: "dc",
long: "Domain Component",
},
// PKCS-9
"1.2.840.113549.1.9.1": {
short: "e",
long: "Email Address",
},
// Incorporated Locations
"1.3.6.1.4.1.311.60.2.1.1": {
short: undefined,
long: "Inc. Locality",
},
"1.3.6.1.4.1.311.60.2.1.2": {
short: undefined,
long: "Inc. State / Province",
},
"1.3.6.1.4.1.311.60.2.1.3": {
short: undefined,
long: "Inc. Country",
},
// microsoft cryptographic extensions
"1.3.6.1.4.1.311.21.7": {
name: {
short: "Certificate Template",
long: "Microsoft Certificate Template",
},
},
"1.3.6.1.4.1.311.21.10": {
name: {
short: "Certificate Policies",
long: "Microsoft Certificate Policies",
},
},
// certificate extensions
"1.3.6.1.4.1.11129.2.4.2": {
name: {
short: "Embedded SCTs",
long: "Embedded Signed Certificate Timestamps",
},
},
"1.3.6.1.5.5.7.1.1": {
name: {
short: undefined,
long: "Authority Information Access",
},
},
"1.3.6.1.5.5.7.1.24": {
name: {
short: "OCSP Stapling",
long: "Online Certificate Status Protocol Stapling",
},
},
// X.500 attribute types
"2.5.4.1": {
short: undefined,
long: "Aliased Entry",
},
"2.5.4.2": {
short: undefined,
long: "Knowledge Information",
},
"2.5.4.3": {
short: "cn",
long: "Common Name",
},
"2.5.4.4": {
short: "sn",
long: "Surname",
},
"2.5.4.5": {
short: "serialNumber",
long: "Serial Number",
},
"2.5.4.6": {
short: "c",
long: "Country",
},
"2.5.4.7": {
short: "l",
long: "Locality",
},
"2.5.4.8": {
short: "s",
long: "State / Province",
},
"2.5.4.9": {
short: "street",
long: "Stress Address",
},
"2.5.4.10": {
short: "o",
long: "Organization",
},
"2.5.4.11": {
short: "ou",
long: "Organizational Unit",
},
"2.5.4.12": {
short: "t",
long: "Title",
},
"2.5.4.13": {
short: "description",
long: "Description",
},
"2.5.4.14": {
short: undefined,
long: "Search Guide",
},
"2.5.4.15": {
short: undefined,
long: "Business Category",
},
"2.5.4.16": {
short: undefined,
long: "Postal Address",
},
"2.5.4.17": {
short: "postalCode",
long: "Postal Code",
},
"2.5.4.18": {
short: "POBox",
long: "PO Box",
},
"2.5.4.19": {
short: undefined,
long: "Physical Delivery Office Name",
},
"2.5.4.20": {
short: "phone",
long: "Phone Number",
},
"2.5.4.21": {
short: undefined,
long: "Telex Number",
},
"2.5.4.22": {
short: undefined,
long: "Teletex Terminal Identifier",
},
"2.5.4.23": {
short: undefined,
long: "Fax Number",
},
"2.5.4.24": {
short: undefined,
long: "X.121 Address",
},
"2.5.4.25": {
short: undefined,
long: "International ISDN Number",
},
"2.5.4.26": {
short: undefined,
long: "Registered Address",
},
"2.5.4.27": {
short: undefined,
long: "Destination Indicator",
},
"2.5.4.28": {
short: undefined,
long: "Preferred Delivery Method",
},
"2.5.4.29": {
short: undefined,
long: "Presentation Address",
},
"2.5.4.30": {
short: undefined,
long: "Supported Application Context",
},
"2.5.4.31": {
short: undefined,
long: "Member",
},
"2.5.4.32": {
short: undefined,
long: "Owner",
},
"2.5.4.33": {
short: undefined,
long: "Role Occupant",
},
"2.5.4.34": {
short: undefined,
long: "See Also",
},
"2.5.4.35": {
short: undefined,
long: "User Password",
},
"2.5.4.36": {
short: undefined,
long: "User Certificate",
},
"2.5.4.37": {
short: undefined,
long: "CA Certificate",
},
"2.5.4.38": {
short: undefined,
long: "Authority Revocation List",
},
"2.5.4.39": {
short: undefined,
long: "Certificate Revocation List",
},
"2.5.4.40": {
short: undefined,
long: "Cross-certificate Pair",
},
"2.5.4.41": {
short: undefined,
long: "Name",
},
"2.5.4.42": {
short: "g",
long: "Given Name",
},
"2.5.4.43": {
short: "i",
long: "Initials",
},
"2.5.4.44": {
short: undefined,
long: "Generation Qualifier",
},
"2.5.4.45": {
short: undefined,
long: "Unique Identifier",
},
"2.5.4.46": {
short: undefined,
long: "DN Qualifier",
},
"2.5.4.47": {
short: undefined,
long: "Enhanced Search Guide",
},
"2.5.4.48": {
short: undefined,
long: "Protocol Information",
},
"2.5.4.49": {
short: "dn",
long: "Distinguished Name",
},
"2.5.4.50": {
short: undefined,
long: "Unique Member",
},
"2.5.4.51": {
short: undefined,
long: "House Identifier",
},
"2.5.4.52": {
short: undefined,
long: "Supported Algorithms",
},
"2.5.4.53": {
short: undefined,
long: "Delta Revocation List",
},
"2.5.4.58": {
short: undefined,
long: "Attribute Certificate Attribute", // huh
},
"2.5.4.65": {
short: undefined,
long: "Pseudonym",
},
// extensions
"2.5.29.14": {
name: {
short: "Subject Key ID",
long: "Subject Key Identifier",
},
},
"2.5.29.15": {
name: {
short: undefined,
long: "Key Usages",
},
},
"2.5.29.17": {
name: {
short: "Subject Alt Names",
long: "Subject Alternative Names",
},
},
"2.5.29.19": {
name: {
short: undefined,
long: "Basic Constraints",
},
},
"2.5.29.31": {
name: {
short: "CRL Endpoints",
long: "Certificate Revocation List Endpoints",
},
},
"2.5.29.32": {
name: {
short: undefined,
long: "Certificate Policies",
},
},
"2.5.29.35": {
name: {
short: "Authority Key ID",
long: "Authority Key Identifier",
},
},
"2.5.29.37": {
name: {
short: undefined,
long: "Extended Key Usages",
},
},
},
keyUsages: [
"CRL Signing",
"Certificate Signing",
"Key Agreement",
"Data Encipherment",
"Key Encipherment",
"Non-Repudiation",
"Digital Signature",
],
san: [
"Other Name",
"RFC 822 Name",
"DNS Name",
"X.400 Address",
"Directory Name",
"EDI Party Name",
"URI",
"IP Address",
"Registered ID",
],
eKU: {
"1.3.6.1.4.1.311.10.3.1": "Certificate Trust List (CTL) Signing",
"1.3.6.1.4.1.311.10.3.2": "Timestamp Signing",
"1.3.6.1.4.1.311.10.3.4": "EFS Encryption",
"1.3.6.1.4.1.311.10.3.4.1": "EFS Recovery",
"1.3.6.1.4.1.311.10.3.5":
"Windows Hardware Quality Labs (WHQL) Cryptography",
"1.3.6.1.4.1.311.10.3.7": "Windows NT 5 Cryptography",
"1.3.6.1.4.1.311.10.3.8": "Windows NT Embedded Cryptography",
"1.3.6.1.4.1.311.10.3.10": "Qualified Subordination",
"1.3.6.1.4.1.311.10.3.11": "Escrowed Key Recovery",
"1.3.6.1.4.1.311.10.3.12": "Document Signing",
"1.3.6.1.4.1.311.10.5.1": "Digital Rights Management",
"1.3.6.1.4.1.311.10.6.1": "Key Pack Licenses",
"1.3.6.1.4.1.311.10.6.2": "License Server",
"1.3.6.1.4.1.311.20.2.1": "Enrollment Agent",
"1.3.6.1.4.1.311.20.2.2": "Smartcard Login",
"1.3.6.1.4.1.311.21.5": "Certificate Authority Private Key Archival",
"1.3.6.1.4.1.311.21.6": "Key Recovery Agent",
"1.3.6.1.4.1.311.21.19": "Directory Service Email Replication",
"1.3.6.1.5.5.7.3.1": "Server Authentication",
"1.3.6.1.5.5.7.3.2": "Client Authentication",
"1.3.6.1.5.5.7.3.3": "Code Signing",
"1.3.6.1.5.5.7.3.4": "E-mail Protection",
"1.3.6.1.5.5.7.3.5": "IPsec End System",
"1.3.6.1.5.5.7.3.6": "IPsec Tunnel",
"1.3.6.1.5.5.7.3.7": "IPSec User",
"1.3.6.1.5.5.7.3.8": "Timestamping",
"1.3.6.1.5.5.7.3.9": "OCSP Signing",
"1.3.6.1.5.5.8.2.2": "Internet Key Exchange (IKE)",
},
signature: {
"1.2.840.113549.1.1.4": "MD5 with RSA Encryption",
"1.2.840.113549.1.1.5": "SHA-1 with RSA Encryption",
"1.2.840.113549.1.1.11": "SHA-256 with RSA Encryption",
"1.2.840.113549.1.1.12": "SHA-384 with RSA Encryption",
"1.2.840.113549.1.1.13": "SHA-512 with RSA Encryption",
"1.2.840.10040.4.3": "DSA with SHA-1",
"2.16.840.1.101.3.4.3.2": "DSA with SHA-256",
"1.2.840.10045.4.1": "ECDSA with SHA-1",
"1.2.840.10045.4.3.2": "ECDSA with SHA-256",
"1.2.840.10045.4.3.3": "ECDSA with SHA-384",
"1.2.840.10045.4.3.4": "ECDSA with SHA-512",
},
aia: {
"1.3.6.1.5.5.7.48.1": "Online Certificate Status Protocol (OCSP)",
"1.3.6.1.5.5.7.48.2": "CA Issuers",
},
// this includes qualifiers as well
cps: {
"1.3.6.1.4.1": {
name: "Statement Identifier",
value: undefined,
},
"1.3.6.1.5.5.7.2.1": {
name: "Practices Statement",
value: undefined,
},
"1.3.6.1.5.5.7.2.2": {
name: "User Notice",
value: undefined,
},
"2.16.840": {
name: "ANSI Organizational Identifier",
value: undefined,
},
"2.23.140.1.1": {
name: "Certificate Type",
value: "Extended Validation",
},
"2.23.140.1.2.1": {
name: "Certificate Type",
value: "Domain Validation",
},
"2.23.140.1.2.2": {
name: "Certificate Type",
value: "Organization Validation",
},
"2.23.140.1.2.3": {
name: "Certificate Type",
value: "Individual Validation",
},
"2.23.140.1.3": {
name: "Certificate Type",
value: "Extended Validation (Code Signing)",
},
"2.23.140.1.31": {
name: "Certificate Type",
value: ".onion Extended Validation",
},
"2.23.140.2.1": {
name: "Certificate Type",
value: "Test Certificate",
},
},
microsoftCertificateTypes: {
Administrator: "Administrator",
CA: "Root Certification Authority",
CAExchange: "CA Exchange",
CEPEncryption: "CEP Encryption",
CertificateRequestAgent: "Certificate Request Agent",
ClientAuth: "Authenticated Session",
CodeSigning: "Code Signing",
CrossCA: "Cross Certification Authority",
CTLSigning: "Trust List Signing",
DirectoryEmailReplication: "Directory Email Replication",
DomainController: "Domain Controller",
DomainControllerAuthentication: "Domain Controller Authentication",
EFS: "Basic EFS",
EFSRecovery: "EFS Recovery Agent",
EnrollmentAgent: "Enrollment Agent",
EnrollmentAgentOffline: "Exchange Enrollment Agent (Offline request)",
ExchangeUser: "Exchange User",
ExchangeUserSignature: "Exchange Signature Only",
IPSECIntermediateOffline: "IPSec (Offline request)",
IPSECIntermediateOnline: "IPSEC",
KerberosAuthentication: "Kerberos Authentication",
KeyRecoveryAgent: "Key Recovery Agent",
Machine: "Computer",
MachineEnrollmentAgent: "Enrollment Agent (Computer)",
OCSPResponseSigning: "OCSP Response Signing",
OfflineRouter: "Router (Offline request)",
RASAndIASServer: "RAS and IAS Server",
SmartcardLogon: "Smartcard Logon",
SmartcardUser: "Smartcard User",
SubCA: "Subordinate Certification Authority",
User: "User",
UserSignature: "User Signature Only",
WebServer: "Web Server",
Workstation: "Workstation Authentication",
},
};

View File

@ -1,82 +0,0 @@
/* 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 { Integer } = asn1js.asn1js;
const { fromBase64, stringToArrayBuffer } = pvutils.pvutils;
export const b64urltodec = b64 => {
return new Integer({
valueHex: stringToArrayBuffer(fromBase64("AQAB", true, true)),
}).valueBlock._valueDec;
};
export const b64urltohex = b64 => {
const hexBuffer = new Integer({
valueHex: stringToArrayBuffer(fromBase64(b64, true, true)),
}).valueBlock._valueHex;
const hexArray = Array.from(new Uint8Array(hexBuffer));
return hexArray.map(b => ("00" + b.toString(16)).slice(-2));
};
// this particular prototype override makes it easy to chain down complex objects
export const getObjPath = (obj, path) => {
path = path.split(".");
for (let i = 0, len = path.length; i < len; i++) {
if (Array.isArray(obj[path[i]])) {
obj = obj[path[i]][path[i + 1]];
i++;
} else {
obj = obj[path[i]];
}
}
return obj;
};
export const hash = async (algo, buffer) => {
const hashBuffer = await crypto.subtle.digest(algo, buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray
.map(b => ("00" + b.toString(16)).slice(-2))
.join(":")
.toUpperCase();
};
export const hashify = hash => {
if (typeof hash === "string") {
return hash
.match(/.{2}/g)
.join(":")
.toUpperCase();
}
return hash.join(":").toUpperCase();
};
export const pemToDER = pem => {
return stringToArrayBuffer(window.atob(pem));
};
export const normalizeToKebabCase = string => {
let kebabString = string
// Turn all dots into dashes
.replace(/\./g, "-")
// Turn whitespace into dashes
.replace(/\s+/g, "-")
// Remove all non-characters or numbers
.replace(/[^a-z0-9\-]/gi, "")
// De-dupe dashes
.replace(/--/g, "-")
// Remove trailing and leading dashes
.replace(/^-/g, "")
.replace(/-$/g, "")
.toLowerCase();
return kebabString;
};
export const b64ToPEM = string => {
let wrapped = string.match(/.{1,64}/g).join("\r\n");
return `-----BEGIN CERTIFICATE-----\r\n${wrapped}\r\n-----END CERTIFICATE-----\r\n`;
};

View File

@ -1,4 +1,4 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.asn1js = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=globalThis}g.asn1js = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -5875,3 +5875,5 @@ function clearProps(object, propsArray) {
},{}]},{},[1])(1) },{}]},{},[1])(1)
}); });
var asn1js = globalThis.asn1js;
var EXPORTED_SYMBOLS = ["asn1js"];

View File

@ -1,4 +1,4 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pkijs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=globalThis}g.pkijs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
@ -47421,3 +47421,5 @@ module.exports = {
},{"pkijs":111}]},{},[115])(115) },{"pkijs":111}]},{},[115])(115)
}); });
var pkijs = globalThis.pkijs;
var EXPORTED_SYMBOLS = ["pkijs"];

View File

@ -1,4 +1,4 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pvutils = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=globalThis}g.pvutils = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
@ -789,3 +789,5 @@ module.exports = {
},{"pvutils":1}]},{},[2])(2) },{"pvutils":1}]},{},[2])(2)
}); });
var pvutils = globalThis.pvutils;
var EXPORTED_SYMBOLS = ["pvutils"];

View File

@ -3,28 +3,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar: toolkit.jar:
content/global/certviewer/certviewer.html (content/certviewer.html) content/global/certviewer/certviewer.html (content/certviewer.html)
content/global/certviewer/certviewer.css (content/certviewer.css) content/global/certviewer/certviewer.css (content/certviewer.css)
content/global/certviewer/certviewer.js (content/certviewer.js) content/global/certviewer/certviewer.js (content/certviewer.js)
content/global/certviewer/components/about-certificate-section.js (content/components/about-certificate-section.js) content/global/certviewer/components/ (content/components/*.js)
content/global/certviewer/components/about-certificate-section.css (content/components/about-certificate-section.css) content/global/certviewer/components/ (content/components/*.css)
content/global/certviewer/components/about-certificate-items.js (content/components/about-certificate-items.js) content/global/certviewer/certDecoder.js (content/certDecoder.js)
content/global/certviewer/components/certificate-section.js (content/components/certificate-section.js) content/global/certviewer/pvutils_bundle.js (content/vendor/pvutils_bundle.js)
content/global/certviewer/components/certificate-tabs-section.js (content/components/certificate-tabs-section.js) content/global/certviewer/asn1js_bundle.js (content/vendor/asn1js_bundle.js)
content/global/certviewer/components/certificate-section.css (content/components/certificate-section.css) content/global/certviewer/pkijs_bundle.js (content/vendor/pkijs_bundle.js)
content/global/certviewer/components/error-section.js (content/components/error-section.js)
content/global/certviewer/components/error-section.css (content/components/error-section.css)
content/global/certviewer/components/info-group.js (content/components/info-group.js)
content/global/certviewer/components/info-group.css (content/components/info-group.css)
content/global/certviewer/components/info-group-container.js (content/components/info-group-container.js)
content/global/certviewer/components/info-item.js (content/components/info-item.js)
content/global/certviewer/components/info-item.css (content/components/info-item.css)
content/global/certviewer/components/list-item.js (content/components/list-item.js)
content/global/certviewer/components/list-item.css (content/components/list-item.css)
content/global/certviewer/certDecoder.js (content/certDecoder.js)
content/global/certviewer/strings.js (content/strings.js)
content/global/certviewer/ctlognames.js (content/ctlognames.js)
content/global/certviewer/utils.js (content/utils.js)
content/global/certviewer/pvutils_bundle.js (content/vendor/pvutils_bundle.js)
content/global/certviewer/asn1js_bundle.js (content/vendor/asn1js_bundle.js)
content/global/certviewer/pkijs_bundle.js (content/vendor/pkijs_bundle.js)

View File

@ -4,10 +4,6 @@
<title>certviewer adjustCertInformation test</title> <title>certviewer adjustCertInformation test</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://global/content/certviewer/pvutils_bundle.js"></script>
<script src="chrome://global/content/certviewer/asn1js_bundle.js"></script>
<script src="chrome://global/content/certviewer/pkijs_bundle.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head> </head>
<body> <body>

View File

@ -4,16 +4,27 @@
<title>certviewer parse test</title> <title>certviewer parse test</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://global/content/certviewer/pvutils_bundle.js"></script>
<script src="chrome://global/content/certviewer/asn1js_bundle.js"></script>
<script src="chrome://global/content/certviewer/pkijs_bundle.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head> </head>
<body> <body>
<script type="module"> <script type="module">
import { parse } from "chrome://global/content/certviewer/certDecoder.js"; import "chrome://global/content/certviewer/pvutils_bundle.js";
import { pemToDER } from "chrome://global/content/certviewer/utils.js"; import "chrome://global/content/certviewer/asn1js_bundle.js";
import "chrome://global/content/certviewer/pkijs_bundle.js";
import "chrome://global/content/certviewer/certDecoder.js";
const { Integer, fromBER } = globalThis.asn1js.asn1js;
const { Certificate } = globalThis.pkijs.pkijs;
const { fromBase64, stringToArrayBuffer } = globalThis.pvutils.pvutils;
const { parse, pemToDER } = globalThis.certDecoderInitializer(
Integer,
fromBER,
Certificate,
fromBase64,
stringToArrayBuffer,
crypto
);
// inputPEM is the same input to CS extension (https://github.com/april/certainly-something) // inputPEM is the same input to CS extension (https://github.com/april/certainly-something)
const inputPEM = "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"; const inputPEM = "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";

View File

@ -4,17 +4,29 @@
<title>certviewer parse test</title> <title>certviewer parse test</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://global/content/certviewer/pvutils_bundle.js"></script>
<script src="chrome://global/content/certviewer/asn1js_bundle.js"></script>
<script src="chrome://global/content/certviewer/pkijs_bundle.js"></script>
<script type="module" src="CSoutput.js"></script> <script type="module" src="CSoutput.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head> </head>
<body> <body>
<script type="module"> <script type="module">
import { parse } from "chrome://global/content/certviewer/certDecoder.js"; import "chrome://global/content/certviewer/pvutils_bundle.js";
import { pemToDER } from "chrome://global/content/certviewer/utils.js"; import "chrome://global/content/certviewer/asn1js_bundle.js";
import "chrome://global/content/certviewer/pkijs_bundle.js";
import "chrome://global/content/certviewer/certDecoder.js";
const { Integer, fromBER } = globalThis.asn1js.asn1js;
const { Certificate } = globalThis.pkijs.pkijs;
const { fromBase64, stringToArrayBuffer } = globalThis.pvutils.pvutils;
const { parse, pemToDER } = globalThis.certDecoderInitializer(
Integer,
fromBER,
Certificate,
fromBase64,
stringToArrayBuffer,
crypto
);
import { certOutputCS } from "./CSoutput.js"; import { certOutputCS } from "./CSoutput.js";
// inputPEM is the same input to CS extension (https://github.com/april/certainly-something) // inputPEM is the same input to CS extension (https://github.com/april/certainly-something)

View File

@ -4,10 +4,6 @@
<title>certviewer adjustCertInformation test</title> <title>certviewer adjustCertInformation test</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://global/content/certviewer/pvutils_bundle.js"></script>
<script src="chrome://global/content/certviewer/asn1js_bundle.js"></script>
<script src="chrome://global/content/certviewer/pkijs_bundle.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head> </head>
<body> <body>