#include <security_cdsa_utils/cuPrintCert.h>
#include <security_cdsa_utils/cuOidParser.h>
#include <security_cdsa_utils/cuFileIo.h>
#include <clAppUtils/clutils.h>
#include <utilLib/common.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <Security/cssmtype.h>
#include <Security/cssmapi.h>
#include <Security/oidscert.h>
static const CSSM_OID *knownOids[] =
{
&CSSMOID_X509V1Version, &CSSMOID_X509V1SerialNumber,
&CSSMOID_X509V1IssuerNameCStruct,
&CSSMOID_X509V1SubjectNameCStruct,
&CSSMOID_CSSMKeyStruct,
&CSSMOID_X509V1SubjectPublicKeyCStruct,
&CSSMOID_X509V1ValidityNotBefore,
&CSSMOID_X509V1ValidityNotAfter,
&CSSMOID_X509V1SignatureAlgorithmTBS,
&CSSMOID_X509V1SignatureAlgorithm,
&CSSMOID_X509V1Signature,
&CSSMOID_X509V3CertificateExtensionCStruct,
&CSSMOID_KeyUsage,
&CSSMOID_BasicConstraints,
&CSSMOID_ExtendedKeyUsage,
&CSSMOID_CertificatePolicies,
&CSSMOID_NetscapeCertType
};
#define NUM_KNOWN_OIDS (sizeof(knownOids) / sizeof(CSSM_OID *))
static const char *oidNames[] =
{
"CSSMOID_X509V1Version",
"CSSMOID_X509V1SerialNumber",
"CSSMOID_X509V1IssuerNameCStruct",
"CSSMOID_X509V1SubjectNameCStruct",
"CSSMOID_CSSMKeyStruct",
"CSSMOID_X509V1SubjectPublicKeyCStruct",
"CSSMOID_X509V1ValidityNotBefore",
"CSSMOID_X509V1ValidityNotAfter",
"CSSMOID_X509V1SignatureAlgorithmTBS",
"CSSMOID_X509V1SignatureAlgorithm",
"CSSMOID_X509V1Signature",
"CSSMOID_X509V3CertificateExtensionCStruct",
"CSSMOID_KeyUsage",
"CSSMOID_BasicConstraints",
"CSSMOID_ExtendedKeyUsage",
"CSSMOID_CertificatePolicies",
"CSSMOID_NetscapeCertType"
};
static void usage(char **argv)
{
printf("Usage: %s certFile\n", argv[0]);
exit(1);
}
int main(int argc, char **argv)
{
CSSM_DATA certData = {0, NULL};
CSSM_CL_HANDLE clHand = CSSM_INVALID_HANDLE;
CSSM_HANDLE cacheHand = CSSM_INVALID_HANDLE;
CSSM_HANDLE searchHand = CSSM_INVALID_HANDLE;
char resp;
CSSM_RETURN crtn;
unsigned fieldDex;
CSSM_DATA_PTR fieldValue;
uint32 numFields;
CSSM_FIELD field;
CSSM_FIELD_PTR fieldPtr;
OidParser parser;
unsigned len;
if(argc != 2) {
usage(argv);
}
if(readFile(argv[1], &certData.Data, &len)) {
printf("Can't read file %s' aborting.\n", argv[1]);
exit(1);
}
certData.Length = len;
while(1) {
fpurge(stdin);
printf("a load/attach\n");
printf("d detach/unload\n");
printf("c cache the cert\n");
printf("u uncache the cert\n");
printf("g get field (uncached)\n");
printf("G get field (cached)\n");
printf("f get all fields, then free\n");
printf("q quit\n");
printf("Enter command: ");
resp = getchar();
switch(resp) {
case 'a':
if(clHand != CSSM_INVALID_HANDLE) {
printf("***Multiple attaches; expect leaks\n");
}
clHand = clStartup();
if(clHand == CSSM_INVALID_HANDLE) {
printf("***Error attaching to CL.\n");
}
else {
printf("...ok\n");
}
break;
case 'd':
clShutdown(clHand);
clHand = CSSM_INVALID_HANDLE;
printf("...ok\n");
break;
case 'c':
if(cacheHand != CSSM_INVALID_HANDLE) {
printf("***NOTE: a cert is already cached. Expect leaks.\n"); }
crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand);
if(crtn) {
printError("CSSM_CL_CertCache", crtn);
}
else {
printf("...ok\n");
}
break;
case 'u':
crtn = CSSM_CL_CertAbortCache(clHand, cacheHand);
if(crtn) {
printError("CSSM_CL_CertAbortCache", crtn);
}
else {
cacheHand = CSSM_INVALID_HANDLE;
printf("...ok\n");
}
break;
case 'g':
fieldDex = genRand(0, NUM_KNOWN_OIDS - 1);
crtn = CSSM_CL_CertGetFirstFieldValue(clHand,
&certData,
knownOids[fieldDex],
&searchHand,
&numFields,
&fieldValue);
if(crtn) {
printf("***Error fetching field %s\n", oidNames[fieldDex]);
printError("CSSM_CL_CertGetFirstFieldValue", crtn);
break;
}
printf("%s: %u fields found\n", oidNames[fieldDex], (unsigned)numFields);
field.FieldValue = *fieldValue;
field.FieldOid = *(knownOids[fieldDex]);
printCertField(field, parser, CSSM_TRUE);
crtn = CSSM_CL_FreeFieldValue(clHand, knownOids[fieldDex], fieldValue);
if(crtn) {
printError("CSSM_CL_FreeFieldValue", crtn);
}
for(unsigned i=1; i<numFields; i++) {
crtn = CSSM_CL_CertGetNextFieldValue(clHand,
searchHand,
&fieldValue);
if(crtn) {
printError("CSSM_CL_CertGetNextFieldValue", crtn);
break;
}
field.FieldValue = *fieldValue;
printCertField(field, parser, CSSM_TRUE);
crtn = CSSM_CL_FreeFieldValue(clHand,
knownOids[fieldDex], fieldValue);
if(crtn) {
printError("CSSM_CL_FreeFieldValue", crtn);
}
}
crtn = CSSM_CL_CertGetNextFieldValue(clHand,
searchHand,
&fieldValue);
if(crtn != CSSMERR_CL_NO_FIELD_VALUES) {
if(crtn == CSSM_OK) {
printf("***unexpected success on final GetNextFieldValue\n");
}
else {
printError("Wrong error on final GetNextFieldValue", crtn);
}
}
crtn = CSSM_CL_CertAbortQuery(clHand, searchHand);
if(crtn) {
printError("CSSM_CL_CertAbortQuery", crtn);
}
break;
case 'G':
fieldDex = genRand(0, NUM_KNOWN_OIDS - 1);
crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand,
cacheHand,
knownOids[fieldDex],
&searchHand,
&numFields,
&fieldValue);
if(crtn) {
printf("***Error fetching field %s\n", oidNames[fieldDex]);
printError("CSSM_CL_CertGetFirstCachedFieldValue", crtn);
break;
}
printf("%s: %u fields found\n", oidNames[fieldDex], (unsigned)numFields);
field.FieldValue = *fieldValue;
field.FieldOid = *(knownOids[fieldDex]);
printCertField(field, parser, CSSM_TRUE);
crtn = CSSM_CL_FreeFieldValue(clHand, knownOids[fieldDex], fieldValue);
if(crtn) {
printError("CSSM_CL_FreeFieldValue", crtn);
}
for(unsigned i=1; i<numFields; i++) {
crtn = CSSM_CL_CertGetNextCachedFieldValue(clHand,
searchHand,
&fieldValue);
if(crtn) {
printError("CSSM_CL_CertGetNextCachedFieldValue", crtn);
break;
}
field.FieldValue = *fieldValue;
printCertField(field, parser, CSSM_TRUE);
crtn = CSSM_CL_FreeFieldValue(clHand,
knownOids[fieldDex], fieldValue);
if(crtn) {
printError("CSSM_CL_FreeFieldValue", crtn);
}
}
crtn = CSSM_CL_CertGetNextCachedFieldValue(clHand,
searchHand,
&fieldValue);
if(crtn != CSSMERR_CL_NO_FIELD_VALUES) {
if(crtn == CSSM_OK) {
printf("***unexpected success on final GetNextCachedFieldValue\n");
}
else {
printError("Wrong error on final GetNextCachedFieldValue", crtn);
}
}
crtn = CSSM_CL_CertAbortQuery(clHand, searchHand);
if(crtn) {
printError("CSSM_CL_CertAbortQuery", crtn);
}
break;
case 'f':
crtn = CSSM_CL_CertGetAllFields(clHand,
&certData,
&numFields,
&fieldPtr);
if(crtn) {
printError("CSSM_CL_CertGetAllFields", crtn);
break;
}
printf("...numFields %u\n", (unsigned)numFields);
crtn = CSSM_CL_FreeFields(clHand, numFields, &fieldPtr);
if(crtn) {
printError("CSSM_CL_FreeFields", crtn);
}
break;
case 'q':
goto quit;
default:
printf("Huh?\n");
break;
}
}
quit:
free(certData.Data);
if(clHand != CSSM_INVALID_HANDLE) {
clShutdown(clHand);
}
return 0;
}