#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Security/cssm.h>
#include <Security/cssmapple.h>
#include "cspwrap.h"
#include "common.h"
#include "bsafeUtils.h"
#include <string.h>
#define OLOOPS_DEF 10
#define ILOOPS_DEF 10
#define MAX_TEXT_SIZE 1024
#define LOOP_NOTIFY 20
#define DO_MULTI_UPDATE CSSM_TRUE
static void usage(char **argv)
{
printf("usage: %s [options]\n", argv[0]);
printf(" Options:\n");
printf(" a=alg (r=RSA, d=DSA; default=RSA)\n");
printf(" l=outerloops (default=%d; 0=forever)\n", OLOOPS_DEF);
printf(" i=innerLoops (default=%d)\n", ILOOPS_DEF);
printf(" k=keySizeInBits; default is random\n");
printf(" p=pauseInterval (default=0, no pause)\n");
printf(" D (CSP/DL; default = bare CSP)\n");
printf(" v(erbose)\n");
printf(" q(uiet)\n");
printf(" h(elp)\n");
exit(1);
}
int main(int argc, char **argv)
{
int arg;
char *argp;
unsigned oloop;
unsigned iloop;
CSSM_DATA ptext = {0, NULL};
CSSM_CSP_HANDLE cspHand;
int i;
int rtn = 0;
uint32 keySizeInBits = 0;
CSSM_KEY pubKey;
CSSM_KEY privKey;
CSSM_DATA sig = {0, NULL};
CSSM_DATA digest = {0, NULL};
CSSM_RETURN crtn;
const char *digestStr;
CSSM_BOOL keySizeSpec = CSSM_FALSE;
unsigned oloops = OLOOPS_DEF;
unsigned iloops = ILOOPS_DEF;
CSSM_BOOL verbose = CSSM_FALSE;
CSSM_BOOL quiet = CSSM_FALSE;
unsigned pauseInterval = 0;
CSSM_BOOL bareCsp = CSSM_TRUE;
CSSM_ALGORITHMS rawSigAlg = CSSM_ALGID_RSA;
for(arg=1; arg<argc; arg++) {
argp = argv[arg];
switch(argp[0]) {
case 'a':
switch(argp[2]) {
case 'r':
rawSigAlg = CSSM_ALGID_RSA;
break;
case 'd':
rawSigAlg = CSSM_ALGID_DSA;
break;
default:
usage(argv);
}
break;
case 'l':
oloops = atoi(&argp[2]);
break;
case 'i':
iloops = atoi(&argp[2]);
break;
case 'k':
keySizeInBits = atoi(&argp[2]);
keySizeSpec = CSSM_TRUE;
break;
case 'v':
verbose = CSSM_TRUE;
break;
case 'D':
bareCsp = CSSM_FALSE;
break;
case 'q':
quiet = CSSM_TRUE;
break;
case 'p':
pauseInterval = atoi(&argp[2]);;
break;
case 'h':
default:
usage(argv);
}
}
ptext.Data = (uint8 *)CSSM_MALLOC(MAX_TEXT_SIZE);
if(ptext.Data == NULL) {
printf("Insufficient heap space\n");
exit(1);
}
printf("Starting rawRsaSig; args: ");
for(i=1; i<argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
cspHand = cspDlDbStartup(bareCsp, NULL);
if(cspHand == 0) {
exit(1);
}
if(pauseInterval) {
fpurge(stdin);
printf("Top of test; hit CR to proceed: ");
getchar();
}
for(oloop=0; ; oloop++) {
if(!keySizeSpec) {
keySizeInBits = randKeySizeBits(rawSigAlg, OT_Sign);
}
if(!quiet) {
if(verbose || ((oloop % LOOP_NOTIFY) == 0)) {
printf("...oloop %d keySize %u\n", oloop, (unsigned)keySizeInBits);
}
}
crtn = cspGenKeyPair(cspHand,
rawSigAlg,
"foo",
3,
keySizeInBits,
&pubKey,
CSSM_TRUE, CSSM_KEYUSE_VERIFY,
CSSM_KEYBLOB_RAW_FORMAT_NONE,
&privKey,
CSSM_TRUE,
CSSM_KEYUSE_SIGN,
CSSM_KEYBLOB_RAW_FORMAT_NONE,
CSSM_FALSE); if(crtn) {
return testError(quiet);
}
for(iloop=0; iloop<iloops; iloop++) {
CSSM_ALGORITHMS sigAlg;
CSSM_ALGORITHMS digestAlg;
CSSM_CC_HANDLE sigHand;
if(rawSigAlg == CSSM_ALGID_RSA) {
if(iloop & 1) {
sigAlg = CSSM_ALGID_SHA1WithRSA;
digestAlg = CSSM_ALGID_SHA1;
digestStr = "SHA1";
}
else {
sigAlg = CSSM_ALGID_MD5WithRSA;
digestAlg = CSSM_ALGID_MD5;
digestStr = "MD5 ";
}
}
else {
sigAlg = CSSM_ALGID_SHA1WithDSA;
digestAlg = CSSM_ALGID_SHA1;
digestStr = "SHA1";
}
simpleGenData(&ptext, 1, MAX_TEXT_SIZE);
if(!quiet) {
if(verbose || ((iloop % LOOP_NOTIFY) == 0)) {
printf(" ...iloop %d digest %s text size %lu\n",
iloop, digestStr, ptext.Length);
}
}
crtn = cspStagedSign(cspHand,
sigAlg,
&privKey,
&ptext,
DO_MULTI_UPDATE, &sig);
if(crtn && testError(quiet)) {
goto abort;
}
crtn = cspStagedDigest(cspHand,
digestAlg,
CSSM_FALSE, DO_MULTI_UPDATE, &ptext,
&digest);
if(crtn && testError(quiet)) {
goto abort;
}
crtn = CSSM_CSP_CreateSignatureContext(cspHand,
rawSigAlg,
NULL, &pubKey,
&sigHand);
if(crtn) {
printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
return crtn;
}
crtn = CSSM_VerifyData(sigHand,
&digest,
1,
digestAlg,
&sig);
if(crtn) {
printError("CSSM_VerifyData(raw RSA)", crtn);
if(testError(quiet)) {
goto abort;
}
}
appFreeCssmData(&sig, CSSM_FALSE);
CSSM_DeleteContext(sigHand);
crtn = CSSM_CSP_CreateSignatureContext(cspHand,
rawSigAlg,
NULL, &privKey,
&sigHand);
if(crtn) {
printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
return crtn;
}
crtn = CSSM_SignData(sigHand,
&digest,
1,
digestAlg,
&sig);
if(crtn) {
printError("CSSM_SignData(raw RSA)", crtn);
if(testError(quiet)) {
goto abort;
}
}
crtn = cspStagedSigVerify(cspHand,
sigAlg,
&pubKey,
&ptext,
&sig,
DO_MULTI_UPDATE, CSSM_OK);
if(crtn && testError(quiet)) {
goto abort;
}
appFreeCssmData(&sig, CSSM_FALSE);
appFreeCssmData(&digest, CSSM_FALSE);
CSSM_DeleteContext(sigHand);
}
cspFreeKey(cspHand, &pubKey);
cspFreeKey(cspHand, &privKey);
if(oloops && (oloop == oloops)) {
break;
}
if(pauseInterval && ((oloop % pauseInterval) == 0)) {
fpurge(stdin);
printf("hit CR to proceed: ");
getchar();
}
}
abort:
cspShutdown(cspHand, bareCsp);
if(pauseInterval) {
fpurge(stdin);
printf("ModuleDetach/Unload complete; hit CR to exit: ");
getchar();
}
if((rtn == 0) && !quiet) {
printf("%s test complete\n", argv[0]);
}
CSSM_FREE(ptext.Data);
return rtn;
}