X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/secTrustTime/secTrustTime.cpp diff --git a/SecurityTests/clxutils/secTrustTime/secTrustTime.cpp b/SecurityTests/clxutils/secTrustTime/secTrustTime.cpp new file mode 100644 index 00000000..6311fc98 --- /dev/null +++ b/SecurityTests/clxutils/secTrustTime/secTrustTime.cpp @@ -0,0 +1,378 @@ +/* + * secTrustTime.cpp - measure performance of SecTrust and TP cert verify + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS_DEF 100 + +const char *certFiles[] = { + "keybank_v3.100.cer", "keybank_v3.101.cer", "keybank_v3.102.cer" +}; + +#define NUM_CERTS (sizeof(certFiles) / sizeof(certFiles[0])) + +static void usage(char **argv) +{ + printf("usage: %s [options]\n", argv[0]); + printf("Options:\n"); + printf(" -l loops -- loops; default %d; 0=forever\n", LOOPS_DEF); + printf(" -k -- open and hold keychains\n"); + printf(" -t -- TP, not SecTrust\n"); + printf(" -T -- TP, no Trust Settings\n"); + printf(" -n -- don't include root in cert chain\n"); + printf(" -K -- set empty KC list\n"); + /* etc. */ + exit(1); +} + +static SecCertificateRef readCertFile( + const char *fileName) +{ + unsigned char *cp = NULL; + unsigned len = 0; + CSSM_DATA certData; + OSStatus ortn; + + if(readFile(fileName, &cp, &len)) { + printf("***Error reading file %s\n", fileName); + return NULL; + } + certData.Length = len; + certData.Data = cp; + SecCertificateRef certRef; + + ortn = SecCertificateCreateFromData(&certData, + CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certRef); + if(ortn) { + cssmPerror("SecCertificateCreateFromData", ortn); + return NULL; + } + free(cp); + return certRef; +} + +/* perfrom one cert chain evaluation using SecTrust */ +static OSStatus doEval( + CFArrayRef certArray, + SecPolicyRef policyRef, + CFArrayRef kcList) +{ + OSStatus ortn; + SecTrustRef trustRef; + + ortn = SecTrustCreateWithCertificates(certArray, policyRef, &trustRef); + if(ortn) { + cssmPerror("SecTrustCreateWithCertificates", ortn); + return ortn; + } + if(kcList) { + ortn = SecTrustSetKeychains(trustRef, kcList); + if(ortn) { + cssmPerror("SecTrustCreateWithCertificates", ortn); + return ortn; + } + } + SecTrustResultType secTrustResult; + ortn = SecTrustEvaluate(trustRef, &secTrustResult); + if(ortn) { + cssmPerror("SecTrustEvaluate", ortn); + return ortn; + } + switch(secTrustResult) { + case kSecTrustResultProceed: + case kSecTrustResultUnspecified: + break; + default: + printf("***Unexpected SecTrustResultType (%d)\n", (int)secTrustResult); + ortn = -1; + } + CFRelease(trustRef); + return ortn; +} + +/* cached CSSM anchors - simulate old SecTrustGetCSSMAnchorCertificates() */ +static CFArrayRef cachedRootArray = NULL; +static CSSM_DATA *cachedAnchors = NULL; +static unsigned cachedNumAnchors = 0; + +static OSStatus getAnchors( + CSSM_DATA **anchors, /* RETURNED */ + unsigned *numAnchors) /* RETURNED */ +{ + if(cachedRootArray == NULL) { + /* fetch, once */ + OSStatus ortn = getSystemAnchors(&cachedRootArray, &cachedAnchors, + &cachedNumAnchors); + if(ortn) { + return ortn; + } + } + *anchors = cachedAnchors; + *numAnchors = cachedNumAnchors; + return noErr; +} + +/* perfrom one cert chain evaluation using CSSM_TP_CertGroupVerify */ +static CSSM_RETURN doTpEval( + CSSM_TP_HANDLE tpHand, + CSSM_CL_HANDLE clHand, + CSSM_CSP_HANDLE cspHand, + CSSM_DATA_PTR certs, + uint32 numCerts, + bool useTrustSettings) +{ + CSSM_FIELD policyId; + + policyId.FieldOid = CSSMOID_APPLE_X509_BASIC; + policyId.FieldValue.Data = NULL; + policyId.FieldValue.Length = 0; + + CSSM_TP_CALLERAUTH_CONTEXT authCtx; + memset(&authCtx, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT)); + authCtx.Policy.NumberOfPolicyIds = 1; + authCtx.Policy.PolicyIds = &policyId; + authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY; + if(!useTrustSettings) { + OSStatus ortn = getAnchors(&authCtx.AnchorCerts, + &authCtx.NumberOfAnchorCerts); + if(ortn) { + return ortn; + } + } + CSSM_APPLE_TP_ACTION_DATA tpAction; + tpAction.Version = CSSM_APPLE_TP_ACTION_VERSION; + if(useTrustSettings) { + tpAction.ActionFlags = CSSM_TP_ACTION_TRUST_SETTINGS; + } + else { + tpAction.ActionFlags = 0; + } + + CSSM_TP_VERIFY_CONTEXT vfyCtx; + memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT)); + vfyCtx.ActionData.Data = (uint8 *)&tpAction; + vfyCtx.ActionData.Length = sizeof(tpAction); + vfyCtx.Action = CSSM_TP_ACTION_DEFAULT; + vfyCtx.Cred = &authCtx; + + CSSM_CERTGROUP cssmCerts; + cssmCerts.CertType = CSSM_CERT_X_509v3; + cssmCerts.CertEncoding = CSSM_CERT_ENCODING_DER; + cssmCerts.NumCerts = numCerts; + cssmCerts.GroupList.CertList = certs; + cssmCerts.CertGroupType = CSSM_CERTGROUP_DATA; + + CSSM_RETURN crtn = CSSM_TP_CertGroupVerify(tpHand, clHand, cspHand, + &cssmCerts, + &vfyCtx, + NULL); /* no results */ + if(crtn) { + cssmPerror("CSSM_TP_CertGroupVerify", crtn); + } + return crtn; +} + +int main(int argc, char **argv) +{ + unsigned dex; + CSSM_RETURN crtn; + + /* common SecTrust args */ + CFMutableArrayRef kcList = NULL; + CFMutableArrayRef certArray = NULL; + SecPolicyRef policyRef = NULL; + unsigned numCerts = NUM_CERTS; + CFArrayRef emptyKCList = NULL; + + /* common TP args */ + CSSM_TP_HANDLE tpHand; + CSSM_CL_HANDLE clHand; + CSSM_CSP_HANDLE cspHand; + CSSM_DATA cssmCerts[NUM_CERTS]; + + /* user-spec'd variables */ + unsigned loops = LOOPS_DEF; + bool holdKeychains = false; /* hold references to KC list during operation */ + bool useTp = false; /* TP, not SecTrust */ + bool useTrustSettings = true; /* TP w/TrustSettings; false = old school TP way */ + bool noRoot = false; /* don't include root in chain to be verified */ + bool emptyList = false; /* SecTrust only: specify empty KC list */ + + extern char *optarg; + int arg; + while ((arg = getopt(argc, argv, "l:ktTnKh")) != -1) { + switch (arg) { + case 'l': + loops = atoi(optarg); + break; + case 'k': + holdKeychains = true; + break; + case 't': + useTp = true; + break; + case 'T': + useTp = true; + useTrustSettings = false; + break; + case 'n': + numCerts--; + noRoot = true; + break; + case 'K': + emptyList = true; + emptyKCList = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); + break; + case 'h': + usage(argv); + } + } + if(optind != argc) { + usage(argv); + } + + /* gather certs to verify */ + certArray = CFArrayCreateMutable(NULL, 3, &kCFTypeArrayCallBacks); + for(dex=0; dex