Bug Summary

File:s/cmd/rsapoptst/rsapoptst.c
Warning:line 594, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name rsapoptst.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/rsapoptst -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/rsapoptst -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -I ../../../dist/public/seccmd -I ../../../dist/public/dbm -I ../../../dist/public/softoken -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c rsapoptst.c
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
14struct test_args {
15 char *arg;
16 int mask_value;
17 char *description;
18};
19
20static 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};
28static const int test_array_size =
29 (sizeof(test_array) / sizeof(struct test_args));
30
31static void
32Usage(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
55const 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
75static void
76resetTemplate(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
88static SECStatus
89copyAttribute(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
105static SECStatus
106readKey(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
120fail:
121 resetTemplate(template, start, i);
122 return rv;
123}
124
125#define ATTR_STRING(x)getNameFromAttribute(x) getNameFromAttribute(x)
126
127static void
128dumphex(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
139void
140dumpTemplate(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
177void
178dumpItem(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
200PRBool
201rsaKeysAreEqual(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
251static int exp_exp_prime_fail_count = 0;
252
253#define LEAK_ID0xf 0xf
254
255static int
256doRSAPopulateTest(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 */
511enum {
512 opt_Exponent = 0,
513 opt_KeySize,
514 opt_Repeat,
515 opt_Tests
516};
517
518static 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
525int
526is_delimiter(char c)
527{
528 if ((c == '+') || (c == ',') || (c == '|')) {
529 return 1;
530 }
531 return 0;
532}
533
534int
535parse_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
560int
561main(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}