Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #include <stdio.h> |
michael@0 | 6 | #include <stdlib.h> |
michael@0 | 7 | #include "plgetopt.h" |
michael@0 | 8 | #include "nss.h" |
michael@0 | 9 | #include "secutil.h" |
michael@0 | 10 | #include "pk11table.h" |
michael@0 | 11 | #include "secmodt.h" |
michael@0 | 12 | #include "pk11pub.h" |
michael@0 | 13 | |
michael@0 | 14 | |
michael@0 | 15 | struct test_args { |
michael@0 | 16 | char *arg; |
michael@0 | 17 | int mask_value; |
michael@0 | 18 | char *description; |
michael@0 | 19 | }; |
michael@0 | 20 | |
michael@0 | 21 | static const struct test_args test_array[] = { |
michael@0 | 22 | {"all", 0x1f, "run all the tests" }, |
michael@0 | 23 | {"e_n_p", 0x01, "public exponent, modulus, prime1"}, |
michael@0 | 24 | {"d_n_q", 0x02, "private exponent, modulus, prime2"}, |
michael@0 | 25 | {"d_p_q", 0x04, "private exponent, prime1, prime2"}, |
michael@0 | 26 | {"e_d_q", 0x08, "public exponent, private exponent, prime2"}, |
michael@0 | 27 | {"e_d_n", 0x10, "public exponent, private exponent, moduls"} |
michael@0 | 28 | }; |
michael@0 | 29 | static const int test_array_size = |
michael@0 | 30 | (sizeof(test_array)/sizeof(struct test_args)); |
michael@0 | 31 | |
michael@0 | 32 | static void Usage(char *progName) |
michael@0 | 33 | { |
michael@0 | 34 | int i; |
michael@0 | 35 | #define PRINTUSAGE(subject, option, predicate) \ |
michael@0 | 36 | fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate); |
michael@0 | 37 | fprintf(stderr, "%s [-k keysize] [-e exp] [-r rounds] [-t tests]\n " |
michael@0 | 38 | "Test creating RSA private keys from Partial components\n", |
michael@0 | 39 | progName); |
michael@0 | 40 | PRINTUSAGE("", "-k", "key size (in bit)"); |
michael@0 | 41 | PRINTUSAGE("", "-e", "rsa public exponent"); |
michael@0 | 42 | PRINTUSAGE("", "-r", "number times to repeat the test"); |
michael@0 | 43 | PRINTUSAGE("", "-t", "run the specified tests"); |
michael@0 | 44 | for (i=0; i < test_array_size; i++) { |
michael@0 | 45 | PRINTUSAGE("", test_array[i].arg, test_array[i].description); |
michael@0 | 46 | } |
michael@0 | 47 | fprintf(stderr,"\n"); |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | /* |
michael@0 | 51 | * Test the RSA populate command to see that it can really build |
michael@0 | 52 | * keys from it's components. |
michael@0 | 53 | */ |
michael@0 | 54 | |
michael@0 | 55 | const static CK_ATTRIBUTE rsaTemplate[] = { |
michael@0 | 56 | {CKA_CLASS, NULL, 0 }, |
michael@0 | 57 | {CKA_KEY_TYPE, NULL, 0 }, |
michael@0 | 58 | {CKA_TOKEN, NULL, 0 }, |
michael@0 | 59 | {CKA_SENSITIVE, NULL, 0 }, |
michael@0 | 60 | {CKA_PRIVATE, NULL, 0 }, |
michael@0 | 61 | {CKA_MODULUS, NULL, 0 }, |
michael@0 | 62 | {CKA_PUBLIC_EXPONENT, NULL, 0 }, |
michael@0 | 63 | {CKA_PRIVATE_EXPONENT, NULL, 0 }, |
michael@0 | 64 | {CKA_PRIME_1, NULL, 0 }, |
michael@0 | 65 | {CKA_PRIME_2, NULL, 0 }, |
michael@0 | 66 | {CKA_EXPONENT_1, NULL, 0 }, |
michael@0 | 67 | {CKA_EXPONENT_2, NULL, 0 }, |
michael@0 | 68 | {CKA_COEFFICIENT, NULL, 0 }, |
michael@0 | 69 | }; |
michael@0 | 70 | |
michael@0 | 71 | #define RSA_SIZE (sizeof(rsaTemplate)) |
michael@0 | 72 | #define RSA_ATTRIBUTES (sizeof(rsaTemplate)/sizeof(CK_ATTRIBUTE)) |
michael@0 | 73 | |
michael@0 | 74 | static void |
michael@0 | 75 | resetTemplate(CK_ATTRIBUTE *attribute, int start, int end) |
michael@0 | 76 | { |
michael@0 | 77 | int i; |
michael@0 | 78 | for (i=start; i < end; i++) { |
michael@0 | 79 | if (attribute[i].pValue) { |
michael@0 | 80 | PORT_Free(attribute[i].pValue); |
michael@0 | 81 | } |
michael@0 | 82 | attribute[i].pValue = NULL; |
michael@0 | 83 | attribute[i].ulValueLen = 0; |
michael@0 | 84 | } |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | static SECStatus |
michael@0 | 88 | copyAttribute(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template, |
michael@0 | 89 | int offset, CK_ATTRIBUTE_TYPE attrType) |
michael@0 | 90 | { |
michael@0 | 91 | SECItem attributeItem = {0, 0, 0}; |
michael@0 | 92 | SECStatus rv; |
michael@0 | 93 | |
michael@0 | 94 | rv = PK11_ReadRawAttribute(objType, object, attrType, &attributeItem); |
michael@0 | 95 | if (rv != SECSuccess) { |
michael@0 | 96 | return rv; |
michael@0 | 97 | } |
michael@0 | 98 | template[offset].type = attrType; |
michael@0 | 99 | template[offset].pValue = attributeItem.data; |
michael@0 | 100 | template[offset].ulValueLen = attributeItem.len; |
michael@0 | 101 | return SECSuccess; |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | static SECStatus |
michael@0 | 105 | readKey(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template, |
michael@0 | 106 | int start, int end) |
michael@0 | 107 | { |
michael@0 | 108 | int i; |
michael@0 | 109 | SECStatus rv; |
michael@0 | 110 | |
michael@0 | 111 | for (i=start; i < end; i++) { |
michael@0 | 112 | rv = copyAttribute(objType, object, template, i, template[i].type); |
michael@0 | 113 | if (rv != SECSuccess) { |
michael@0 | 114 | goto fail; |
michael@0 | 115 | } |
michael@0 | 116 | } |
michael@0 | 117 | return SECSuccess; |
michael@0 | 118 | |
michael@0 | 119 | fail: |
michael@0 | 120 | resetTemplate(template, start, i); |
michael@0 | 121 | return rv; |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | #define ATTR_STRING(x) getNameFromAttribute(x) |
michael@0 | 125 | |
michael@0 | 126 | void |
michael@0 | 127 | dumpTemplate(CK_ATTRIBUTE *template, int start, int end) |
michael@0 | 128 | { |
michael@0 | 129 | int i,j; |
michael@0 | 130 | for (i=0; i < end; i++) { |
michael@0 | 131 | unsigned char cval; |
michael@0 | 132 | CK_ULONG ulval; |
michael@0 | 133 | unsigned char *cpval; |
michael@0 | 134 | |
michael@0 | 135 | fprintf(stderr, "%s:", ATTR_STRING(template[i].type)); |
michael@0 | 136 | switch (template[i].ulValueLen) { |
michael@0 | 137 | case 1: |
michael@0 | 138 | cval =*(unsigned char *)template[i].pValue; |
michael@0 | 139 | switch(cval) { |
michael@0 | 140 | case 0: fprintf(stderr, " false"); break; |
michael@0 | 141 | case 1: fprintf(stderr, " true"); break; |
michael@0 | 142 | default: |
michael@0 | 143 | fprintf(stderr, " %d (=0x%02x,'%c')",cval,cval,cval); |
michael@0 | 144 | break; |
michael@0 | 145 | } |
michael@0 | 146 | break; |
michael@0 | 147 | case sizeof(CK_ULONG): |
michael@0 | 148 | ulval = *(CK_ULONG *)template[i].pValue; |
michael@0 | 149 | fprintf(stderr," %ld (=0x%04lx)", ulval, ulval); |
michael@0 | 150 | break; |
michael@0 | 151 | default: |
michael@0 | 152 | cpval = (unsigned char *)template[i].pValue; |
michael@0 | 153 | for (j=0; j < template[i].ulValueLen; j++) { |
michael@0 | 154 | if ((j % 16) == 0) fprintf(stderr, "\n "); |
michael@0 | 155 | fprintf(stderr," %02x",cpval[j]); |
michael@0 | 156 | } |
michael@0 | 157 | break; |
michael@0 | 158 | } |
michael@0 | 159 | fprintf(stderr,"\n"); |
michael@0 | 160 | } |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | PRBool |
michael@0 | 164 | rsaKeysAreEqual(PK11ObjectType srcType, void *src, |
michael@0 | 165 | PK11ObjectType destType, void *dest) |
michael@0 | 166 | { |
michael@0 | 167 | |
michael@0 | 168 | CK_ATTRIBUTE srcTemplate[RSA_ATTRIBUTES]; |
michael@0 | 169 | CK_ATTRIBUTE destTemplate[RSA_ATTRIBUTES]; |
michael@0 | 170 | PRBool areEqual = PR_TRUE; |
michael@0 | 171 | SECStatus rv; |
michael@0 | 172 | int i; |
michael@0 | 173 | |
michael@0 | 174 | memcpy(srcTemplate, rsaTemplate, RSA_SIZE); |
michael@0 | 175 | memcpy(destTemplate, rsaTemplate, RSA_SIZE); |
michael@0 | 176 | |
michael@0 | 177 | rv = readKey(srcType, src, srcTemplate, 0, RSA_ATTRIBUTES); |
michael@0 | 178 | if (rv != SECSuccess) { |
michael@0 | 179 | printf("Could read source key\n"); |
michael@0 | 180 | return PR_FALSE; |
michael@0 | 181 | } |
michael@0 | 182 | readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES); |
michael@0 | 183 | if (rv != SECSuccess) { |
michael@0 | 184 | printf("Could read dest key\n"); |
michael@0 | 185 | return PR_FALSE; |
michael@0 | 186 | } |
michael@0 | 187 | |
michael@0 | 188 | for (i=0; i < RSA_ATTRIBUTES; i++) { |
michael@0 | 189 | if (srcTemplate[i].ulValueLen != destTemplate[i].ulValueLen) { |
michael@0 | 190 | printf("key->%s not equal src_len = %ld, dest_len=%ld\n", |
michael@0 | 191 | ATTR_STRING(srcTemplate[i].type), |
michael@0 | 192 | srcTemplate[i].ulValueLen, destTemplate[i].ulValueLen); |
michael@0 | 193 | areEqual = 0; |
michael@0 | 194 | } else if (memcmp(srcTemplate[i].pValue, destTemplate[i].pValue, |
michael@0 | 195 | destTemplate[i].ulValueLen) != 0) { |
michael@0 | 196 | printf("key->%s not equal.\n", ATTR_STRING(srcTemplate[i].type)); |
michael@0 | 197 | areEqual = 0; |
michael@0 | 198 | } |
michael@0 | 199 | } |
michael@0 | 200 | if (!areEqual) { |
michael@0 | 201 | fprintf(stderr, "original key:\n"); |
michael@0 | 202 | dumpTemplate(srcTemplate,0, RSA_ATTRIBUTES); |
michael@0 | 203 | fprintf(stderr, "created key:\n"); |
michael@0 | 204 | dumpTemplate(destTemplate,0, RSA_ATTRIBUTES); |
michael@0 | 205 | } |
michael@0 | 206 | return areEqual; |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | static int exp_exp_prime_fail_count = 0; |
michael@0 | 210 | |
michael@0 | 211 | static int |
michael@0 | 212 | doRSAPopulateTest(unsigned int keySize, unsigned long exponent, |
michael@0 | 213 | int mask, void *pwarg) |
michael@0 | 214 | { |
michael@0 | 215 | SECKEYPrivateKey *rsaPrivKey; |
michael@0 | 216 | SECKEYPublicKey *rsaPubKey; |
michael@0 | 217 | PK11GenericObject *tstPrivKey; |
michael@0 | 218 | CK_ATTRIBUTE tstTemplate[RSA_ATTRIBUTES]; |
michael@0 | 219 | int tstHeaderCount; |
michael@0 | 220 | PK11SlotInfo *slot = NULL; |
michael@0 | 221 | PK11RSAGenParams rsaParams; |
michael@0 | 222 | CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; |
michael@0 | 223 | CK_KEY_TYPE key_type = CKK_RSA; |
michael@0 | 224 | CK_BBOOL ck_false = CK_FALSE; |
michael@0 | 225 | int failed = 0; |
michael@0 | 226 | |
michael@0 | 227 | rsaParams.pe = exponent; |
michael@0 | 228 | rsaParams.keySizeInBits = keySize; |
michael@0 | 229 | |
michael@0 | 230 | slot = PK11_GetInternalSlot(); |
michael@0 | 231 | if (slot == NULL) { |
michael@0 | 232 | fprintf(stderr, "Couldn't get the internal slot for the test \n"); |
michael@0 | 233 | return -1; |
michael@0 | 234 | } |
michael@0 | 235 | |
michael@0 | 236 | rsaPrivKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, |
michael@0 | 237 | &rsaParams, &rsaPubKey, PR_FALSE, |
michael@0 | 238 | PR_FALSE, pwarg); |
michael@0 | 239 | if (rsaPrivKey == NULL) { |
michael@0 | 240 | fprintf(stderr, "RSA Key Gen failed"); |
michael@0 | 241 | PK11_FreeSlot(slot); |
michael@0 | 242 | return -1; |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | memcpy(tstTemplate, rsaTemplate, RSA_SIZE); |
michael@0 | 246 | |
michael@0 | 247 | tstTemplate[0].pValue = &obj_class; |
michael@0 | 248 | tstTemplate[0].ulValueLen = sizeof(obj_class); |
michael@0 | 249 | tstTemplate[1].pValue = &key_type; |
michael@0 | 250 | tstTemplate[1].ulValueLen = sizeof(key_type); |
michael@0 | 251 | tstTemplate[2].pValue = &ck_false; |
michael@0 | 252 | tstTemplate[2].ulValueLen = sizeof(ck_false); |
michael@0 | 253 | tstTemplate[3].pValue = &ck_false; |
michael@0 | 254 | tstTemplate[3].ulValueLen = sizeof(ck_false); |
michael@0 | 255 | tstTemplate[4].pValue = &ck_false; |
michael@0 | 256 | tstTemplate[4].ulValueLen = sizeof(ck_false); |
michael@0 | 257 | tstHeaderCount = 5; |
michael@0 | 258 | |
michael@0 | 259 | if (mask & 1) { |
michael@0 | 260 | printf("%s\n",test_array[1].description); |
michael@0 | 261 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
michael@0 | 262 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 263 | tstHeaderCount, CKA_PUBLIC_EXPONENT); |
michael@0 | 264 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 265 | tstHeaderCount+1, CKA_MODULUS); |
michael@0 | 266 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 267 | tstHeaderCount+2, CKA_PRIME_1); |
michael@0 | 268 | |
michael@0 | 269 | tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
michael@0 | 270 | tstHeaderCount+3, PR_FALSE); |
michael@0 | 271 | if (tstPrivKey == NULL) { |
michael@0 | 272 | fprintf(stderr, "RSA Populate failed: pubExp mod p\n"); |
michael@0 | 273 | failed = 1; |
michael@0 | 274 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
michael@0 | 275 | PK11_TypeGeneric, tstPrivKey)) { |
michael@0 | 276 | fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n"); |
michael@0 | 277 | failed = 1; |
michael@0 | 278 | } |
michael@0 | 279 | if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
michael@0 | 280 | } |
michael@0 | 281 | if (mask & 2) { |
michael@0 | 282 | printf("%s\n",test_array[2].description); |
michael@0 | 283 | /* test the basic2 case, public exponent, modulus, prime2 */ |
michael@0 | 284 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
michael@0 | 285 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 286 | tstHeaderCount, CKA_PUBLIC_EXPONENT); |
michael@0 | 287 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 288 | tstHeaderCount+1, CKA_MODULUS); |
michael@0 | 289 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 290 | tstHeaderCount+2, CKA_PRIME_2); |
michael@0 | 291 | /* test with q in the prime1 position */ |
michael@0 | 292 | tstTemplate[tstHeaderCount+2].type = CKA_PRIME_1; |
michael@0 | 293 | |
michael@0 | 294 | tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
michael@0 | 295 | tstHeaderCount+3, PR_FALSE); |
michael@0 | 296 | if (tstPrivKey == NULL) { |
michael@0 | 297 | fprintf(stderr, "RSA Populate failed: pubExp mod q\n"); |
michael@0 | 298 | failed = 1; |
michael@0 | 299 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
michael@0 | 300 | PK11_TypeGeneric, tstPrivKey)) { |
michael@0 | 301 | fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n"); |
michael@0 | 302 | failed = 1; |
michael@0 | 303 | } |
michael@0 | 304 | if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
michael@0 | 305 | } |
michael@0 | 306 | if (mask & 4) { |
michael@0 | 307 | printf("%s\n",test_array[3].description); |
michael@0 | 308 | /* test the medium case, private exponent, prime1, prime2 */ |
michael@0 | 309 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
michael@0 | 310 | |
michael@0 | 311 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 312 | tstHeaderCount, CKA_PRIVATE_EXPONENT); |
michael@0 | 313 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 314 | tstHeaderCount+1, CKA_PRIME_1); |
michael@0 | 315 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 316 | tstHeaderCount+2, CKA_PRIME_2); |
michael@0 | 317 | /* test with p & q swapped. Underlying code should swap these back */ |
michael@0 | 318 | tstTemplate[tstHeaderCount+2].type = CKA_PRIME_1; |
michael@0 | 319 | tstTemplate[tstHeaderCount+1].type = CKA_PRIME_2; |
michael@0 | 320 | |
michael@0 | 321 | tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
michael@0 | 322 | tstHeaderCount+3, PR_FALSE); |
michael@0 | 323 | if (tstPrivKey == NULL) { |
michael@0 | 324 | fprintf(stderr, "RSA Populate failed: privExp p q\n"); |
michael@0 | 325 | failed = 1; |
michael@0 | 326 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
michael@0 | 327 | PK11_TypeGeneric, tstPrivKey)) { |
michael@0 | 328 | fprintf(stderr, "RSA Populate key mismatch: privExp p q\n"); |
michael@0 | 329 | failed = 1; |
michael@0 | 330 | } |
michael@0 | 331 | if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
michael@0 | 332 | } |
michael@0 | 333 | if (mask & 8) { |
michael@0 | 334 | printf("%s\n",test_array[4].description); |
michael@0 | 335 | /* test the advanced case, public exponent, private exponent, prime2 */ |
michael@0 | 336 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
michael@0 | 337 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 338 | tstHeaderCount, CKA_PRIVATE_EXPONENT); |
michael@0 | 339 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 340 | tstHeaderCount+1, CKA_PUBLIC_EXPONENT); |
michael@0 | 341 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 342 | tstHeaderCount+2, CKA_PRIME_2); |
michael@0 | 343 | |
michael@0 | 344 | tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
michael@0 | 345 | tstHeaderCount+3, PR_FALSE); |
michael@0 | 346 | if (tstPrivKey == NULL) { |
michael@0 | 347 | fprintf(stderr, "RSA Populate failed: pubExp privExp q\n"); |
michael@0 | 348 | fprintf(stderr, " this is expected periodically. It means we\n"); |
michael@0 | 349 | fprintf(stderr, " had more than one key that meets the " |
michael@0 | 350 | "specification\n"); |
michael@0 | 351 | exp_exp_prime_fail_count++; |
michael@0 | 352 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
michael@0 | 353 | PK11_TypeGeneric, tstPrivKey)) { |
michael@0 | 354 | fprintf(stderr, "RSA Populate key mismatch: pubExp privExp q\n"); |
michael@0 | 355 | failed = 1; |
michael@0 | 356 | } |
michael@0 | 357 | if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
michael@0 | 358 | } |
michael@0 | 359 | if (mask & 16) { |
michael@0 | 360 | printf("%s\n",test_array[5].description); |
michael@0 | 361 | /* test the advanced case2, public exponent, private exponent, modulus |
michael@0 | 362 | */ |
michael@0 | 363 | resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
michael@0 | 364 | |
michael@0 | 365 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 366 | tstHeaderCount, CKA_PRIVATE_EXPONENT); |
michael@0 | 367 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 368 | tstHeaderCount+1, CKA_PUBLIC_EXPONENT); |
michael@0 | 369 | copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
michael@0 | 370 | tstHeaderCount+2, CKA_MODULUS); |
michael@0 | 371 | |
michael@0 | 372 | tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
michael@0 | 373 | tstHeaderCount+3, PR_FALSE); |
michael@0 | 374 | if (tstPrivKey == NULL) { |
michael@0 | 375 | fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n"); |
michael@0 | 376 | failed = 1; |
michael@0 | 377 | } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
michael@0 | 378 | PK11_TypeGeneric, tstPrivKey)) { |
michael@0 | 379 | fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n"); |
michael@0 | 380 | failed = 1; |
michael@0 | 381 | } |
michael@0 | 382 | if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
michael@0 | 383 | } |
michael@0 | 384 | |
michael@0 | 385 | |
michael@0 | 386 | PK11_FreeSlot(slot); |
michael@0 | 387 | return failed ? -1 : 0; |
michael@0 | 388 | } |
michael@0 | 389 | |
michael@0 | 390 | /* populate options */ |
michael@0 | 391 | enum { |
michael@0 | 392 | opt_Exponent = 0, |
michael@0 | 393 | opt_KeySize, |
michael@0 | 394 | opt_Repeat, |
michael@0 | 395 | opt_Tests |
michael@0 | 396 | }; |
michael@0 | 397 | |
michael@0 | 398 | static secuCommandFlag populate_options[] = |
michael@0 | 399 | { |
michael@0 | 400 | { /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE }, |
michael@0 | 401 | { /* opt_KeySize */ 'k', PR_TRUE, 0, PR_FALSE }, |
michael@0 | 402 | { /* opt_Repeat */ 'r', PR_TRUE, 0, PR_FALSE }, |
michael@0 | 403 | { /* opt_Tests */ 't', PR_TRUE, 0, PR_FALSE }, |
michael@0 | 404 | }; |
michael@0 | 405 | |
michael@0 | 406 | int |
michael@0 | 407 | is_delimiter(char c) |
michael@0 | 408 | { |
michael@0 | 409 | if ((c=='+') || (c==',') || (c=='|')) { |
michael@0 | 410 | return 1; |
michael@0 | 411 | } |
michael@0 | 412 | return 0; |
michael@0 | 413 | } |
michael@0 | 414 | |
michael@0 | 415 | int |
michael@0 | 416 | parse_tests(char *test_string) |
michael@0 | 417 | { |
michael@0 | 418 | int mask = 0; |
michael@0 | 419 | int i; |
michael@0 | 420 | |
michael@0 | 421 | while (*test_string) { |
michael@0 | 422 | if (is_delimiter(*test_string)) { |
michael@0 | 423 | test_string++; |
michael@0 | 424 | } |
michael@0 | 425 | for (i=0; i < test_array_size; i++) { |
michael@0 | 426 | char *arg = test_array[i].arg; |
michael@0 | 427 | int len = strlen(arg); |
michael@0 | 428 | if (strncmp(test_string,arg,len) == 0) { |
michael@0 | 429 | test_string += len; |
michael@0 | 430 | mask |= test_array[i].mask_value; |
michael@0 | 431 | break; |
michael@0 | 432 | } |
michael@0 | 433 | } |
michael@0 | 434 | if (i == test_array_size) { |
michael@0 | 435 | break; |
michael@0 | 436 | } |
michael@0 | 437 | } |
michael@0 | 438 | return mask; |
michael@0 | 439 | } |
michael@0 | 440 | |
michael@0 | 441 | int main(int argc, char **argv) |
michael@0 | 442 | { |
michael@0 | 443 | unsigned int keySize = 1024; |
michael@0 | 444 | unsigned long exponent = 65537; |
michael@0 | 445 | int i, repeat = 1, ret = 0; |
michael@0 | 446 | SECStatus rv = SECFailure; |
michael@0 | 447 | secuCommand populateArgs; |
michael@0 | 448 | char *progName; |
michael@0 | 449 | int mask = 0xff; |
michael@0 | 450 | |
michael@0 | 451 | populateArgs.numCommands = 0; |
michael@0 | 452 | populateArgs.numOptions = sizeof(populate_options) / |
michael@0 | 453 | sizeof(secuCommandFlag); |
michael@0 | 454 | populateArgs.commands = NULL; |
michael@0 | 455 | populateArgs.options = populate_options; |
michael@0 | 456 | |
michael@0 | 457 | progName = strrchr(argv[0], '/'); |
michael@0 | 458 | if (!progName) |
michael@0 | 459 | progName = strrchr(argv[0], '\\'); |
michael@0 | 460 | progName = progName ? progName+1 : argv[0]; |
michael@0 | 461 | |
michael@0 | 462 | rv = NSS_NoDB_Init(NULL); |
michael@0 | 463 | if (rv != SECSuccess) { |
michael@0 | 464 | SECU_PrintPRandOSError(progName); |
michael@0 | 465 | return -1; |
michael@0 | 466 | } |
michael@0 | 467 | |
michael@0 | 468 | rv = SECU_ParseCommandLine(argc, argv, progName, &populateArgs); |
michael@0 | 469 | if (rv == SECFailure) { |
michael@0 | 470 | fprintf(stderr, "%s: command line parsing error!\n", progName); |
michael@0 | 471 | Usage(progName); |
michael@0 | 472 | return -1; |
michael@0 | 473 | } |
michael@0 | 474 | rv = SECFailure; |
michael@0 | 475 | |
michael@0 | 476 | |
michael@0 | 477 | if (populateArgs.options[opt_KeySize].activated) { |
michael@0 | 478 | keySize = PORT_Atoi(populateArgs.options[opt_KeySize].arg); |
michael@0 | 479 | } |
michael@0 | 480 | if (populateArgs.options[opt_Repeat].activated) { |
michael@0 | 481 | repeat = PORT_Atoi(populateArgs.options[opt_Repeat].arg); |
michael@0 | 482 | } |
michael@0 | 483 | if (populateArgs.options[opt_Exponent].activated) { |
michael@0 | 484 | exponent = PORT_Atoi(populateArgs.options[opt_Exponent].arg); |
michael@0 | 485 | } |
michael@0 | 486 | if (populateArgs.options[opt_Tests].activated) { |
michael@0 | 487 | char * test_string = populateArgs.options[opt_Tests].arg; |
michael@0 | 488 | mask = PORT_Atoi(test_string); |
michael@0 | 489 | if (mask == 0) { |
michael@0 | 490 | mask = parse_tests(test_string); |
michael@0 | 491 | } |
michael@0 | 492 | if (mask == 0) { |
michael@0 | 493 | Usage(progName); |
michael@0 | 494 | return -1; |
michael@0 | 495 | } |
michael@0 | 496 | } |
michael@0 | 497 | |
michael@0 | 498 | exp_exp_prime_fail_count = 0; |
michael@0 | 499 | for (i=0; i < repeat; i++) { |
michael@0 | 500 | printf("Running RSA Populate test run %d\n",i); |
michael@0 | 501 | ret = doRSAPopulateTest(keySize, exponent, mask, NULL); |
michael@0 | 502 | if (ret != 0) { |
michael@0 | 503 | i++; |
michael@0 | 504 | break; |
michael@0 | 505 | } |
michael@0 | 506 | } |
michael@0 | 507 | if (ret != 0) { |
michael@0 | 508 | fprintf(stderr,"RSA Populate test round %d: FAILED\n",i); |
michael@0 | 509 | } |
michael@0 | 510 | if (repeat > 1) { |
michael@0 | 511 | printf(" pub priv prime test: %d failures out of %d runs (%f %%)\n", |
michael@0 | 512 | exp_exp_prime_fail_count, i, |
michael@0 | 513 | (((double)exp_exp_prime_fail_count) * 100.0)/(double) i); |
michael@0 | 514 | } |
michael@0 | 515 | return ret; |
michael@0 | 516 | } |