michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0:
michael@0: const Ci = Components.interfaces;
michael@0: const Cu = Components.utils;
michael@0: const Cc = Components.classes;
michael@0:
michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0: Cu.import("resource://gre/modules/Services.jsm");
michael@0: Cu.import("resource://gre/modules/Prompt.jsm");
michael@0:
michael@0: // -----------------------------------------------------------------------
michael@0: // NSS Dialog Service
michael@0: // -----------------------------------------------------------------------
michael@0:
michael@0: function dump(a) {
michael@0: Components.classes["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
michael@0: }
michael@0:
michael@0: function NSSDialogs() { }
michael@0:
michael@0: NSSDialogs.prototype = {
michael@0: classID: Components.ID("{cbc08081-49b6-4561-9c18-a7707a50bda1}"),
michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsICertificateDialogs, Ci.nsIClientAuthDialogs]),
michael@0:
michael@0: getString: function(aName) {
michael@0: if (!this.bundle) {
michael@0: this.bundle = Services.strings.createBundle("chrome://browser/locale/pippki.properties");
michael@0: }
michael@0: return this.bundle.GetStringFromName(aName);
michael@0: },
michael@0:
michael@0: formatString: function(aName, argList) {
michael@0: if (!this.bundle) {
michael@0: this.bundle = Services.strings.createBundle("chrome://browser/locale/pippki.properties");
michael@0: }
michael@0: return this.bundle.formatStringFromName(aName, argList, 1);
michael@0: },
michael@0:
michael@0: getPrompt: function(aTitle, aText, aButtons) {
michael@0: return new Prompt({
michael@0: title: aTitle,
michael@0: text: aText,
michael@0: buttons: aButtons,
michael@0: });
michael@0: },
michael@0:
michael@0: showPrompt: function(aPrompt) {
michael@0: let response = null;
michael@0: aPrompt.show(function(data) {
michael@0: response = data;
michael@0: });
michael@0:
michael@0: // Spin this thread while we wait for a result
michael@0: let thread = Services.tm.currentThread;
michael@0: while (response === null)
michael@0: thread.processNextEvent(true);
michael@0:
michael@0: return response;
michael@0: },
michael@0:
michael@0: confirmDownloadCACert: function(aCtx, aCert, aTrust) {
michael@0: while (true) {
michael@0: let prompt = this.getPrompt(this.getString("downloadCert.title"),
michael@0: this.getString("downloadCert.message1"),
michael@0: [ this.getString("nssdialogs.ok.label"),
michael@0: this.getString("downloadCert.viewCert.label"),
michael@0: this.getString("nssdialogs.cancel.label")
michael@0: ]);
michael@0:
michael@0: prompt.addCheckbox({ id: "trustSSL", label: this.getString("downloadCert.trustSSL"), checked: false })
michael@0: .addCheckbox({ id: "trustEmail", label: this.getString("downloadCert.trustEmail"), checked: false })
michael@0: .addCheckbox({ id: "trustSign", label: this.getString("downloadCert.trustObjSign"), checked: false });
michael@0: let response = this.showPrompt(prompt);
michael@0:
michael@0: // they hit the "view cert" button, so show the cert and try again
michael@0: if (response.button == 1) {
michael@0: this.viewCert(aCtx, aCert);
michael@0: continue;
michael@0: } else if (response.button != 0) {
michael@0: return false;
michael@0: }
michael@0:
michael@0: aTrust.value = Ci.nsIX509CertDB.UNTRUSTED;
michael@0: if (response.trustSSL == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_SSL;
michael@0: if (response.trustEmail == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_EMAIL;
michael@0: if (response.trustSign == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_OBJSIGN;
michael@0: return true;
michael@0: }
michael@0: },
michael@0:
michael@0: notifyCACertExists: function(aCtx) {
michael@0: let p = this.getPrompt(this.getString("caCertExists.title"), this.getString("caCertExists.message"));
michael@0: this.showPrompt(p);
michael@0: },
michael@0:
michael@0: setPKCS12FilePassword: function(aCtx, aPassword) {
michael@0: // this dialog is never shown in Fennec; in Desktop it is shown while backing up a personal
michael@0: // certificate to a file via Preferences->Advanced->Encryption->View Certificates->Your Certificates
michael@0: throw "Unimplemented";
michael@0: },
michael@0:
michael@0: getPKCS12FilePassword: function(aCtx, aPassword) {
michael@0: let prompt = this.getPrompt(this.getString("pkcs12.getpassword.title"),
michael@0: this.getString("pkcs12.getpassword.message"),
michael@0: [ this.getString("nssdialogs.ok.label"),
michael@0: this.getString("nssdialogs.cancel.label")
michael@0: ]).addPassword({id: "pw"});
michael@0: let response = this.showPrompt(prompt);
michael@0: if (response.button != 0) {
michael@0: return false;
michael@0: }
michael@0:
michael@0: aPassword.value = response.pw;
michael@0: return true;
michael@0: },
michael@0:
michael@0: certInfoSection: function(aHeading, aDataPairs, aTrailingNewline = true) {
michael@0: var str = "" + this.getString(aHeading) + "
";
michael@0: for (var i = 0; i < aDataPairs.length; i += 2) {
michael@0: str += this.getString(aDataPairs[i]) + ": " + aDataPairs[i+1] + "
";
michael@0: }
michael@0: return str + (aTrailingNewline ? "
" : "");
michael@0: },
michael@0:
michael@0: viewCert: function(aCtx, aCert) {
michael@0: let p = this.getPrompt(this.getString("certmgr.title"),
michael@0: "",
michael@0: [ this.getString("nssdialogs.ok.label") ])
michael@0: p.addLabel({ label: this.certInfoSection("certmgr.subjectinfo.label",
michael@0: ["certmgr.certdetail.cn", aCert.commonName,
michael@0: "certmgr.certdetail.o", aCert.organization,
michael@0: "certmgr.certdetail.ou", aCert.organizationalUnit,
michael@0: "certmgr.certdetail.serialnumber", aCert.serialNumber])})
michael@0: .addLabel({ label: this.certInfoSection("certmgr.issuerinfo.label",
michael@0: ["certmgr.certdetail.cn", aCert.issuerCommonName,
michael@0: "certmgr.certdetail.o", aCert.issuerOrganization,
michael@0: "certmgr.certdetail.ou", aCert.issuerOrganizationUnit])})
michael@0: .addLabel({ label: this.certInfoSection("certmgr.periodofvalidity.label",
michael@0: ["certmgr.begins", aCert.validity.notBeforeLocalDay,
michael@0: "certmgr.expires", aCert.validity.notAfterLocalDay])})
michael@0: .addLabel({ label: this.certInfoSection("certmgr.fingerprints.label",
michael@0: ["certmgr.certdetail.sha1fingerprint", aCert.sha1Fingerprint,
michael@0: "certmgr.certdetail.md5fingerprint", aCert.md5Fingerprint], false) });
michael@0: this.showPrompt(p);
michael@0: },
michael@0:
michael@0: viewCertDetails: function(details) {
michael@0: let p = this.getPrompt(this.getString("clientAuthAsk.message3"),
michael@0: '',
michael@0: [ this.getString("nssdialogs.ok.label") ]);
michael@0: p.addLabel({ label: details });
michael@0: this.showPrompt(p);
michael@0: },
michael@0:
michael@0: ChooseCertificate: function(aCtx, cn, organization, issuer, certNickList, certDetailsList, count, selectedIndex, canceled) {
michael@0: let rememberSetting = true;
michael@0: var pref = Cc['@mozilla.org/preferences-service;1']
michael@0: .getService(Components.interfaces.nsIPrefService);
michael@0: if (pref) {
michael@0: pref = pref.getBranch(null);
michael@0: try {
michael@0: rememberSetting = pref.getBoolPref("security.remember_cert_checkbox_default_setting");
michael@0: } catch (e) {
michael@0: // pref is missing
michael@0: }
michael@0: }
michael@0:
michael@0: let organizationString = this.formatString("clientAuthAsk.organization",
michael@0: [organization]);
michael@0: let issuerString = this.formatString("clientAuthAsk.issuer",
michael@0: [issuer]);
michael@0: let serverRequestedDetails = cn + '
' + organizationString + '
' + issuerString;
michael@0:
michael@0: selectedIndex = 0;
michael@0: while (true) {
michael@0: let prompt = this.getPrompt(this.getString("clientAuthAsk.title"),
michael@0: this.getString("clientAuthAsk.message1"),
michael@0: [ this.getString("nssdialogs.ok.label"),
michael@0: this.getString("clientAuthAsk.viewCert.label"),
michael@0: this.getString("nssdialogs.cancel.label")
michael@0: ])
michael@0: .addLabel({ id: "requestedDetails", label: serverRequestedDetails } )
michael@0: .addMenulist({
michael@0: id: "nicknames",
michael@0: label: this.getString("clientAuthAsk.message2"),
michael@0: values: certNickList, selected: selectedIndex
michael@0: }).addCheckbox({
michael@0: id: "rememberBox",
michael@0: label: this.getString("clientAuthAsk.remember.label"),
michael@0: checked: rememberSetting
michael@0: });
michael@0: let response = this.showPrompt(prompt);
michael@0: selectedIndex = response.nicknames;
michael@0: if (response.button == 1) {
michael@0: this.viewCertDetails(certDetailsList[selectedIndex]);
michael@0: continue;
michael@0: } else if (response.button == 0) {
michael@0: canceled.value = false;
michael@0: if (response.rememberBox == "true") {
michael@0: aCtx.QueryInterface(Ci.nsIClientAuthUserDecision).rememberClientAuthCertificate = true;
michael@0: }
michael@0: return true;
michael@0: }
michael@0: canceled.value = true;
michael@0: return false;
michael@0: }
michael@0: }
michael@0: };
michael@0:
michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NSSDialogs]);