|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include <e32svr.h> |
|
20 #include "tcrypt.h" |
|
21 |
|
22 // EXTERNAL FUNCTION PROTOTYPES |
|
23 extern "C" { |
|
24 IMPORT_C char *crypt(const char *key, const char *salt); |
|
25 IMPORT_C void setkey(const char *key); |
|
26 IMPORT_C void encrypt(char block[], int edflag); |
|
27 } |
|
28 |
|
29 // LOCAL FUNCTION PROTOTYPES |
|
30 LOCAL_C void GetBitVector(char data[], char* buffer); |
|
31 LOCAL_C char *TrimWhiteSpaces(char *string); |
|
32 |
|
33 // ============================= LOCAL FUNCTIONS =============================== |
|
34 |
|
35 // ----------------------------------------------------------------------------- |
|
36 // TrimWhiteSpaces |
|
37 // To to trim whitespaces in the input string |
|
38 // ----------------------------------------------------------------------------- |
|
39 // |
|
40 LOCAL_C char *TrimWhiteSpaces(char *string) |
|
41 { |
|
42 char *pTemp = string; |
|
43 for(;*string != '\0'; string++) |
|
44 { |
|
45 if((*string == ' ') || (*string == '\t')) |
|
46 { |
|
47 pTemp++; |
|
48 } |
|
49 } |
|
50 |
|
51 return pTemp; |
|
52 } |
|
53 |
|
54 // ----------------------------------------------------------------------------- |
|
55 // GetBitVector |
|
56 // This function unpacks the byte to obtain the corresponding bit vector |
|
57 // ----------------------------------------------------------------------------- |
|
58 // |
|
59 LOCAL_C void GetBitVector(char data[], char* buffer) |
|
60 { |
|
61 int temp; |
|
62 if(buffer != NULL ) |
|
63 { |
|
64 temp = strlen(buffer); |
|
65 for(int i = 0 ; i<temp ; ++i, ++buffer) |
|
66 { |
|
67 data[i] = *buffer - '0'; |
|
68 } |
|
69 } |
|
70 } |
|
71 |
|
72 |
|
73 CTestCrypt::~CTestCrypt() |
|
74 { |
|
75 |
|
76 } |
|
77 |
|
78 CTestCrypt::CTestCrypt(const TDesC& aStepName) |
|
79 { |
|
80 // MANDATORY Call to base class method to set up the human readable name for logging. |
|
81 SetTestStepName(aStepName); |
|
82 } |
|
83 |
|
84 TVerdict CTestCrypt::doTestStepPreambleL() |
|
85 { |
|
86 __UHEAP_MARK; |
|
87 |
|
88 SetTestStepResult(EPass); |
|
89 iTestDataFile = fopen("C:\\tcrypt\\test_data.dat", "r"); |
|
90 if(iTestDataFile == NULL) |
|
91 { |
|
92 SetTestStepResult(EFail); |
|
93 } |
|
94 |
|
95 return TestStepResult(); |
|
96 } |
|
97 |
|
98 TVerdict CTestCrypt::doTestStepPostambleL() |
|
99 { |
|
100 fclose(iTestDataFile); |
|
101 __UHEAP_MARKEND; |
|
102 return TestStepResult(); |
|
103 } |
|
104 |
|
105 TVerdict CTestCrypt::doTestStepL() |
|
106 { |
|
107 int err; |
|
108 |
|
109 if(TestStepName() == KEncrypt) |
|
110 { |
|
111 INFO_PRINTF1(_L("Encrypt():")); |
|
112 err = Encrypt(); |
|
113 SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); |
|
114 } |
|
115 else if(TestStepName() == KCrypt) |
|
116 { |
|
117 INFO_PRINTF1(_L("Crypt():")); |
|
118 err = Crypt(); |
|
119 SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); |
|
120 } |
|
121 |
|
122 return TestStepResult(); |
|
123 } |
|
124 |
|
125 |
|
126 // ----------------------------------------------------------------------------- |
|
127 // CTestCrypt::Encrypt |
|
128 // Encrypt function |
|
129 // ----------------------------------------------------------------------------- |
|
130 // |
|
131 TInt CTestCrypt::Encrypt() |
|
132 { |
|
133 static int tId = 0; |
|
134 char pTemp[30]; |
|
135 memset(pTemp, 0, 30); |
|
136 sprintf(pTemp, "ENCRYPT_TEST_DATA_%d", ++tId); |
|
137 INFO_PRINTF2(_L("Begin: ENCRYPT_TEST_DATA_%d\n"), tId); |
|
138 |
|
139 // locate "test_data_id" from within the file |
|
140 if(!RepositionFilePointer(pTemp)) |
|
141 { |
|
142 // String not found...invalid test data ID |
|
143 INFO_PRINTF1(_L("Requested test data ID could not be found\n")); |
|
144 return KErrNotFound; |
|
145 } |
|
146 |
|
147 // Get the key, data block, operation to be performed and the |
|
148 // expected output for the current test data ID |
|
149 char key[64] = |
|
150 { |
|
151 0 |
|
152 }; |
|
153 char block[64] = |
|
154 { |
|
155 0 |
|
156 }; |
|
157 char output[64] = |
|
158 { |
|
159 0 |
|
160 }; |
|
161 int edflag = -1; |
|
162 if(GetEncryptTestData(key, block, &edflag, output) != KErrNone) |
|
163 { |
|
164 // Test data not found or is not present in the expected |
|
165 // format |
|
166 INFO_PRINTF1(_L("Test data not found or is not present in the expected format\n")); |
|
167 return KErrNotFound; |
|
168 } |
|
169 |
|
170 // Perform encryption/decryption |
|
171 |
|
172 // Invoke setkey from the libcrypt library |
|
173 setkey(key); |
|
174 |
|
175 // Call the encrypt function |
|
176 encrypt(block,edflag); |
|
177 |
|
178 // Verify if the final output is same as the expected output |
|
179 |
|
180 if(!strcmp(block,block)) |
|
181 { |
|
182 INFO_PRINTF2(_L("End: ENCRYPT_TEST_DATA_%d\n"), tId); |
|
183 // Test case passed |
|
184 return KErrNone; |
|
185 } |
|
186 INFO_PRINTF1(_L("Output from the encrypt() function does not match the \"expected output\"")); |
|
187 INFO_PRINTF2(_L("End: ENCRYPT_TEST_DATA_%d\n"), tId); |
|
188 return KErrNotFound; |
|
189 } |
|
190 |
|
191 // ----------------------------------------------------------------------------- |
|
192 // CTestCrypt::RepositionFilePointer |
|
193 // This function positions the file pointer to the line immediately following |
|
194 // the string aString |
|
195 // ----------------------------------------------------------------------------- |
|
196 // |
|
197 |
|
198 TInt CTestCrypt::RepositionFilePointer(const char *aString) |
|
199 { |
|
200 char buffer[256]; |
|
201 char * ptr = NULL; |
|
202 while(fgets((char*)buffer, 256, iTestDataFile) != NULL) |
|
203 { |
|
204 ptr = NULL; |
|
205 |
|
206 if((ptr=strchr(buffer,'\r')) || (ptr=strchr(buffer,'\n'))) //check for both |
|
207 *ptr='\0'; |
|
208 if(!strcmp(buffer, aString)) |
|
209 { |
|
210 return 1; |
|
211 } |
|
212 memset(buffer, 0, 256); |
|
213 } |
|
214 return 0; |
|
215 } |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CTestCrypt::GetEncryptTestData |
|
219 // This function reads the test data for encrypt() API |
|
220 // ----------------------------------------------------------------------------- |
|
221 // |
|
222 TInt CTestCrypt::GetEncryptTestData(char key[], char block[], int *edflag, char output[]) |
|
223 { |
|
224 char buffer[256]; |
|
225 char *p = NULL; |
|
226 bool bKey = false, // will be set to true upon reading 'key' |
|
227 bBlock = false, // will be set to true upon reading 'data block' |
|
228 bEdflag = false, // will be set to true upon reading 'edflag' |
|
229 bOutput = false; // will be set to true upon reading 'expected output' |
|
230 |
|
231 char *pTemp = NULL; |
|
232 char * ptr = NULL; |
|
233 |
|
234 while((p = fgets(buffer, 256, iTestDataFile)) != NULL) |
|
235 { |
|
236 |
|
237 ptr = NULL; |
|
238 |
|
239 if((ptr=strchr(buffer,'\r')) || (ptr=strchr(buffer,'\n'))) //check for both |
|
240 *ptr='\0'; |
|
241 if(strstr(buffer, "//") != NULL) |
|
242 { |
|
243 continue; |
|
244 } |
|
245 if(!strcmp(buffer, "END_TEST_DATA")) |
|
246 { |
|
247 if(bKey && bBlock && bEdflag && bOutput) |
|
248 { |
|
249 return KErrNone; |
|
250 } |
|
251 return KErrNotFound; |
|
252 } |
|
253 if(strstr(buffer, "KEY") != NULL) |
|
254 { |
|
255 // Read the key |
|
256 |
|
257 // Get bytes... |
|
258 pTemp = strstr(buffer, ":"); |
|
259 if(pTemp != NULL) |
|
260 { |
|
261 pTemp++; |
|
262 pTemp = TrimWhiteSpaces(pTemp); |
|
263 GetBitVector(key, pTemp); |
|
264 } |
|
265 bKey = true; |
|
266 continue; |
|
267 } |
|
268 if(strstr(buffer, "DATA_BLOCK") != NULL) |
|
269 { |
|
270 // Read the data block |
|
271 |
|
272 pTemp = strstr(buffer, ":"); |
|
273 if(pTemp != NULL) |
|
274 { |
|
275 pTemp++; |
|
276 pTemp = TrimWhiteSpaces(pTemp); |
|
277 GetBitVector(block, pTemp); |
|
278 } |
|
279 bBlock = true; |
|
280 continue; |
|
281 } |
|
282 if(strstr(buffer, "ED_FLAG") != NULL) |
|
283 { |
|
284 // Read the ed_flag parameter |
|
285 |
|
286 pTemp = strstr(buffer, ":"); |
|
287 if(pTemp != NULL) |
|
288 { |
|
289 pTemp++; |
|
290 pTemp = TrimWhiteSpaces(pTemp); |
|
291 *edflag = (*pTemp) - '0'; |
|
292 } |
|
293 bEdflag = true; |
|
294 continue; |
|
295 } |
|
296 if(strstr(buffer, "EXPECTED_OUTPUT") != NULL) |
|
297 { |
|
298 // Read the bit vector for the expected output |
|
299 |
|
300 pTemp = strstr(buffer, ":"); |
|
301 if(pTemp != NULL) |
|
302 { |
|
303 pTemp++; |
|
304 pTemp = TrimWhiteSpaces(pTemp); |
|
305 GetBitVector(output, pTemp); |
|
306 } |
|
307 bOutput = true; |
|
308 continue; |
|
309 } |
|
310 } |
|
311 |
|
312 return KErrNotFound; |
|
313 } |
|
314 |
|
315 // ----------------------------------------------------------------------------- |
|
316 // CTestCrypt::Crypt |
|
317 // Test function to perform crypt() on the input data |
|
318 // ----------------------------------------------------------------------------- |
|
319 // |
|
320 TInt CTestCrypt::Crypt() |
|
321 { |
|
322 static int tId = 0; |
|
323 char pTemp[30]; |
|
324 memset(pTemp, 0, 30); |
|
325 sprintf(pTemp, "CRYPT_TEST_DATA_%d", ++tId); |
|
326 INFO_PRINTF2(_L("Begin CRYPT_TEST_DATA_%d\n"), tId); |
|
327 |
|
328 // locate "test_data_id" from within the file |
|
329 if(!RepositionFilePointer(pTemp)) |
|
330 { |
|
331 // String not found...invalid test data ID |
|
332 INFO_PRINTF1(_L("Requested test data ID could not be found\n")); |
|
333 return KErrNotFound; |
|
334 } |
|
335 |
|
336 char password[34] = |
|
337 { |
|
338 '\0' |
|
339 }; |
|
340 char salt[30] = |
|
341 { |
|
342 '\0' |
|
343 }; |
|
344 char output[35] = |
|
345 { |
|
346 '\0' |
|
347 }; |
|
348 |
|
349 if(GetCryptTestData(password, salt, output) != KErrNone) |
|
350 { |
|
351 // Data not in the expected format or is invalid |
|
352 INFO_PRINTF1(_L("Test data not found or is not present in the expected format\n")); |
|
353 return KErrNotFound; |
|
354 } |
|
355 |
|
356 char *crypt_output = NULL; |
|
357 // Invoke crypt() |
|
358 crypt_output = crypt(password,salt); |
|
359 if(!strcmp(output,"")) |
|
360 { |
|
361 // Since salt is NULL, the expected output is ignored... |
|
362 return KErrNone; |
|
363 } |
|
364 if(!strcmp(salt, "")) |
|
365 { |
|
366 // salt is NULL, so skip the first byte from the crypt output |
|
367 if(crypt_output != NULL) |
|
368 { |
|
369 crypt_output++; |
|
370 if(!strcmp(crypt_output, &output[0])) |
|
371 { |
|
372 INFO_PRINTF2(_L("End: CRYPT_TEST_DATA_%d\n"), tId); |
|
373 return KErrNone; |
|
374 } |
|
375 INFO_PRINTF1(_L("Output from the crypt() function does not match the \"expected output\"")); |
|
376 return KErrNotFound; |
|
377 } |
|
378 } |
|
379 else |
|
380 { |
|
381 // salt is not NULL |
|
382 if(!strcmp(crypt_output, output)) |
|
383 { |
|
384 INFO_PRINTF2(_L("End: CRYPT_TEST_DATA_%d\n"), tId); |
|
385 return KErrNone; |
|
386 } |
|
387 INFO_PRINTF1(_L("Output from the crypt() function does not match the \"expected output\"")); |
|
388 return KErrNotFound; |
|
389 } |
|
390 return KErrNotFound; |
|
391 } |
|
392 |
|
393 // ----------------------------------------------------------------------------- |
|
394 // CTestCrypt::GetCryptTestData |
|
395 // To retrieve the test data for crypt() API |
|
396 // ----------------------------------------------------------------------------- |
|
397 // |
|
398 TInt CTestCrypt::GetCryptTestData(char password[], char salt[], char output[]) |
|
399 { |
|
400 char buffer[256]; |
|
401 char *p = NULL; |
|
402 char *pTemp = NULL; |
|
403 int nLength = 0; |
|
404 bool bPassword = false, |
|
405 bSalt = false, |
|
406 bOutput = false; |
|
407 char * ptr = NULL; |
|
408 |
|
409 while((p = fgets(buffer, 256, iTestDataFile)) != NULL) |
|
410 { |
|
411 ptr = NULL; |
|
412 |
|
413 if((ptr=strchr(buffer,'\r')) || (ptr=strchr(buffer,'\n'))) //check for both |
|
414 *ptr='\0'; |
|
415 if(strstr(buffer, "//") != NULL) // skip the comments |
|
416 { |
|
417 // "//" could appear within password or salt, so further |
|
418 // check is required |
|
419 |
|
420 // Since judicious use of whitespaces is allowed only from within |
|
421 // the comment lines, the comment line will always start with |
|
422 // "//" |
|
423 if(buffer[0] == '/' && buffer[1] == '/') |
|
424 { |
|
425 continue; |
|
426 } |
|
427 } |
|
428 if(!strcmp(buffer, "END_TEST_DATA")) |
|
429 { |
|
430 if(bPassword && bSalt && bOutput) |
|
431 { |
|
432 return KErrNone; |
|
433 } |
|
434 return KErrNotFound; |
|
435 } |
|
436 |
|
437 // Verify if the input buffer has "data". Data is followed by ":" |
|
438 pTemp = strstr(buffer, ":"); |
|
439 if(pTemp != NULL) |
|
440 { |
|
441 pTemp++; |
|
442 pTemp = TrimWhiteSpaces(pTemp); |
|
443 nLength = strlen(pTemp); |
|
444 if(strstr(buffer, "PASSWORD") != NULL) |
|
445 { |
|
446 strncpy(password,pTemp,nLength); |
|
447 bPassword = true; |
|
448 continue; |
|
449 } |
|
450 else if(strstr(buffer, "SALT") != NULL) |
|
451 { |
|
452 strncpy(salt,pTemp,nLength); |
|
453 bSalt = true; |
|
454 continue; |
|
455 } |
|
456 else if(strstr(buffer, "EXPECTED_OUTPUT") != NULL) |
|
457 { |
|
458 strncpy(output,pTemp,nLength); |
|
459 bOutput = true; |
|
460 continue; |
|
461 } |
|
462 else |
|
463 { |
|
464 // Unexpected output |
|
465 return KErrNotFound; |
|
466 } |
|
467 } |
|
468 } |
|
469 return KErrNotFound; |
|
470 } |
|
471 |
|
472 // End of File |
|
473 |