]> git.saurik.com Git - apple/security.git/blob - keychain/securityd/Regressions/secd-71-engine-save.m
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / securityd / Regressions / secd-71-engine-save.m
1 /*
2 * Copyright (c) 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 // Test save and restore of SOSEngine states
26
27 #include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h"
28 #include "keychain/SecureObjectSync/Regressions/SOSTestDataSource.h"
29 #include "secd_regressions.h"
30 #include "SecdTestKeychainUtilities.h"
31
32 #include "keychain/SecureObjectSync/SOSEngine.h"
33 #include "keychain/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 "keychain/securityd/SecItemServer.h"
39 #include "keychain/securityd/SecItemDataSource.h"
40 #include <utilities/SecCFWrappers.h>
41 #include <utilities/SecIOFormat.h>
42 #include <utilities/SecFileLocations.h>
43 #include "SOSAccountTesting.h"
44
45 #include <AssertMacros.h>
46 #include <stdint.h>
47 #if SOS_ENABLED
48
49 static int kTestTestCount = 8;
50
51 /*
52 Attributes for a v0 engine-state genp item
53
54 MANGO-iPhone:~ mobile$ security item class=genp,acct=engine-state
55 acct : engine-state
56 agrp : com.apple.security.sos
57 cdat : 2016-04-18 20:40:33 +0000
58 mdat : 2016-04-18 20:40:33 +0000
59 musr : //
60 pdmn : dk
61 svce : SOSDataSource-ak
62 sync : 0
63 tomb : 0
64 */
65
66 #include "secd-71-engine-save-sample1.h"
67
68 static bool verifyV2EngineState(SOSDataSourceRef ds, CFStringRef myPeerID) {
69 bool rx = false;
70 CFErrorRef error = NULL;
71 SOSTransactionRef txn = NULL;
72 CFDataRef basicEngineState = NULL;
73 CFDictionaryRef engineState = NULL;
74
75 SKIP: {
76 CFDataRef basicEngineState = SOSDataSourceCopyStateWithKey(ds, kSOSEngineStatev2, kSecAttrAccessibleAlwaysPrivate, txn, &error);
77 skip("Failed to get V2 engine state", 2, basicEngineState);
78 ok(basicEngineState, "SOSDataSourceCopyStateWithKey:kSOSEngineStatev2");
79 engineState = derStateToDictionaryCopy(basicEngineState, &error);
80 skip("Failed to DER decode V2 engine state", 1, basicEngineState);
81 CFStringRef engID = (CFStringRef)asString(CFDictionaryGetValue(engineState, CFSTR("id")), &error);
82 ok(CFEqualSafe(myPeerID, engID),"Check myPeerID");
83 rx = true;
84 }
85
86 CFReleaseSafe(basicEngineState);
87 CFReleaseSafe(engineState);
88 CFReleaseSafe(error);
89 return rx;
90 }
91
92 static bool verifyV2PeerStates(SOSDataSourceRef ds, CFStringRef myPeerID, CFArrayRef peers) {
93 bool rx = false;
94 __block CFErrorRef error = NULL;
95 SOSTransactionRef txn = NULL;
96 CFDictionaryRef peerStateDict = NULL;
97 CFDataRef data = NULL;
98 __block CFIndex peerCount = CFArrayGetCount(peers) - 1; // drop myPeerID
99
100 SKIP: {
101 data = SOSDataSourceCopyStateWithKey(ds, kSOSEnginePeerStates, kSOSEngineProtectionDomainClassD, txn, &error);
102 skip("Failed to get V2 peerStates", 3, data);
103
104 peerStateDict = derStateToDictionaryCopy(data, &error);
105 skip("Failed to DER decode V2 peerStates", 2, peerStateDict);
106 ok(peerStateDict, "SOSDataSourceCopyStateWithKey:kSOSEnginePeerStates");
107
108 // Check that each peer passed in exists in peerStateDict
109 CFArrayForEach(peers, ^(const void *key) {
110 CFStringRef peerID = (CFStringRef)asString(key, &error);
111 if (!CFEqualSafe(myPeerID, peerID)) {
112 if (CFDictionaryContainsKey(peerStateDict, peerID))
113 peerCount--;
114 }
115 });
116 ok(peerCount==0,"Peers exist in peer list (%ld)", (CFArrayGetCount(peers) - 1 - peerCount));
117 rx = true;
118 }
119
120 CFReleaseSafe(peerStateDict);
121 CFReleaseSafe(data);
122 CFReleaseSafe(error);
123 return rx;
124 }
125
126 static bool checkV2EngineStates(SOSTestDeviceRef td, CFStringRef myPeerID, CFArrayRef peers) {
127 bool rx = true;
128 CFErrorRef error = NULL;
129 SOSTransactionRef txn = NULL;
130 CFDictionaryRef manifestCache = NULL;
131 CFDataRef data = NULL;
132 // CFMutableDictionaryRef codersDict = NULL; // SOSEngineLoadCoders
133
134 rx &= verifyV2EngineState(td->ds, myPeerID);
135
136 data = SOSDataSourceCopyStateWithKey(td->ds, kSOSEngineManifestCache, kSOSEngineProtectionDomainClassD, txn, &error);
137 manifestCache = derStateToDictionaryCopy(data, &error);
138 CFReleaseNull(data);
139
140 rx &= verifyV2PeerStates(td->ds, myPeerID, peers);
141
142 CFReleaseSafe(manifestCache);
143 return rx;
144 }
145
146 static void testSaveRestore(void) {
147 CFMutableArrayRef deviceIDs = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
148 CFArrayAppendValue(deviceIDs, CFSTR("lemon"));
149 CFArrayAppendValue(deviceIDs, CFSTR("lime"));
150 CFArrayAppendValue(deviceIDs, CFSTR("orange"));
151 bool bx = false;
152 int version = 2;
153 CFErrorRef error = NULL;
154 __block int devIdx = 0;
155 CFMutableDictionaryRef testDevices = SOSTestDeviceListCreate(false, version, deviceIDs, ^(SOSDataSourceRef ds) {
156 // This block is called before SOSEngineLoad
157 if (devIdx == 0) {
158 // Test migration of v0 to v2 engine state
159 CFDataRef engineStateData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, es_mango_bin, es_mango_bin_len, kCFAllocatorNull);
160 SOSTestDeviceAddV0EngineStateWithData(ds, engineStateData);
161 CFReleaseSafe(engineStateData);
162 }
163 devIdx++;
164 });
165
166 CFStringRef sourceID = (CFStringRef)CFArrayGetValueAtIndex(deviceIDs, 0);
167 SOSTestDeviceRef source = (SOSTestDeviceRef)CFDictionaryGetValue(testDevices, sourceID);
168
169 ok(SOSTestDeviceEngineSave(source, &error),"SOSTestDeviceEngineSave: %@",error);
170
171 bx = SOSTestDeviceEngineLoad(source, &error);
172 ok(bx,"SOSTestEngineLoad: %@",error);
173
174 bx = checkV2EngineStates(source, sourceID, deviceIDs);
175 ok(bx,"getV2EngineStates: %@",error);
176
177 bx = SOSTestDeviceEngineSave(source, &error);
178 ok(bx,"SOSTestDeviceEngineSave v2: %@",error);
179
180 SOSTestDeviceDestroyEngine(testDevices);
181 CFReleaseSafe(deviceIDs);
182 CFReleaseSafe(testDevices);
183 CFReleaseSafe(error);
184 }
185 #endif
186
187 int secd_71_engine_save(int argc, char *const *argv)
188 {
189 #if SOS_ENABLED
190 plan_tests(kTestTestCount);
191 testSaveRestore();
192 #else
193 plan_tests(0);
194 #endif
195 return 0;
196 }