]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/keyHashAsym/keyHashAsym.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / keyHashAsym / keyHashAsym.c
1 /*
2 * keyHashAsym.c - CSSM_APPLECSP_KEYDIGEST passthrough test for all
3 * known asymmetric algorithms and key formats
4 */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <time.h>
9 #include <string.h>
10 #include <Security/cssm.h>
11 #include "cspwrap.h"
12 #include "common.h"
13 #include "cspdlTesting.h"
14 #include <security_cdsa_utils/cuFileIo.h>
15
16 #define USAGE_NAME "noUsage"
17 #define USAGE_NAME_LEN (strlen(USAGE_NAME))
18 #define LOOPS_DEF 10
19
20 #define DSA_PARAM_FILE "dsaParams_512.der"
21 #define DH_PARAM_FILE "dhParams_512.der"
22
23 static void usage(char **argv)
24 {
25 printf("usage: %s [options]\n", argv[0]);
26 printf("Options:\n");
27 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
28 printf(" D (CSP/DL; default = bare CSP)\n");
29 printf(" p(ause on each loop)\n");
30 printf(" q(uiet)\n");
31 printf(" v(erbose))\n");
32 exit(1);
33 }
34
35 static CSSM_DATA dsa512Params;
36 static CSSM_DATA dh512Params;
37
38 /*
39 * Describe parameters for one test iteration.
40 */
41 typedef struct {
42 CSSM_ALGORITHMS keyAlg;
43 CSSM_KEYBLOB_FORMAT pubKeyForm;
44 CSSM_KEYBLOB_FORMAT privKeyForm;
45 uint32 keySizeInBits;
46 CSSM_DATA *algParams; // optional
47 } KeyHashTest;
48
49 KeyHashTest KeyHashTestParams[] =
50 {
51 /* RSA */
52 { CSSM_ALGID_RSA,
53 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_NONE,
54 512, NULL
55 },
56 { CSSM_ALGID_RSA,
57 CSSM_KEYBLOB_RAW_FORMAT_PKCS1, CSSM_KEYBLOB_RAW_FORMAT_NONE,
58 512, NULL
59 },
60 { CSSM_ALGID_RSA,
61 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_NONE,
62 512, NULL
63 },
64 { CSSM_ALGID_RSA,
65 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS1,
66 512, NULL
67 },
68 { CSSM_ALGID_RSA,
69 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
70 512, NULL
71 },
72
73 /* ECDSA */
74 { CSSM_ALGID_ECDSA,
75 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_NONE,
76 192, NULL
77 },
78 { CSSM_ALGID_ECDSA,
79 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
80 256, NULL
81 },
82 { CSSM_ALGID_ECDSA,
83 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
84 384, NULL
85 },
86 { CSSM_ALGID_ECDSA,
87 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
88 521, NULL
89 },
90
91 /* DSA */
92 { CSSM_ALGID_DSA,
93 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_NONE,
94 512, &dsa512Params
95 },
96 { CSSM_ALGID_DSA,
97 CSSM_KEYBLOB_RAW_FORMAT_FIPS186, CSSM_KEYBLOB_RAW_FORMAT_NONE,
98 512, &dsa512Params
99 },
100 { CSSM_ALGID_DSA,
101 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_NONE,
102 512, &dsa512Params
103 },
104 { CSSM_ALGID_DSA,
105 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_FIPS186,
106 512, &dsa512Params
107 },
108 { CSSM_ALGID_DSA,
109 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_OPENSSL,
110 512, &dsa512Params
111 },
112 { CSSM_ALGID_DSA,
113 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
114 512, &dsa512Params
115 },
116 { CSSM_ALGID_DSA,
117 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
118 512, &dsa512Params
119 },
120
121 /* Diffie-Hellman */
122 { CSSM_ALGID_DH,
123 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_NONE,
124 512, &dh512Params
125 },
126 { CSSM_ALGID_DH,
127 CSSM_KEYBLOB_RAW_FORMAT_PKCS3, CSSM_KEYBLOB_RAW_FORMAT_NONE,
128 512, &dh512Params
129 },
130 { CSSM_ALGID_DH,
131 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS3,
132 512, &dh512Params
133 },
134 { CSSM_ALGID_DH,
135 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
136 512, &dh512Params
137 },
138 { CSSM_ALGID_DH,
139 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_NONE,
140 512, &dh512Params
141 },
142 { CSSM_ALGID_DH,
143 CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
144 512, &dh512Params
145 },
146
147 /* FEE */
148 { CSSM_ALGID_FEE,
149 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_NONE,
150 127, NULL
151 },
152 { CSSM_ALGID_FEE,
153 CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING, CSSM_KEYBLOB_RAW_FORMAT_NONE,
154 128, NULL
155 },
156 { CSSM_ALGID_FEE,
157 CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,
158 161, NULL
159 },
160 { CSSM_ALGID_FEE,
161 CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,
162 CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,
163 192, NULL
164 },
165
166 };
167 #define NUM_TEST_PARAMS\
168 (sizeof(KeyHashTestParams) / sizeof(KeyHashTestParams[0]))
169
170 static void dumpBuf(uint8 *buf,
171 unsigned len)
172 {
173 unsigned i;
174
175 printf(" ");
176 for(i=0; i<len; i++) {
177 printf("%02X ", buf[i]);
178 if((i % 24) == 23) {
179 printf("\n ");
180 }
181 }
182 printf("\n");
183 }
184
185 const char *formStr(CSSM_KEYBLOB_FORMAT form)
186 {
187 switch(form) {
188 case CSSM_KEYBLOB_RAW_FORMAT_NONE: return "NONE";
189 case CSSM_KEYBLOB_RAW_FORMAT_PKCS1: return "PKCS1";
190 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3: return "PKCS3";
191 case CSSM_KEYBLOB_RAW_FORMAT_FIPS186: return "FIPS186";
192 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: return "PKCS8";
193 case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING: return "OCTET_STRING";
194 case CSSM_KEYBLOB_RAW_FORMAT_OTHER: return "OTHER";
195 case CSSM_KEYBLOB_RAW_FORMAT_X509: return "X509";
196 case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH: return "OPENSSH";
197 case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL: return "OPENSSL";
198 default:
199 printf("**BRRZAP! formStr needs work\n");
200 exit(1);
201 }
202 }
203
204 const char *algStr(CSSM_ALGORITHMS alg)
205 {
206 switch(alg) {
207 case CSSM_ALGID_RSA: return "RSA";
208 case CSSM_ALGID_DSA: return "DSA";
209 case CSSM_ALGID_DH: return "DH";
210 case CSSM_ALGID_FEE: return "FEE";
211 case CSSM_ALGID_ECDSA: return "ECDSA";
212 default:
213 printf("**BRRZAP! algStr needs work\n");
214 exit(1);
215 }
216 }
217
218 static void showTestParams(KeyHashTest *testParam)
219 {
220 printf("alg %s pubForm %s privForm %s\n",
221 algStr(testParam->keyAlg),
222 formStr(testParam->pubKeyForm),
223 formStr(testParam->privKeyForm));
224
225 }
226
227 /*
228 * Generate key pair of specified alg and raw format.
229 * Alg params are optional, though they are expected to be here
230 * for DH and DSA.
231 */
232 static CSSM_RETURN genKeyPair(
233 CSSM_CSP_HANDLE cspHand,
234 CSSM_ALGORITHMS keyAlg,
235 uint32 keySize, // in bits
236 CSSM_KEY_PTR pubKey,
237 CSSM_KEYBLOB_FORMAT pubFormat,
238 CSSM_KEY_PTR privKey,
239 CSSM_KEYBLOB_FORMAT privFormat,
240 const CSSM_DATA *inParams) // optional
241 {
242 CSSM_RETURN crtn;
243 CSSM_CC_HANDLE ccHand;
244 CSSM_DATA keyLabelData;
245 CSSM_RETURN ocrtn = CSSM_OK;
246
247 keyLabelData.Data = (uint8 *)USAGE_NAME,
248 keyLabelData.Length = USAGE_NAME_LEN;
249 memset(pubKey, 0, sizeof(CSSM_KEY));
250 memset(privKey, 0, sizeof(CSSM_KEY));
251
252 crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
253 keyAlg,
254 keySize,
255 NULL, // Seed
256 NULL, // Salt
257 NULL, // StartDate
258 NULL, // EndDate
259 inParams, // Params, may be NULL
260 &ccHand);
261 if(crtn) {
262 printError("CSSM_CSP_CreateKeyGenContext", crtn);
263 return crtn;
264 }
265
266 /* optional format specifiers */
267 if(pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) {
268 crtn = AddContextAttribute(ccHand,
269 CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT,
270 sizeof(uint32),
271 CAT_Uint32,
272 NULL,
273 pubFormat);
274 if(crtn) {
275 printError("AddContextAttribute("
276 "CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn);
277 return crtn;
278 }
279 }
280 if(privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) {
281 crtn = AddContextAttribute(ccHand,
282 CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT,
283 sizeof(uint32),
284 CAT_Uint32,
285 NULL,
286 privFormat);
287 if(crtn) {
288 printError("AddContextAttribute("
289 "CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn);
290 return crtn;
291 }
292 }
293 CSSM_KEYATTR_FLAGS attrFlags = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
294 crtn = CSSM_GenerateKeyPair(ccHand,
295 CSSM_KEYUSE_DERIVE,
296 attrFlags,
297 &keyLabelData,
298 pubKey,
299 CSSM_KEYUSE_DERIVE,
300 attrFlags,
301 &keyLabelData, // same labels
302 NULL, // CredAndAclEntry
303 privKey);
304 if(crtn) {
305 printError("CSSM_GenerateKeyPair", crtn);
306 ocrtn = crtn;
307 }
308 if(ccHand != 0) {
309 crtn = CSSM_DeleteContext(ccHand);
310 if(crtn) {
311 printError("CSSM_DeleteContext", crtn);
312 ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
313 }
314 }
315 return ocrtn;
316 }
317
318 /*
319 * Given two keys (presumably, in this test, one a raw key and
320 * one an equivalent ref key), calculate the key digest of both of them
321 * and ensure they're the same.
322 */
323 static int compareKeyHashes(
324 const CSSM_DATA *key1Hash,
325 const char *key1Descr,
326 const CSSM_DATA *key2Hash,
327 const char *key2Descr,
328 CSSM_BOOL verbose)
329 {
330 if(appCompareCssmData(key1Hash, key2Hash)) {
331 return 0;
332 }
333 printf("***Key Digest miscompare (%s,%s)***\n", key1Descr, key2Descr);
334 if(!verbose) {
335 printf("...%s hash:\n", key1Descr);
336 dumpBuf(key1Hash->Data, key1Hash->Length);
337 printf("...%s hash:\n", key2Descr);
338 dumpBuf(key2Hash->Data, key2Hash->Length);
339 }
340 return 1;
341 }
342
343 /*
344 * Given a KeyHashTest:
345 * -- cook up key pair, raw, specified formats
346 * -- NULL unwrap each raw to ref;
347 * -- obtain four key digests;
348 * -- ensure all digests match;
349 */
350 static int doTest(
351 CSSM_CSP_HANDLE rawCspHand, // generate keys here
352 CSSM_CSP_HANDLE refCspHand, // null unwrap here
353 KeyHashTest *testParam,
354 CSSM_BOOL verbose,
355 CSSM_BOOL quiet)
356 {
357 CSSM_RETURN crtn;
358 CSSM_KEY pubKey;
359 CSSM_KEY privKey;
360 CSSM_KEY pubKeyRef;
361 CSSM_KEY privKeyRef;
362 CSSM_DATA_PTR rawPubHash;
363 CSSM_DATA_PTR rawPrivHash;
364 CSSM_DATA_PTR refPubHash;
365 CSSM_DATA_PTR refPrivHash;
366 int rtn = 0;
367
368 /* generate key pair, specified raw form */
369 crtn = genKeyPair(rawCspHand,
370 testParam->keyAlg,
371 testParam->keySizeInBits,
372 &pubKey,
373 testParam->pubKeyForm,
374 &privKey,
375 testParam->privKeyForm,
376 testParam->algParams);
377 if(crtn) {
378 return testError(quiet);
379 }
380
381 /* null unwrap both raw keys to ref form */
382 crtn = cspRawKeyToRef(refCspHand, &pubKey, &pubKeyRef);
383 if(crtn) {
384 return testError(quiet);
385 }
386 crtn = cspRawKeyToRef(refCspHand, &privKey, &privKeyRef);
387 if(crtn) {
388 return testError(quiet);
389 }
390
391 /* calculate four key digests */
392 crtn = cspKeyHash(rawCspHand, &pubKey, &rawPubHash);
393 if(crtn) {
394 return testError(quiet);
395 }
396 crtn = cspKeyHash(rawCspHand, &privKey, &rawPrivHash);
397 if(crtn) {
398 return testError(quiet);
399 }
400 crtn = cspKeyHash(refCspHand, &pubKeyRef, &refPubHash);
401 if(crtn) {
402 return testError(quiet);
403 }
404 crtn = cspKeyHash(refCspHand, &privKeyRef, &refPrivHash);
405 if(crtn) {
406 return testError(quiet);
407 }
408
409 if(verbose) {
410 printf("...raw pub key hash:\n");
411 dumpBuf(rawPubHash->Data, rawPubHash->Length);
412 printf("...ref pub key hash:\n");
413 dumpBuf(refPubHash->Data, refPubHash->Length);
414 printf("...raw priv key hash:\n");
415 dumpBuf(rawPrivHash->Data, rawPrivHash->Length);
416 printf("...ref priv key hash:\n");
417 dumpBuf(refPrivHash->Data, refPrivHash->Length);
418 }
419
420 /* compare */
421 rtn += compareKeyHashes(rawPubHash, "Raw public",
422 refPubHash, "Ref public", verbose);
423 rtn += compareKeyHashes(rawPrivHash, "Raw private",
424 refPrivHash, "Ref private", verbose);
425 rtn += compareKeyHashes(refPubHash, "Ref public",
426 refPrivHash, "Ref private", verbose);
427 if(rtn) {
428 rtn = testError(quiet);
429 }
430 cspFreeKey(rawCspHand, &pubKey);
431 cspFreeKey(rawCspHand, &privKey);
432 cspFreeKey(refCspHand, &pubKeyRef);
433 cspFreeKey(refCspHand, &privKeyRef);
434 appFreeCssmData(rawPubHash, CSSM_TRUE);
435 appFreeCssmData(rawPrivHash, CSSM_TRUE);
436 appFreeCssmData(refPubHash, CSSM_TRUE);
437 appFreeCssmData(refPrivHash, CSSM_TRUE);
438 return rtn;
439 }
440
441 int main(int argc, char **argv)
442 {
443 int arg;
444 char *argp;
445 unsigned loop;
446 CSSM_CSP_HANDLE rawCspHand; // always Raw CSP
447 CSSM_CSP_HANDLE refCspHand; // CSPDL if !bareCsp
448 int rtn = 0;
449 int i;
450 unsigned len;
451
452 /*
453 * User-spec'd params
454 */
455 unsigned loops = LOOPS_DEF;
456 CSSM_BOOL verbose = CSSM_FALSE;
457 CSSM_BOOL quiet = CSSM_FALSE;
458 CSSM_BOOL bareCsp = CSSM_TRUE;
459 CSSM_BOOL doPause = CSSM_FALSE;
460
461 for(arg=1; arg<argc; arg++) {
462 argp = argv[arg];
463 switch(argp[0]) {
464 case 'l':
465 loops = atoi(&argp[2]);
466 break;
467 case 'D':
468 bareCsp = CSSM_FALSE;
469 break;
470 case 'p':
471 doPause = CSSM_TRUE;
472 break;
473 case 'v':
474 verbose = CSSM_TRUE;
475 break;
476 case 'q':
477 quiet = CSSM_TRUE;
478 break;
479 case 'h':
480 default:
481 usage(argv);
482 }
483 }
484
485 /* prefetch the alg params */
486 rtn = readFile(DSA_PARAM_FILE, &dsa512Params.Data, &len);
487 if(rtn) {
488 printf("***%s file missing. Aborting.\n", DSA_PARAM_FILE);
489 exit(1);
490 }
491 dsa512Params.Length = len;
492 rtn = readFile(DH_PARAM_FILE, &dh512Params.Data, &len);
493 if(rtn) {
494 printf("***%s file missing. Aborting.\n", DH_PARAM_FILE);
495 exit(1);
496 }
497 dh512Params.Length = len;
498
499 printf("Starting keyHashAsym; args: ");
500 for(i=1; i<argc; i++) {
501 printf("%s ", argv[i]);
502 }
503 printf("\n");
504 refCspHand = cspDlDbStartup(bareCsp, NULL);
505 if(refCspHand == 0) {
506 exit(1);
507 }
508 if(bareCsp) {
509 /* raw and ref on same CSP */
510 rawCspHand = refCspHand;
511 }
512 else {
513 /* generate on CSPDL, NULL unwrap to bare CSP */
514 rawCspHand = cspDlDbStartup(CSSM_TRUE, NULL);
515 if(rawCspHand == 0) {
516 exit(1);
517 }
518 }
519 for(loop=1; ; loop++) {
520 if(!quiet) {
521 printf("...loop %d\n", loop);
522 }
523 for(unsigned testNum=0; testNum<NUM_TEST_PARAMS; testNum++) {
524 KeyHashTest *testParams = &KeyHashTestParams[testNum];
525 if(!quiet) {
526 printf("..."); showTestParams(testParams);
527 }
528 rtn = doTest(rawCspHand, refCspHand, testParams, verbose, quiet);
529 if(rtn) {
530 goto done;
531 }
532 if(doPause) {
533 fpurge(stdin);
534 printf("Hit CR to proceed: ");
535 getchar();
536 }
537 }
538 if(loops && (loop == loops)) {
539 break;
540 }
541 }
542 done:
543 if((rtn == 0) && !quiet) {
544 printf("...%s complete\n", argv[0]);
545 }
546 return rtn;
547 }