1/* 2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// 25// SecAKSWrappers.c 26// utilities 27// 28 29#include <utilities/SecAKSWrappers.h> 30#include <utilities/SecCFWrappers.h> 31 32#if TARGET_IPHONE_SIMULATOR 33# define change_notification "com.apple.will.never.happen" 34#elif TARGET_OS_IPHONE 35# include <MobileKeyBag/MobileKeyBag.h> 36# define change_notification kMobileKeyBagLockStatusNotificationID 37#elif TARGET_OS_MAC 38# include <AppleKeyStoreEvents.h> 39# define change_notification kAppleKeyStoreLockStatusNotificationID 40#else 41# error "unsupported target platform" 42#endif 43 44const char * const kUserKeybagStateChangeNotification = change_notification; 45 46bool SecAKSDoWhileUserBagLocked(CFErrorRef *error, dispatch_block_t action) 47{ 48#if TARGET_IPHONE_SIMULATOR 49 action(); 50 return true; 51#else 52 // Acquire lock assertion, ref count? 53 54 __block kern_return_t status = kIOReturnSuccess; 55 static dispatch_once_t queue_once; 56 static dispatch_queue_t assertion_queue; 57 58#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED // OS X 59 AKSAssertionType_t lockAssertType = kAKSAssertTypeOther; 60 keybag_handle_t keybagHandle = session_keybag_handle; 61#else // iOS, but not simulator 62 AKSAssertionType_t lockAssertType = kAKSAssertTypeProfile; // Profile supports timeouts, but only available on iOS 63 keybag_handle_t keybagHandle = device_keybag_handle; 64#endif 65 66 dispatch_once(&queue_once, ^{ 67 assertion_queue = dispatch_queue_create("AKS Lock Assertion Queue", NULL); 68 }); 69 70 static uint32_t count = 0; 71 72 dispatch_sync(assertion_queue, ^{ 73 if (count == 0) { 74 uint64_t timeout = 60ull; 75 secnotice("lockassertions", "Requesting lock assertion for %lld seconds", timeout); 76 status = aks_assert_hold(keybagHandle, lockAssertType, timeout); 77 } 78 79 if (status == kIOReturnSuccess) 80 ++count; 81 }); 82 83 if (status == kIOReturnSuccess) { 84 action(); 85 dispatch_sync(assertion_queue, ^{ 86 if (count && (--count == 0)) { 87 secnotice("lockassertions", "Dropping lock assertion"); 88 status = aks_assert_drop(keybagHandle, lockAssertType); 89 } 90 }); 91 } 92 return SecKernError(status, error, CFSTR("Kern return error")); 93#endif /* !TARGET_IPHONE_SIMULATOR */ 94} 95