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 exporting a certificate and key as a PKCS#12 blob if the user has a
// primary password set.
do_get_profile();
const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx";
const CERT_COMMON_NAME = "test_cert_from_windows";
const TEST_CERT_PASSWORD = "黒い";
var gPrompt = {
password: "password",
clickOk: true,
QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]),
// This intentionally does not use arrow function syntax to avoid an issue
// where in the context of the arrow function, |this != gPrompt| due to
// how objects get wrapped when going across xpcom boundaries.
alert(title, text) {
info(`alert('${text}')`);
ok(false, "not expecting alert() to be called");
},
promptPassword(dialogTitle, text, password, checkMsg) {
equal(
text,
"Please enter your Primary Password.",
"password prompt text should be as expected"
);
equal(checkMsg, null, "checkMsg should be null");
password.value = this.password;
return this.clickOk;
},
};
const gPromptFactory = {
QueryInterface: ChromeUtils.generateQI(["nsIPromptFactory"]),
getPrompt: () => gPrompt,
};
function findCertByCommonName(commonName) {
for (let cert of gCertDB.getCerts()) {
if (cert.commonName == commonName) {
return cert;
}
}
return null;
}
function run_test() {
let promptFactoryCID = MockRegistrar.register(
"@mozilla.org/prompter;1",
gPromptFactory
);
registerCleanupFunction(() => {
MockRegistrar.unregister(promptFactoryCID);
});
// Set a primary password.
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
Ci.nsIPK11TokenDB
);
let token = tokenDB.getInternalKeyToken();
token.initPassword("password");
token.logoutSimple();
// Import the certificate and key so we have something to export.
let cert = findCertByCommonName(CERT_COMMON_NAME);
equal(cert, null, "cert should not be found before import");
let certFile = do_get_file(PKCS12_FILE);
ok(certFile, `${PKCS12_FILE} should exist`);
let errorCode = gCertDB.importPKCS12File(certFile, TEST_CERT_PASSWORD);
equal(errorCode, Ci.nsIX509CertDB.Success, "cert should import");
cert = findCertByCommonName(CERT_COMMON_NAME);
notEqual(cert, null, "cert should be found now");
// Log out so we're prompted for the password.
token.logoutSimple();
// Export the certificate and key (and don't cancel the password request
// dialog).
let output = do_get_tempdir();
output.append("output.p12");
ok(!output.exists(), "output shouldn't exist before exporting PKCS12 file");
errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD);
equal(errorCode, Ci.nsIX509CertDB.Success, "cert should export");
ok(output.exists(), "output should exist after exporting PKCS12 file");
output.remove(false /* not a directory; recursive doesn't apply */);
// Log out again so we're prompted for the password.
token.logoutSimple();
// Attempt to export the certificate and key, but this time cancel the
// password request dialog. The export operation should also be canceled.
gPrompt.clickOk = false;
let output2 = do_get_tempdir();
output2.append("output2.p12");
ok(!output2.exists(), "output2 shouldn't exist before exporting PKCS12 file");
errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD);
equal(
errorCode,
Ci.nsIX509CertDB.ERROR_PKCS12_BACKUP_FAILED,
"cert should not export"
);
ok(!output2.exists(), "output2 shouldn't exist after failing to export");
}