]> git.saurik.com Git - apple/security.git/blob - keychain/securityd/Regressions/secd-50-message.m
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / securityd / Regressions / secd-50-message.m
1 /*
2 * Copyright (c) 2013-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 #include "keychain/SecureObjectSync/SOSManifest.h"
26 #include "keychain/SecureObjectSync/SOSMessage.h"
27
28 #include "secd_regressions.h"
29
30 #include <utilities/SecCFWrappers.h>
31 #include <utilities/der_plist.h>
32 #include "keychain/SecureObjectSync/SOSDigestVector.h"
33 #include "keychain/securityd/SecDbItem.h"
34 #include "SOSAccountTesting.h"
35
36 #if SOS_ENABLED
37
38 static void testNullMessage(uint64_t msgid)
39 {
40 SOSMessageRef sentMessage = NULL;
41 SOSMessageRef rcvdMessage = NULL;
42 SOSManifestRef sender = NULL;
43 CFErrorRef error = NULL;
44 CFDataRef data = NULL;
45
46 // Encode
47 ok(sender = SOSManifestCreateWithBytes(NULL, 0, &error), "empty sender manifest create: %@", error);
48 CFReleaseNull(error);
49 ok(sentMessage = SOSMessageCreateWithManifests(kCFAllocatorDefault, sender, NULL, NULL, false, &error), "sentMessage create: %@", error);
50 CFReleaseNull(error);
51 ok(data = SOSMessageCreateData(sentMessage, msgid, &error), "sentMessage data create: %@", error);
52 CFReleaseNull(error);
53
54 // Decode
55 ok(rcvdMessage = SOSMessageCreateWithData(kCFAllocatorDefault, data, &error), "rcvdMessage create: %@", error);
56 CFReleaseNull(error);
57 __block size_t numObjects = 0;
58 SOSMessageWithObjects(sentMessage, &error, ^(CFDataRef object, bool *stop) {
59 numObjects++;
60 });
61 ok(numObjects == 0, "no objects");
62
63 // Check if we got what we started with
64 ok(sentMessage && rcvdMessage && CFEqual(sentMessage, rcvdMessage), "sent %@ == rcvd %@", sentMessage, rcvdMessage);
65
66 CFReleaseNull(data);
67 CFReleaseNull(sentMessage);
68 CFReleaseNull(rcvdMessage);
69 CFReleaseNull(sender);
70 }
71
72 __unused static void testFlaggedMessage(const char *test_directive, const char *test_reason, uint64_t msgid, SOSMessageFlags flags)
73 {
74 SOSMessageRef sentMessage = NULL;
75 SOSMessageRef rcvdMessage = NULL;
76 SOSManifestRef sender = NULL;
77 CFErrorRef error = NULL;
78 CFDataRef data = NULL;
79
80 ok(sender = SOSManifestCreateWithBytes(NULL, 0, &error), "empty sender manifest create: %@", error);
81 CFReleaseNull(error);
82 ok(sentMessage = SOSMessageCreateWithManifests(kCFAllocatorDefault, sender, NULL, NULL, false, &error), "sentMessage create: %@", error);
83 CFReleaseNull(error);
84 SOSMessageSetFlags(sentMessage, flags);
85 ok(data = SOSMessageCreateData(sentMessage, msgid, &error), "sentMessage data create: %@", error);
86 CFReleaseNull(error);
87
88 // Decode
89 ok(rcvdMessage = SOSMessageCreateWithData(kCFAllocatorDefault, data, &error), "rcvdMessage create: %@", error);
90 CFReleaseNull(error);
91 __block size_t numObjects = 0;
92 SOSMessageWithObjects(sentMessage, &error, ^(CFDataRef object, bool *stop) {
93 numObjects++;
94 });
95 ok(numObjects == 0, "no objects");
96
97 is(SOSMessageGetFlags(sentMessage), flags, "flags match after roundtrip");
98 ok(sentMessage && rcvdMessage && CFEqual(sentMessage, rcvdMessage), "sent %@ == rcvd %@", sentMessage, rcvdMessage);
99
100 CFReleaseNull(data);
101 CFReleaseNull(sentMessage);
102 CFReleaseNull(rcvdMessage);
103 CFReleaseNull(sender);
104 }
105
106 __unused static void testDeltaManifestMessage(const char *test_directive, const char *test_reason, uint64_t msgid)
107 {
108 SOSMessageRef sentMessage = NULL;
109 SOSMessageRef rcvdMessage = NULL;
110 SOSManifestRef sender = NULL;
111 SOSManifestRef proposed = NULL;
112 SOSManifestRef base = NULL;
113 CFErrorRef error = NULL;
114 CFDataRef data = NULL;
115
116 struct SOSDigestVector dv = SOSDigestVectorInit;
117 SOSDigestVectorAppend(&dv, (const uint8_t *)"sha1 hash that is 20 bytes long or so and stuff");
118 SOSDigestVectorAppend(&dv, (const uint8_t *)"sha1 hash that was 23 bytes long or so and stuff");
119 SOSDigestVectorSort(&dv);
120 base = SOSManifestCreateWithBytes((const uint8_t *)dv.digest, dv.count * SOSDigestSize, &error);
121 SOSDigestVectorAppend(&dv, (const uint8_t *)"so much more is good to see here is another one for me");
122 SOSDigestVectorAppend(&dv, (const uint8_t *)"sha1 hash that was 23 bytes long or so and stuff!");
123 SOSDigestVectorAppend(&dv, (const uint8_t *)"so much for is good to see here is another one for me");
124 SOSDigestVectorSort(&dv);
125 if (msgid)
126 proposed = SOSManifestCreateWithBytes((const uint8_t *)dv.digest, dv.count * SOSDigestSize, &error);
127
128 CFReleaseNull(error);
129 ok(sentMessage = SOSMessageCreateWithManifests(kCFAllocatorDefault, proposed, base, proposed, true, &error), "sentMessage create: %@", error);
130 CFReleaseNull(base);
131 CFReleaseNull(proposed);
132 CFReleaseNull(error);
133 ok(data = SOSMessageCreateData(sentMessage, msgid, &error), "sentMessage data create: %@ .. %@", error, sentMessage);
134 CFReleaseNull(error);
135
136 // Decode
137 ok(rcvdMessage = SOSMessageCreateWithData(kCFAllocatorDefault, data, &error), "rcvdMessage create: %@", error);
138 CFReleaseNull(error);
139 __block size_t numObjects = 0;
140 SOSMessageWithObjects(sentMessage, &error, ^(CFDataRef object, bool *stop) {
141 numObjects++;
142 });
143 ok(numObjects == 0, "no objects");
144
145 ok(sentMessage && rcvdMessage && CFEqual(sentMessage, rcvdMessage), "sent %@ == rcvd %@", sentMessage, rcvdMessage);
146
147 CFReleaseNull(data);
148 CFReleaseNull(sentMessage);
149 CFReleaseNull(rcvdMessage);
150 CFReleaseNull(sender);
151 }
152
153 static CFDataRef testCopyAddedObject(SOSMessageRef message, CFPropertyListRef plist)
154 {
155 CFErrorRef error = NULL;
156 CFDataRef der;
157 ok(der = CFPropertyListCreateDERData(kCFAllocatorDefault, plist, &error), "copy der: %@", error);
158 CFReleaseNull(error);
159 ok(SOSMessageAppendObject(message, der, &error), "likes object: %@", error);
160 CFReleaseNull(error);
161 return der;
162 }
163
164 __unused static void testObjectsMessage(const char *test_directive, const char *test_reason, uint64_t msgid)
165 {
166 SOSMessageRef sentMessage = NULL;
167 SOSMessageRef rcvdMessage = NULL;
168 SOSManifestRef sender = NULL;
169 SOSManifestRef proposed = NULL;
170 SOSManifestRef base = NULL;
171 CFErrorRef error = NULL;
172 CFDataRef data = NULL;
173
174 struct SOSDigestVector dv1 = SOSDigestVectorInit;
175 struct SOSDigestVector dv2 = SOSDigestVectorInit;
176 SOSDigestVectorAppend(&dv1, (const uint8_t *)"sha1 hash that is 20 bytes long or so and stuff");
177 SOSDigestVectorAppend(&dv2, (const uint8_t *)"sha1 hash that was 23 bytes long or so and stuff");
178 SOSDigestVectorAppend(&dv1, (const uint8_t *)"so much more is good to see here is another one for me");
179 SOSDigestVectorAppend(&dv2, (const uint8_t *)"so much more is good to see here is another one for me");
180 SOSDigestVectorAppend(&dv1, (const uint8_t *)"sha1 hash that was 23 bytes long or so and stuff");
181 SOSDigestVectorAppend(&dv1, (const uint8_t *)"sha1 hash that was 23 bytes long or so and stuff!");
182 SOSDigestVectorAppend(&dv2, (const uint8_t *)"so much for is good to see here is another one for me");
183 SOSDigestVectorSort(&dv1);
184 SOSDigestVectorSort(&dv2);
185 base = SOSManifestCreateWithBytes((const uint8_t *)dv1.digest, dv1.count * SOSDigestSize, &error);
186 if (msgid)
187 proposed = SOSManifestCreateWithBytes((const uint8_t *)dv2.digest, dv2.count * SOSDigestSize, &error);
188 CFReleaseNull(error);
189 ok(sentMessage = SOSMessageCreateWithManifests(kCFAllocatorDefault, proposed, base, proposed, true, &error), "sentMessage create: %@", error);
190 CFReleaseNull(base);
191 CFReleaseNull(proposed);
192 CFDataRef O0, O1, O2, O3;
193 CFDataRef o0 = CFDataCreate(kCFAllocatorDefault, NULL, 0);
194 O0 = testCopyAddedObject(sentMessage, o0);
195 CFDataRef o1 = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)"test", 4);
196 O1 = testCopyAddedObject(sentMessage, o1);
197 CFDataRef o2 = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)"what an object", 14);
198 O2 = testCopyAddedObject(sentMessage, o2);
199 CFDataRef o3 = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)"This one even has shiny stripe.", 31);
200 O3 = testCopyAddedObject(sentMessage, o3);
201 ok(data = SOSMessageCreateData(sentMessage, msgid, &error), "sentMessage data create: %@ .. %@", error, sentMessage);
202 CFReleaseNull(error);
203
204 // Decode
205 ok(rcvdMessage = SOSMessageCreateWithData(kCFAllocatorDefault, data, &error), "rcvdMessage create: %@", error);
206 CFReleaseNull(error);
207 __block size_t numObjects = 0;
208 __block bool f0, f1, f2, f3;
209 f0 = f1 = f2 = f3 = false;
210 if (rcvdMessage) SOSMessageWithObjects(rcvdMessage, &error, ^(CFDataRef object, bool *stop) {
211 if (CFEqualSafe(object, O0)) f0 = true;
212 if (CFEqualSafe(object, O1)) f1 = true;
213 if (CFEqualSafe(object, O2)) f2 = true;
214 if (CFEqualSafe(object, O3)) f3 = true;
215 numObjects++;
216 });
217 ok(f0, "got O0");
218 ok(f1, "got O1");
219 ok(f2, "got O2");
220 ok(f3, "got O3");
221
222 ok(sentMessage && rcvdMessage && CFEqual(sentMessage, rcvdMessage), "sent %@ == rcvd %@", sentMessage, rcvdMessage);
223
224 CFReleaseNull(o0);
225 CFReleaseNull(o1);
226 CFReleaseNull(o2);
227 CFReleaseNull(o3);
228 CFReleaseNull(O0);
229 CFReleaseNull(O1);
230 CFReleaseNull(O2);
231 CFReleaseNull(O3);
232 CFReleaseNull(data);
233 CFReleaseNull(sentMessage);
234 CFReleaseNull(rcvdMessage);
235 CFReleaseNull(sender);
236 }
237
238 static void tests(void)
239 {
240 testNullMessage(0); // v0
241
242 uint64_t msgid = 0;
243 testNullMessage(++msgid); // v2
244 testFlaggedMessage(test_directive, test_reason, ++msgid, 0x865);
245 testFlaggedMessage(test_directive, test_reason, ++msgid, 0xdeadbeef);
246 }
247 #endif
248
249 int secd_50_message(int argc, char *const *argv)
250 {
251 #if SOS_ENABLED
252 plan_tests(26);
253 tests();
254 #else
255 plan_tests(0);
256 #endif
257 return 0;
258 }