mirror of
https://github.com/ManchildProductions/UXP-Fixed.git
synced 2026-06-29 00:41:02 +00:00
225 lines
8.6 KiB
JavaScript
225 lines
8.6 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
"use strict";
|
|
|
|
// Repeatedly opens the certificate viewer dialog with various certificates and
|
|
// determines that the viewer correctly identifies either what usages those
|
|
// certificates are valid for or what errors prevented the certificates from
|
|
// being verified.
|
|
|
|
var { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
|
|
|
|
add_task(function* testCAandTitle() {
|
|
let cert = yield readCertificate("ca.pem", "CTu,CTu,CTu");
|
|
let win = yield displayCertificate(cert);
|
|
checkUsages(win, ["SSL Certificate Authority"]);
|
|
|
|
// There's no real need to test the title for every cert, so we just test it
|
|
// once here.
|
|
Assert.equal(win.document.title, "Certificate Viewer: \u201Cca\u201D",
|
|
"Actual and expected title should match");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testSSLEndEntity() {
|
|
let cert = yield readCertificate("ssl-ee.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkUsages(win, ["SSL Server Certificate", "SSL Client Certificate"]);
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testEmailEndEntity() {
|
|
let cert = yield readCertificate("email-ee.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkUsages(win, ["Email Recipient Certificate", "Email Signer Certificate"]);
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testCodeSignEndEntity() {
|
|
let cert = yield readCertificate("code-ee.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkUsages(win, ["Object Signer"]);
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testExpired() {
|
|
let cert = yield readCertificate("expired-ca.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win, "Could not verify this certificate because it has expired.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testIssuerExpired() {
|
|
let cert = yield readCertificate("ee-from-expired-ca.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win,
|
|
"Could not verify this certificate because the CA certificate " +
|
|
"is invalid.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testUnknownIssuer() {
|
|
let cert = yield readCertificate("unknown-issuer.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win,
|
|
"Could not verify this certificate because the issuer is " +
|
|
"unknown.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testInsecureAlgo() {
|
|
let cert = yield readCertificate("md5-ee.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win,
|
|
"Could not verify this certificate because it was signed using " +
|
|
"a signature algorithm that was disabled because that algorithm " +
|
|
"is not secure.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testUntrusted() {
|
|
let cert = yield readCertificate("untrusted-ca.pem", "p,p,p");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win,
|
|
"Could not verify this certificate because it is not trusted.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testUntrustedIssuer() {
|
|
let cert = yield readCertificate("ee-from-untrusted-ca.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win,
|
|
"Could not verify this certificate because the issuer is not " +
|
|
"trusted.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testRevoked() {
|
|
// Note that there's currently no way to un-do this. This should only be a
|
|
// problem if another test re-uses a certificate with this same key (perhaps
|
|
// likely) and subject (less likely).
|
|
let certBlocklist = Cc["@mozilla.org/security/certblocklist;1"]
|
|
.getService(Ci.nsICertBlocklist);
|
|
certBlocklist.revokeCertBySubjectAndPubKey(
|
|
"MBIxEDAOBgNVBAMMB3Jldm9rZWQ=", // CN=revoked
|
|
"VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="); // hash of the shared key
|
|
let cert = yield readCertificate("revoked.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
// As of bug 1312827, OneCRL only applies to TLS web server certificates, so
|
|
// this certificate will actually verify successfully for every end-entity
|
|
// usage except TLS web server.
|
|
checkUsages(win, ["Email Recipient Certificate", "Email Signer Certificate",
|
|
"Object Signer", "SSL Client Certificate"]);
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
add_task(function* testInvalid() {
|
|
// This certificate has a keyUsage extension asserting cRLSign and
|
|
// keyCertSign, but it doesn't have a basicConstraints extension. This
|
|
// shouldn't be valid for any usage. Sadly, we give a pretty lame error
|
|
// message in this case.
|
|
let cert = yield readCertificate("invalid.pem", ",,");
|
|
let win = yield displayCertificate(cert);
|
|
checkError(win, "Could not verify this certificate for unknown reasons.");
|
|
yield BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
/**
|
|
* Given a certificate, returns a promise that will resolve when the certificate
|
|
* viewer has opened is displaying that certificate, and has finished
|
|
* determining its valid usages.
|
|
*
|
|
* @param {nsIX509Cert} certificate
|
|
* The certificate to view and determine usages for.
|
|
* @return {Promise}
|
|
* A promise that will resolve with a handle on the opened certificate
|
|
* viewer window when the usages have been determined.
|
|
*/
|
|
function displayCertificate(certificate) {
|
|
let win = window.openDialog("chrome://pippki/content/certViewer.xul", "",
|
|
"", certificate);
|
|
return TestUtils.topicObserved("ViewCertDetails:CertUsagesDone",
|
|
(subject, data) => subject == win)
|
|
.then(([subject, data]) => subject, error => { throw error; });
|
|
}
|
|
|
|
/**
|
|
* Given a certificate viewer window, finds the usages the certificate is valid
|
|
* for.
|
|
*
|
|
* @param {window} win
|
|
* The certificate viewer window.
|
|
* @return {String[]}
|
|
* An array of strings describing the usages the certificate is valid
|
|
* for.
|
|
*/
|
|
function getUsages(win) {
|
|
let determinedUsages = [];
|
|
let verifyInfoBox = win.document.getElementById("verify_info_box");
|
|
Array.from(verifyInfoBox.children).forEach(child => {
|
|
if (child.getAttribute("hidden") != "true" &&
|
|
child.getAttribute("id") != "verified") {
|
|
determinedUsages.push(child.getAttribute("value"));
|
|
}
|
|
});
|
|
return determinedUsages.sort();
|
|
}
|
|
|
|
/**
|
|
* Given a certificate viewer window, returns the error string describing a
|
|
* failure encountered when determining the certificate's usages. It will be
|
|
* "This certificate has been verified for the following uses:" when the
|
|
* certificate has successfully verified for at least one usage.
|
|
*
|
|
* @param {window} win
|
|
* The certificate viewer window.
|
|
* @return {String}
|
|
* A string describing the error encountered, or the success message if
|
|
* the certificate is valid for at least one usage.
|
|
*/
|
|
function getError(win) {
|
|
return win.document.getElementById("verified").textContent;
|
|
}
|
|
|
|
/**
|
|
* Given a certificate viewer window and an array of expected usage
|
|
* descriptions, verifies that the window is actually showing that the
|
|
* certificate has validated for those usages.
|
|
*
|
|
* @param {window} win
|
|
* The certificate viewer window.
|
|
* @param {String[]} usages
|
|
* An array of expected usage descriptions.
|
|
*/
|
|
function checkUsages(win, usages) {
|
|
Assert.equal(getError(win),
|
|
"This certificate has been verified for the following uses:",
|
|
"should have successful verification message");
|
|
let determinedUsages = getUsages(win);
|
|
usages.sort();
|
|
Assert.equal(determinedUsages.length, usages.length,
|
|
"number of usages as determined by cert viewer should be equal");
|
|
while (usages.length > 0) {
|
|
Assert.equal(determinedUsages.pop(), usages.pop(),
|
|
"usages as determined by cert viewer should be equal");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Given a certificate viewer window and an expected error, verifies that the
|
|
* window is actually showing that error.
|
|
*
|
|
* @param {window} win
|
|
* The certificate viewer window.
|
|
* @param {String} error
|
|
* The expected error message.
|
|
*/
|
|
function checkError(win, error) {
|
|
let determinedUsages = getUsages(win);
|
|
Assert.equal(determinedUsages.length, 0,
|
|
"should not have any successful usages in error case");
|
|
Assert.equal(getError(win), error,
|
|
"determined error should be the same as expected error");
|
|
}
|