1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
|
|
25 |
|
|
26 |
|
|
27 |
|
|
28 |
|
|
29 |
|
|
30 |
|
|
31 |
|
|
32 |
|
|
33 |
|
|
34 |
|
|
35 |
|
|
36 |
|
|
37 |
|
|
38 |
|
|
39 |
|
|
40 |
|
|
41 |
|
|
42 |
|
|
43 |
|
|
44 |
|
|
45 |
|
|
46 |
|
package issrg.SAWS.callback; |
47 |
|
|
48 |
|
import issrg.SAWS.util.CertificateData; |
49 |
|
|
50 |
|
import issrg.SAWS.util.SAWSLogWriter; |
51 |
|
import java.io.File; |
52 |
|
import java.io.FileInputStream; |
53 |
|
|
54 |
|
import java.io.FileNotFoundException; |
55 |
|
|
56 |
|
import java.io.PrintStream; |
57 |
|
import java.io.IOException; |
58 |
|
|
59 |
|
import java.util.Calendar; |
60 |
|
import java.util.PropertyResourceBundle; |
61 |
|
|
62 |
|
import javax.security.auth.callback.Callback; |
63 |
|
import javax.security.auth.callback.CallbackHandler; |
64 |
|
import javax.security.auth.callback.UnsupportedCallbackException; |
65 |
|
|
66 |
|
|
67 |
|
|
68 |
|
|
69 |
|
|
70 |
|
@author |
71 |
|
@version |
72 |
|
|
73 |
|
|
|
|
| 66.7% |
Uncovered Elements: 72 (216) |
Complexity: 47 |
Complexity Density: 0.36 |
|
74 |
|
public class SAWSFileCallbackHandler implements CallbackHandler { |
75 |
|
|
76 |
|
private static SAWSLogWriter sawsDebugLog = new SAWSLogWriter(SAWSFileCallbackHandler.class.getName()); |
77 |
|
private String inputFile, outputFile; |
78 |
|
private PropertyResourceBundle replies; |
79 |
|
private PrintStream output; |
80 |
|
|
81 |
|
|
82 |
|
|
83 |
|
|
|
|
| - |
Uncovered Elements: 0 (0) |
Complexity: 1 |
Complexity Density: - |
|
84 |
0
|
private SAWSFileCallbackHandler() {... |
85 |
|
} |
86 |
|
|
|
|
| 71.4% |
Uncovered Elements: 4 (14) |
Complexity: 4 |
Complexity Density: 0.33 |
|
87 |
8
|
public SAWSFileCallbackHandler(String inputFile, String outputFile) {... |
88 |
8
|
this.setInputFile(inputFile); |
89 |
8
|
this.setOutputFile(outputFile); |
90 |
8
|
FileInputStream is = null; |
91 |
8
|
try { |
92 |
8
|
is = new FileInputStream(new File(inputFile)); |
93 |
8
|
if (this.outputFile != null) { |
94 |
8
|
this.output = new PrintStream(new File(outputFile)); |
95 |
|
} else { |
96 |
0
|
this.output = System.out; |
97 |
|
} |
98 |
|
} catch (FileNotFoundException e) { |
99 |
0
|
throw new IllegalArgumentException("The input file '" + inputFile |
100 |
|
+ "' could not be found."); |
101 |
|
} |
102 |
8
|
try { |
103 |
8
|
this.replies = new PropertyResourceBundle(is); |
104 |
|
} catch (IOException e) { |
105 |
0
|
throw new IllegalArgumentException("Fail accessing the input file."); |
106 |
|
} |
107 |
|
} |
108 |
|
|
109 |
|
|
110 |
|
|
111 |
|
|
112 |
|
@param |
113 |
|
@throws |
114 |
|
|
|
|
| 51.9% |
Uncovered Elements: 38 (79) |
Complexity: 17 |
Complexity Density: 0.29 |
|
115 |
33
|
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {... |
116 |
33
|
if (callbacks == null) { |
117 |
0
|
throw new UnsupportedCallbackException(null, "ERROR: Callbacks can not be null."); |
118 |
|
} |
119 |
|
|
120 |
68
|
for (int i = 0; i < callbacks.length; i++) { |
121 |
35
|
if (callbacks[i] instanceof SAWSTextOutputCallback) { |
122 |
6
|
switch (((SAWSTextOutputCallback)callbacks[i]).getMessageType()) { |
123 |
0
|
case SAWSTextOutputCallback.ERROR: |
124 |
0
|
this.output.println("\nERROR: " + ((SAWSTextOutputCallback)callbacks[i]).getMessage()); |
125 |
0
|
break; |
126 |
6
|
case SAWSTextOutputCallback.INFORMATION: |
127 |
6
|
this.output.println("\nINFO: " + ((SAWSTextOutputCallback)callbacks[i]).getMessage()); |
128 |
6
|
break; |
129 |
0
|
case SAWSTextOutputCallback.WARNING: |
130 |
0
|
this.output.println("\nWARNING: " + ((SAWSTextOutputCallback)callbacks[i]).getMessage()); |
131 |
0
|
break; |
132 |
0
|
case SAWSTextOutputCallback.LONG_MESSAGE: |
133 |
0
|
this.output.println("\n" + ((SAWSTextOutputCallback)callbacks[i]).getMessage()); |
134 |
0
|
break; |
135 |
|
} |
136 |
|
|
137 |
6
|
this.output.flush(); |
138 |
6
|
if (this.output.checkError()) { |
139 |
0
|
sawsDebugLog.write("Error:Fail writing in the output file."); |
140 |
0
|
System.exit(-1); |
141 |
|
} |
142 |
29
|
} else if (callbacks[i] instanceof SAWSPasswordCallback) { |
143 |
16
|
SAWSPasswordCallback pc = (SAWSPasswordCallback)callbacks[i]; |
144 |
|
|
145 |
16
|
this.output.println("Reading password " + pc.getCurrentPasswordShare() |
146 |
|
+ " of " + pc.getPasswordShares() + " for the " + pc.getType() + " keystore..."); |
147 |
|
|
148 |
16
|
pc.setPassword(this.replies.getString(pc.getType() + "Password" + pc.getCurrentPasswordShare() |
149 |
|
+ "of" + pc.getPasswordShares()).toCharArray()); |
150 |
|
|
151 |
13
|
} else if (callbacks[i] instanceof CertificateDataCallback) { |
152 |
2
|
CertificateDataCallback cdc = (CertificateDataCallback) callbacks[i]; |
153 |
2
|
CertificateData cd = null; |
154 |
2
|
this.output.println("Reading Certificate Data from the input file..." + "\n"); |
155 |
|
|
156 |
2
|
try { |
157 |
2
|
cd = this.readCertificateData(cdc); |
158 |
|
} catch (IllegalArgumentException iae) { |
159 |
0
|
this.output.println(iae.getMessage()); |
160 |
0
|
this.output.flush(); |
161 |
0
|
if (this.output.checkError()) { |
162 |
0
|
sawsDebugLog.write("Error: Fail writing in the output file."); |
163 |
|
} |
164 |
0
|
System.exit(-1); |
165 |
|
} |
166 |
|
|
167 |
2
|
this.output.println("Subject Name: " + cd.toSubjectName() + "\n"); |
168 |
2
|
cdc.setCertData(cd); |
169 |
11
|
} else if (callbacks[i] instanceof SAWSChoiceCallback) { |
170 |
11
|
SAWSChoiceCallback cc = (SAWSChoiceCallback) callbacks[i]; |
171 |
11
|
this.output.println(cc.getPrompt()); |
172 |
11
|
int choice = cc.getDefaultOption(); |
173 |
11
|
try { |
174 |
11
|
choice = Integer.parseInt(this.replies.getString(cc.getKey())); |
175 |
|
} catch (NumberFormatException nfe) { |
176 |
0
|
this.output.println("Warning: The value for the key " + cc.getKey() |
177 |
|
+ " must be a number. Please check the input file and try again."); |
178 |
0
|
this.output.flush(); |
179 |
0
|
if (this.output.checkError()) { |
180 |
0
|
this.sawsDebugLog.write("Fail wrinting the output file."); |
181 |
|
} |
182 |
|
} |
183 |
11
|
this.output.println("Selected index: " + (choice)); |
184 |
11
|
this.output.flush(); |
185 |
11
|
cc.setSelectedIndex(choice - 1); |
186 |
0
|
} else if (callbacks[i] instanceof SAWSTextInputCallback) { |
187 |
0
|
SAWSTextInputCallback stic = (SAWSTextInputCallback) callbacks[i]; |
188 |
0
|
this.output.println(stic.getPrompt() + "\n"); |
189 |
0
|
String value = this.replies.getString(stic.getKey()); |
190 |
0
|
this.output.println("Input value: " + value + "\n"); |
191 |
0
|
this.output.flush(); |
192 |
0
|
stic.setText(value); |
193 |
|
} else { |
194 |
0
|
throw new UnsupportedCallbackException |
195 |
|
(callbacks[i], "ERROR: Unrecognized Callback."); |
196 |
|
} |
197 |
|
} |
198 |
|
} |
199 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
200 |
0
|
public String getInputFile() {... |
201 |
0
|
return inputFile; |
202 |
|
} |
203 |
|
|
|
|
| 60% |
Uncovered Elements: 2 (5) |
Complexity: 3 |
Complexity Density: 1 |
|
204 |
8
|
public void setInputFile(String inputFile) {... |
205 |
8
|
if (inputFile != null && inputFile.length() > 0) { |
206 |
8
|
this.inputFile = inputFile; |
207 |
|
} else { |
208 |
0
|
throw new IllegalArgumentException("Invalid name for the input file."); |
209 |
|
} |
210 |
|
} |
211 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
212 |
0
|
public String getOutputFile() {... |
213 |
0
|
return outputFile; |
214 |
|
} |
215 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 3 |
Complexity Density: 1.5 |
|
216 |
8
|
public void setOutputFile(String outputFile) {... |
217 |
8
|
if (outputFile != null && outputFile.length() > 0) { |
218 |
8
|
this.outputFile = outputFile; |
219 |
|
} |
220 |
|
} |
221 |
|
|
222 |
|
|
223 |
|
|
224 |
|
|
225 |
|
|
226 |
|
@param |
227 |
|
@return |
228 |
|
|
|
|
| 78.8% |
Uncovered Elements: 22 (104) |
Complexity: 24 |
Complexity Density: 0.32 |
|
229 |
2
|
private CertificateData readCertificateData(CertificateDataCallback cdc) {... |
230 |
2
|
CertificateData cd = new CertificateData(); |
231 |
2
|
byte type = cdc.getType(); |
232 |
|
|
233 |
2
|
String prefix = ""; |
234 |
2
|
if (type == CertificateDataCallback.ENCRYPTION) { |
235 |
1
|
prefix = "EncCert"; |
236 |
1
|
} else if (type == CertificateDataCallback.SIGNING) { |
237 |
1
|
prefix = "SigCert"; |
238 |
|
} |
239 |
|
|
240 |
|
|
241 |
2
|
String validity = this.replies.getString(prefix + "Validity"); |
242 |
2
|
if (validity.length() != 8) { |
243 |
0
|
throw new IllegalArgumentException("WARNING: Please input a date in the format DDMMYYYY."); |
244 |
|
} |
245 |
|
|
246 |
2
|
Calendar c = Calendar.getInstance(); |
247 |
2
|
c.setLenient(false); |
248 |
2
|
try { |
249 |
2
|
c.set(Calendar.YEAR, Integer.parseInt(validity.substring(4, 8))); |
250 |
2
|
c.set(Calendar.MONTH, Integer.parseInt(validity.substring(2, 4)) - 1); |
251 |
2
|
c.set(Calendar.DATE, Integer.parseInt(validity.substring(0, 2))); |
252 |
|
|
253 |
2
|
Calendar today = Calendar.getInstance(); |
254 |
2
|
today.set(Calendar.HOUR, 0); |
255 |
2
|
today.set(Calendar.MINUTE, 0); |
256 |
2
|
today.set(Calendar.SECOND, 0); |
257 |
|
|
258 |
2
|
Calendar temp = Calendar.getInstance(); |
259 |
2
|
temp.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), |
260 |
|
c.get(Calendar.DATE), 0, 0, 0); |
261 |
|
|
262 |
2
|
long todayMili = today.getTimeInMillis(); |
263 |
2
|
long dateMili = temp.getTimeInMillis(); |
264 |
|
|
265 |
2
|
if (todayMili > dateMili) { |
266 |
0
|
throw new IllegalArgumentException("WARNING: The selected date must be after to " |
267 |
|
+ today.get(Calendar.DATE) + "/" + (today.get(Calendar.MONTH) + 1) + "/" |
268 |
|
+ today.get(Calendar.YEAR) + "."); |
269 |
|
} |
270 |
|
|
271 |
|
|
272 |
|
|
273 |
2
|
int days = (int)((dateMili - todayMili) / 1000 / 60 / 60 / 24); |
274 |
2
|
today.add(Calendar.DATE, days); |
275 |
|
|
276 |
2
|
if (today.compareTo(temp) > 0) { |
277 |
0
|
days = days - 1; |
278 |
2
|
} else if (today.compareTo(temp) < 0) { |
279 |
2
|
days = days + 1; |
280 |
|
} |
281 |
|
|
282 |
2
|
cd.setValidity(days); |
283 |
|
|
284 |
|
} catch (NumberFormatException nfe) { |
285 |
0
|
throw new IllegalArgumentException("WARNING: The date can not contain letters, only numbers. Please type again."); |
286 |
|
} catch (IllegalArgumentException iae) { |
287 |
0
|
throw new IllegalArgumentException("WARNING: " + iae.getMessage() + " is not valid. Please type the validity date again."); |
288 |
|
} |
289 |
|
|
290 |
|
|
291 |
2
|
cd.setCommonName(this.replies.getString(prefix + "CN")); |
292 |
2
|
cd.setOrganizationUnitName(this.replies.getString(prefix + "OU")); |
293 |
2
|
cd.setOrganizationName(this.replies.getString(prefix + "O")); |
294 |
2
|
cd.setLocalityName(this.replies.getString(prefix + "L")); |
295 |
2
|
cd.setStateName(this.replies.getString(prefix + "S")); |
296 |
|
|
297 |
2
|
String country = this.replies.getString(prefix + "C"); |
298 |
2
|
if (country != null && !country.equals("") && country.length() != 2) { |
299 |
0
|
throw new IllegalArgumentException("WARNING: The country code, if specified, " |
300 |
|
+ "must contain two letters. Please try again."); |
301 |
|
} else { |
302 |
2
|
cd.setCountryName(country); |
303 |
|
} |
304 |
|
|
305 |
2
|
String sn = cd.toSubjectName(); |
306 |
2
|
if (sn == null || sn.equals("")) { |
307 |
0
|
throw new IllegalArgumentException("WARNING: Subject name can not be null or empty. Please try again."); |
308 |
|
} |
309 |
|
|
310 |
|
|
311 |
|
|
312 |
2
|
String alg = this.replies.getString(prefix + "Algorithm"); |
313 |
|
|
314 |
2
|
if (type == CertificateDataCallback.ENCRYPTION) { |
315 |
1
|
if (alg.equalsIgnoreCase("RSA")) { |
316 |
1
|
cd.setAlgorithm("RSA"); |
317 |
|
} else { |
318 |
0
|
throw new IllegalArgumentException("WARNING: The supported algorithm for the " |
319 |
|
+ "encryption keystore is RSA. Please check the input file and try again."); |
320 |
|
} |
321 |
|
} else { |
322 |
1
|
if (alg.equalsIgnoreCase("RSA") || alg.equalsIgnoreCase("DSA")) { |
323 |
1
|
cd.setAlgorithm(alg); |
324 |
|
} else { |
325 |
0
|
throw new IllegalArgumentException("WARNING: The supported algorithm for the " |
326 |
|
+ "signing keystore are RSA and DSA. Please check the input file and try again."); |
327 |
|
} |
328 |
|
} |
329 |
|
|
330 |
2
|
int[] keySizes = null; |
331 |
2
|
alg = cd.getAlgorithm(); |
332 |
|
|
333 |
2
|
if (alg.equalsIgnoreCase("RSA")) { |
334 |
1
|
keySizes = new int[]{1024, 2048, 3072, 4096}; |
335 |
|
} else { |
336 |
1
|
keySizes = new int[]{512, 640, 768, 896, 1024}; |
337 |
|
} |
338 |
|
|
339 |
2
|
int keySize = 1024; |
340 |
2
|
try { |
341 |
2
|
keySize = Integer.parseInt(this.replies.getString(prefix + "KeySize")); |
342 |
|
} catch (Exception ex) { |
343 |
0
|
throw new IllegalArgumentException("WARNING: Invalid option. Please input a valid number for the key size."); |
344 |
|
} |
345 |
|
|
346 |
2
|
boolean found = false; |
347 |
|
|
348 |
|
|
349 |
2
|
String sizes = ""; |
350 |
|
|
351 |
4
|
for (int i = 0;!found && i < keySizes.length; i = i + 1) { |
352 |
2
|
if (keySizes[i] == keySize) { |
353 |
2
|
found = true; |
354 |
|
} |
355 |
|
|
356 |
2
|
sizes = sizes + ", " + keySizes[i]; |
357 |
|
} |
358 |
|
|
359 |
2
|
if (!found) { |
360 |
0
|
throw new IllegalArgumentException("WARNING: Invalid key size. Please input one of the following: " + sizes); |
361 |
|
} else { |
362 |
2
|
cd.setKeySize(keySize); |
363 |
|
} |
364 |
|
|
365 |
2
|
return cd; |
366 |
|
} |
367 |
|
} |