X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/84aacf34eae6543be9f0280b2015385f91e5c2c6..b54c578e17e9bcbd74aa30ea75e25e955b9a6205:/SecurityTool/trusted_cert_add.c?ds=inline diff --git a/SecurityTool/trusted_cert_add.c b/SecurityTool/trusted_cert_add.c deleted file mode 100644 index c2b1d12b..00000000 --- a/SecurityTool/trusted_cert_add.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (c) 2006-2010,2012,2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * trust_cert_add.c - */ - -/* - * This command is fairly versatile and hence the usage might be a bit confusing. - * The standard usage of this command is to add one or more certs to a Trust - * Settings domain, along with optional usage constraints. Often, but not - * necessarily, you'd also add the cert to a keychain while you're adding - * it to Trust Settings. - * - * -- To add someRoot.cer to your login keychain and to your Trust Settings as - * an unrestricted root cert: - * - * % security add-trusted-cert -k login.keychain someRoot.cer - * - * -- To add anotherRoot.cer to the local admin trust settings, only for policy - * ssl, without adding it to a keychain (presumably because it's already in - * a keychain somewhere else): - * - * % security add-trusted-cert -p ssl -d anotherRoot.cer - * - * The more obscure uses involve trust settings files. - * - * This command can also operate on trust settings as files instead of - * modifying an actual on-disk Trust Settings record. One standard use for - * this function is in the creation of the system Trust Settings, which - * are immutable at runtime via the SecTrustSettings API. You provide a - * file name for this option via -f settingsFile. If the file does not - * exist, a new empty Trust Settings will be created, and certs and/or - * a default will be added to that record, and the record will be written - * out to the filename you provide (infile = outfile, always). - * - * -- To create Trust Settings record with one cert in it, restricted to - * policy SSL: - * - * % security add-trusted-cert -p ssl -f someTrustSettingsFile.plist -r someRoot.cer - * - * You can also use the -f option and specify no certs, in which case an empty - * Trust Settings record will be created. This can be useful if you want to - * quickly reset the Trust Settings in a given domain to "empty"; the - * empty Trust Settings record can be imported via the trust-settings-import - * command. - * - * -- To reset the admin trust settings to "empty": - * - * % security add-trusted-cert -f emptySettingsFile.plist - * % security trust-settings-import -d emptySettingsFile.plist - */ - -#include "trusted_cert_add.h" -#include "trusted_cert_utils.h" -#include "security_tool.h" -#include "keychain_utilities.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* r/w files as CFData */ -static CFDataRef CF_RETURNS_RETAINED readFileData( - const char *fileName) -{ - unsigned char *d; - size_t dLen; - - if(readFileSizet(fileName, &d, &dLen)) { - return NULL; - } - CFDataRef cfd = CFDataCreate(NULL, (const UInt8 *)d, dLen); - free(d); - return cfd; -} - -static int writeFileData( - const char *fileName, - CFDataRef cfd) -{ - unsigned long l = (unsigned long)CFDataGetLength(cfd); - int rtn = writeFileSizet(fileName, CFDataGetBytePtr(cfd), l); - if(rtn) { - fprintf(stderr, "Error %d writing to %s\n", rtn, fileName); - } - else if(!do_quiet) { - fprintf(stdout, "...wrote %ld bytes to %s\n", l, fileName); - } - return rtn; -} - -static int appendConstraintsToDict( - const char *appPath, /* optional */ - const char *policy, /* optional - smime, ssl, etc. */ - const char *policyStr, /* optional policy string */ - SecTrustSettingsResult resultType, - CSSM_RETURN allowErr, /* optional allowed error */ - SecTrustSettingsKeyUsage keyUse,/* optional key use */ - CFMutableDictionaryRef *dict) /* result RETURNED here, created if necessary */ -{ - if(*dict == NULL) { - *dict = CFDictionaryCreateMutable(NULL, - 0, // capacity - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - } - - /* OID string to an OID pointer */ - const CSSM_OID *oid = NULL; - if(policy != NULL) { - oid = policyStringToOid(policy); - if(oid == NULL) { - return SHOW_USAGE_MESSAGE; - } - - /* OID to SecPolicyRef */ - SecPolicyRef policyRef = oidToPolicy(oid); - if(policyRef == NULL) { - return SHOW_USAGE_MESSAGE; - } - CFDictionaryAddValue(*dict, kSecTrustSettingsPolicy, policyRef); - CFRelease(policyRef); - } - - /* app string to SecTrustedApplicationRef */ - if(appPath != NULL) { - SecTrustedApplicationRef appRef; - OSStatus ortn = SecTrustedApplicationCreateFromPath(appPath, &appRef); - if(ortn) { - cssmPerror("SecTrustedApplicationCreateFromPath", ortn); - return -1; - } - CFDictionaryAddValue(*dict, kSecTrustSettingsApplication, appRef); - CFRelease(appRef); - } - - if(policyStr != NULL) { - CFStringRef pstr = CFStringCreateWithCString(NULL, policyStr, kCFStringEncodingUTF8); - CFDictionaryAddValue(*dict, kSecTrustSettingsPolicyString, pstr); - CFRelease(pstr); - } - - if(allowErr) { - SInt32 ae = (SInt32)allowErr; - CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &ae); - CFDictionaryAddValue(*dict, kSecTrustSettingsAllowedError, cfNum); - CFRelease(cfNum); - } - - if(keyUse != 0) { - SInt32 ku = (SInt32)keyUse; - CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &ku); - CFDictionaryAddValue(*dict, kSecTrustSettingsKeyUsage, cfNum); - CFRelease(cfNum); - } - - if(resultType != kSecTrustSettingsResultTrustRoot) { - SInt32 rt = (SInt32)resultType; - CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &rt); - CFDictionaryAddValue(*dict, kSecTrustSettingsResult, cfNum); - CFRelease(cfNum); - } - - return 0; -} - - -int -trusted_cert_add(int argc, char * const *argv) -{ - extern char *optarg; - extern int optind; - OSStatus ortn; - int arg; - SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser; - int ourRtn = 0; - SecKeychainRef kcRef = NULL; - char *certFile = NULL; - SecCertificateRef certRef = NULL; - - /* for operating in file-based settings */ - char *settingsFileIn = NULL; - char *settingsFileOut = NULL; - CFDataRef settingsIn = NULL; - CFDataRef settingsOut = NULL; - - /* optional usage constraints */ -// char *policy = NULL; - char *appPath = NULL; -// char *policyString = NULL; - SecTrustSettingsResult resultType = kSecTrustSettingsResultTrustRoot; - CSSM_RETURN allowErr = CSSM_OK; - SecTrustSettingsKeyUsage keyUse = 0; - CFMutableArrayRef trustSettings = NULL; - int haveConstraints = 0; - - const int maxPolicies = 16; // upper limit on policies that can be set in one invocation - char *policyNames[maxPolicies]; - char *policyStrings[maxPolicies]; - int allowedErrors[maxPolicies]; - int policyNameCount = 0, policyStringCount = 0, allowedErrorCount = 0; - - if(argc < 2) { - return SHOW_USAGE_MESSAGE; - } - - optind = 1; - while ((arg = getopt(argc, argv, "dr:a:p:s:e:u:k:i:o:h")) != -1) { - switch (arg) { - case 'd': - domain = kSecTrustSettingsDomainAdmin; - break; - case 'r': - if(!strcmp(optarg, "trustRoot")) { - resultType = kSecTrustSettingsResultTrustRoot; - } - else if(!strcmp(optarg, "trustAsRoot")) { - resultType = kSecTrustSettingsResultTrustAsRoot; - } - else if(!strcmp(optarg, "deny")) { - resultType = kSecTrustSettingsResultDeny; - } - else if(!strcmp(optarg, "unspecified")) { - resultType = kSecTrustSettingsResultUnspecified; - } - else { - return SHOW_USAGE_MESSAGE; - } - haveConstraints = 1; - break; - case 'p': - if (policyNameCount < maxPolicies) { - policyNames[policyNameCount++] = optarg; - } else { - fprintf(stderr, "Too many policy arguments.\n"); - return SHOW_USAGE_MESSAGE; - } - haveConstraints = 1; - break; - case 'a': - appPath = optarg; - haveConstraints = 1; - break; - case 's': - if (policyStringCount < maxPolicies) { - policyStrings[policyStringCount++] = optarg; - } else { - fprintf(stderr, "Too many policy string arguments.\n"); - return SHOW_USAGE_MESSAGE; - } - haveConstraints = 1; - break; - case 'e': - if (allowedErrorCount < maxPolicies) { - if (!strcmp("certExpired", optarg)) - allowErr = -2147409654; // 0x8001210A = CSSMERR_TP_CERT_EXPIRED - else if (!strcmp("hostnameMismatch", optarg)) - allowErr = -2147408896; // 0x80012400 = CSSMERR_APPLETP_HOSTNAME_MISMATCH - else - allowErr = (CSSM_RETURN)atoi(optarg); - if (!allowErr) { - fprintf(stderr, "Invalid value for allowed error.\n"); - return SHOW_USAGE_MESSAGE; - } - allowedErrors[allowedErrorCount++] = allowErr; - } else { - fprintf(stderr, "Too many \"allowed error\" arguments.\n"); - return SHOW_USAGE_MESSAGE; - } - haveConstraints = 1; - break; - case 'u': - keyUse = (SecTrustSettingsKeyUsage)atoi(optarg); - haveConstraints = 1; - break; - case 'k': - kcRef = keychain_open(optarg); - if(kcRef == NULL) { - return 1; - } - break; - case 'i': - settingsFileIn = optarg; - break; - case 'o': - settingsFileOut = optarg; - break; - default: - case 'h': - return SHOW_USAGE_MESSAGE; - } - } - if(ourRtn) { - goto errOut; - } - - switch(argc - optind) { - case 0: - /* no certs */ - break; - case 1: - certFile = argv[optind]; - break; - default: - ourRtn = 2; - goto errOut; - } - - /* validate inputs */ - if((certFile == NULL) && (settingsFileOut == NULL)) { - /* no cert file - only legal for r/w file */ - fprintf(stderr, "No cert file specified.\n"); - ourRtn = 2; - goto errOut; - } - if((settingsFileOut != NULL) && (domain != kSecTrustSettingsDomainUser)) { - fprintf(stderr, "Can't specify both domain and a settingsFile\n"); - ourRtn = 2; - goto errOut; - } - if((settingsFileIn != NULL) && (settingsFileOut == NULL)) { - /* on the other hand, fileOut with no fileIn is OK */ - fprintf(stderr, "Can't specify settingsFileIn and no settingsFileOut\n"); - ourRtn = 2; - goto errOut; - } - - /* build per-policy constraints dictionaries */ - if(haveConstraints) { - int i, j, k; - for (i=0; i