File: | s/cmd/rsapoptst/rsapoptst.c |
Warning: | line 594, column 5 Value stored to 'rv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | #include <stdio.h> |
6 | #include <stdlib.h> |
7 | #include "plgetopt.h" |
8 | #include "nss.h" |
9 | #include "secutil.h" |
10 | #include "pk11table.h" |
11 | #include "secmodt.h" |
12 | #include "pk11pub.h" |
13 | |
14 | struct test_args { |
15 | char *arg; |
16 | int mask_value; |
17 | char *description; |
18 | }; |
19 | |
20 | static const struct test_args test_array[] = { |
21 | { "all", 0x1f, "run all the tests" }, |
22 | { "e_n_p", 0x01, "public exponent, modulus, prime1" }, |
23 | { "d_n_q", 0x02, "private exponent, modulus, prime2" }, |
24 | { "d_p_q", 0x04, "private exponent, prime1, prime2" }, |
25 | { "e_d_q", 0x08, "public exponent, private exponent, prime2" }, |
26 | { "e_d_n", 0x10, "public exponent, private exponent, modulus" } |
27 | }; |
28 | static const int test_array_size = |
29 | (sizeof(test_array) / sizeof(struct test_args)); |
30 | |
31 | static void |
32 | Usage(char *progName) |
33 | { |
34 | int i; |
35 | #define PRINTUSAGE(subject, option, predicate)fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate); \ |
36 | fprintf(stderrstderr, "%10s %s\t%s\n", subject, option, predicate); |
37 | fprintf(stderrstderr, "%s [-k keysize] [-e exp] [-r rounds] [-t tests]\n " |
38 | "Test creating RSA private keys from Partial components\n", |
39 | progName); |
40 | PRINTUSAGE("", "-k", "key size (in bit)")fprintf(stderr, "%10s %s\t%s\n", "", "-k", "key size (in bit)" );; |
41 | PRINTUSAGE("", "-e", "rsa public exponent")fprintf(stderr, "%10s %s\t%s\n", "", "-e", "rsa public exponent" );; |
42 | PRINTUSAGE("", "-r", "number times to repeat the test")fprintf(stderr, "%10s %s\t%s\n", "", "-r", "number times to repeat the test" );; |
43 | PRINTUSAGE("", "-t", "run the specified tests")fprintf(stderr, "%10s %s\t%s\n", "", "-t", "run the specified tests" );; |
44 | for (i = 0; i < test_array_size; i++) { |
45 | PRINTUSAGE("", test_array[i].arg, test_array[i].description)fprintf(stderr, "%10s %s\t%s\n", "", test_array[i].arg, test_array [i].description);; |
46 | } |
47 | fprintf(stderrstderr, "\n"); |
48 | } |
49 | |
50 | /* |
51 | * Test the RSA populate command to see that it can really build |
52 | * keys from it's components. |
53 | */ |
54 | |
55 | const static CK_ATTRIBUTE rsaTemplate[] = { |
56 | { CKA_CLASS0x00000000UL, NULL((void*)0), 0 }, |
57 | { CKA_KEY_TYPE0x00000100UL, NULL((void*)0), 0 }, |
58 | { CKA_TOKEN0x00000001UL, NULL((void*)0), 0 }, |
59 | { CKA_SENSITIVE0x00000103UL, NULL((void*)0), 0 }, |
60 | { CKA_PRIVATE0x00000002UL, NULL((void*)0), 0 }, |
61 | { CKA_ID0x00000102UL, NULL((void*)0), 0 }, |
62 | { CKA_MODULUS0x00000120UL, NULL((void*)0), 0 }, |
63 | { CKA_PUBLIC_EXPONENT0x00000122UL, NULL((void*)0), 0 }, |
64 | { CKA_PRIVATE_EXPONENT0x00000123UL, NULL((void*)0), 0 }, |
65 | { CKA_PRIME_10x00000124UL, NULL((void*)0), 0 }, |
66 | { CKA_PRIME_20x00000125UL, NULL((void*)0), 0 }, |
67 | { CKA_EXPONENT_10x00000126UL, NULL((void*)0), 0 }, |
68 | { CKA_EXPONENT_20x00000127UL, NULL((void*)0), 0 }, |
69 | { CKA_COEFFICIENT0x00000128UL, NULL((void*)0), 0 }, |
70 | }; |
71 | |
72 | #define RSA_SIZE(sizeof(rsaTemplate)) (sizeof(rsaTemplate)) |
73 | #define RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE)) (sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE)) |
74 | |
75 | static void |
76 | resetTemplate(CK_ATTRIBUTE *attribute, int start, int end) |
77 | { |
78 | int i; |
79 | for (i = start; i < end; i++) { |
80 | if (attribute[i].pValue) { |
81 | PORT_FreePORT_Free_Util(attribute[i].pValue); |
82 | } |
83 | attribute[i].pValue = NULL((void*)0); |
84 | attribute[i].ulValueLen = 0; |
85 | } |
86 | } |
87 | |
88 | static SECStatus |
89 | copyAttribute(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template, |
90 | int offset, CK_ATTRIBUTE_TYPE attrType) |
91 | { |
92 | SECItem attributeItem = { 0, 0, 0 }; |
93 | SECStatus rv; |
94 | |
95 | rv = PK11_ReadRawAttribute(objType, object, attrType, &attributeItem); |
96 | if (rv != SECSuccess) { |
97 | return rv; |
98 | } |
99 | template[offset].type = attrType; |
100 | template[offset].pValue = attributeItem.data; |
101 | template[offset].ulValueLen = attributeItem.len; |
102 | return SECSuccess; |
103 | } |
104 | |
105 | static SECStatus |
106 | readKey(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template, |
107 | int start, int end) |
108 | { |
109 | int i; |
110 | SECStatus rv; |
111 | |
112 | for (i = start; i < end; i++) { |
113 | rv = copyAttribute(objType, object, template, i, template[i].type); |
114 | if (rv != SECSuccess) { |
115 | goto fail; |
116 | } |
117 | } |
118 | return SECSuccess; |
119 | |
120 | fail: |
121 | resetTemplate(template, start, i); |
122 | return rv; |
123 | } |
124 | |
125 | #define ATTR_STRING(x)getNameFromAttribute(x) getNameFromAttribute(x) |
126 | |
127 | static void |
128 | dumphex(FILE *file, const unsigned char *cpval, int start, int end) |
129 | { |
130 | int i; |
131 | for (i = start; i < end; i++) { |
132 | if ((i % 16) == 0) |
133 | fprintf(file, "\n "); |
134 | fprintf(file, " %02x", cpval[i]); |
135 | } |
136 | return; |
137 | } |
138 | |
139 | void |
140 | dumpTemplate(FILE *file, const CK_ATTRIBUTE *template, int start, int end) |
141 | { |
142 | int i; |
143 | for (i = start; i < end; i++) { |
144 | unsigned char cval; |
145 | CK_ULONG ulval; |
146 | const unsigned char *cpval; |
147 | |
148 | fprintf(file, "%s:", ATTR_STRING(template[i].type)getNameFromAttribute(template[i].type)); |
149 | switch (template[i].ulValueLen) { |
150 | case 1: |
151 | cval = *(unsigned char *)template[i].pValue; |
152 | switch (cval) { |
153 | case 0: |
154 | fprintf(file, " false"); |
155 | break; |
156 | case 1: |
157 | fprintf(file, " true"); |
158 | break; |
159 | default: |
160 | fprintf(file, " %d (=0x%02x,'%c')", cval, cval, cval); |
161 | break; |
162 | } |
163 | break; |
164 | case sizeof(CK_ULONG): |
165 | ulval = *(CK_ULONG *)template[i].pValue; |
166 | fprintf(file, " %ld (=0x%04lx)", ulval, ulval); |
167 | break; |
168 | default: |
169 | cpval = (const unsigned char *)template[i].pValue; |
170 | dumphex(file, cpval, 0, template[i].ulValueLen); |
171 | break; |
172 | } |
173 | fprintf(file, "\n"); |
174 | } |
175 | } |
176 | |
177 | void |
178 | dumpItem(FILE *file, const SECItem *item) |
179 | { |
180 | const unsigned char *cpval; |
181 | |
182 | if (item == NULL((void*)0)) { |
183 | fprintf(file, " pNULL "); |
184 | return; |
185 | } |
186 | if (item->data == NULL((void*)0)) { |
187 | fprintf(file, " NULL "); |
188 | return; |
189 | } |
190 | if (item->len == 0) { |
191 | fprintf(file, " Empty "); |
192 | return; |
193 | } |
194 | cpval = item->data; |
195 | dumphex(file, cpval, 0, item->len); |
196 | fprintf(file, " "); |
197 | return; |
198 | } |
199 | |
200 | PRBool |
201 | rsaKeysAreEqual(PK11ObjectType srcType, void *src, |
202 | PK11ObjectType destType, void *dest) |
203 | { |
204 | |
205 | CK_ATTRIBUTE srcTemplate[RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))]; |
206 | CK_ATTRIBUTE destTemplate[RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))]; |
207 | PRBool areEqual = PR_TRUE1; |
208 | SECStatus rv; |
209 | int i; |
210 | |
211 | memcpy(srcTemplate, rsaTemplate, RSA_SIZE(sizeof(rsaTemplate))); |
212 | memcpy(destTemplate, rsaTemplate, RSA_SIZE(sizeof(rsaTemplate))); |
213 | |
214 | rv = readKey(srcType, src, srcTemplate, 0, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
215 | if (rv != SECSuccess) { |
216 | printf("Could read source key\n"); |
217 | return PR_FALSE0; |
218 | } |
219 | rv = readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
220 | if (rv != SECSuccess) { |
221 | printf("Could read dest key\n"); |
222 | return PR_FALSE0; |
223 | } |
224 | |
225 | for (i = 0; i < RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE)); i++) { |
226 | if (srcTemplate[i].type == CKA_ID0x00000102UL) { |
227 | continue; /* we purposefully make the CKA_ID different */ |
228 | } |
229 | if (srcTemplate[i].ulValueLen != destTemplate[i].ulValueLen) { |
230 | printf("key->%s not equal src_len = %ld, dest_len=%ld\n", |
231 | ATTR_STRING(srcTemplate[i].type)getNameFromAttribute(srcTemplate[i].type), |
232 | srcTemplate[i].ulValueLen, destTemplate[i].ulValueLen); |
233 | areEqual = 0; |
234 | } else if (memcmp(srcTemplate[i].pValue, destTemplate[i].pValue, |
235 | destTemplate[i].ulValueLen) != 0) { |
236 | printf("key->%s not equal.\n", ATTR_STRING(srcTemplate[i].type)getNameFromAttribute(srcTemplate[i].type)); |
237 | areEqual = 0; |
238 | } |
239 | } |
240 | if (!areEqual) { |
241 | fprintf(stderrstderr, "original key:\n"); |
242 | dumpTemplate(stderrstderr, srcTemplate, 0, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
243 | fprintf(stderrstderr, "created key:\n"); |
244 | dumpTemplate(stderrstderr, destTemplate, 0, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
245 | } |
246 | resetTemplate(srcTemplate, 0, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
247 | resetTemplate(destTemplate, 0, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
248 | return areEqual; |
249 | } |
250 | |
251 | static int exp_exp_prime_fail_count = 0; |
252 | |
253 | #define LEAK_ID0xf 0xf |
254 | |
255 | static int |
256 | doRSAPopulateTest(unsigned int keySize, unsigned long exponent, |
257 | int mask, int round, void *pwarg) |
258 | { |
259 | SECKEYPrivateKey *rsaPrivKey; |
260 | SECKEYPublicKey *rsaPubKey; |
261 | PK11GenericObject *tstPrivKey; |
262 | CK_ATTRIBUTE tstTemplate[RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))]; |
263 | int tstHeaderCount; |
264 | PK11SlotInfo *slot = NULL((void*)0); |
265 | PK11RSAGenParams rsaParams; |
266 | CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY0x00000003UL; |
267 | CK_KEY_TYPE key_type = CKK_RSA0x00000000UL; |
268 | CK_BBOOL ck_false = CK_FALSE0; |
269 | CK_BYTE cka_id[2] = { 0, 0 }; |
270 | int failed = 0; |
271 | int leak_found; /* did we find the expected leak */ |
272 | int expect_leak = 0; /* are we expecting a leak? */ |
273 | |
274 | rsaParams.pe = exponent; |
275 | rsaParams.keySizeInBits = keySize; |
276 | |
277 | slot = PK11_GetInternalSlot(); |
278 | if (slot == NULL((void*)0)) { |
279 | fprintf(stderrstderr, "Couldn't get the internal slot for the test \n"); |
280 | return -1; |
281 | } |
282 | |
283 | rsaPrivKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN0x00000000UL, |
284 | &rsaParams, &rsaPubKey, PR_FALSE0, |
285 | PR_FALSE0, pwarg); |
286 | if (rsaPrivKey == NULL((void*)0)) { |
287 | fprintf(stderrstderr, "RSA Key Gen failed"); |
288 | PK11_FreeSlot(slot); |
289 | return -1; |
290 | } |
291 | |
292 | memcpy(tstTemplate, rsaTemplate, RSA_SIZE(sizeof(rsaTemplate))); |
293 | |
294 | tstTemplate[0].pValue = &obj_class; |
295 | tstTemplate[0].ulValueLen = sizeof(obj_class); |
296 | tstTemplate[1].pValue = &key_type; |
297 | tstTemplate[1].ulValueLen = sizeof(key_type); |
298 | tstTemplate[2].pValue = &ck_false; |
299 | tstTemplate[2].ulValueLen = sizeof(ck_false); |
300 | tstTemplate[3].pValue = &ck_false; |
301 | tstTemplate[3].ulValueLen = sizeof(ck_false); |
302 | tstTemplate[4].pValue = &ck_false; |
303 | tstTemplate[4].ulValueLen = sizeof(ck_false); |
304 | tstTemplate[5].pValue = &cka_id[0]; |
305 | tstTemplate[5].ulValueLen = sizeof(cka_id); |
306 | tstHeaderCount = 6; |
307 | cka_id[0] = round; |
308 | |
309 | if (mask & 1) { |
310 | printf("%s\n", test_array[1].description); |
311 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
312 | cka_id[1] = 0; |
313 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
314 | tstHeaderCount, CKA_PUBLIC_EXPONENT0x00000122UL); |
315 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
316 | tstHeaderCount + 1, CKA_MODULUS0x00000120UL); |
317 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
318 | tstHeaderCount + 2, CKA_PRIME_10x00000124UL); |
319 | |
320 | tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, |
321 | tstHeaderCount + |
322 | 3, |
323 | PR_FALSE0); |
324 | if (tstPrivKey == NULL((void*)0)) { |
325 | fprintf(stderrstderr, "RSA Populate failed: pubExp mod p\n"); |
326 | failed = 1; |
327 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
328 | PK11_TypeGeneric, tstPrivKey)) { |
329 | fprintf(stderrstderr, "RSA Populate key mismatch: pubExp mod p\n"); |
330 | failed = 1; |
331 | } |
332 | if (tstPrivKey) |
333 | PK11_DestroyGenericObject(tstPrivKey); |
334 | } |
335 | if (mask & 2) { |
336 | printf("%s\n", test_array[2].description); |
337 | /* test the basic2 case, public exponent, modulus, prime2 */ |
338 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
339 | cka_id[1] = 1; |
340 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
341 | tstHeaderCount, CKA_PUBLIC_EXPONENT0x00000122UL); |
342 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
343 | tstHeaderCount + 1, CKA_MODULUS0x00000120UL); |
344 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
345 | tstHeaderCount + 2, CKA_PRIME_20x00000125UL); |
346 | /* test with q in the prime1 position */ |
347 | tstTemplate[tstHeaderCount + 2].type = CKA_PRIME_10x00000124UL; |
348 | |
349 | tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, |
350 | tstHeaderCount + |
351 | 3, |
352 | PR_FALSE0); |
353 | if (tstPrivKey == NULL((void*)0)) { |
354 | fprintf(stderrstderr, "RSA Populate failed: pubExp mod q\n"); |
355 | failed = 1; |
356 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
357 | PK11_TypeGeneric, tstPrivKey)) { |
358 | fprintf(stderrstderr, "RSA Populate key mismatch: pubExp mod q\n"); |
359 | failed = 1; |
360 | } |
361 | if (tstPrivKey) |
362 | PK11_DestroyGenericObject(tstPrivKey); |
363 | } |
364 | if (mask & 4) { |
365 | printf("%s\n", test_array[3].description); |
366 | /* test the medium case, private exponent, prime1, prime2 */ |
367 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
368 | cka_id[1] = 2; |
369 | |
370 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
371 | tstHeaderCount, CKA_PRIVATE_EXPONENT0x00000123UL); |
372 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
373 | tstHeaderCount + 1, CKA_PRIME_10x00000124UL); |
374 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
375 | tstHeaderCount + 2, CKA_PRIME_20x00000125UL); |
376 | /* test with p & q swapped. Underlying code should swap these back */ |
377 | tstTemplate[tstHeaderCount + 2].type = CKA_PRIME_10x00000124UL; |
378 | tstTemplate[tstHeaderCount + 1].type = CKA_PRIME_20x00000125UL; |
379 | |
380 | tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, |
381 | tstHeaderCount + |
382 | 3, |
383 | PR_FALSE0); |
384 | if (tstPrivKey == NULL((void*)0)) { |
385 | fprintf(stderrstderr, "RSA Populate failed: privExp p q\n"); |
386 | failed = 1; |
387 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
388 | PK11_TypeGeneric, tstPrivKey)) { |
389 | fprintf(stderrstderr, "RSA Populate key mismatch: privExp p q\n"); |
390 | failed = 1; |
391 | } |
392 | if (tstPrivKey) |
393 | PK11_DestroyGenericObject(tstPrivKey); |
394 | } |
395 | if (mask & 8) { |
396 | printf("%s\n", test_array[4].description); |
397 | /* test the advanced case, public exponent, private exponent, prime2 */ |
398 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
399 | cka_id[1] = 3; |
400 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
401 | tstHeaderCount, CKA_PRIVATE_EXPONENT0x00000123UL); |
402 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
403 | tstHeaderCount + 1, CKA_PUBLIC_EXPONENT0x00000122UL); |
404 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
405 | tstHeaderCount + 2, CKA_PRIME_20x00000125UL); |
406 | |
407 | tstPrivKey = PK11_CreateManagedGenericObject(slot, tstTemplate, |
408 | tstHeaderCount + |
409 | 3, |
410 | PR_FALSE0); |
411 | if (tstPrivKey == NULL((void*)0)) { |
412 | fprintf(stderrstderr, "RSA Populate failed: pubExp privExp q\n"); |
413 | fprintf(stderrstderr, " this is expected periodically. It means we\n"); |
414 | fprintf(stderrstderr, " had more than one key that meets the " |
415 | "specification\n"); |
416 | exp_exp_prime_fail_count++; |
417 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
418 | PK11_TypeGeneric, tstPrivKey)) { |
419 | fprintf(stderrstderr, "RSA Populate key mismatch: pubExp privExp q\n"); |
420 | failed = 1; |
421 | } |
422 | if (tstPrivKey) |
423 | PK11_DestroyGenericObject(tstPrivKey); |
424 | } |
425 | if (mask & 0x10) { |
426 | printf("%s\n", test_array[5].description); |
427 | /* test the advanced case2, public exponent, private exponent, modulus |
428 | */ |
429 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
430 | cka_id[1] = LEAK_ID0xf; |
431 | |
432 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
433 | tstHeaderCount, CKA_PRIVATE_EXPONENT0x00000123UL); |
434 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
435 | tstHeaderCount + 1, CKA_PUBLIC_EXPONENT0x00000122UL); |
436 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
437 | tstHeaderCount + 2, CKA_MODULUS0x00000120UL); |
438 | |
439 | /* purposefully use the old version. This will create a leak */ |
440 | tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
441 | tstHeaderCount + |
442 | 3, |
443 | PR_FALSE0); |
444 | if (tstPrivKey == NULL((void*)0)) { |
445 | fprintf(stderrstderr, "RSA Populate failed: pubExp privExp mod\n"); |
446 | failed = 1; |
447 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
448 | PK11_TypeGeneric, tstPrivKey)) { |
449 | fprintf(stderrstderr, "RSA Populate key mismatch: pubExp privExp mod\n"); |
450 | failed = 1; |
451 | } |
452 | expect_leak = 1; |
453 | if (tstPrivKey) |
454 | PK11_DestroyGenericObject(tstPrivKey); |
455 | } |
456 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES(sizeof(rsaTemplate) / sizeof(CK_ATTRIBUTE))); |
457 | SECKEY_DestroyPrivateKey(rsaPrivKey); |
458 | SECKEY_DestroyPublicKey(rsaPubKey); |
459 | |
460 | /* make sure we didn't leak */ |
461 | leak_found = 0; |
462 | tstPrivKey = PK11_FindGenericObjects(slot, CKO_PRIVATE_KEY0x00000003UL); |
463 | if (tstPrivKey) { |
464 | SECStatus rv; |
465 | PK11GenericObject *thisKey; |
466 | int i; |
467 | |
468 | fprintf(stderrstderr, "Leaking keys...\n"); |
469 | for (i = 0, thisKey = tstPrivKey; thisKey; i++, |
470 | thisKey = PK11_GetNextGenericObject(thisKey)) { |
471 | SECItem id = { 0, NULL((void*)0), 0 }; |
472 | |
473 | rv = PK11_ReadRawAttribute(PK11_TypeGeneric, thisKey, |
474 | CKA_ID0x00000102UL, &id); |
475 | if (rv != SECSuccess) { |
476 | fprintf(stderrstderr, "Key %d: couldn't read CKA_ID: %s\n", |
477 | i, PORT_ErrorToString(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0)); |
478 | continue; |
479 | } |
480 | fprintf(stderrstderr, "id = { "); |
481 | dumpItem(stderrstderr, &id); |
482 | fprintf(stderrstderr, "};"); |
483 | if (id.data[1] == LEAK_ID0xf) { |
484 | fprintf(stderrstderr, " ---> leak expected\n"); |
485 | if (id.data[0] == round) |
486 | leak_found = 1; |
487 | } else { |
488 | if (id.len != sizeof(cka_id)) { |
489 | fprintf(stderrstderr, |
490 | " ---> ERROR unexpected leak in generated key\n"); |
491 | } else { |
492 | fprintf(stderrstderr, |
493 | " ---> ERROR unexpected leak in constructed key\n"); |
494 | } |
495 | failed = 1; |
496 | } |
497 | SECITEM_FreeItemSECITEM_FreeItem_Util(&id, PR_FALSE0); |
498 | } |
499 | PK11_DestroyGenericObjects(tstPrivKey); |
500 | } |
501 | if (expect_leak && !leak_found) { |
502 | fprintf(stderrstderr, "ERROR expected leak not found\n"); |
503 | failed = 1; |
504 | } |
505 | |
506 | PK11_FreeSlot(slot); |
507 | return failed ? -1 : 0; |
508 | } |
509 | |
510 | /* populate options */ |
511 | enum { |
512 | opt_Exponent = 0, |
513 | opt_KeySize, |
514 | opt_Repeat, |
515 | opt_Tests |
516 | }; |
517 | |
518 | static secuCommandFlag populate_options[] = { |
519 | { /* opt_Exponent */ 'e', PR_TRUE1, 0, PR_FALSE0 }, |
520 | { /* opt_KeySize */ 'k', PR_TRUE1, 0, PR_FALSE0 }, |
521 | { /* opt_Repeat */ 'r', PR_TRUE1, 0, PR_FALSE0 }, |
522 | { /* opt_Tests */ 't', PR_TRUE1, 0, PR_FALSE0 }, |
523 | }; |
524 | |
525 | int |
526 | is_delimiter(char c) |
527 | { |
528 | if ((c == '+') || (c == ',') || (c == '|')) { |
529 | return 1; |
530 | } |
531 | return 0; |
532 | } |
533 | |
534 | int |
535 | parse_tests(char *test_string) |
536 | { |
537 | int mask = 0; |
538 | int i; |
539 | |
540 | while (*test_string) { |
541 | if (is_delimiter(*test_string)) { |
542 | test_string++; |
543 | } |
544 | for (i = 0; i < test_array_size; i++) { |
545 | char *arg = test_array[i].arg; |
546 | int len = strlen(arg); |
547 | if (strncmp(test_string, arg, len) == 0) { |
548 | test_string += len; |
549 | mask |= test_array[i].mask_value; |
550 | break; |
551 | } |
552 | } |
553 | if (i == test_array_size) { |
554 | break; |
555 | } |
556 | } |
557 | return mask; |
558 | } |
559 | |
560 | int |
561 | main(int argc, char **argv) |
562 | { |
563 | unsigned int keySize = 1024; |
564 | unsigned long exponent = 65537; |
565 | int i, repeat = 1, ret = 0; |
566 | SECStatus rv = SECFailure; |
567 | secuCommand populateArgs; |
568 | char *progName; |
569 | int mask = 0xff; |
570 | |
571 | populateArgs.numCommands = 0; |
572 | populateArgs.numOptions = sizeof(populate_options) / |
573 | sizeof(secuCommandFlag); |
574 | populateArgs.commands = NULL((void*)0); |
575 | populateArgs.options = populate_options; |
576 | |
577 | progName = strrchr(argv[0], '/'); |
578 | if (!progName) |
579 | progName = strrchr(argv[0], '\\'); |
580 | progName = progName ? progName + 1 : argv[0]; |
581 | |
582 | rv = NSS_NoDB_Init(NULL((void*)0)); |
583 | if (rv != SECSuccess) { |
584 | SECU_PrintPRandOSError(progName); |
585 | return -1; |
586 | } |
587 | |
588 | rv = SECU_ParseCommandLine(argc, argv, progName, &populateArgs); |
589 | if (rv == SECFailure) { |
590 | fprintf(stderrstderr, "%s: command line parsing error!\n", progName); |
591 | Usage(progName); |
592 | return -1; |
593 | } |
594 | rv = SECFailure; |
Value stored to 'rv' is never read | |
595 | |
596 | if (populateArgs.options[opt_KeySize].activated) { |
597 | keySize = PORT_Atoi(populateArgs.options[opt_KeySize].arg)(int)strtol(populateArgs.options[opt_KeySize].arg, ((void*)0) , 10); |
598 | } |
599 | if (populateArgs.options[opt_Repeat].activated) { |
600 | repeat = PORT_Atoi(populateArgs.options[opt_Repeat].arg)(int)strtol(populateArgs.options[opt_Repeat].arg, ((void*)0), 10); |
601 | } |
602 | if (populateArgs.options[opt_Exponent].activated) { |
603 | exponent = PORT_Atoi(populateArgs.options[opt_Exponent].arg)(int)strtol(populateArgs.options[opt_Exponent].arg, ((void*)0 ), 10); |
604 | } |
605 | if (populateArgs.options[opt_Tests].activated) { |
606 | char *test_string = populateArgs.options[opt_Tests].arg; |
607 | mask = PORT_Atoi(test_string)(int)strtol(test_string, ((void*)0), 10); |
608 | if (mask == 0) { |
609 | mask = parse_tests(test_string); |
610 | } |
611 | if (mask == 0) { |
612 | Usage(progName); |
613 | return -1; |
614 | } |
615 | } |
616 | |
617 | exp_exp_prime_fail_count = 0; |
618 | for (i = 0; i < repeat; i++) { |
619 | printf("Running RSA Populate test run %d\n", i); |
620 | ret = doRSAPopulateTest(keySize, exponent, mask, i, NULL((void*)0)); |
621 | if (ret != 0) { |
622 | i++; |
623 | break; |
624 | } |
625 | } |
626 | if (ret != 0) { |
627 | fprintf(stderrstderr, "RSA Populate test round %d: FAILED\n", i); |
628 | } |
629 | if (repeat > 1) { |
630 | printf(" pub priv prime test: %d failures out of %d runs (%f %%)\n", |
631 | exp_exp_prime_fail_count, i, |
632 | (((double)exp_exp_prime_fail_count) * 100.0) / (double)i); |
633 | } |
634 | if (NSS_Shutdown() != SECSuccess) { |
635 | fprintf(stderrstderr, "Shutdown failed\n"); |
636 | ret = -1; |
637 | } |
638 | return ret; |
639 | } |