X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/clxutils/rootStoreTool/rootStoreTool.cpp diff --git a/SecurityTests/clxutils/rootStoreTool/rootStoreTool.cpp b/SecurityTests/clxutils/rootStoreTool/rootStoreTool.cpp deleted file mode 100644 index eb54e571..00000000 --- a/SecurityTests/clxutils/rootStoreTool/rootStoreTool.cpp +++ /dev/null @@ -1,932 +0,0 @@ -/* - * rootStoreTool.cpp - exercise SecTrustSettings API - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "parseTrustedRootList.h" -#include /* private header */ -#include "rootUtils.h" -#include -#include -#include - -static void usage(char **argv) -{ - printf("usage: %s op [options]\n", argv[0]); - printf("Op values:\n"); - printf(" a -- add cert\n"); - printf(" p -- parse TrustSettings record\n"); - printf(" r -- get certs from TS & display\n"); - printf(" d -- delete entries from TS interactively\n"); - printf(" D -- delete ALL certs from TS (requires -R argument)\n"); - printf(" R -- remove legacy User Trust setting\n"); - - printf("Options:\n"); - printf(" -c certFile -- specify cert\n"); - printf(" -s -- system TrustSettings; default is user\n"); - printf(" -d -- Admin TrustSettings; default is user\n"); - printf(" -t settingsFile -- settings from file; default is user\n"); - printf(" -T settingsFileOut -- settings to file\n"); - printf(" -a appPath -- specify app constraints\n"); - printf(" -p policy -- specify policy constraint\n"); - printf(" policy = ssl, smime, swuSign, codeSign, IPSec, iChat\n"); - printf(" -P appPath policy -- specify app AND policy constraint\n"); - printf(" -e emailAddress -- specify SMIME policy plus email address\n"); - printf(" -L hostname -- specify SSL policy plus hostname\n"); - printf(" -r resultType -- resultType = trust, trustAsRoot, deny, unspecified\n"); - printf(" -w allowErr -- allowed error, an integer; implies result unspecified\n"); - printf(" -W allowErr policy -- allowed error AND policy AND implies result unspecified\n"); - printf(" -u keyUsage -- key usage, an integer\n"); - printf(" -k keychain -- Default is default keychain.\n"); - printf(" -R -- Really. For Delete All op.\n"); - printf(" -v -- verbose cert display\n"); - printf(" -A -- add cert to keychain\n"); - printf(" -U -- use SecTrustSetUserTrust\n"); - printf(" -2 -- use SecTrustSetUserTrustLegacy\n"); - printf(" -l -- loop and pause for malloc debug\n"); - printf(" -h -- help\n"); - exit(1); -} - -/* - * Start up a CFRunLoop. This is needed to field keychain event callbacks, used - * to maintain root cert cache coherency. This operation is only needed in command - * line tools; regular GUI apps already have a CFRunLoop. - */ - -/* first we need something to register so we *have* a run loop */ -static OSStatus kcCacheCallback ( - SecKeychainEvent keychainEvent, - SecKeychainCallbackInfo *info, - void *context) -{ - return noErr; -} - -/* main thread has to wait for this to be set to know a run loop has been set up */ -static int runLoopInitialized = 0; - -/* this is the thread which actually runs the CFRunLoop */ -void *cfRunLoopThread(void *arg) -{ - OSStatus ortn = SecKeychainAddCallback(kcCacheCallback, - kSecTrustSettingsChangedEventMask, NULL); - if(ortn) { - printf("registerCacheCallbacks: SecKeychainAddCallback returned %ld", ortn); - /* Not sure how this could ever happen - maybe if there is no run loop active? */ - return NULL; - } - runLoopInitialized = 1; - CFRunLoopRun(); - /* should not be reached */ - printf("\n*** Hey! CFRunLoopRun() exited!***\n"); - return NULL; -} - -static int startCFRunLoop() -{ - pthread_t runLoopThread; - - int result = pthread_create(&runLoopThread, NULL, cfRunLoopThread, NULL); - if(result) { - printf("***pthread_create returned %d, aborting\n", result); - return -1; - } - return 0; -} - -static SecCertificateRef certFromFile( - const char *fileName) -{ - unsigned char *cp = NULL; - unsigned len = 0; - if(readFile(fileName, &cp, &len)) { - printf("***Error reading file %s\n", fileName); - return NULL; - } - SecCertificateRef certRef; - CSSM_DATA certData = {len, cp}; - OSStatus ortn = SecCertificateCreateFromData(&certData, - CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certRef); - if(ortn) { - cssmPerror("SecCertificateCreateFromData", ortn); - return NULL; - } - free(cp); - return certRef; -} - -/* - * Display usage constraints array as obtained from - * SecTrustSettingsCopyTrustSettings(). - */ -static int displayTrustSettings( - CFArrayRef trustSettings, - OidParser &parser) -{ - /* must always be there though it may be empty */ - if(trustSettings == NULL) { - printf("***displayTrustSettings: missing trust settings array"); - return -1; - } - if(CFGetTypeID(trustSettings) != CFArrayGetTypeID()) { - printf("***displayTrustSettings: malformed trust settings array"); - return -1; - } - - int ourRtn = 0; - CFIndex numUseConstraints = CFArrayGetCount(trustSettings); - indentIncr(); - indent(); printf("Number of trust settings : %ld\n", numUseConstraints); - OSStatus ortn; - SecPolicyRef certPolicy; - SecTrustedApplicationRef certApp; - CFDictionaryRef ucDict; - CFStringRef policyStr; - CFNumberRef cfNum; - - /* grind thru the trust settings dictionaries */ - for(CFIndex ucDex=0; ucDex appPath; - ortn = SecTrustedApplicationCopyData(certApp, appPath.take()); - if(ortn) { - cssmPerror("SecTrustedApplicationCopyData", ortn); - ourRtn = -1; - goto nextAp; - } - indent(); printf("Application : %s", CFDataGetBytePtr(appPath)); - printf("\n"); - } - - /* policy string */ - policyStr = (CFStringRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicyString); - if(policyStr != NULL) { - if(CFGetTypeID(policyStr) != CFStringGetTypeID()) { - printf("***displayTrustSettings: malformed policyStr"); - ourRtn = -1; - goto nextAp; - } - indent(); printf("Policy String : "); - printCfStr(policyStr); printf("\n"); - } - - /* Allowed error */ - cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsAllowedError); - if(cfNum != NULL) { - if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) { - printf("***displayTrustSettings: malformed allowedError"); - ourRtn = -1; - goto nextAp; - } - indent(); printf("Allowed Error : "); - printCssmErr(cfNum); printf("\n"); - } - - /* Result */ - cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsResult); - if(cfNum != NULL) { - if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) { - printf("***displayTrustSettings: malformed Result"); - ourRtn = -1; - goto nextAp; - } - indent(); printf("Result Type : "); - printResult(cfNum); printf("\n"); - } - - /* key usage */ - cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage); - if(cfNum != NULL) { - if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) { - printf("***displayTrustSettings: malformed keyUsage"); - ourRtn = -1; - goto nextAp; - } - indent(); printf("Key Usage : "); - printKeyUsage(cfNum); printf("\n"); - } - - nextAp: - indentDecr(); - } - indentDecr(); - return ourRtn; -} - -/* convert an OID to a SecPolicyRef */ -static SecPolicyRef oidToPolicy( - const CSSM_OID &oid) -{ - SecPolicyRef policyRef = NULL; - - OSStatus ortn = SecPolicyCopy(CSSM_CERT_X_509v3, &oid, &policyRef); - if(ortn) { - cssmPerror("SecPolicyCopy", ortn); - return NULL; - } - return policyRef; -} - -/* Convert cmdline policy string to SecPolicyRef */ -static SecPolicyRef policyStringToPolicy( - const char *policy) -{ - if(policy == NULL) { - return NULL; - } - const CSSM_OID *oid = NULL; - if(!strcmp(policy, "ssl")) { - oid = &CSSMOID_APPLE_TP_SSL; - } - else if(!strcmp(policy, "smime")) { - oid = &CSSMOID_APPLE_TP_SMIME; - } - else if(!strcmp(policy, "codeSign")) { - oid = &CSSMOID_APPLE_TP_CODE_SIGNING; - } - else if(!strcmp(policy, "swuSign")) { - oid = &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING; - } - else if(!strcmp(policy, "IPSec")) { - oid = &CSSMOID_APPLE_TP_IP_SEC; - } - else if(!strcmp(policy, "iChat")) { - oid = &CSSMOID_APPLE_TP_ICHAT; - } - else { - printf("***Unknown policy string (%s)\n", policy); - return NULL; - } - - /* OID to SecPolicyRef */ - return oidToPolicy(*oid); -} - -static int appendConstraintToArray( - const char *appPath, /* optional, "-" means ensure apArray is nonempty */ - const char *policy, /* optional (ssl/smime), "-" as above */ - const char *policyStr, /* optional policy string */ - const SInt32 *allowErr, /* optional allowed error */ - const char *resultType, /* optional allow/confirm/deny */ - SecTrustSettingsKeyUsage keyUse, /* optional key use */ - CFMutableArrayRef &array) /* result RETURNED here, created if necessary */ -{ - if(array == NULL) { - array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - } - - CFMutableDictionaryRef outDict = CFDictionaryCreateMutable(NULL, - 0, // capacity - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - if((policy != NULL) && (strcmp(policy, "-"))) { - - /* policy string to SecPolicyRef */ - SecPolicyRef policyRef = policyStringToPolicy(policy); - if(policyRef == NULL) { - return -1; - } - CFDictionaryAddValue(outDict, kSecTrustSettingsPolicy, policyRef); - CFRelease(policyRef); - } - - /* app string to SecTrustedApplicationRef */ - if((appPath != NULL) && (strcmp(appPath, "-"))) { - SecTrustedApplicationRef appRef; - OSStatus ortn = SecTrustedApplicationCreateFromPath(appPath, &appRef); - if(ortn) { - cssmPerror("SecTrustedApplicationCreateFromPath", ortn); - return -1; - } - CFDictionaryAddValue(outDict, kSecTrustSettingsApplication, appRef); - CFRelease(appRef); - } - - if(policyStr != NULL) { - CFStringRef pstr = CFStringCreateWithCString(NULL, policyStr, kCFStringEncodingASCII); - CFDictionaryAddValue(outDict, kSecTrustSettingsPolicyString, pstr); - CFRelease(pstr); - } - - if(allowErr != NULL) { - CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, allowErr); - CFDictionaryAddValue(outDict, kSecTrustSettingsAllowedError, cfNum); - CFRelease(cfNum); - } - - if(keyUse != 0) { - SInt32 ku = (SInt32)ku; - CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &ku); - CFDictionaryAddValue(outDict, kSecTrustSettingsKeyUsage, cfNum); - CFRelease(cfNum); - } - - if(resultType != NULL) { - SInt32 n; - - if(!strcmp(resultType, "trust")) { - n = kSecTrustSettingsResultTrustRoot; - } - else if(!strcmp(resultType, "trustAsRoot")) { - n = kSecTrustSettingsResultTrustAsRoot; - } - else if(!strcmp(resultType, "deny")) { - n = kSecTrustSettingsResultDeny; - } - else if(!strcmp(resultType, "unspecified")) { - n = kSecTrustSettingsResultUnspecified; - } - else { - printf("***unknown resultType spec (%s)\n", resultType); - return -1; - } - CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &n); - CFDictionaryAddValue(outDict, kSecTrustSettingsResult, cfNum); - CFRelease(cfNum); - } - - /* append dictionary to output */ - CFArrayAppendValue(array, outDict); - /* array owns the dictionary now */ - CFRelease(outDict); - return 0; -} - -/* read a file --> CFDataRef */ -CFDataRef readFileCFData( - const char *fileName) -{ - int rtn; - unsigned char *fileData = NULL; - unsigned fileDataLen = 0; - - rtn = readFile(fileName, &fileData, &fileDataLen); - if(rtn) { - printf("Error (%d) reading %s.\n", rtn, fileName); - return NULL; - } - CFDataRef cfd = CFDataCreate(NULL, (const UInt8 *)fileData, fileDataLen); - free(fileData); - return cfd; -} - -static int fetchParseTrustRecord( - SecTrustSettingsDomain domain, - char *settingsFile) /* optional, ignore domain if present */ -{ - CFDataRef trustSettings = NULL; - - if(settingsFile) { - trustSettings = readFileCFData(settingsFile); - if(trustSettings == NULL) { - return -1; - } - } - else { - OSStatus ortn = SecTrustSettingsCreateExternalRepresentation(domain, &trustSettings); - if(ortn) { - cssmPerror("SecTrustSettingsCreateExternalRepresentation", ortn); - return -1; - } - } - int rtn = parseTrustedRootList(trustSettings); - CFRelease(trustSettings); - return rtn; -} - -static int copyCertsAndDisplay( - bool verbose, - SecTrustSettingsDomain domain) -{ - OSStatus ortn; - - auto_ptr parser(NULL); - - if(verbose) { - parser.reset(new OidParser); - } - - CFArrayRef certArray = NULL; - ortn = SecTrustSettingsCopyCertificates(domain, &certArray); - if(ortn) { - cssmPerror("SecTrustSettingsCopyCertificates", ortn); - return ortn; - } - - CFIndex numCerts = CFArrayGetCount(certArray); - indent(); - printf("Num certs = %ld\n", numCerts); - int ourRtn = 0; - for(CFIndex dex=0; dex appPolicies; - ortn = SecTrustSettingsCopyTrustSettings(certRef, domain, appPolicies.take()); - if(ortn) { - cssmPerror("SecRootCertificateCopyAppPolicyConstraints", ortn); - ourRtn = -1; - continue; - } - if(displayTrustSettings(appPolicies, *parser.get())) { - ourRtn = -1; - } - } - } - CFRelease(certArray); - return ourRtn; -} - -static int deleteCerts( - SecTrustSettingsDomain domain, - bool deleteAll) -{ - OSStatus ortn; - - CFArrayRef certArray = NULL; - ortn = SecTrustSettingsCopyCertificates(domain, &certArray); - if(ortn) { - cssmPerror("SecTrustSettingsCopyCertificates", ortn); - return ortn; - } - - CFIndex numCerts = CFArrayGetCount(certArray); - unsigned numDeleted = 0; - - for(CFIndex dex=0; dex")); - } - if(settingsIn) { - ortn = SecTrustSettingsSetTrustSettingsExternal(settingsIn, - certRef, trustSettings, settingsOut); - if(ortn) { - cssmPerror("SecTrustSettingsSetTrustSettingsExternal", ortn); - return -1; - } - } - else { - ortn = SecTrustSettingsSetTrustSettings(certRef, domain, trustSettings); - if(ortn) { - cssmPerror("SecTrustSettingsSetTrustSettings", ortn); - return -1; - } - printf("...cert added to %s TrustList.\n", domainName); - } - return 0; -} - -static int addCertLegacy( - SecCertificateRef certRef, - const char *policy, - const char *resultStr, - bool useLegacy) -{ - /* OID string to an OID pointer */ - if(policy == NULL) { - printf("***You must specify a policy to set legacy User Trust\n"); - return 1; - } - SecPolicyRef policyRef = policyStringToPolicy(policy); - if(policyRef == NULL) { - return -1; - } - - /* result string to legacy SecTrustUserSetting */ - SecTrustUserSetting setting = kSecTrustResultInvalid; - if(resultStr == NULL) { - setting = kSecTrustResultProceed; - } - else if(!strcmp(resultStr, "trust")) { - setting = kSecTrustResultProceed; - } - else if(!strcmp(resultStr, "trustAsRoot")) { - setting = kSecTrustResultProceed; - } - else if(!strcmp(resultStr, "deny")) { - setting = kSecTrustResultDeny; - } - else if (!strcmp(resultStr, "unspecified")) { - setting = kSecTrustResultUnspecified; - } - else { - printf("***Can't map %s to a SecTrustUserSetting\n", resultStr); - return -1; - } - OSStatus ortn; - if(useLegacy) { - ortn = SecTrustSetUserTrustLegacy(certRef, policyRef, setting); - if(ortn) { - cssmPerror("SecTrustSetUserTrustLegacy", ortn); - } - else { - if(setting == kSecTrustResultUnspecified) { - printf("...User Trust removed via SecTrustSetUserTrustLegacy().\n"); - } - else { - printf("...User Trust set via SecTrustSetUserTrustLegacy().\n"); - } - } - } - else { - #if 1 - printf("...Legacy implementation needs Makefile work to avoid deprecation error\n"); - exit(1); - #else - ortn = SecTrustSetUserTrust(certRef, policyRef, setting); - if(ortn) { - cssmPerror("SecTrustSetUserTrust", ortn); - } - else { - printf("...trust setting set via SecTrustSetUserTrust().\n"); - } - #endif - } - if(policyRef != NULL) { - CFRelease(policyRef); - } - return ortn; -} - -int main(int argc, char **argv) -{ - int arg; - CFMutableArrayRef appPolicies = NULL; - CFDataRef settingsIn = NULL; - CFDataRef settingsOut = NULL; - - /* user-spec'd variables */ - bool loopPause = false; - bool really = false; - bool verbose = false; - char *kcName = NULL; - SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser; - SecCertificateRef certRef = NULL; - bool addToKeychain = false; - char *settingsFileIn = NULL; - char *settingsFileOut = NULL; - bool userTrustLegacy = false; - char *policyStr = NULL; - char *resultStr = NULL; - bool userTrust = false; - - extern char *optarg; - extern int optind; - optind = 2; - while ((arg = getopt(argc, argv, "c:sdt:T:a:p:P:e:L:r:w:W:k:u:RvAU2lh")) != -1) { - switch (arg) { - case 'c': - if(certRef) { - printf("***Only one cert at a time, please.\n"); - usage(argv); - } - certRef = certFromFile(optarg); - if(certRef == NULL) { - exit(1); - } - break; - case 's': - domain = kSecTrustSettingsDomainSystem; - break; - case 'd': - domain = kSecTrustSettingsDomainAdmin; - break; - case 't': - settingsFileIn = optarg; - break; - case 'T': - settingsFileOut = optarg; - break; - case 'a': - if(appendConstraintToArray(optarg, NULL, NULL, NULL, NULL, 0, appPolicies)) { - exit(1); - } - break; - case 'p': - if(appendConstraintToArray(NULL, optarg, NULL, NULL, NULL, 0, appPolicies)) { - exit(1); - } - policyStr = optarg; - break; - case 'P': - /* this takes an additional argument */ - if(optind > (argc - 1)) { - usage(argv); - } - if(appendConstraintToArray(optarg, argv[optind], NULL, NULL, NULL, - 0, appPolicies)) { - exit(1); - } - optind++; - break; - case 'e': - if(appendConstraintToArray(NULL, "smime", optarg, NULL, NULL, - 0, appPolicies)) { - exit(1); - } - policyStr = "smime"; - break; - case 'L': - if(appendConstraintToArray(NULL, "ssl", optarg, NULL, NULL, 0, appPolicies)) { - exit(1); - } - policyStr = "ssl"; - break; - case 'r': - if(appendConstraintToArray(NULL, NULL, NULL, NULL, optarg, 0, appPolicies)) { - exit(1); - } - resultStr = optarg; - break; - case 'w': - { - SInt32 l = atol(optarg); - if(appendConstraintToArray(NULL, NULL, NULL, &l, "unspecified", 0, appPolicies)) { - exit(1); - } - break; - } - case 'W': - { - /* this takes an additional argument */ - if(optind > (argc - 1)) { - usage(argv); - } - SInt32 l = atol(optarg); - if(appendConstraintToArray(NULL, argv[optind], NULL, &l, "unspecified", 0, - appPolicies)) { - exit(1); - } - optind++; - break; - } - case 'u': - { - SInt32 l = atol(optarg); - SecTrustSettingsKeyUsage ku = (SecTrustSettingsKeyUsage)l; - if(appendConstraintToArray(NULL, NULL, NULL, NULL, NULL, ku, appPolicies)) { - exit(1); - } - break; - } - case 'k': - kcName = optarg; - break; - case 'R': - really = true; - break; - case 'v': - verbose = true; - break; - case 'A': - addToKeychain = true; - break; - case 'l': - loopPause = true; - break; - case '2': - userTrustLegacy = true; - break; - case 'U': - userTrust = true; - break; - default: - case 'h': - usage(argv); - } - } - if(optind != argc) { - usage(argv); - } - if(startCFRunLoop()) { - /* enable reception of KC event messages */ - exit(1); - } - - /* give that thread a chance right now */ - while(!runLoopInitialized) { - usleep(1000); - }; - - int ortn = 0; - do { - switch(argv[1][0]) { - case 'a': - if(certRef == NULL) { - printf("You must supply a cert.\n"); - usage(argv); - } - if(settingsFileIn) { - if(!settingsFileOut) { - printf("Modifying trust settings as file requires output file\n"); - return -1; - } - settingsIn = readFileCFData(settingsFileIn); - if(!settingsIn) { - return -1; - } - } - if(userTrustLegacy || userTrust) { - ortn = addCertLegacy(certRef, policyStr, resultStr, userTrustLegacy); - } - else { - ortn = addCert(certRef, domain, addToKeychain, kcName, appPolicies, - settingsIn, &settingsOut); - if((ortn == noErr) && (settingsOut != NULL)) { - unsigned len = CFDataGetLength(settingsOut); - if(writeFile(settingsFileOut, CFDataGetBytePtr(settingsOut), len)) { - printf("***Error writing settings to %s\n", settingsFileOut); - } - else { - printf("...wrote %u bytes to %s\n", len, settingsFileOut); - } - } - } - if(settingsIn) { - CFRelease(settingsIn); - } - if(settingsOut) { - CFRelease(settingsOut); - } - break; - case 'p': - ortn = fetchParseTrustRecord(domain, settingsFileIn); - break; - case 'r': - ortn = copyCertsAndDisplay(verbose, domain); - break; - case 'd': - ortn = deleteCerts(domain, false); - break; - case 'D': - if(!really) { - printf("I do not believe you. Specify -D option to delete all roots.\n"); - exit(1); - } - ortn = deleteCerts(domain, true); - break; - case 'R': - ortn = addCertLegacy(certRef, policyStr, "unspecified", true); - break; - default: - usage(argv); - } - if(loopPause) { - fpurge(stdin); - printf("Pausing for MallocDebug. Hit CR to continue: "); - fflush(stdout); - getchar(); - } - } while(loopPause); - return (int)ortn; -}