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