X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/clTool/clTool.cpp diff --git a/SecurityTests/clxutils/clTool/clTool.cpp b/SecurityTests/clxutils/clTool/clTool.cpp new file mode 100644 index 00000000..e634628e --- /dev/null +++ b/SecurityTests/clxutils/clTool/clTool.cpp @@ -0,0 +1,312 @@ +/* + * clTool.cpp - menu-driven CL exerciser + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * A list of OIDs we inquire about. + */ +static const CSSM_OID *knownOids[] = +{ + &CSSMOID_X509V1Version, // not always present + &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': + /* + * Notes: + * -- this should cause the CL to free up all cached certs + * no matter what - even if we've done multiple certCache + * ops. However the plugin framework doesn't delete the + * session object on detach (yet) so expect leaks in + * that case. + * -- we don't clear out cacheHand or searchHand here; this + * allows verification of proper handling of bogus handles. + */ + clShutdown(clHand); + clHand = CSSM_INVALID_HANDLE; + printf("...ok\n"); + break; + + case 'c': + /* cache the cert */ + 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': + /* abort cache */ + crtn = CSSM_CL_CertAbortCache(clHand, cacheHand); + if(crtn) { + printError("CSSM_CL_CertAbortCache", crtn); + } + else { + cacheHand = CSSM_INVALID_HANDLE; + printf("...ok\n"); + } + break; + + case 'g': + /* get one field (uncached) */ + 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); + /* keep going */ + } + for(unsigned i=1; i