/* * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This 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. */ // // SecCFTypes.cpp - CF runtime interface // #include #include #include #include namespace Security { namespace KeychainCore { SecCFTypes & gTypes() { static ModuleNexus nexus; return nexus(); } } // end namespace KeychainCore } // end namespace Security using namespace KeychainCore; SecCFTypes::SecCFTypes() : Access("SecAccess"), ACL("SecACL"), Certificate("SecCertificate"), CertificateRequest("SecCertificateRequest"), Identity("SecIdentity"), IdentityCursor("SecIdentitySearch"), ItemImpl("SecKeychainItem"), KCCursorImpl("SecKeychainSearch"), KeychainImpl("SecKeychain"), KeyItem("SecKey"), Policy("SecPolicy"), PolicyCursor("SecPolicySearch"), Trust("SecTrust"), TrustedApplication("SecTrustedApplication"), allocator(CFAllocatorCreate(NULL, &CFClass::allocatorContext)) { } // // CFClass // CFAllocatorContext CFClass::allocatorContext = { 0, NULL, NULL, /* retain */ NULL, /* release */ NULL, /* copyDescription */ allocatorAllocate, /* allocate */ allocatorReallocate, /* reallocate */ allocatorDeallocate, /* deallocate */ allocatorPreferredSize /* preferredSize */ }; CFClass::CFClass(const char *name) { // initialize the CFRuntimeClass structure version = 0; className = name; init = NULL; copy = NULL; finalize = NULL; equal = equalType; hash = hashType; copyFormattingDesc = copyFormattingDescType; copyDebugDesc = copyDebugDescType; // register typeID = _CFRuntimeRegisterClass(this); assert(typeID != _kCFRuntimeNotATypeID); } Boolean CFClass::equalType(CFTypeRef cf1, CFTypeRef cf2) { // CF checks for pointer equality and ensures type equality already return SecCFObject::optional(cf1)->equal(*SecCFObject::optional(cf2)); } CFHashCode CFClass::hashType(CFTypeRef cf) { return SecCFObject::optional(cf)->hash(); } CFStringRef CFClass::copyFormattingDescType(CFTypeRef cf, CFDictionaryRef dict) { return SecCFObject::optional(cf)->copyFormattingDesc(dict); } CFStringRef CFClass::copyDebugDescType(CFTypeRef cf) { return SecCFObject::optional(cf)->copyDebugDesc(); } // // CFAllocatorContext callbacks. // void * CFClass::allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info) { return malloc(allocSize); } void * CFClass::allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) { return realloc(ptr, newsize); } void CFClass::allocatorDeallocate(void *ptr, void *info) { /* * Called on a CFRelease of any Sec object: single thread through * same lock held by public API calls. This is a recursive lock * so it's safe to do this for CF objects allocated and released * within the Sec layer. */ StLock _(globals().apiLock); CFTypeRef cf = reinterpret_cast(reinterpret_cast(ptr) + sizeof(CFAllocatorRef)); CFIndex rc = CFGetRetainCount(cf); if (rc == 1) { SecCFObject *obj = SecCFObject::optional(cf); if (!obj->isNew()) obj->~SecCFObject(); free(ptr); } else if (rc > 1) { // Since CFRelease did nothing other than call CFAllocatorDeallocate() followed // by a CFRelease() of the allocator we need to counter that here. CFRetain(CFGetAllocator(cf)); CFRelease(cf); } else { // Something bad happened we're screwed } } CFIndex CFClass::allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info) { return size; }