X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_keychain/lib/Policies.cpp diff --git a/Security/libsecurity_keychain/lib/Policies.cpp b/Security/libsecurity_keychain/lib/Policies.cpp deleted file mode 100644 index 769a78bf..00000000 --- a/Security/libsecurity_keychain/lib/Policies.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2002-2004,2011-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@ - */ - -// -// Policy.cpp - Working with Policies -// -#include -#include -#include -#include - -/* Oids longer than this are considered invalid. */ -#define MAX_OID_SIZE 32 - -//%%FIXME: need to use a common copy of this utility function -static -CFStringRef SecDERItemCopyOIDDecimalRepresentation(uint8 *oid, size_t oidLen) -{ - if (oidLen == 0) - return CFSTR(""); - - if (oidLen > MAX_OID_SIZE) - return CFSTR("Oid too long"); - - CFMutableStringRef result = CFStringCreateMutable(kCFAllocatorDefault, 0); - - // The first two levels are encoded into one byte, since the root level - // has only 3 nodes (40*x + y). However if x = joint-iso-itu-t(2) then - // y may be > 39, so we have to add special-case handling for this. - uint32_t x = oid[0] / 40; - uint32_t y = oid[0] % 40; - if (x > 2) - { - // Handle special case for large y if x = 2 - y += (x - 2) * 40; - x = 2; - } - CFStringAppendFormat(result, NULL, CFSTR("%u.%u"), x, y); - - unsigned long value = 0; - for (x = 1; x < oidLen; ++x) - { - value = (value << 7) | (oid[x] & 0x7F); - /* @@@ value may not span more than 4 bytes. */ - /* A max number of 20 values is allowed. */ - if (!(oid[x] & 0x80)) - { - CFStringAppendFormat(result, NULL, CFSTR(".%lu"), value); - value = 0; - } - } - return result; -} - - -using namespace KeychainCore; - -Policy::Policy(TP supportingTp, const CssmOid &policyOid) - : mTp(supportingTp), - mOid(Allocator::standard(), policyOid), - mValue(Allocator::standard()), - mAuxValue(Allocator::standard()) -{ - // value is as yet unimplemented - secdebug("policy", "Policy() this %p", this); -} - -Policy::~Policy() throw() -{ - secdebug("policy", "~Policy() this %p", this); -} - -void Policy::setValue(const CssmData &value) -{ - StLock_(mMutex); - mValue = value; - mAuxValue.reset(); - - // Certain policy values may contain an embedded pointer. Ask me how I feel about that. - if (mOid == CSSMOID_APPLE_TP_SSL || - mOid == CSSMOID_APPLE_TP_EAP || - mOid == CSSMOID_APPLE_TP_IP_SEC || - mOid == CSSMOID_APPLE_TP_APPLEID_SHARING) - { - CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value.data(); - if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION) - { - if (opts->ServerNameLen > 0) - { - // Copy auxiliary data, then update the embedded pointer to reference our copy - mAuxValue.copy(const_cast(opts->ServerName), opts->ServerNameLen); - mValue.get().interpretedAs()->ServerName = - reinterpret_cast(mAuxValue.data()); - } - else - { - // Clear the embedded pointer! - mValue.get().interpretedAs()->ServerName = - reinterpret_cast(NULL); - } - } - } - else if (mOid == CSSMOID_APPLE_TP_SMIME || - mOid == CSSMOID_APPLE_TP_ICHAT || - mOid == CSSMOID_APPLE_TP_PASSBOOK_SIGNING) - { - CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)value.data(); - if (opts->Version == CSSM_APPLE_TP_SMIME_OPTS_VERSION) - { - if (opts->SenderEmailLen > 0) - { - // Copy auxiliary data, then update the embedded pointer to reference our copy - mAuxValue.copy(const_cast(opts->SenderEmail), opts->SenderEmailLen); - mValue.get().interpretedAs()->SenderEmail = - reinterpret_cast(mAuxValue.data()); - } - else - { - // Clear the embedded pointer! - mValue.get().interpretedAs()->SenderEmail = - reinterpret_cast(NULL); - } - } - } -} - -void Policy::setProperties(CFDictionaryRef properties) -{ - // Set the policy value based on the provided dictionary keys. - if (properties == NULL) - return; - - if (mOid == CSSMOID_APPLE_TP_SSL || - mOid == CSSMOID_APPLE_TP_EAP || - mOid == CSSMOID_APPLE_TP_IP_SEC || - mOid == CSSMOID_APPLE_TP_APPLEID_SHARING) - { - CSSM_APPLE_TP_SSL_OPTIONS options = { CSSM_APPLE_TP_SSL_OPTS_VERSION, 0, NULL, 0 }; - char *buf = NULL; - CFStringRef nameStr = NULL; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyName, (const void **)&nameStr)) { - buf = (char *)malloc(MAXPATHLEN); - if (buf) { - if (CFStringGetCString(nameStr, buf, MAXPATHLEN, kCFStringEncodingUTF8)) { - options.ServerName = buf; - options.ServerNameLen = (unsigned)(strlen(buf)+1); // include terminating null - } - } - } - CFBooleanRef clientRef = NULL; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyClient, (const void **)&clientRef) - && CFBooleanGetValue(clientRef) == true) - options.Flags |= CSSM_APPLE_TP_SSL_CLIENT; - - const CssmData value((uint8*)&options, sizeof(options)); - this->setValue(value); - - if (buf) free(buf); - } - else if (mOid == CSSMOID_APPLE_TP_SMIME || - mOid == CSSMOID_APPLE_TP_ICHAT || - mOid == CSSMOID_APPLE_TP_PASSBOOK_SIGNING) - { - CSSM_APPLE_TP_SMIME_OPTIONS options = { CSSM_APPLE_TP_SMIME_OPTS_VERSION, 0, 0, NULL }; - char *buf = NULL; - CFStringRef nameStr = NULL; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyName, (const void **)&nameStr)) { - buf = (char *)malloc(MAXPATHLEN); - if (buf) { - if (CFStringGetCString(nameStr, buf, MAXPATHLEN, kCFStringEncodingUTF8)) { - CFStringRef teamIDStr = NULL; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyTeamIdentifier, (const void **)&teamIDStr)) { - char *buf2 = (char *)malloc(MAXPATHLEN); - if (buf2) { - if (CFStringGetCString(teamIDStr, buf2, MAXPATHLEN, kCFStringEncodingUTF8)) { - /* append tab separator and team identifier */ - strlcat(buf, "\t", MAXPATHLEN); - strlcat(buf, buf2, MAXPATHLEN); - } - free(buf2); - } - } - options.SenderEmail = buf; - options.SenderEmailLen = (unsigned)(strlen(buf)+1); // include terminating null - } - } - } - CFBooleanRef kuRef = NULL; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_DigitalSignature, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_DigitalSignature; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_NonRepudiation, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_NonRepudiation; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_KeyEncipherment, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_KeyEncipherment; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_DataEncipherment, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_DataEncipherment; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_KeyAgreement, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_KeyAgreement; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_KeyCertSign, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_KeyCertSign; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_CRLSign, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_CRLSign; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_EncipherOnly, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_EncipherOnly; - if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyKU_DecipherOnly, (const void **)&kuRef) - && CFBooleanGetValue(kuRef) == true) - options.IntendedUsage |= CE_KU_DecipherOnly; - - const CssmData value((uint8*)&options, sizeof(options)); - this->setValue(value); - - if (buf) free(buf); - } - -} - -CFDictionaryRef Policy::properties() -{ - // Builds and returns a dictionary which the caller must release. - CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (!properties) return NULL; - - // kSecPolicyOid - CFStringRef oidStr = SecDERItemCopyOIDDecimalRepresentation((uint8*)mOid.data(), mOid.length()); - if (oidStr) { - CFDictionarySetValue(properties, (const void *)kSecPolicyOid, (const void *)oidStr); - CFRelease(oidStr); - } - - // kSecPolicyName - if (mAuxValue) { - CFStringRef nameStr = CFStringCreateWithBytes(NULL, - (const UInt8 *)reinterpret_cast(mAuxValue.data()), - (CFIndex)mAuxValue.length(), kCFStringEncodingUTF8, false); - if (nameStr) { - if (mOid == CSSMOID_APPLE_TP_PASSBOOK_SIGNING) { - CFArrayRef strs = CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, nameStr, CFSTR("\t")); - if (strs) { - CFIndex count = CFArrayGetCount(strs); - if (count > 0) - CFDictionarySetValue(properties, (const void *)kSecPolicyName, (const void *)CFArrayGetValueAtIndex(strs, 0)); - if (count > 1) - CFDictionarySetValue(properties, (const void *)kSecPolicyTeamIdentifier, (const void *)CFArrayGetValueAtIndex(strs, 1)); - CFRelease(strs); - } - } - else { - CFDictionarySetValue(properties, (const void *)kSecPolicyName, (const void *)nameStr); - } - CFRelease(nameStr); - } - } - - // kSecPolicyClient - if (mValue) { - if (mOid == CSSMOID_APPLE_TP_SSL || - mOid == CSSMOID_APPLE_TP_EAP || - mOid == CSSMOID_APPLE_TP_IP_SEC || - mOid == CSSMOID_APPLE_TP_APPLEID_SHARING) - { - CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)mValue.data(); - if (opts->Flags & CSSM_APPLE_TP_SSL_CLIENT) { - CFDictionarySetValue(properties, (const void *)kSecPolicyClient, (const void *)kCFBooleanTrue); - } - } - } - - // key usage flags (currently only for S/MIME and iChat policies) - if (mValue) { - if (mOid == CSSMOID_APPLE_TP_SMIME || - mOid == CSSMOID_APPLE_TP_ICHAT) - { - CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)mValue.data(); - CE_KeyUsage usage = opts->IntendedUsage; - if (usage & CE_KU_DigitalSignature) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_DigitalSignature, (const void *)kCFBooleanTrue); - if (usage & CE_KU_NonRepudiation) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_NonRepudiation, (const void *)kCFBooleanTrue); - if (usage & CE_KU_KeyEncipherment) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_KeyEncipherment, (const void *)kCFBooleanTrue); - if (usage & CE_KU_DataEncipherment) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_DataEncipherment, (const void *)kCFBooleanTrue); - if (usage & CE_KU_KeyAgreement) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_KeyAgreement, (const void *)kCFBooleanTrue); - if (usage & CE_KU_KeyCertSign) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_KeyCertSign, (const void *)kCFBooleanTrue); - if (usage & CE_KU_CRLSign) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_CRLSign, (const void *)kCFBooleanTrue); - if (usage & CE_KU_EncipherOnly) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_EncipherOnly, (const void *)kCFBooleanTrue); - if (usage & CE_KU_DecipherOnly) - CFDictionarySetValue(properties, (const void *)kSecPolicyKU_DecipherOnly, (const void *)kCFBooleanTrue); - } - } - return properties; -} - - -bool Policy::operator < (const Policy& other) const -{ - //@@@ inefficient - return (oid() < other.oid()) || - (oid() == other.oid() && value() < other.value()); -} - -bool Policy::operator == (const Policy& other) const -{ - return oid() == other.oid() && value() == other.value(); -}