Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// Any copyright is dedicated to the Public Domain.
"use strict";
// Tests that a CA certificate can still be imported if the user has a primary
// password set.
do_get_profile();
const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
const CA_CERT_COMMON_NAME = "importedCA";
let gCACertImportDialogCount = 0;
// Mock implementation of nsICertificateDialogs.
const gCertificateDialogs = {
confirmDownloadCACert: (ctx, cert, trust) => {
gCACertImportDialogCount++;
equal(
cert.commonName,
CA_CERT_COMMON_NAME,
"CA cert to import should have the correct CN"
);
trust.value = Ci.nsIX509CertDB.TRUSTED_EMAIL;
return true;
},
setPKCS12FilePassword: () => {
// This is only relevant to exporting.
ok(false, "setPKCS12FilePassword() should not have been called");
},
getPKCS12FilePassword: () => {
// We don't test anything that calls this method yet.
ok(false, "getPKCS12FilePassword() should not have been called");
},
QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]),
};
var gMockPrompter = {
passwordToTry: "password",
numPrompts: 0,
// This intentionally does not use arrow function syntax to avoid an issue
// where in the context of the arrow function, |this != gMockPrompter| due to
// how objects get wrapped when going across xpcom boundaries.
promptPassword(dialogTitle, text, password, checkMsg) {
this.numPrompts++;
if (this.numPrompts > 1) {
// don't keep retrying a bad password
return false;
}
equal(
text,
"Please enter your Primary Password.",
"password prompt text should be as expected"
);
equal(checkMsg, null, "checkMsg should be null");
ok(this.passwordToTry, "passwordToTry should be non-null");
password.value = this.passwordToTry;
return true;
},
QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]),
// Again with the arrow function issue.
getInterface(iid) {
if (iid.equals(Ci.nsIPrompt)) {
return this;
}
throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
},
};
function getCertAsByteArray(certPath) {
let certFile = do_get_file(certPath, false);
let certBytes = readFile(certFile);
let byteArray = [];
for (let i = 0; i < certBytes.length; i++) {
byteArray.push(certBytes.charCodeAt(i));
}
return byteArray;
}
function findCertByCommonName(commonName) {
for (let cert of gCertDB.getCerts()) {
if (cert.commonName == commonName) {
return cert;
}
}
return null;
}
function run_test() {
let certificateDialogsCID = MockRegistrar.register(
"@mozilla.org/nsCertificateDialogs;1",
gCertificateDialogs
);
registerCleanupFunction(() => {
MockRegistrar.unregister(certificateDialogsCID);
});
// Set a primary password.
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
Ci.nsIPK11TokenDB
);
let token = tokenDB.getInternalKeyToken();
token.initPassword("password");
token.logoutSimple();
// Sanity check the CA cert is missing.
equal(
findCertByCommonName(CA_CERT_COMMON_NAME),
null,
"CA cert should not be in the database before import"
);
// Import and check for success.
let caArray = getCertAsByteArray("test_certDB_import/importedCA.pem");
gCertDB.importCertificates(
caArray,
caArray.length,
Ci.nsIX509Cert.CA_CERT,
gMockPrompter
);
equal(
gCACertImportDialogCount,
1,
"Confirmation dialog for the CA cert should only be shown once"
);
let caCert = findCertByCommonName(CA_CERT_COMMON_NAME);
notEqual(caCert, null, "CA cert should now be found in the database");
ok(
gCertDB.isCertTrusted(
caCert,
Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_EMAIL
),
"CA cert should be trusted for e-mail"
);
}