2 * keyHashAsym.c - CSSM_APPLECSP_KEYDIGEST passthrough test for all
3 * known asymmetric algorithms and key formats
10 #include <Security/cssm.h>
13 #include "cspdlTesting.h"
14 #include <security_cdsa_utils/cuFileIo.h>
16 #define USAGE_NAME "noUsage"
17 #define USAGE_NAME_LEN (strlen(USAGE_NAME))
20 #define DSA_PARAM_FILE "dsaParams_512.der"
21 #define DH_PARAM_FILE "dhParams_512.der"
23 static void usage(char **argv
)
25 printf("usage: %s [options]\n", argv
[0]);
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");
31 printf(" v(erbose))\n");
35 static CSSM_DATA dsa512Params
;
36 static CSSM_DATA dh512Params
;
39 * Describe parameters for one test iteration.
42 CSSM_ALGORITHMS keyAlg
;
43 CSSM_KEYBLOB_FORMAT pubKeyForm
;
44 CSSM_KEYBLOB_FORMAT privKeyForm
;
46 CSSM_DATA
*algParams
; // optional
49 KeyHashTest KeyHashTestParams
[] =
53 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
57 CSSM_KEYBLOB_RAW_FORMAT_PKCS1
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
61 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
65 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_PKCS1
,
69 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
75 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
79 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
83 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
87 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
93 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
97 CSSM_KEYBLOB_RAW_FORMAT_FIPS186
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
101 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
105 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_FIPS186
,
109 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_OPENSSL
,
113 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
117 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
123 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
127 CSSM_KEYBLOB_RAW_FORMAT_PKCS3
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
131 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_PKCS3
,
135 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
139 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
143 CSSM_KEYBLOB_RAW_FORMAT_X509
, CSSM_KEYBLOB_RAW_FORMAT_PKCS8
,
149 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
153 CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING
, CSSM_KEYBLOB_RAW_FORMAT_NONE
,
157 CSSM_KEYBLOB_RAW_FORMAT_NONE
, CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING
,
161 CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING
,
162 CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING
,
167 #define NUM_TEST_PARAMS\
168 (sizeof(KeyHashTestParams) / sizeof(KeyHashTestParams[0]))
170 static void dumpBuf(uint8
*buf
,
176 for(i
=0; i
<len
; i
++) {
177 printf("%02X ", buf
[i
]);
185 const char *formStr(CSSM_KEYBLOB_FORMAT 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";
199 printf("**BRRZAP! formStr needs work\n");
204 const char *algStr(CSSM_ALGORITHMS 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";
213 printf("**BRRZAP! algStr needs work\n");
218 static void showTestParams(KeyHashTest
*testParam
)
220 printf("alg %s pubForm %s privForm %s\n",
221 algStr(testParam
->keyAlg
),
222 formStr(testParam
->pubKeyForm
),
223 formStr(testParam
->privKeyForm
));
228 * Generate key pair of specified alg and raw format.
229 * Alg params are optional, though they are expected to be here
232 static CSSM_RETURN
genKeyPair(
233 CSSM_CSP_HANDLE cspHand
,
234 CSSM_ALGORITHMS keyAlg
,
235 uint32 keySize
, // in bits
237 CSSM_KEYBLOB_FORMAT pubFormat
,
238 CSSM_KEY_PTR privKey
,
239 CSSM_KEYBLOB_FORMAT privFormat
,
240 const CSSM_DATA
*inParams
) // optional
243 CSSM_CC_HANDLE ccHand
;
244 CSSM_DATA keyLabelData
;
245 CSSM_RETURN ocrtn
= CSSM_OK
;
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
));
252 crtn
= CSSM_CSP_CreateKeyGenContext(cspHand
,
259 inParams
, // Params, may be NULL
262 printError("CSSM_CSP_CreateKeyGenContext", crtn
);
266 /* optional format specifiers */
267 if(pubFormat
!= CSSM_KEYBLOB_RAW_FORMAT_NONE
) {
268 crtn
= AddContextAttribute(ccHand
,
269 CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT
,
275 printError("AddContextAttribute("
276 "CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn
);
280 if(privFormat
!= CSSM_KEYBLOB_RAW_FORMAT_NONE
) {
281 crtn
= AddContextAttribute(ccHand
,
282 CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT
,
288 printError("AddContextAttribute("
289 "CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn
);
293 CSSM_KEYATTR_FLAGS attrFlags
= CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_EXTRACTABLE
;
294 crtn
= CSSM_GenerateKeyPair(ccHand
,
301 &keyLabelData
, // same labels
302 NULL
, // CredAndAclEntry
305 printError("CSSM_GenerateKeyPair", crtn
);
309 crtn
= CSSM_DeleteContext(ccHand
);
311 printError("CSSM_DeleteContext", crtn
);
312 ocrtn
= CSSM_ERRCODE_INTERNAL_ERROR
;
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.
323 static int compareKeyHashes(
324 const CSSM_DATA
*key1Hash
,
325 const char *key1Descr
,
326 const CSSM_DATA
*key2Hash
,
327 const char *key2Descr
,
330 if(appCompareCssmData(key1Hash
, key2Hash
)) {
333 printf("***Key Digest miscompare (%s,%s)***\n", key1Descr
, key2Descr
);
335 printf("...%s hash:\n", key1Descr
);
336 dumpBuf(key1Hash
->Data
, key1Hash
->Length
);
337 printf("...%s hash:\n", key2Descr
);
338 dumpBuf(key2Hash
->Data
, key2Hash
->Length
);
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;
351 CSSM_CSP_HANDLE rawCspHand
, // generate keys here
352 CSSM_CSP_HANDLE refCspHand
, // null unwrap here
353 KeyHashTest
*testParam
,
362 CSSM_DATA_PTR rawPubHash
;
363 CSSM_DATA_PTR rawPrivHash
;
364 CSSM_DATA_PTR refPubHash
;
365 CSSM_DATA_PTR refPrivHash
;
368 /* generate key pair, specified raw form */
369 crtn
= genKeyPair(rawCspHand
,
371 testParam
->keySizeInBits
,
373 testParam
->pubKeyForm
,
375 testParam
->privKeyForm
,
376 testParam
->algParams
);
378 return testError(quiet
);
381 /* null unwrap both raw keys to ref form */
382 crtn
= cspRawKeyToRef(refCspHand
, &pubKey
, &pubKeyRef
);
384 return testError(quiet
);
386 crtn
= cspRawKeyToRef(refCspHand
, &privKey
, &privKeyRef
);
388 return testError(quiet
);
391 /* calculate four key digests */
392 crtn
= cspKeyHash(rawCspHand
, &pubKey
, &rawPubHash
);
394 return testError(quiet
);
396 crtn
= cspKeyHash(rawCspHand
, &privKey
, &rawPrivHash
);
398 return testError(quiet
);
400 crtn
= cspKeyHash(refCspHand
, &pubKeyRef
, &refPubHash
);
402 return testError(quiet
);
404 crtn
= cspKeyHash(refCspHand
, &privKeyRef
, &refPrivHash
);
406 return testError(quiet
);
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
);
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
);
428 rtn
= testError(quiet
);
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
);
441 int main(int argc
, char **argv
)
446 CSSM_CSP_HANDLE rawCspHand
; // always Raw CSP
447 CSSM_CSP_HANDLE refCspHand
; // CSPDL if !bareCsp
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
;
461 for(arg
=1; arg
<argc
; arg
++) {
465 loops
= atoi(&argp
[2]);
468 bareCsp
= CSSM_FALSE
;
485 /* prefetch the alg params */
486 rtn
= readFile(DSA_PARAM_FILE
, &dsa512Params
.Data
, &len
);
488 printf("***%s file missing. Aborting.\n", DSA_PARAM_FILE
);
491 dsa512Params
.Length
= len
;
492 rtn
= readFile(DH_PARAM_FILE
, &dh512Params
.Data
, &len
);
494 printf("***%s file missing. Aborting.\n", DH_PARAM_FILE
);
497 dh512Params
.Length
= len
;
499 printf("Starting keyHashAsym; args: ");
500 for(i
=1; i
<argc
; i
++) {
501 printf("%s ", argv
[i
]);
504 refCspHand
= cspDlDbStartup(bareCsp
, NULL
);
505 if(refCspHand
== 0) {
509 /* raw and ref on same CSP */
510 rawCspHand
= refCspHand
;
513 /* generate on CSPDL, NULL unwrap to bare CSP */
514 rawCspHand
= cspDlDbStartup(CSSM_TRUE
, NULL
);
515 if(rawCspHand
== 0) {
519 for(loop
=1; ; loop
++) {
521 printf("...loop %d\n", loop
);
523 for(unsigned testNum
=0; testNum
<NUM_TEST_PARAMS
; testNum
++) {
524 KeyHashTest
*testParams
= &KeyHashTestParams
[testNum
];
526 printf("..."); showTestParams(testParams
);
528 rtn
= doTest(rawCspHand
, refCspHand
, testParams
, verbose
, quiet
);
534 printf("Hit CR to proceed: ");
538 if(loops
&& (loop
== loops
)) {
543 if((rtn
== 0) && !quiet
) {
544 printf("...%s complete\n", argv
[0]);