|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const Ci = Components.interfaces; |
|
6 const Cu = Components.utils; |
|
7 const Cc = Components.classes; |
|
8 |
|
9 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
10 Cu.import("resource://gre/modules/Services.jsm"); |
|
11 Cu.import("resource://gre/modules/Prompt.jsm"); |
|
12 |
|
13 // ----------------------------------------------------------------------- |
|
14 // NSS Dialog Service |
|
15 // ----------------------------------------------------------------------- |
|
16 |
|
17 function dump(a) { |
|
18 Components.classes["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a); |
|
19 } |
|
20 |
|
21 function NSSDialogs() { } |
|
22 |
|
23 NSSDialogs.prototype = { |
|
24 classID: Components.ID("{cbc08081-49b6-4561-9c18-a7707a50bda1}"), |
|
25 QueryInterface: XPCOMUtils.generateQI([Ci.nsICertificateDialogs, Ci.nsIClientAuthDialogs]), |
|
26 |
|
27 getString: function(aName) { |
|
28 if (!this.bundle) { |
|
29 this.bundle = Services.strings.createBundle("chrome://browser/locale/pippki.properties"); |
|
30 } |
|
31 return this.bundle.GetStringFromName(aName); |
|
32 }, |
|
33 |
|
34 formatString: function(aName, argList) { |
|
35 if (!this.bundle) { |
|
36 this.bundle = Services.strings.createBundle("chrome://browser/locale/pippki.properties"); |
|
37 } |
|
38 return this.bundle.formatStringFromName(aName, argList, 1); |
|
39 }, |
|
40 |
|
41 getPrompt: function(aTitle, aText, aButtons) { |
|
42 return new Prompt({ |
|
43 title: aTitle, |
|
44 text: aText, |
|
45 buttons: aButtons, |
|
46 }); |
|
47 }, |
|
48 |
|
49 showPrompt: function(aPrompt) { |
|
50 let response = null; |
|
51 aPrompt.show(function(data) { |
|
52 response = data; |
|
53 }); |
|
54 |
|
55 // Spin this thread while we wait for a result |
|
56 let thread = Services.tm.currentThread; |
|
57 while (response === null) |
|
58 thread.processNextEvent(true); |
|
59 |
|
60 return response; |
|
61 }, |
|
62 |
|
63 confirmDownloadCACert: function(aCtx, aCert, aTrust) { |
|
64 while (true) { |
|
65 let prompt = this.getPrompt(this.getString("downloadCert.title"), |
|
66 this.getString("downloadCert.message1"), |
|
67 [ this.getString("nssdialogs.ok.label"), |
|
68 this.getString("downloadCert.viewCert.label"), |
|
69 this.getString("nssdialogs.cancel.label") |
|
70 ]); |
|
71 |
|
72 prompt.addCheckbox({ id: "trustSSL", label: this.getString("downloadCert.trustSSL"), checked: false }) |
|
73 .addCheckbox({ id: "trustEmail", label: this.getString("downloadCert.trustEmail"), checked: false }) |
|
74 .addCheckbox({ id: "trustSign", label: this.getString("downloadCert.trustObjSign"), checked: false }); |
|
75 let response = this.showPrompt(prompt); |
|
76 |
|
77 // they hit the "view cert" button, so show the cert and try again |
|
78 if (response.button == 1) { |
|
79 this.viewCert(aCtx, aCert); |
|
80 continue; |
|
81 } else if (response.button != 0) { |
|
82 return false; |
|
83 } |
|
84 |
|
85 aTrust.value = Ci.nsIX509CertDB.UNTRUSTED; |
|
86 if (response.trustSSL == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_SSL; |
|
87 if (response.trustEmail == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_EMAIL; |
|
88 if (response.trustSign == "true") aTrust.value |= Ci.nsIX509CertDB.TRUSTED_OBJSIGN; |
|
89 return true; |
|
90 } |
|
91 }, |
|
92 |
|
93 notifyCACertExists: function(aCtx) { |
|
94 let p = this.getPrompt(this.getString("caCertExists.title"), this.getString("caCertExists.message")); |
|
95 this.showPrompt(p); |
|
96 }, |
|
97 |
|
98 setPKCS12FilePassword: function(aCtx, aPassword) { |
|
99 // this dialog is never shown in Fennec; in Desktop it is shown while backing up a personal |
|
100 // certificate to a file via Preferences->Advanced->Encryption->View Certificates->Your Certificates |
|
101 throw "Unimplemented"; |
|
102 }, |
|
103 |
|
104 getPKCS12FilePassword: function(aCtx, aPassword) { |
|
105 let prompt = this.getPrompt(this.getString("pkcs12.getpassword.title"), |
|
106 this.getString("pkcs12.getpassword.message"), |
|
107 [ this.getString("nssdialogs.ok.label"), |
|
108 this.getString("nssdialogs.cancel.label") |
|
109 ]).addPassword({id: "pw"}); |
|
110 let response = this.showPrompt(prompt); |
|
111 if (response.button != 0) { |
|
112 return false; |
|
113 } |
|
114 |
|
115 aPassword.value = response.pw; |
|
116 return true; |
|
117 }, |
|
118 |
|
119 certInfoSection: function(aHeading, aDataPairs, aTrailingNewline = true) { |
|
120 var str = "<big>" + this.getString(aHeading) + "</big><br/>"; |
|
121 for (var i = 0; i < aDataPairs.length; i += 2) { |
|
122 str += this.getString(aDataPairs[i]) + ": " + aDataPairs[i+1] + "<br/>"; |
|
123 } |
|
124 return str + (aTrailingNewline ? "<br/>" : ""); |
|
125 }, |
|
126 |
|
127 viewCert: function(aCtx, aCert) { |
|
128 let p = this.getPrompt(this.getString("certmgr.title"), |
|
129 "", |
|
130 [ this.getString("nssdialogs.ok.label") ]) |
|
131 p.addLabel({ label: this.certInfoSection("certmgr.subjectinfo.label", |
|
132 ["certmgr.certdetail.cn", aCert.commonName, |
|
133 "certmgr.certdetail.o", aCert.organization, |
|
134 "certmgr.certdetail.ou", aCert.organizationalUnit, |
|
135 "certmgr.certdetail.serialnumber", aCert.serialNumber])}) |
|
136 .addLabel({ label: this.certInfoSection("certmgr.issuerinfo.label", |
|
137 ["certmgr.certdetail.cn", aCert.issuerCommonName, |
|
138 "certmgr.certdetail.o", aCert.issuerOrganization, |
|
139 "certmgr.certdetail.ou", aCert.issuerOrganizationUnit])}) |
|
140 .addLabel({ label: this.certInfoSection("certmgr.periodofvalidity.label", |
|
141 ["certmgr.begins", aCert.validity.notBeforeLocalDay, |
|
142 "certmgr.expires", aCert.validity.notAfterLocalDay])}) |
|
143 .addLabel({ label: this.certInfoSection("certmgr.fingerprints.label", |
|
144 ["certmgr.certdetail.sha1fingerprint", aCert.sha1Fingerprint, |
|
145 "certmgr.certdetail.md5fingerprint", aCert.md5Fingerprint], false) }); |
|
146 this.showPrompt(p); |
|
147 }, |
|
148 |
|
149 viewCertDetails: function(details) { |
|
150 let p = this.getPrompt(this.getString("clientAuthAsk.message3"), |
|
151 '', |
|
152 [ this.getString("nssdialogs.ok.label") ]); |
|
153 p.addLabel({ label: details }); |
|
154 this.showPrompt(p); |
|
155 }, |
|
156 |
|
157 ChooseCertificate: function(aCtx, cn, organization, issuer, certNickList, certDetailsList, count, selectedIndex, canceled) { |
|
158 let rememberSetting = true; |
|
159 var pref = Cc['@mozilla.org/preferences-service;1'] |
|
160 .getService(Components.interfaces.nsIPrefService); |
|
161 if (pref) { |
|
162 pref = pref.getBranch(null); |
|
163 try { |
|
164 rememberSetting = pref.getBoolPref("security.remember_cert_checkbox_default_setting"); |
|
165 } catch (e) { |
|
166 // pref is missing |
|
167 } |
|
168 } |
|
169 |
|
170 let organizationString = this.formatString("clientAuthAsk.organization", |
|
171 [organization]); |
|
172 let issuerString = this.formatString("clientAuthAsk.issuer", |
|
173 [issuer]); |
|
174 let serverRequestedDetails = cn + '<br/>' + organizationString + '<br/>' + issuerString; |
|
175 |
|
176 selectedIndex = 0; |
|
177 while (true) { |
|
178 let prompt = this.getPrompt(this.getString("clientAuthAsk.title"), |
|
179 this.getString("clientAuthAsk.message1"), |
|
180 [ this.getString("nssdialogs.ok.label"), |
|
181 this.getString("clientAuthAsk.viewCert.label"), |
|
182 this.getString("nssdialogs.cancel.label") |
|
183 ]) |
|
184 .addLabel({ id: "requestedDetails", label: serverRequestedDetails } ) |
|
185 .addMenulist({ |
|
186 id: "nicknames", |
|
187 label: this.getString("clientAuthAsk.message2"), |
|
188 values: certNickList, selected: selectedIndex |
|
189 }).addCheckbox({ |
|
190 id: "rememberBox", |
|
191 label: this.getString("clientAuthAsk.remember.label"), |
|
192 checked: rememberSetting |
|
193 }); |
|
194 let response = this.showPrompt(prompt); |
|
195 selectedIndex = response.nicknames; |
|
196 if (response.button == 1) { |
|
197 this.viewCertDetails(certDetailsList[selectedIndex]); |
|
198 continue; |
|
199 } else if (response.button == 0) { |
|
200 canceled.value = false; |
|
201 if (response.rememberBox == "true") { |
|
202 aCtx.QueryInterface(Ci.nsIClientAuthUserDecision).rememberClientAuthCertificate = true; |
|
203 } |
|
204 return true; |
|
205 } |
|
206 canceled.value = true; |
|
207 return false; |
|
208 } |
|
209 } |
|
210 }; |
|
211 |
|
212 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NSSDialogs]); |