]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/Regressions/secd-49-manifests.m
Security-58286.1.32.tar.gz
[apple/security.git] / OSX / sec / securityd / Regressions / secd-49-manifests.m
1 /*
2 * Copyright (c) 2015 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 <Security/SecureObjectSync/SOSManifest.h>
26 #include <Security/SecureObjectSync/SOSMessage.h>
27
28 #include "secd_regressions.h"
29
30 #include <utilities/SecCFWrappers.h>
31 #include <utilities/SecCFRelease.h>
32 #include <utilities/der_plist.h>
33 #include <Security/SecureObjectSync/SOSDigestVector.h>
34 #include <securityd/SecDbItem.h>
35 #include <stdlib.h>
36
37 static int kTestTestCount = 68;
38
39
40 #define okmfcomplement(r, b, n, ...) test_okmfcomplement(r, b, n, test_create_description(__VA_ARGS__), test_directive, test_reason, __FILE__, __LINE__, NULL)
41 #define okmfdiff(a, b, eab,eba, ...) test_okmfdiff(a, b, eab, eba, test_create_description(__VA_ARGS__), test_directive, test_reason, __FILE__, __LINE__, NULL)
42 #define okmfintersection(a, b, n, ...) test_okmfintersection(a, b, n, test_create_description(__VA_ARGS__), test_directive, test_reason, __FILE__, __LINE__, NULL)
43 #define okmfpatch(b, r, a, n, ...) test_okmfpatch(b, r, a, n, test_create_description(__VA_ARGS__), test_directive, test_reason, __FILE__, __LINE__, NULL)
44 #define okmfunion(a, b, n, ...) test_okmfunion(a, b, n, test_create_description(__VA_ARGS__), test_directive, test_reason, __FILE__, __LINE__, NULL)
45
46 static void appendManifestDescription(CFMutableStringRef string, CFStringRef prefix, SOSManifestRef mf) {
47 if (prefix)
48 CFStringAppend(string, prefix);
49 if (!mf) {
50 CFStringAppend(string, CFSTR("null"));
51 } else if (SOSManifestGetCount(mf) == 0) {
52 CFStringAppend(string, CFSTR("empty"));
53 } else {
54 char prefix = '{';
55 const uint8_t *d = SOSManifestGetBytePtr(mf);
56 for (CFIndex endIX = SOSManifestGetCount(mf), curIX = 0; curIX < endIX; ++curIX, d += SOSDigestSize) {
57 CFStringAppendFormat(string, NULL, CFSTR("%c%c"), prefix, *d);
58 prefix = ' ';
59 }
60 CFStringAppend(string, CFSTR("}"));
61 }
62 }
63
64 static int appendManifestComparison(CFMutableStringRef string, CFStringRef prefix, SOSManifestRef expected, SOSManifestRef computed) {
65 int passed = 0;
66 appendManifestDescription(string, prefix, computed);
67 if (CFEqualSafe(computed, expected)) {
68 // ok
69 passed = 1;
70 } else {
71 // wrong
72 appendManifestDescription(string, CFSTR("!="), expected);
73 }
74 return passed;
75 }
76
77 static void test_okmfcomplement(SOSManifestRef r, SOSManifestRef b, SOSManifestRef n, __attribute((cf_consumed)) CFStringRef test_description, const char *test_directive, const char *reason, const char *file, unsigned line, const char *fmt, ...) {
78 CFErrorRef error = NULL;
79 int passed = 0;
80 CFMutableStringRef extendedDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, test_description);
81 if (test_description && CFStringGetLength(test_description) != 0)
82 CFStringAppend(extendedDescription, CFSTR(" "));
83 appendManifestDescription(extendedDescription, CFSTR("complement "), r);
84 appendManifestDescription(extendedDescription, CFSTR("->"), b);
85 SOSManifestRef new = SOSManifestCreateComplement(r, b, &error);
86 if (!new) {
87 CFStringAppendFormat(extendedDescription, NULL, CFSTR(" SOSManifestCreateComplement: %@"), error);
88 } else {
89 passed = appendManifestComparison(extendedDescription, CFSTR(" -> "), n, new);
90 }
91 test_ok(passed, extendedDescription, test_directive, test_reason, file, line, NULL);
92 CFReleaseSafe(test_description);
93 CFReleaseSafe(new);
94 CFReleaseSafe(error);
95 }
96
97 static void test_okmfdiff(SOSManifestRef a, SOSManifestRef b, SOSManifestRef exp_a_b, SOSManifestRef exp_b_a, __attribute((cf_consumed)) CFStringRef test_description, const char *test_directive, const char *reason, const char *file, unsigned line, const char *fmt, ...) {
98 CFErrorRef error = NULL;
99 SOSManifestRef a_minus_b = NULL;
100 SOSManifestRef b_minus_a = NULL;
101 int passed = 0;
102 CFMutableStringRef extendedDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, test_description);
103 if (test_description && CFStringGetLength(test_description) != 0)
104 CFStringAppend(extendedDescription, CFSTR(" "));
105 appendManifestDescription(extendedDescription, CFSTR("diff "), a);
106 appendManifestDescription(extendedDescription, CFSTR("->"), b);
107 if (!SOSManifestDiff(a, b, &a_minus_b, &b_minus_a, &error)) {
108 CFStringAppendFormat(extendedDescription, NULL, CFSTR(" SOSManifestDiff: %@"), error);
109 } else {
110 passed = appendManifestComparison(extendedDescription, CFSTR(" -> "), exp_a_b, a_minus_b);
111 passed &= appendManifestComparison(extendedDescription, CFSTR("->"), exp_b_a, b_minus_a);
112 }
113 test_ok(passed, extendedDescription, test_directive, test_reason, file, line, NULL);
114 CFReleaseSafe(test_description);
115 CFReleaseSafe(a_minus_b);
116 CFReleaseSafe(b_minus_a);
117 CFReleaseSafe(error);
118 }
119
120 static void test_okmfintersection(SOSManifestRef a, SOSManifestRef b, SOSManifestRef n, __attribute((cf_consumed)) CFStringRef test_description, const char *test_directive, const char *reason, const char *file, unsigned line, const char *fmt, ...) {
121 CFErrorRef error = NULL;
122 int passed = 0;
123 CFMutableStringRef extendedDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, test_description);
124 if (test_description && CFStringGetLength(test_description) != 0)
125 CFStringAppend(extendedDescription, CFSTR(" "));
126 appendManifestDescription(extendedDescription, CFSTR("intersection "), a);
127 appendManifestDescription(extendedDescription, CFSTR("->") /*CFSTR(" \xe2\x88\xa9 ")*/, b);
128 SOSManifestRef new = SOSManifestCreateIntersection(a, b, &error);
129 if (!new) {
130 CFStringAppendFormat(extendedDescription, NULL, CFSTR(" SOSManifestCreateIntersection: %@"), error);
131 } else {
132 passed = appendManifestComparison(extendedDescription, CFSTR(" -> "), n, new);
133 }
134 test_ok(passed, extendedDescription, test_directive, test_reason, file, line, NULL);
135 CFReleaseSafe(test_description);
136 CFReleaseSafe(new);
137 CFReleaseSafe(error);
138 }
139
140 static void test_okmfpatch(SOSManifestRef b, SOSManifestRef r, SOSManifestRef a, SOSManifestRef n, __attribute((cf_consumed)) CFStringRef test_description, const char *test_directive, const char *reason, const char *file, unsigned line, const char *fmt, ...) {
141 CFErrorRef error = NULL;
142 int passed = 0;
143 CFMutableStringRef extendedDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, test_description);
144 if (test_description && CFStringGetLength(test_description) != 0)
145 CFStringAppend(extendedDescription, CFSTR(" "));
146 appendManifestDescription(extendedDescription, CFSTR("patch "), b);
147 appendManifestDescription(extendedDescription, CFSTR("->"), r);
148 appendManifestDescription(extendedDescription, CFSTR("->"), a);
149 SOSManifestRef new = SOSManifestCreateWithPatch(b, r, a, &error);
150 if (!new) {
151 CFStringAppendFormat(extendedDescription, NULL, CFSTR(" SOSManifestCreateWithPatch: %@"), error);
152 } else {
153 passed = appendManifestComparison(extendedDescription, CFSTR(" -> "), n, new);
154 }
155 test_ok(passed, extendedDescription, test_directive, test_reason, file, line, NULL);
156 CFReleaseSafe(test_description);
157 CFReleaseSafe(new);
158 CFReleaseSafe(error);
159 }
160
161 static void test_okmfunion(SOSManifestRef a, SOSManifestRef b, SOSManifestRef n, __attribute((cf_consumed)) CFStringRef test_description, const char *test_directive, const char *reason, const char *file, unsigned line, const char *fmt, ...) {
162 CFErrorRef error = NULL;
163 int passed = 0;
164 CFMutableStringRef extendedDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, test_description);
165 if (test_description && CFStringGetLength(test_description) != 0)
166 CFStringAppend(extendedDescription, CFSTR(" "));
167 appendManifestDescription(extendedDescription, CFSTR("union "), a);
168 appendManifestDescription(extendedDescription, CFSTR("->") /*CFSTR(" \xe2\x88\xaa ")*/, b);
169 SOSManifestRef new = SOSManifestCreateUnion(a, b, &error);
170 if (!new) {
171 CFStringAppendFormat(extendedDescription, NULL, CFSTR(" SOSManifestCreateUnion: %@"), error);
172 } else {
173 passed = appendManifestComparison(extendedDescription, CFSTR(" -> "), n, new);
174 }
175 test_ok(passed, extendedDescription, test_directive, test_reason, file, line, NULL);
176 CFReleaseSafe(test_description);
177 CFReleaseSafe(new);
178 CFReleaseSafe(error);
179 }
180
181 static SOSManifestRef createManifestWithString(CFStringRef string) {
182 struct SOSDigestVector dv = SOSDigestVectorInit;
183 CFIndex length = string ? CFStringGetLength(string) : 0;
184 CFStringInlineBuffer buf = {};
185 CFRange range = { 0, length };
186 CFStringInitInlineBuffer(string, &buf, range);
187 for (CFIndex ix = 0; ix < length; ++ix) {
188 uint8_t digest[20] = " ";
189 UniChar c = CFStringGetCharacterFromInlineBuffer(&buf, ix);
190 digest[0] = c;
191 SOSDigestVectorAppend(&dv, digest);
192 }
193 SOSManifestRef mf = NULL;
194 mf = SOSManifestCreateWithDigestVector(&dv, NULL);
195 SOSDigestVectorFree(&dv);
196 return mf;
197 }
198
199 static SOSManifestRef testCreateBadManifest() {
200 SOSManifestRef mf = createManifestWithString(CFSTR("bab"));
201 is(SOSManifestGetCount(mf), (size_t)2, "dupes eliminated?");
202 return mf;
203 }
204
205
206 typedef struct mf_vectors {
207 SOSManifestRef null;
208 SOSManifestRef empty;
209 SOSManifestRef a;
210 SOSManifestRef b;
211 SOSManifestRef ab;
212 SOSManifestRef bab;
213 SOSManifestRef agh;
214 SOSManifestRef gh;
215 SOSManifestRef agghhjk;
216 SOSManifestRef gghh;
217 SOSManifestRef agghh;
218 } mf_t;
219
220 static void setupMF(mf_t *mf) {
221 CFErrorRef error = NULL;
222 mf->null = NULL;
223 mf->empty = SOSManifestCreateWithBytes(NULL, 0, &error);
224 mf->a = createManifestWithString(CFSTR("a"));
225 mf->b = createManifestWithString(CFSTR("b"));
226 mf->ab = createManifestWithString(CFSTR("ab"));
227 mf->bab = testCreateBadManifest();
228 mf->gh = createManifestWithString(CFSTR("gh"));
229 mf->agh = createManifestWithString(CFSTR("agh"));
230 mf->agghhjk = createManifestWithString(CFSTR("agghhjk"));
231 mf->gghh = createManifestWithString(CFSTR("gghh"));
232 mf->agghh = createManifestWithString(CFSTR("agghh"));
233 }
234
235 static void teardownMF(mf_t *mf) {
236 if (!mf) return;
237 CFReleaseSafe(mf->empty);
238 CFReleaseSafe(mf->a);
239 CFReleaseSafe(mf->b);
240 CFReleaseSafe(mf->ab);
241 CFReleaseSafe(mf->bab);
242 CFReleaseSafe(mf->gh);
243 CFReleaseSafe(mf->agh);
244 CFReleaseSafe(mf->agghhjk);
245 CFReleaseSafe(mf->gghh);
246 CFReleaseSafe(mf->agghh);
247 }
248
249 static void testNullManifest(SOSManifestRef mf)
250 {
251 is(SOSManifestGetCount(mf), (size_t)0, "count is 0");
252 is(SOSManifestGetSize(mf), (size_t)0, "capacity is 0");
253 }
254
255 static void testNull(mf_t *mf) {
256 testNullManifest(mf->null);
257 testNullManifest(mf->empty);
258 }
259
260 static void testDiff(mf_t *mf) {
261 okmfdiff(mf->null, mf->null, mf->empty, mf->empty);
262 okmfdiff(mf->null, mf->empty, mf->empty, mf->empty);
263 okmfdiff(mf->null, mf->a, mf->empty, mf->a);
264 okmfdiff(mf->empty, mf->null, mf->empty, mf->empty);
265 okmfdiff(mf->empty, mf->empty, mf->empty, mf->empty);
266 okmfdiff(mf->empty, mf->a, mf->empty, mf->a);
267 okmfdiff(mf->a, mf->null, mf->a, mf->empty);
268 okmfdiff(mf->a, mf->empty, mf->a, mf->empty);
269 okmfdiff(mf->a, mf->a, mf->empty, mf->empty);
270 okmfdiff(mf->bab, mf->empty, mf->ab, mf->empty);
271 okmfdiff(mf->bab, mf->a, mf->b, mf->empty);
272 okmfdiff(mf->a, mf->bab, mf->empty, mf->b);
273 okmfdiff(mf->bab, mf->b, mf->a, mf->empty);
274 okmfdiff(mf->b, mf->bab, mf->empty, mf->a);
275 okmfdiff(mf->bab, mf->bab, mf->empty, mf->empty);
276 }
277
278 static void testPatch(mf_t *mf) {
279 okmfpatch(mf->null, mf->null, mf->null, mf->empty);
280 okmfpatch(mf->empty, mf->empty, mf->empty, mf->empty);
281 okmfpatch(mf->bab, mf->b, mf->a, mf->a);
282 okmfpatch(mf->ab, mf->empty, mf->empty, mf->ab);
283 okmfpatch(mf->ab, mf->empty, mf->a, mf->ab);
284 okmfpatch(mf->bab, mf->empty, mf->a, mf->ab);
285 okmfpatch(mf->bab, mf->ab, mf->null, mf->empty);
286 okmfpatch(mf->bab, mf->empty, mf->empty, mf->ab);
287 }
288
289 static void testUnion(mf_t *mf) {
290 okmfunion(mf->null, mf->null, mf->empty);
291 okmfunion(mf->null, mf->empty, mf->empty);
292 okmfunion(mf->empty, mf->null, mf->empty);
293 okmfunion(mf->empty, mf->empty, mf->empty);
294 okmfunion(mf->null, mf->a, mf->a);
295 okmfunion(mf->a, mf->null, mf->a);
296 okmfunion(mf->empty, mf->a, mf->a);
297 okmfunion(mf->a, mf->empty, mf->a);
298 okmfunion(mf->bab, mf->ab, mf->ab);
299 okmfunion(mf->empty, mf->bab, mf->ab);
300 okmfunion(mf->bab, mf->empty, mf->ab);
301 }
302
303 static void testIntersect(mf_t *mf) {
304 okmfintersection(mf->null, mf->null, mf->empty);
305 okmfintersection(mf->null, mf->empty, mf->empty);
306 okmfintersection(mf->empty, mf->null, mf->empty);
307 okmfintersection(mf->empty, mf->empty, mf->empty);
308 okmfintersection(mf->null, mf->a, mf->empty);
309 okmfintersection(mf->a, mf->null, mf->empty);
310 okmfintersection(mf->empty, mf->a, mf->empty);
311 okmfintersection(mf->a, mf->empty, mf->empty);
312 okmfintersection(mf->bab, mf->ab, mf->ab);
313 okmfintersection(mf->bab, mf->a, mf->a);
314 okmfintersection(mf->a, mf->bab, mf->a);
315 okmfintersection(mf->b, mf->bab, mf->b);
316 okmfintersection(mf->bab, mf->bab, mf->ab);
317 okmfintersection(mf->gghh, mf->agghh, mf->gh);
318 okmfintersection(mf->agghhjk, mf->agghh, mf->agh);
319 }
320
321 static void testComplement(mf_t *mf) {
322 okmfcomplement(mf->null, mf->null, mf->empty);
323 okmfcomplement(mf->null, mf->empty, mf->empty);
324 okmfcomplement(mf->empty, mf->null, mf->empty);
325 okmfcomplement(mf->empty, mf->empty, mf->empty);
326 okmfcomplement(mf->null, mf->a, mf->a);
327 okmfcomplement(mf->a, mf->null, mf->empty);
328 okmfcomplement(mf->empty, mf->a, mf->a);
329 okmfcomplement(mf->a, mf->empty, mf->empty);
330 okmfcomplement(mf->bab, mf->ab, mf->empty);
331 okmfcomplement(mf->ab, mf->bab, mf->empty);
332 okmfcomplement(mf->bab, mf->a, mf->empty);
333 okmfcomplement(mf->a, mf->bab, mf->b);
334 okmfcomplement(mf->b, mf->bab, mf->a);
335 okmfcomplement(mf->empty, mf->bab, mf->ab);
336 }
337
338 static void tests(void)
339 {
340 mf_t mf;
341 setupMF(&mf);
342
343 testNull(&mf);
344 testDiff(&mf);
345 testPatch(&mf);
346 testUnion(&mf);
347 testIntersect(&mf);
348 testComplement(&mf);
349
350 teardownMF(&mf);
351 }
352
353 int secd_49_manifests(int argc, char *const *argv)
354 {
355 plan_tests(kTestTestCount);
356
357 tests();
358
359 return 0;
360 }