]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/clTool/clTool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / clTool / clTool.cpp
diff --git a/SecurityTests/clxutils/clTool/clTool.cpp b/SecurityTests/clxutils/clTool/clTool.cpp
new file mode 100644 (file)
index 0000000..e634628
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * clTool.cpp - menu-driven CL exerciser
+ */
+#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>
+
+/*
+ * 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<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);
+                                               /* keep going */
+                                       }
+                               } /* for additional fields */
+                               
+                               /* verify one more getField results in error */
+                               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':
+                               /* get one field (uncached) */
+                               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);
+                                       /* keep going */
+                               }
+                               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);
+                                               /* keep going */
+                                       }
+                               } /* for additional cached fields */
+                               
+                               /* verify one more getField results in error */
+                               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':
+                               /* get all fields (for leak testing) */
+                               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;
+               }       /* switch resp */
+       }
+quit:
+       free(certData.Data);
+       if(clHand != CSSM_INVALID_HANDLE) {
+               clShutdown(clHand);
+       }
+       return 0;
+}