2 * Copyright (c) 2015 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@
25 * This is to fool os services to not provide the Keychain manager
26 * interface tht doens't work since we don't have unified headers
27 * between iOS and OS X. rdar://23405418/
29 #define __KEYCHAINCORE__ 1
32 #import <Foundation/Foundation.h>
33 #import <CoreFoundation/CoreFoundation.h>
34 #import <Security/SecBase.h>
35 #import <Security/SecItem.h>
36 #import <Security/SecItemPriv.h>
37 #import <Security/SecInternal.h>
38 #import <utilities/SecCFWrappers.h>
39 #import <utilities/SecFileLocations.h>
40 #import "keychain/securityd/SecItemServer.h"
44 #include "secd_regressions.h"
45 #include "SecdTestKeychainUtilities.h"
46 #include "server_security_helpers.h"
49 secd_21_transmogrify(int argc, char *const *argv)
51 plan_tests(kSecdTestSetupTestCount + 14);
54 CFErrorRef error = NULL;
55 CFDictionaryRef result = NULL;
58 CFArrayRef currentACL = CFRetainSafe(SecAccessGroupsGetCurrent());
60 NSMutableArray *newACL = [NSMutableArray arrayWithArray:(__bridge NSArray *)currentACL];
61 [newACL addObjectsFromArray:@[
62 @"com.apple.private.system-keychain",
63 @"com.apple.private.syncbubble-keychain",
64 @"com.apple.private.migrate-musr-system-keychain",
65 @"com.apple.ProtectedCloudStorage",
68 SecAccessGroupsSetCurrent((__bridge CFArrayRef)newACL);
71 secd_test_setup_temp_keychain("secd_21_transmogrify", NULL);
74 * Add to user keychain
77 res = SecItemAdd((CFDictionaryRef)@{
78 (id)kSecClass : (id)kSecClassGenericPassword,
79 (id)kSecAttrAccount : @"user-label-me",
80 (id)kSecValueData : [NSData dataWithBytes:"password" length:8]
82 is(res, 0, "SecItemAdd(user)");
84 SecurityClient client = {
86 .accessGroups = (__bridge CFArrayRef)@[
87 @"com.apple.ProtectedCloudStorage"
89 .allowSystemKeychain = true,
90 .allowSyncBubbleKeychain = true,
96 is(_SecServerTransmogrifyToSystemKeychain(&client, &error), true, "_SecServerTransmogrifyToSystemKeychain: %@", error);
98 CFDataRef musr = SecMUSRCreateActiveUserUUID(502);
100 client.inMultiUser = true;
103 SecSecuritySetMusrMode(true, 502, 502);
105 res = SecItemCopyMatching((CFDictionaryRef)@{
106 (id)kSecClass : (id)kSecClassGenericPassword,
107 (id)kSecAttrAccount : @"user-label-me",
108 (id)kSecUseSystemKeychain : (id)kCFBooleanTrue,
109 (id)kSecReturnAttributes : (id)kCFBooleanTrue,
110 (id)kSecReturnData : @(YES)
111 }, (CFTypeRef *)&result);
112 is(res, 0, "SecItemCopyMatching(system)");
114 ok(isDictionary(result), "found item");
115 if (isDictionary(result)) {
116 NSData *data = ((__bridge NSDictionary *)result)[@"musr"];
117 ok([data isEqual:(__bridge id)SecMUSRGetSystemKeychainUUID()], "item is system keychain");
119 NSData* passwordData = [(__bridge NSDictionary*)result valueForKey:(id)kSecValueData];
120 ok([passwordData isEqual:[NSData dataWithBytes:"password" length:8]], "no data found in transmogrified item");
122 ok(0, "returned item is: %@", result);
124 CFReleaseNull(result);
130 res = _SecItemAdd((__bridge CFDictionaryRef)@{
131 (id)kSecClass : (id)kSecClassGenericPassword,
132 (id)kSecAttrAccessGroup : @"com.apple.ProtectedCloudStorage",
133 (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock,
134 (id)kSecAttrAccount : @"pcs-label-me",
135 (id)kSecValueData : [NSData dataWithBytes:"some data" length:9],
136 }, &client, NULL, NULL);
137 is(res, true, "SecItemAdd(user)");
139 res = _SecItemCopyMatching((__bridge CFDictionaryRef)@{
140 (id)kSecClass : (id)kSecClassGenericPassword,
141 (id)kSecAttrAccount : @"pcs-label-me",
142 (id)kSecReturnAttributes : (id)kCFBooleanTrue,
143 (id)kSecReturnData : @(YES),
144 }, &client, (CFTypeRef *)&result, &error);
145 is(res, true, "SecItemCopyMatching(system): %@", error);
147 ok(isDictionary(result), "result is dictionary");
148 ok([[(__bridge NSDictionary*)result valueForKey:(__bridge id)kSecValueData] isEqual:[NSData dataWithBytes:"some data" length:9]], "retrieved data matches stored data");
150 /* Check that data are in 502 active user keychain */
151 ok (CFEqualSafe(((__bridge CFDataRef)((__bridge NSDictionary *)result)[@"musr"]), musr), "not in msr 502");
153 CFReleaseNull(result);
156 ok(_SecServerTransmogrifyToSyncBubble((__bridge CFArrayRef)@[@"com.apple.mailq.sync.xpc" ], client.uid, &client, &error),
157 "_SecServerTransmogrifyToSyncBubble: %@", error);
159 CFReleaseNull(error);
162 * first check normal keychain
165 res = _SecItemCopyMatching((__bridge CFDictionaryRef)@{
166 (id)kSecClass : (id)kSecClassGenericPassword,
167 (id)kSecAttrAccount : @"pcs-label-me",
168 (id)kSecReturnAttributes : (id)kCFBooleanTrue,
169 }, &client, (CFTypeRef *)&result, &error);
170 is(res, true, "SecItemCopyMatching(active): %@", error);
172 ok(isDictionary(result), "result is dictionary");
173 CFReleaseNull(result);
175 SecSecuritySetMusrMode(true, 503, 503);
178 * then syncbubble keychain
181 res = _SecItemCopyMatching((__bridge CFDictionaryRef)@{
182 (id)kSecClass : (id)kSecClassGenericPassword,
183 (id)kSecAttrAccount : @"pcs-label-me",
184 (id)kSecReturnAttributes : (id)kCFBooleanTrue,
185 (id)kSecUseSyncBubbleKeychain : @502,
186 }, &client, (CFTypeRef *)&result, &error);
187 is(res, true, "SecItemCopyMatching(syncbubble): %@", error);
188 ok(isDictionary(result), "result is dictionary");
190 CFReleaseNull(result);
192 SecSecuritySetMusrMode(false, 501, -1);
194 SecAccessGroupsSetCurrent(currentACL);
195 CFReleaseNull(currentACL);
199 plan_skip_all("not support on non TARGET_OS_IOS");