#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <Security/cssm.h>
#include "cspwrap.h"
#include "common.h"
#include "cspdlTesting.h"
#define USAGE_NAME "noUsage"
#define USAGE_NAME_LEN (strlen(USAGE_NAME))
#define LOOPS_DEF 10
static void usage(char **argv)
{
printf("usage: %s [options]\n", argv[0]);
printf("Options:\n");
printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
printf(" D (CSP/DL; default = bare CSP)\n");
printf(" p(ause on each loop)\n");
printf(" q(uiet)\n");
printf(" v(erbose))\n");
exit(1);
}
static void dumpBuf(uint8 *buf,
unsigned len)
{
unsigned i;
printf(" ");
for(i=0; i<len; i++) {
printf("%02X ", buf[i]);
if((i % 24) == 23) {
printf("\n ");
}
}
printf("\n");
}
static int doTest(
CSSM_CSP_HANDLE cspHand, CSSM_CSP_HANDLE rawCspHand, CSSM_KEY_PTR refKey,
CSSM_BOOL verbose,
CSSM_BOOL quiet)
{
CSSM_KEY rawKey;
CSSM_RETURN crtn;
CSSM_DATA_PTR refHash;
CSSM_DATA_PTR rawHash;
if(refKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
printf("Hey! this only works on ref keys!!\n");
exit(1);
}
crtn = cspWrapKey(cspHand,
refKey,
NULL, CSSM_ALGID_NONE,
CSSM_ALGMODE_NONE,
CSSM_KEYBLOB_WRAPPED_FORMAT_NONE,
CSSM_PADDING_NONE,
NULL, NULL, &rawKey);
if(crtn) {
return testError(quiet);
}
crtn = cspKeyHash(cspHand, refKey, &refHash);
if(crtn) {
return testError(quiet);
}
else {
if(verbose) {
printf(" ...Ref key hash:\n ");
dumpBuf(refHash->Data, refHash->Length);
}
}
crtn = cspKeyHash(rawCspHand, &rawKey, &rawHash);
if(crtn) {
return testError(quiet);
}
else {
if(verbose) {
printf(" ...Raw key hash:\n ");
dumpBuf(rawHash->Data, rawHash->Length);
}
}
if(!appCompareCssmData(refHash, rawHash)) {
printf("***Key Hash Miscompare!\n");
return testError(quiet);
}
appFreeCssmData(refHash, CSSM_TRUE);
appFreeCssmData(rawHash, CSSM_TRUE);
cspFreeKey(cspHand, &rawKey);
return 0;
}
int main(int argc, char **argv)
{
int arg;
char *argp;
unsigned loop;
CSSM_CSP_HANDLE cspHand;
CSSM_CSP_HANDLE rawCspHand;
int rtn = 0;
CSSM_KEY pubKey;
CSSM_KEY privKey;
CSSM_KEY_PTR symKey;
int i;
unsigned loops = LOOPS_DEF;
CSSM_BOOL verbose = CSSM_FALSE;
CSSM_BOOL quiet = CSSM_FALSE;
CSSM_BOOL bareCsp = CSSM_TRUE;
CSSM_BOOL doPause = CSSM_FALSE;
for(arg=1; arg<argc; arg++) {
argp = argv[arg];
switch(argp[0]) {
case 'l':
loops = atoi(&argp[2]);
break;
case 'D':
bareCsp = CSSM_FALSE;
break;
case 'p':
doPause = CSSM_TRUE;
break;
case 'v':
verbose = CSSM_TRUE;
break;
case 'q':
quiet = CSSM_TRUE;
break;
case 'h':
default:
usage(argv);
}
}
printf("Starting keyHash; args: ");
for(i=1; i<argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
cspHand = cspDlDbStartup(bareCsp, NULL);
if(cspHand == 0) {
exit(1);
}
if(bareCsp) {
rawCspHand = cspHand;
}
else {
rawCspHand = cspDlDbStartup(CSSM_TRUE, NULL);
if(rawCspHand == 0) {
exit(1);
}
}
for(loop=1; ; loop++) {
if(!quiet) {
printf("...loop %d\n", loop);
}
if(verbose) {
printf(" ...testing DES key\n");
}
symKey = cspGenSymKey(cspHand,
CSSM_ALGID_DES,
USAGE_NAME,
USAGE_NAME_LEN,
CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
64,
CSSM_TRUE); if(symKey == NULL) {
if(testError(quiet)) {
break;
}
}
if(doTest(cspHand, rawCspHand, symKey, verbose, quiet)) {
break;
}
CSSM_FreeKey(cspHand, NULL, symKey, CSSM_TRUE);
CSSM_FREE(symKey);
rtn = cspGenKeyPair(cspHand,
CSSM_ALGID_RSA,
USAGE_NAME,
USAGE_NAME_LEN,
CSP_RSA_KEY_SIZE_DEFAULT,
&pubKey,
CSSM_TRUE, CSSM_KEYUSE_ENCRYPT,
CSSM_KEYBLOB_RAW_FORMAT_NONE,
&privKey,
CSSM_TRUE, CSSM_KEYUSE_DECRYPT,
CSSM_KEYBLOB_RAW_FORMAT_NONE,
CSSM_FALSE); if(rtn) {
if(testError(quiet)) {
break;
}
}
if(verbose) {
printf(" ...testing RSA public key\n");
}
if(doTest(cspHand, rawCspHand, &pubKey, verbose, quiet)) {
break;
}
if(verbose) {
printf(" ...testing RSA private key\n");
}
if(doTest(cspHand, rawCspHand, &privKey, verbose, quiet)) {
break;
}
CSSM_FreeKey(cspHand, NULL, &pubKey, CSSM_TRUE);
CSSM_FreeKey(cspHand, NULL, &privKey, CSSM_TRUE);
if(loops && (loop == loops)) {
break;
}
if(doPause) {
fpurge(stdin);
printf("Hit CR to proceed: ");
getchar();
}
}
return 0;
}