]> git.saurik.com Git - apple/security.git/blob - keychain/securityd/Regressions/secd-71-engine-save.m
Security-59306.101.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
44 #include <AssertMacros.h>
45 #include <stdint.h>
46
47 static int kTestTestCount = 8;
48
49 /*
50 Attributes for a v0 engine-state genp item
51
52 MANGO-iPhone:~ mobile$ security item class=genp,acct=engine-state
53 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
57 musr : //
58 pdmn : dk
59 svce : SOSDataSource-ak
60 sync : 0
61 tomb : 0
62 */
63
64 #include "secd-71-engine-save-sample1.h"
65
66 static bool verifyV2EngineState(SOSDataSourceRef ds, CFStringRef myPeerID) {
67 bool rx = false;
68 CFErrorRef error = NULL;
69 SOSTransactionRef txn = NULL;
70 CFDataRef basicEngineState = NULL;
71 CFDictionaryRef engineState = NULL;
72
73 SKIP: {
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");
81 rx = true;
82 }
83
84 CFReleaseSafe(basicEngineState);
85 CFReleaseSafe(engineState);
86 CFReleaseSafe(error);
87 return rx;
88 }
89
90 static bool verifyV2PeerStates(SOSDataSourceRef ds, CFStringRef myPeerID, CFArrayRef peers) {
91 bool rx = false;
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
97
98 SKIP: {
99 data = SOSDataSourceCopyStateWithKey(ds, kSOSEnginePeerStates, kSOSEngineProtectionDomainClassD, txn, &error);
100 skip("Failed to get V2 peerStates", 3, data);
101
102 peerStateDict = derStateToDictionaryCopy(data, &error);
103 skip("Failed to DER decode V2 peerStates", 2, peerStateDict);
104 ok(peerStateDict, "SOSDataSourceCopyStateWithKey:kSOSEnginePeerStates");
105
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))
111 peerCount--;
112 }
113 });
114 ok(peerCount==0,"Peers exist in peer list (%ld)", (CFArrayGetCount(peers) - 1 - peerCount));
115 rx = true;
116 }
117
118 CFReleaseSafe(peerStateDict);
119 CFReleaseSafe(data);
120 CFReleaseSafe(error);
121 return rx;
122 }
123
124 static bool checkV2EngineStates(SOSTestDeviceRef td, CFStringRef myPeerID, CFArrayRef peers) {
125 bool rx = true;
126 CFErrorRef error = NULL;
127 SOSTransactionRef txn = NULL;
128 CFDictionaryRef manifestCache = NULL;
129 CFDataRef data = NULL;
130 // CFMutableDictionaryRef codersDict = NULL; // SOSEngineLoadCoders
131
132 rx &= verifyV2EngineState(td->ds, myPeerID);
133
134 data = SOSDataSourceCopyStateWithKey(td->ds, kSOSEngineManifestCache, kSOSEngineProtectionDomainClassD, txn, &error);
135 manifestCache = derStateToDictionaryCopy(data, &error);
136 CFReleaseNull(data);
137
138 rx &= verifyV2PeerStates(td->ds, myPeerID, peers);
139
140 CFReleaseSafe(manifestCache);
141 return rx;
142 }
143
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"));
149 bool bx = false;
150 int version = 2;
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
155 if (devIdx == 0) {
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);
160 }
161 devIdx++;
162 });
163
164 CFStringRef sourceID = (CFStringRef)CFArrayGetValueAtIndex(deviceIDs, 0);
165 SOSTestDeviceRef source = (SOSTestDeviceRef)CFDictionaryGetValue(testDevices, sourceID);
166
167 ok(SOSTestDeviceEngineSave(source, &error),"SOSTestDeviceEngineSave: %@",error);
168
169 bx = SOSTestDeviceEngineLoad(source, &error);
170 ok(bx,"SOSTestEngineLoad: %@",error);
171
172 bx = checkV2EngineStates(source, sourceID, deviceIDs);
173 ok(bx,"getV2EngineStates: %@",error);
174
175 bx = SOSTestDeviceEngineSave(source, &error);
176 ok(bx,"SOSTestDeviceEngineSave v2: %@",error);
177
178 SOSTestDeviceDestroyEngine(testDevices);
179 CFReleaseSafe(deviceIDs);
180 CFReleaseSafe(testDevices);
181 CFReleaseSafe(error);
182 }
183
184 int secd_71_engine_save(int argc, char *const *argv)
185 {
186 plan_tests(kTestTestCount);
187
188 testSaveRestore();
189
190 return 0;
191 }