#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <strings.h>
#include <ctype.h>
#include <Security/cssm.h>
#include <Security/cssmapple.h>
#include "cspwrap.h"
#include "common.h"
#include "cspdlTesting.h"
static void usage(char **argv)
{
printf("usage: %s dbFileName alg class keysize [options]\n", argv[0]);
printf(" alg : rsa|dsa|dh|ecdsa\n");
printf(" class : priv|pub\n");
printf("Options:\n");
printf(" -q quiet\n");
exit(1);
}
static const char *recordTypeStr(
CSSM_DB_RECORDTYPE recordType)
{
static char unk[100];
switch(recordType) {
case CSSM_DL_DB_RECORD_PRIVATE_KEY:
return "Private Key";
case CSSM_DL_DB_RECORD_PUBLIC_KEY:
return "Public Key";
case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
return "Symmetric Key";
default:
sprintf(unk, "**Unknown record type %u\n", (unsigned)recordType);
return unk;
}
}
static int doVerify(
CSSM_DL_DB_HANDLE dlDbHand,
unsigned numRecords, CSSM_DB_RECORDTYPE recordType,
uint32 keySize,
CSSM_ALGORITHMS keyAlg)
{
CSSM_QUERY query;
CSSM_DB_UNIQUE_RECORD_PTR record = NULL;
CSSM_RETURN crtn;
CSSM_HANDLE resultHand;
CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs;
query.RecordType = recordType;
query.Conjunctive = CSSM_DB_NONE;
query.NumSelectionPredicates = 0;
query.QueryLimits.TimeLimit = 0; query.QueryLimits.SizeLimit = 1; query.QueryFlags = 0;
recordAttrs.DataRecordType = recordType;
recordAttrs.NumberOfAttributes = 0;
recordAttrs.AttributeData = NULL;
CSSM_DATA recordData = {0, NULL};
crtn = CSSM_DL_DataGetFirst(dlDbHand,
&query,
&resultHand,
&recordAttrs,
&recordData,
&record);
switch(crtn) {
case CSSM_OK:
if(numRecords == 0) {
printf("***Expected zero records of type %s, found one\n",
recordTypeStr(recordType));
CSSM_DL_FreeUniqueRecord(dlDbHand, record);
CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
return 1;
}
break; case CSSMERR_DL_ENDOFDATA:
if(numRecords == 0) {
return 0;
}
printf("**Error: no records of type %s found\n",
recordTypeStr(recordType));
return 1;
default:
printError("DataGetFirst", crtn);
return 1;
}
CSSM_KEY_PTR theKey = (CSSM_KEY_PTR)recordData.Data;
int ourRtn = 0;
CSSM_KEYHEADER &hdr = theKey->KeyHeader;
if(hdr.AlgorithmId != keyAlg) {
printf("***Algorithm mismatch: expect %u, got %u\n",
(unsigned)keyAlg, (unsigned)hdr.AlgorithmId);
ourRtn++;
}
if(hdr.LogicalKeySizeInBits != keySize) {
printf("***Key Size: expect %u, got %u\n",
(unsigned)keySize, (unsigned)hdr.LogicalKeySizeInBits);
ourRtn++;
}
CSSM_DL_FreeUniqueRecord(dlDbHand, record);
crtn = CSSM_DL_DataGetNext(dlDbHand,
resultHand,
&recordAttrs,
NULL,
&record);
if(crtn == CSSM_OK) {
printf("***More than 1 record of type %s found\n",
recordTypeStr(recordType));
ourRtn++;
CSSM_DL_FreeUniqueRecord(dlDbHand, record);
}
CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
return ourRtn;
}
int main(
int argc,
char **argv)
{
int arg;
char *argp;
char *dbFileName;
CSSM_ALGORITHMS keyAlg;
CSSM_DB_RECORDTYPE recordType;
uint32 keySize;
CSSM_DL_DB_HANDLE dlDbHand;
CSSM_BOOL quiet = CSSM_FALSE;
CSSM_RETURN crtn = CSSM_OK;
if(argc < 5) {
usage(argv);
}
dbFileName = argv[1];
if(!strcmp(argv[2], "rsa")) {
keyAlg = CSSM_ALGID_RSA;
}
else if(!strcmp(argv[2], "dsa")) {
keyAlg = CSSM_ALGID_DSA;
}
else if(!strcmp(argv[2], "dh")) {
keyAlg = CSSM_ALGID_DH;
}
else if(!strcmp(argv[2], "ecdsa")) {
keyAlg = CSSM_ALGID_ECDSA;
}
else {
usage(argv);
}
if(!strcmp(argv[3], "priv")) {
recordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
}
else if(!strcmp(argv[3], "pub")) {
recordType = CSSM_DL_DB_RECORD_PUBLIC_KEY;
}
else {
usage(argv);
}
keySize = atoi(argv[4]);
for(arg=5; arg<argc; arg++) {
argp = argv[arg];
if(!strcmp(argp, "-q")) {
quiet = CSSM_TRUE;
}
else {
usage(argv);
}
}
dlDbHand.DLHandle = dlStartup();
if(dlDbHand.DLHandle == 0) {
exit(1);
}
crtn = dbCreateOpen(dlDbHand.DLHandle, dbFileName,
CSSM_FALSE, CSSM_FALSE, NULL, &dlDbHand.DBHandle);
if(crtn) {
exit(1);
}
if(doVerify(dlDbHand, 1, recordType, keySize, keyAlg)) {
return 1;
}
if(doVerify(dlDbHand, 0,
(recordType == CSSM_DL_DB_RECORD_PRIVATE_KEY) ?
CSSM_DL_DB_RECORD_PUBLIC_KEY : CSSM_DL_DB_RECORD_PRIVATE_KEY,
keySize, keyAlg)) {
return 1;
}
if(!quiet) {
printf("...%s verify succussful\n", recordTypeStr(recordType));
}
CSSM_DL_DbClose(dlDbHand);
CSSM_ModuleDetach(dlDbHand.DLHandle);
return 0;
}