2 * Copyright (c) 2013 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
29 #include <utilities/SecAKSWrappers.h>
30 #include <utilities/SecCFWrappers.h>
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
38 # include <AppleKeyStoreEvents.h>
39 # define change_notification kAppleKeyStoreLockStatusNotificationID
41 # error "unsupported target platform"
44 const char * const kUserKeybagStateChangeNotification
= change_notification
;
46 bool SecAKSDoWhileUserBagLocked(CFErrorRef
*error
, dispatch_block_t action
)
48 #if TARGET_IPHONE_SIMULATOR
52 // Acquire lock assertion, ref count?
54 __block kern_return_t status
= kIOReturnSuccess
;
55 static dispatch_once_t queue_once
;
56 static dispatch_queue_t assertion_queue
;
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
;
66 dispatch_once(&queue_once
, ^{
67 assertion_queue
= dispatch_queue_create("AKS Lock Assertion Queue", NULL
);
70 static uint32_t count
= 0;
72 dispatch_sync(assertion_queue
, ^{
74 uint64_t timeout
= 60ull;
75 secnotice("lockassertions", "Requesting lock assertion for %lld seconds", timeout
);
76 status
= aks_assert_hold(keybagHandle
, lockAssertType
, timeout
);
79 if (status
== kIOReturnSuccess
)
83 if (status
== kIOReturnSuccess
) {
85 dispatch_sync(assertion_queue
, ^{
86 if (count
&& (--count
== 0)) {
87 secnotice("lockassertions", "Dropping lock assertion");
88 status
= aks_assert_drop(keybagHandle
, lockAssertType
);
92 return SecKernError(status
, error
, CFSTR("Kern return error"));
93 #endif /* !TARGET_IPHONE_SIMULATOR */