2 * Copyright (c) 2014 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 // Test save and restore of SOSEngine states
27 #include <SOSCircle/Regressions/SOSTestDevice.h>
28 #include <SOSCircle/Regressions/SOSTestDataSource.h>
29 #include "secd_regressions.h"
30 #include "SecdTestKeychainUtilities.h"
32 #include <Security/SecureObjectSync/SOSEnginePriv.h>
33 #include <Security/SecureObjectSync/SOSPeer.h>
34 #include <Security/SecBase64.h>
35 #include <Security/SecItem.h>
36 #include <Security/SecItemPriv.h>
37 #include <corecrypto/ccsha2.h>
38 #include <securityd/SecItemServer.h>
39 #include <securityd/SecItemDataSource.h>
40 #include <utilities/SecCFWrappers.h>
41 #include <utilities/SecIOFormat.h>
42 #include <utilities/SecFileLocations.h>
44 #include <AssertMacros.h>
47 static int kTestTestCount
= 8;
50 Attributes for a v0 engine-state genp item
52 MANGO-iPhone:~ mobile$ security item class=genp,acct=engine-state
54 agrp : com.apple.security.sos
55 cdat : 2016-04-18 20:40:33 +0000
56 mdat : 2016-04-18 20:40:33 +0000
59 svce : SOSDataSource-ak
64 #include "secd-71-engine-save-sample1.h"
66 static bool verifyV2EngineState(SOSDataSourceRef ds
, CFStringRef myPeerID
) {
68 CFErrorRef error
= NULL
;
69 SOSTransactionRef txn
= NULL
;
70 CFDataRef basicEngineState
= NULL
;
71 CFDictionaryRef engineState
= NULL
;
74 CFDataRef basicEngineState
= SOSDataSourceCopyStateWithKey(ds
, kSOSEngineStatev2
, kSecAttrAccessibleAlwaysPrivate
, txn
, &error
);
75 skip("Failed to get V2 engine state", 2, basicEngineState
);
76 ok(basicEngineState
, "SOSDataSourceCopyStateWithKey:kSOSEngineStatev2");
77 engineState
= derStateToDictionaryCopy(basicEngineState
, &error
);
78 skip("Failed to DER decode V2 engine state", 1, basicEngineState
);
79 CFStringRef engID
= (CFStringRef
)asString(CFDictionaryGetValue(engineState
, CFSTR("id")), &error
);
80 ok(CFEqualSafe(myPeerID
, engID
),"Check myPeerID");
84 CFReleaseSafe(basicEngineState
);
85 CFReleaseSafe(engineState
);
90 static bool verifyV2PeerStates(SOSDataSourceRef ds
, CFStringRef myPeerID
, CFArrayRef peers
) {
92 __block CFErrorRef error
= NULL
;
93 SOSTransactionRef txn
= NULL
;
94 CFDictionaryRef peerStateDict
= NULL
;
95 CFDataRef data
= NULL
;
96 __block CFIndex peerCount
= CFArrayGetCount(peers
) - 1; // drop myPeerID
99 data
= SOSDataSourceCopyStateWithKey(ds
, kSOSEnginePeerStates
, kSOSEngineProtectionDomainClassD
, txn
, &error
);
100 skip("Failed to get V2 peerStates", 3, data
);
102 peerStateDict
= derStateToDictionaryCopy(data
, &error
);
103 skip("Failed to DER decode V2 peerStates", 2, peerStateDict
);
104 ok(peerStateDict
, "SOSDataSourceCopyStateWithKey:kSOSEnginePeerStates");
106 // Check that each peer passed in exists in peerStateDict
107 CFArrayForEach(peers
, ^(const void *key
) {
108 CFStringRef peerID
= (CFStringRef
)asString(key
, &error
);
109 if (!CFEqualSafe(myPeerID
, peerID
)) {
110 if (CFDictionaryContainsKey(peerStateDict
, peerID
))
114 ok(peerCount
==0,"Peers exist in peer list (%ld)", (CFArrayGetCount(peers
) - 1 - peerCount
));
118 CFReleaseSafe(peerStateDict
);
120 CFReleaseSafe(error
);
124 static bool checkV2EngineStates(SOSTestDeviceRef td
, CFStringRef myPeerID
, CFArrayRef peers
) {
126 CFErrorRef error
= NULL
;
127 SOSTransactionRef txn
= NULL
;
128 CFDictionaryRef manifestCache
= NULL
;
129 CFDataRef data
= NULL
;
130 // CFMutableDictionaryRef codersDict = NULL; // SOSEngineLoadCoders
132 rx
&= verifyV2EngineState(td
->ds
, myPeerID
);
134 data
= SOSDataSourceCopyStateWithKey(td
->ds
, kSOSEngineManifestCache
, kSOSEngineProtectionDomainClassD
, txn
, &error
);
135 manifestCache
= derStateToDictionaryCopy(data
, &error
);
138 rx
&= verifyV2PeerStates(td
->ds
, myPeerID
, peers
);
140 CFReleaseSafe(manifestCache
);
144 static void testSaveRestore(void) {
145 CFMutableArrayRef deviceIDs
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
);
146 CFArrayAppendValue(deviceIDs
, CFSTR("lemon"));
147 CFArrayAppendValue(deviceIDs
, CFSTR("lime"));
148 CFArrayAppendValue(deviceIDs
, CFSTR("orange"));
151 CFErrorRef error
= NULL
;
152 __block
int devIdx
= 0;
153 CFMutableDictionaryRef testDevices
= SOSTestDeviceListCreate(false, version
, deviceIDs
, ^(SOSDataSourceRef ds
) {
154 // This block is called before SOSEngineLoad
156 // Test migration of v0 to v2 engine state
157 CFDataRef engineStateData
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, es_mango_bin
, es_mango_bin_len
, kCFAllocatorNull
);
158 SOSTestDeviceAddV0EngineStateWithData(ds
, engineStateData
);
159 CFReleaseSafe(engineStateData
);
164 CFStringRef sourceID
= (CFStringRef
)CFArrayGetValueAtIndex(deviceIDs
, 0);
165 SOSTestDeviceRef source
= (SOSTestDeviceRef
)CFDictionaryGetValue(testDevices
, sourceID
);
167 ok(SOSTestDeviceEngineSave(source
, &error
),"SOSTestDeviceEngineSave: %@",error
);
169 bx
= SOSTestDeviceEngineLoad(source
, &error
);
170 ok(bx
,"SOSTestEngineLoad: %@",error
);
172 bx
= checkV2EngineStates(source
, sourceID
, deviceIDs
);
173 ok(bx
,"getV2EngineStates: %@",error
);
175 bx
= SOSTestDeviceEngineSave(source
, &error
);
176 ok(bx
,"SOSTestDeviceEngineSave v2: %@",error
);
178 SOSTestDeviceDestroyEngine(testDevices
);
179 CFReleaseSafe(deviceIDs
);
180 CFReleaseSafe(testDevices
);
181 CFReleaseSafe(error
);
184 int secd_71_engine_save(int argc
, char *const *argv
)
186 plan_tests(kTestTestCount
);