]> git.saurik.com Git - apple/security.git/blob - SecurityTests/xdr_rpc/xdr_test.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / xdr_rpc / xdr_test.cpp
1 /*
2 * g++ -F/usr/local/SecurityPieces/Frameworks -g -Wall path/to/xdr_test.cpp
3 * -framework [securityd_client, security_cdsa_utilities, security_utilities]
4 *
5 * -W triggers a lot of warnings in Security code....
6 */
7 #include <stdio.h>
8 #include <rpc/types.h> /* bool_t */
9 #include <stdlib.h> /* exit(3), malloc(3) */
10 #include <string.h> /* memcmp(3), memset(3), strdup(3) */
11 #include <fcntl.h> /* open(2) */
12 #include <errno.h> /* errno */
13 #include <sys/types.h> /* read() */
14 #include <sys/uio.h> /* read() */
15 #include <unistd.h> /* read(), getopt(3) */
16 #include <Security/cssmtype.h>
17 #include <security_cdsa_utilities/walkers.h>
18 #include <security_cdsa_utilities/context.h>
19 #include <security_cdsa_utilities/cssmaclpod.h>
20 #include <securityd_client/xdr_cssm.h>
21 #include "securityd_data_saver.h"
22
23 using Security::DataWalkers::Copier;
24
25 const char *testString = "FOOBAR";
26
27 /*
28 * securityd is extremely sloppy about zeroing out data fields it doesn't
29 * use. It's unlikely that sloppiness will be cleaned up in one fell
30 * swoop, so we'll never be able to set this to 0; instead, search on the
31 * symbol name and selectively unbracket code as securityd is fixed.
32 */
33 #define SECURITYD_SENDS_GARBAGE 1
34
35
36 /*
37 * The securityd RPC protocol can't handle 64-bit quantities until both
38 * securityd itself and our XDR implementation do. Ergo, don't be tempted
39 * to make ALIGNMENT depend on __LP64__.
40 *
41 * ALIGNMENT and ALIGNUP borrowed from libsecurityd, sec_xdr.c. They
42 * really should be defined once in a more central location, like
43 * libsecurity_utilities.
44 */
45 #define LP64_FULLY_SUPPORTED 0
46
47 #if LP64_FULLY_SUPPORTED
48 #define ALIGNMENT 8
49 #else
50 #define ALIGNMENT 4
51 #endif // LP64_FULLY_SUPPORTED
52
53 #define ALIGNUP(LEN) (((LEN - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
54 #define ALIGNSIZE(TYPE) ALIGNUP(sizeof(TYPE))
55
56 #define NULLCHECK(a, b, func) \
57 if (!(a) && !(b))\
58 return OK;\
59 else if (!(a) && (b) || (a) && !(b))\
60 {\
61 fprintf(stderr, "%s (NULL and non-NULL parameter)\n", (func));\
62 return MISMATCH;\
63 }
64
65 #define N_ITERS 3 /* # of encode/decode cycles */
66
67 #define OK 0
68 #define XDR_ENCODE_ERROR -1
69 #define XDR_DECODE_ERROR -2
70 #define MISMATCH -3
71 #define UNKNOWN_TYPE -4 /* invalid union discriminator */
72 #define MEM_ERROR -10
73 #define BAD_PARAM -11
74 #define BAD_FILE -12
75 #define BAD_READ -13
76 #define READ_EOF -14 /* not an error per se */
77 #define INCOMPATIBLE -98 /* input data format not recognized */
78 #define NOT_IMPLEMENTED -99
79
80 /* This isn't publicly exposed */
81 #ifdef __cplusplus
82 extern "C" {
83 extern unsigned long xdr_sizeof(xdrproc_t, void *);
84 }
85 #endif
86
87 /*
88 * CSSM data structures of interest. Chosen either for their complexity
89 * (e.g., CSSM_CONTEXT) or their ubiquity (CSSM_DATA).
90 *
91 * CSSM_DATA
92 * CSSM_GUID
93 * CSSM_CRYPTO_DATA (possible callback)
94 * CSSM_LIST_ELEMENT (union)
95 * CSSM_LIST (pointers)
96 * CSSM_SAMPLEGROUP (array of CSSM_SAMPLEs)
97 * CSSM_DATE (fixed-size arrays handled via xdr_vector())
98 * CSSM_KEY (heavily used)
99 * CSSM_DB_RECORD_ATTRIBUTE_DATA (exercises a lot of the above)
100 * CSSM_CONTEXT (exercises a lot of the above)
101 * AccessCredentials
102 * CSSM_AUTHORIZATIONGROUP
103 * CSSM_ACL_VALIDITY_PERIOD
104 * CSSM_ACL_ENTRY_PROTOTYPE
105 * CSSM_ACL_OWNER_PROTOTYPE
106 * CSSM_ACL_ENTRY_INPUT
107 * CSSM_ACL_ENTRY_INFO
108 * CSSM_QUERY
109 */
110
111 /* utility routines */
112 bool_t xdr_stdio(void *data, xdrproc_t proc, enum xdr_op op); /* XXX/gh needed? */
113 bool_t xdr_mem_encode(void *input, void **output, u_int *outlen,
114 xdrproc_t proc);
115 bool_t xdr_mem_decode(void *input, void *output, u_int bytesNeeded,
116 xdrproc_t proc);
117 void flip(uint8_t *addr, size_t size);
118 int readPreamble(int fd, uint32_t *doflip, uint32_t *vers, uint32_t *type);
119 int fill_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr,
120 CSSM_ATTRIBUTE_TYPE type,
121 uint32_t attrlen,
122 void *attrval);
123
124 /* byte reordering routines */
125 void hostorder_CSSM_DATA(CSSM_DATA *data, off_t offset);
126 void hostorder_CSSM_GUID(CSSM_GUID *guid);
127 void hostorder_CSSM_VERSION(CSSM_VERSION *version);
128 void hostorder_CSSM_SUBSERVICE_UID(CSSM_SUBSERVICE_UID *ssuid);
129 void hostorder_CSSM_CRYPTO_DATA(CSSM_CRYPTO_DATA *crypto, off_t offset);
130 void hostorder_CSSM_LIST(CSSM_LIST *list, off_t offset);
131 void hostorder_CSSM_LIST_ELEMENT(CSSM_LIST_ELEMENT *element, off_t offset);
132 void hostorder_CSSM_SAMPLE(CSSM_SAMPLE *sample, off_t offset);
133 void hostorder_CSSM_SAMPLEGROUP(CSSM_SAMPLEGROUP *sgrp, off_t offset);
134 void hostorder_CSSM_ENCODED_CERT(CSSM_ENCODED_CERT *cert, off_t offset);
135 void hostorder_CSSM_CERTGROUP(CSSM_CERTGROUP *grp, off_t offset);
136 void hostorder_CSSM_BASE_CERTS(CSSM_BASE_CERTS *certs, off_t offset);
137 void hostorder_CSSM_ACCESS_CREDENTIALS(CSSM_ACCESS_CREDENTIALS *creds,
138 off_t offset);
139 void hostorder_CSSM_AUTHORIZATIONGROUP(CSSM_AUTHORIZATIONGROUP *grp,
140 off_t offset);
141 void hostorder_CSSM_ACL_VALIDITY_PERIOD(CSSM_ACL_VALIDITY_PERIOD *period,
142 off_t offset);
143 void hostorder_CSSM_ACL_ENTRY_PROTOTYPE(CSSM_ACL_ENTRY_PROTOTYPE *proto,
144 off_t offset);
145 void hostorder_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *proto,
146 off_t offset);
147 void hostorder_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *input, off_t offset);
148 void hostorder_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *info, off_t offset);
149 void hostorder_CSSM_KEYHEADER(CSSM_KEYHEADER *key);
150 void hostorder_CSSM_KEY(CSSM_KEY *key, off_t offset);
151 void hostorder_CSSM_DL_DB_HANDLE(CSSM_DL_DB_HANDLE *handle);
152 void hostorder_CSSM_RANGE(CSSM_RANGE *range);
153 void hostorder_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr,
154 off_t offset);
155 void hostorder_CSSM_CONTEXT(CSSM_CONTEXT *ctx, CSSM_CONTEXT_ATTRIBUTE *attrs);
156 void hostorder_CSSM_OID(CSSM_OID *oid, off_t offset);
157 void hostorder_CSSM_DB_ATTRIBUTE_INFO(CSSM_DB_ATTRIBUTE_INFO *attrinfo,
158 off_t offset);
159 void hostorder_CSSM_DB_ATTRIBUTE_DATA(CSSM_DB_ATTRIBUTE_DATA *attrdata,
160 off_t offset);
161 void hostorder_CSSM_SELECTION_PREDICATE(CSSM_SELECTION_PREDICATE *pred,
162 off_t offset);
163 void hostorder_CSSM_QUERY_LIMITS(CSSM_QUERY_LIMITS *limits);
164 void hostorder_CSSM_QUERY(CSSM_QUERY *range, off_t offset);
165
166 /* comparators */
167 int compare_CSSM_DATA(CSSM_DATA *data1, CSSM_DATA *data2);
168 int compare_CSSM_SUBSERVICE_UID(const CSSM_SUBSERVICE_UID *ssuid1,
169 const CSSM_SUBSERVICE_UID *ssuid2);
170 int compare_CSSM_CRYPTO_DATA(CSSM_CRYPTO_DATA *data1, CSSM_CRYPTO_DATA *data2);
171 int compare_CSSM_LIST(const CSSM_LIST *list1, const CSSM_LIST *list2);
172 int compare_CSSM_SAMPLE(const CSSM_SAMPLE *sample1, const CSSM_SAMPLE *sample2);
173 int compare_CSSM_SAMPLEGROUP(CSSM_SAMPLEGROUP *sgrp1, CSSM_SAMPLEGROUP *sgrp2);
174 int compare_CSSM_ENCODED_CERT(CSSM_ENCODED_CERT *cert1,
175 CSSM_ENCODED_CERT *cert2);
176 int compare_CSSM_CERTGROUP(CSSM_CERTGROUP *grp1, CSSM_CERTGROUP *grp2);
177 int compare_CSSM_BASE_CERTS(CSSM_BASE_CERTS *bases1, CSSM_BASE_CERTS *bases2);
178 int compare_CSSM_ACCESS_CREDENTIALS(CSSM_ACCESS_CREDENTIALS *creds1,
179 CSSM_ACCESS_CREDENTIALS *creds2);
180 int compare_CSSM_AUTHORIZATIONGROUP(CSSM_AUTHORIZATIONGROUP *grp1,
181 CSSM_AUTHORIZATIONGROUP *grp2);
182 int compare_CSSM_ACL_VALIDITY_PERIOD(CSSM_ACL_VALIDITY_PERIOD *period1,
183 CSSM_ACL_VALIDITY_PERIOD *period2);
184 int compare_CSSM_ACL_ENTRY_PROTOTYPE(CSSM_ACL_ENTRY_PROTOTYPE *proto1,
185 CSSM_ACL_ENTRY_PROTOTYPE *proto2,
186 int skipGarbage);
187 int compare_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *proto1,
188 CSSM_ACL_OWNER_PROTOTYPE *proto2);
189 int compare_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *input1,
190 CSSM_ACL_ENTRY_INPUT *input2);
191 int compare_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *info1,
192 CSSM_ACL_ENTRY_INFO *info2);
193 int compare_CSSM_DATE(CSSM_DATE *date1, CSSM_DATE *date2);
194 int compare_CSSM_KEYHEADER(CSSM_KEYHEADER *hdr1, CSSM_KEYHEADER *hdr2);
195 int compare_CSSM_KEY(CSSM_KEY *key1, CSSM_KEY *key2);
196 int compare_CSSM_RANGE(CSSM_RANGE *range1, CSSM_RANGE *range2);
197 int compare_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr1,
198 CSSM_CONTEXT_ATTRIBUTE *attr2);
199 int compare_CSSM_OID(CSSM_OID *oid1, CSSM_OID *oid2);
200 int compare_CSSM_CONTEXT(CSSM_CONTEXT *ctx1, CSSM_CONTEXT *ctx2);
201 int compare_CSSM_DB_ATTRIBUTE_INFO(CSSM_DB_ATTRIBUTE_INFO *attrinfo1,
202 CSSM_DB_ATTRIBUTE_INFO *attrinfo2);
203 int compare_CSSM_DB_ATTRIBUTE_DATA(CSSM_DB_ATTRIBUTE_DATA *attrdata1,
204 CSSM_DB_ATTRIBUTE_DATA *attrdata2);
205 int compare_CSSM_SELECTION_PREDICATE(CSSM_SELECTION_PREDICATE *pred1,
206 CSSM_SELECTION_PREDICATE *pred2);
207 int compare_CSSM_QUERY_LIMITS(CSSM_QUERY_LIMITS *limits1,
208 CSSM_QUERY_LIMITS *limits2);
209 int compare_CSSM_QUERY(CSSM_QUERY *query1, CSSM_QUERY *query2);
210
211 CSSM_RETURN dummyCSSMCallback(CSSM_DATA *data, void *context);
212 CSSM_RETURN dummyACLSubjectCallback(const CSSM_LIST *subjectRequest,
213 void *callerContext,
214 const CSSM_MEMORY_FUNCS *MemFuncs);
215
216 /* the actual test functions */
217 int test_CSSM_DB_RECORD_ATTRIBUTE_DATA(const char *srcfile); /* TODO/gh */
218 int test_xdrwalk_CSSM_CONTEXT(CSSM_CONTEXT *ctx, int dbglvl);
219 int test_CSSM_CONTEXT(int fd, int doflip, int dbglvl);
220 int test_xdrwalk_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *aclOwnerPrototype, int dbglvl);
221 int test_CSSM_ACL_OWNER_PROTOTYPE(int fd, int doflip, int dbglvl);
222 int test_xdrwalk_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *aclEntryInput,
223 int dbglvl);
224 int test_CSSM_ACL_ENTRY_INPUT(int fd, int doflip, int dbglvl);
225 int test_xdrwalk_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *aclEntryInfo,
226 int dbglvl);
227 int test_CSSM_ACL_ENTRY_INFO(int fd, int doflip, int dbglvl);
228 int test_xdrwalk_CSSM_QUERY(CSSM_QUERY *query, int dbglvl);
229 int test_CSSM_QUERY(int fd, int doflip, int dbglvl);
230
231
232 /**************************************************************************
233 * misc utility functions
234 **************************************************************************/
235
236 /* XXX/gh needed? */
237 /* XXX/gh should "data" be a uint8_t *? */
238 bool_t xdr_stdio(void *data, xdrproc_t proc, enum xdr_op op)
239 {
240 XDR xdr;
241 /* should we call xdrstdio_create(...,..., XDR_FREE) when done? */
242 xdrstdio_create(&xdr, stdout, op);
243 if (proc(&xdr, data))
244 return (FALSE);
245 return (TRUE);
246 }
247
248 /* note no error-checking of parameters */
249 bool_t xdr_mem_encode(void *input, void **output, u_int *outlen,
250 xdrproc_t proc)
251 {
252 XDR xdr;
253 char *data;
254 u_int length;
255
256 length = xdr_sizeof(proc, input);
257 if ((data = (char *)malloc(length)) == NULL)
258 {
259 fprintf(stderr, "xdr_mem_encode(): malloc() error\n");
260 return (FALSE);
261 }
262 xdrmem_create(&xdr, data, length, XDR_ENCODE);
263 if (!proc(&xdr, input))
264 {
265 fprintf(stderr, "xdr_mem_encode(): XDR error\n");
266 free(data);
267 return (FALSE);
268 }
269 *output = data;
270 if (outlen)
271 *outlen = length;
272 return (TRUE);
273 }
274
275 /* note no error-checking of parameters */
276 bool_t xdr_mem_decode(void *input, void *output, u_int bytesNeeded,
277 xdrproc_t proc)
278 {
279 XDR xdr;
280
281 xdrmem_create(&xdr, (char *)input, bytesNeeded, XDR_DECODE);
282 if (!proc(&xdr, output))
283 return (FALSE);
284 return (TRUE);
285 }
286
287 /*
288 * Because sometimes ntoh*() isn't enough. Stolen from securityd and
289 * slightly modified to avoid type dependencies.
290 */
291 void flip(void *inaddr, size_t size)
292 {
293 uint8 *addr = reinterpret_cast<uint8 *>(inaddr);
294 size_t n;
295
296 assert(size > 1 && (size % 2 == 0));
297 uint8_t *word = addr;
298 for (n = 0; n < size/2; n++)
299 {
300 uint8_t b = word[n];
301 word[n] = word[size-1-n];
302 word[size-1-n] = b;
303 }
304 }
305
306 /*
307 * note that if this returns prematurely, you can make no assumption about
308 * the value of "doflip," "vers," or "type"
309 */
310 int readPreamble(int fd, uint32_t *doflip, uint32_t *vers, uint32_t *type)
311 {
312 const char *func = "readPreamble()";
313 uint32_t value;
314 ssize_t bytesRead;
315
316 /* byte order sentry value */
317 if ((bytesRead = read(fd, &value, sizeof(value))) != sizeof(value))
318 {
319 if (bytesRead == 0)
320 return READ_EOF;
321 fprintf(stderr, "%s: error reading byte order sentry\n", func);
322 return BAD_READ;
323 }
324 if (value == SecuritydDataSave::sentry)
325 *doflip = 0;
326 else if (value == 0x34120000)
327 *doflip = 1;
328 else
329 {
330 fprintf(stderr, "%s: unrecognized sentry value %d\n", func, value);
331 return INCOMPATIBLE;
332 }
333
334 /* version info (for this disk-saving protocol) */
335 if (read(fd, &value, sizeof(value)) != sizeof(value))
336 {
337 fprintf(stderr, "%s: error reading data format version\n", func);
338 return BAD_READ;
339 }
340 if (*doflip)
341 flip(&value, sizeof(value));
342 *vers = value;
343
344 switch(*vers)
345 {
346 case 1:
347 /* type of record */
348 if (read(fd, &value, sizeof(value)) != sizeof(value))
349 {
350 fprintf(stderr, "%s: error reading data type\n", func);
351 return BAD_READ;
352 }
353 if (*doflip)
354 flip(&value, sizeof(value));
355 *type = value;
356 break;
357 default:
358 fprintf(stderr, "%s: incompatible version (expected <= %d, got %d)\n",
359 func, SecuritydDataSave::version, *vers);
360 return INCOMPATIBLE;
361 break;
362 }
363 return OK;
364 }
365
366 int fill_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr,
367 CSSM_ATTRIBUTE_TYPE type,
368 uint32_t attrlen,
369 void *attrval)
370 {
371 if (!attr || !attrval)
372 return BAD_PARAM;
373 attr->AttributeType = type;
374 attr->AttributeLength = attrlen;
375 /* XXX copy instead of assigning */
376 switch (type & CSSM_ATTRIBUTE_TYPE_MASK)
377 {
378 case CSSM_ATTRIBUTE_DATA_UINT32:
379 attr->Attribute.Uint32 = *(reinterpret_cast<uint32_t *>(attrval));
380 break;
381 case CSSM_ATTRIBUTE_DATA_CSSM_DATA:
382 attr->Attribute.Data = (CSSM_DATA_PTR)attrval;
383 break;
384 case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
385 attr->Attribute.CryptoData = (CSSM_CRYPTO_DATA_PTR)attrval;
386 break;
387 case CSSM_ATTRIBUTE_DATA_KEY:
388 attr->Attribute.Key = (CSSM_KEY_PTR)attrval;
389 break;
390 case CSSM_ATTRIBUTE_DATA_STRING:
391 attr->Attribute.String = (char *)attrval;
392 break;
393 case CSSM_ATTRIBUTE_DATA_DATE:
394 attr->Attribute.Date = (CSSM_DATE_PTR)attrval;
395 break;
396 case CSSM_ATTRIBUTE_DATA_RANGE:
397 attr->Attribute.Range = (CSSM_RANGE_PTR)attrval;
398 break;
399 case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS:
400 attr->Attribute.AccessCredentials = (CSSM_ACCESS_CREDENTIALS_PTR)attrval;
401 break;
402 case CSSM_ATTRIBUTE_DATA_VERSION:
403 attr->Attribute.Version = (CSSM_VERSION_PTR)attrval;
404 break;
405 case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE:
406 attr->Attribute.DLDBHandle = (CSSM_DL_DB_HANDLE_PTR)attrval;
407 break;
408 /* _KR_PROFILE not supported? */
409 default:
410 return BAD_PARAM;
411 }
412 return OK;
413 }
414
415
416 /**************************************************************************
417 * These do their best to handle byte-ordering issues.
418 *
419 * Note that pointers are generally (maybe always) byte-order swapped in
420 * these routines, since you generally need to do some kind of arithmetic
421 * with them (relocation).
422 **************************************************************************/
423
424 void hostorder_CSSM_DATA(CSSM_DATA *data, off_t offset)
425 {
426 intptr_t newaddr; /* for readability */
427
428 if (!data) return;
429 flip(&data->Length, sizeof(data->Length));
430 if (data->Data)
431 {
432 flip(&data->Data, sizeof(data->Data));
433 newaddr = reinterpret_cast<intptr_t>(data->Data) + offset;
434 data->Data = reinterpret_cast<uint8 *>(newaddr);
435 }
436 }
437
438 void hostorder_CSSM_GUID(CSSM_GUID *guid)
439 {
440 if (!guid) return;
441 flip(&guid->Data1, sizeof(guid->Data1));
442 flip(&guid->Data2, sizeof(guid->Data2));
443 flip(&guid->Data3, sizeof(guid->Data3));
444 }
445
446 void hostorder_CSSM_VERSION(CSSM_VERSION *version)
447 {
448 if (!version) return;
449 flip(&version->Major, sizeof(version->Major));
450 flip(&version->Minor, sizeof(version->Minor));
451 }
452
453 void hostorder_CSSM_SUBSERVICE_UID(CSSM_SUBSERVICE_UID *ssuid)
454 {
455 if (!ssuid) return;
456 hostorder_CSSM_GUID(&ssuid->Guid);
457 hostorder_CSSM_VERSION(&ssuid->Version);
458 flip(&ssuid->SubserviceId, sizeof(ssuid->SubserviceId));
459 flip(&ssuid->SubserviceType, sizeof(ssuid->SubserviceType));
460 }
461
462 void hostorder_CSSM_CRYPTO_DATA(CSSM_CRYPTO_DATA *crypto, off_t offset)
463 {
464 if (!crypto) return;
465 hostorder_CSSM_DATA(&crypto->Param, offset);
466 flip(&crypto->Callback, sizeof(crypto->Callback));
467 flip(&crypto->CallerCtx, sizeof(crypto->CallerCtx));
468 }
469
470 void hostorder_CSSM_LIST(CSSM_LIST *list, off_t offset)
471 {
472 CSSM_LIST_ELEMENT_PTR ptr;
473 intptr_t newaddr; /* for readability */
474
475 if (!list) return;
476
477 flip(&list->ListType, sizeof(list->ListType));
478
479 if (list->Head)
480 {
481 flip(&list->Head, sizeof(list->Head));
482 newaddr = reinterpret_cast<intptr_t>(list->Head) + offset;
483 list->Head = reinterpret_cast<CSSM_LIST_ELEMENT *>(newaddr);
484 }
485
486 if (list->Tail)
487 {
488 flip(&list->Tail, sizeof(list->Tail));
489 newaddr = reinterpret_cast<intptr_t>(list->Tail) + offset;
490 list->Tail = reinterpret_cast<CSSM_LIST_ELEMENT *>(newaddr);
491 }
492
493 for (ptr = list->Head; ptr != NULL; ptr = ptr->NextElement)
494 {
495 hostorder_CSSM_LIST_ELEMENT(ptr, offset);
496 }
497 }
498
499 void hostorder_CSSM_LIST_ELEMENT(CSSM_LIST_ELEMENT *element, off_t offset)
500 {
501 intptr_t newaddr; /* for readability */
502
503 if (!element) return;
504
505 if (element->NextElement)
506 {
507 flip(&element->NextElement, sizeof(element->NextElement));
508 newaddr = reinterpret_cast<intptr_t>(element->NextElement) + offset;
509 element->NextElement = reinterpret_cast<CSSM_LIST_ELEMENT_PTR>(newaddr);
510 }
511
512 flip(&element->WordID, sizeof(element->WordID));
513 flip(&element->ElementType, sizeof(element->ElementType));
514 switch (element->ElementType)
515 {
516 case CSSM_LIST_ELEMENT_DATUM:
517 hostorder_CSSM_DATA(&element->Element.Word, offset);
518 break;
519 case CSSM_LIST_ELEMENT_SUBLIST:
520 hostorder_CSSM_LIST(&element->Element.Sublist, offset);
521 break;
522 case CSSM_LIST_ELEMENT_WORDID:
523 break;
524 default:
525 fprintf(stderr, "hostorder_CSSM_LIST_ELEMENT() (unknown ListElement type)\n");
526 }
527 }
528
529 void hostorder_CSSM_SAMPLE(CSSM_SAMPLE *sample, off_t offset)
530 {
531 CSSM_SUBSERVICE_UID *ptr;
532
533 if (!sample) return;
534 hostorder_CSSM_LIST(&sample->TypedSample, offset);
535 if (sample->Verifier)
536 {
537 ptr = const_cast<CSSM_SUBSERVICE_UID *>(sample->Verifier);
538 flip(&ptr, sizeof(CSSM_SUBSERVICE_UID *));
539 sample->Verifier = reinterpret_cast<CSSM_SUBSERVICE_UID *>(reinterpret_cast<intptr_t>(ptr) + offset);
540 /* Verifier had better not be really and truly immutable... */
541 hostorder_CSSM_SUBSERVICE_UID(const_cast<CSSM_SUBSERVICE_UID *>(sample->Verifier));
542 }
543 }
544
545 void hostorder_CSSM_SAMPLEGROUP(CSSM_SAMPLEGROUP *sgrp, off_t offset)
546 {
547 u_int i;
548 CSSM_SAMPLE *ptr;
549
550 if (!sgrp) return;
551 flip(&sgrp->NumberOfSamples, sizeof(sgrp->NumberOfSamples));
552 if (sgrp->Samples)
553 {
554 ptr = const_cast<CSSM_SAMPLE *>(sgrp->Samples);
555 flip(&ptr, sizeof(ptr));
556 sgrp->Samples = reinterpret_cast<CSSM_SAMPLE *>(reinterpret_cast<intptr_t>(ptr) + offset);
557 for (i = 0; i < sgrp->NumberOfSamples; ++i)
558 {
559 hostorder_CSSM_SAMPLE(const_cast<CSSM_SAMPLE *>(&sgrp->Samples[i]), offset);
560 }
561 }
562 }
563
564 void hostorder_CSSM_ENCODED_CERT(CSSM_ENCODED_CERT *cert, off_t offset)
565 {
566 if (!cert) return;
567 flip(&cert->CertType, sizeof(cert->CertType));
568 flip(&cert->CertEncoding, sizeof(cert->CertEncoding));
569 hostorder_CSSM_DATA(&cert->CertBlob, offset);
570 }
571
572 void hostorder_CSSM_CERTGROUP(CSSM_CERTGROUP *grp, off_t offset)
573 {
574 const char *func = "hostorder_CSSM_CERTGROUP()";
575 intptr_t newaddr; /* for readability */
576 u_int i;
577
578 if (!grp) return;
579 flip(&grp->CertType, sizeof(grp->CertType));
580 flip(&grp->CertEncoding, sizeof(grp->CertEncoding));
581 flip(&grp->NumCerts, sizeof(grp->NumCerts));
582 /* Any field in the union will do; CertList is the shortest to type */
583 if (grp->GroupList.CertList)
584 {
585 flip(&grp->GroupList.CertList, sizeof(CSSM_DATA *));
586 newaddr = reinterpret_cast<intptr_t>(grp->GroupList.CertList) + offset;
587 grp->GroupList.CertList = reinterpret_cast<CSSM_DATA_PTR>(newaddr);
588 }
589 /* handled out of order of definition since for() loop depends on it */
590 flip(&grp->CertGroupType, sizeof(grp->CertGroupType));
591
592 /* Note: we will crash if GroupList contains NULL and NumCerts > 0 */
593 for (i = 0; i < grp->NumCerts; ++i)
594 {
595 char *err = NULL;
596
597 switch (grp->CertGroupType)
598 {
599 case CSSM_CERTGROUP_DATA:
600 hostorder_CSSM_DATA(&grp->GroupList.CertList[i], offset);
601 break;
602 /* damned if I can find an example of the others */
603 case CSSM_CERTGROUP_ENCODED_CERT:
604 /* See the cautionary note in compare_CSSM_CERTGROUP() */
605 hostorder_CSSM_ENCODED_CERT(&grp->GroupList.EncodedCertList[i],
606 offset);
607 break;
608 case CSSM_CERTGROUP_PARSED_CERT:
609 err = "CSSM_CERTGROUP_PARSED_CERT unimplemented";
610 break;
611 case CSSM_CERTGROUP_CERT_PAIR:
612 err = "CSSM_CERTGROUP_CERT_PAIR unimplemented";
613 break;
614 default:
615 err = "unknown type";
616 break;
617 }
618 if (err)
619 {
620 fprintf(stderr, "%s (%s)\n", func, err);
621 return;
622 }
623 }
624 flip(&grp->Reserved, sizeof(grp->Reserved));
625 /* Depending on how Reserved is used, this code might be required
626 newaddr = reinterpret_cast<intptr_t>(grp->Reserved) + offset;
627 grp->Reserved = reinterpret_cast<void *>(newaddr);
628 */
629 }
630
631 void hostorder_CSSM_BASE_CERTS(CSSM_BASE_CERTS *certs, off_t offset)
632 {
633 if (!certs) return;
634 flip(&certs->TPHandle, sizeof(certs->TPHandle));
635 flip(&certs->CLHandle, sizeof(certs->CLHandle));
636 hostorder_CSSM_CERTGROUP(&certs->Certs, offset);
637 }
638
639 void hostorder_CSSM_AUTHORIZATIONGROUP(CSSM_AUTHORIZATIONGROUP *grp,
640 off_t offset)
641 {
642 intptr_t newaddr; /* for readability */
643 uint32_t i;
644
645 flip(&grp->NumberOfAuthTags, sizeof(grp->NumberOfAuthTags));
646 if (grp->AuthTags)
647 {
648 flip(&grp->AuthTags, sizeof(grp->AuthTags));
649 newaddr = reinterpret_cast<intptr_t>(grp->AuthTags) + offset;
650 grp->AuthTags = reinterpret_cast<CSSM_ACL_AUTHORIZATION_TAG *>(newaddr);
651 }
652 for (i = 0; i < grp->NumberOfAuthTags; ++i)
653 {
654 flip(&grp->AuthTags[i], sizeof(CSSM_ACL_AUTHORIZATION_TAG));
655 }
656 }
657
658 void hostorder_CSSM_ACL_VALIDITY_PERIOD(CSSM_ACL_VALIDITY_PERIOD *period,
659 off_t offset)
660 {
661 hostorder_CSSM_DATA(&period->StartDate, offset);
662 hostorder_CSSM_DATA(&period->EndDate, offset);
663 }
664
665 void hostorder_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *proto,
666 off_t offset)
667 {
668 hostorder_CSSM_LIST(&proto->TypedSubject, offset);
669 flip(&proto->Delegate, sizeof(proto->Delegate));
670 }
671
672 void hostorder_CSSM_ACL_ENTRY_PROTOTYPE(CSSM_ACL_ENTRY_PROTOTYPE *proto,
673 off_t offset)
674 {
675 hostorder_CSSM_LIST(&proto->TypedSubject, offset);
676 flip(&proto->Delegate, sizeof(proto->Delegate));
677 hostorder_CSSM_AUTHORIZATIONGROUP(&proto->Authorization, offset);
678 hostorder_CSSM_ACL_VALIDITY_PERIOD(&proto->TimeRange, offset);
679 }
680
681 void hostorder_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *input, off_t offset)
682 {
683 hostorder_CSSM_ACL_ENTRY_PROTOTYPE(&input->Prototype, offset);
684 flip(&input->Callback, sizeof(input->Callback));
685 flip(&input->CallerContext, sizeof(input->CallerContext));
686 }
687
688 void hostorder_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *info, off_t offset)
689 {
690 hostorder_CSSM_ACL_ENTRY_PROTOTYPE(&info->EntryPublicInfo, offset);
691 flip(&info->EntryHandle, sizeof(info->EntryHandle));
692 }
693
694 void hostorder_CSSM_ACCESS_CREDENTIALS(CSSM_ACCESS_CREDENTIALS *creds,
695 off_t offset)
696 {
697 if (!creds) return;
698 hostorder_CSSM_BASE_CERTS(&creds->BaseCerts, offset);
699 hostorder_CSSM_SAMPLEGROUP(&creds->Samples, offset);
700 flip(&creds->Callback, sizeof(creds->Callback));
701 flip(&creds->CallerCtx, sizeof(creds->CallerCtx));
702 }
703
704 void hostorder_CSSM_KEYHEADER(CSSM_KEYHEADER *hdr)
705 {
706 if (!hdr) return;
707 flip(&hdr->HeaderVersion, sizeof(hdr->HeaderVersion));
708 flip(&hdr->BlobType, sizeof(hdr->BlobType));
709 flip(&hdr->Format, sizeof(hdr->Format));
710 flip(&hdr->AlgorithmId, sizeof(hdr->AlgorithmId));
711 flip(&hdr->KeyClass, sizeof(hdr->KeyClass));
712 flip(&hdr->LogicalKeySizeInBits, sizeof(hdr->LogicalKeySizeInBits));
713 flip(&hdr->KeyAttr, sizeof(hdr->KeyAttr));
714 flip(&hdr->KeyUsage, sizeof(hdr->KeyUsage));
715 flip(&hdr->WrapAlgorithmId, sizeof(hdr->WrapAlgorithmId));
716 flip(&hdr->WrapMode, sizeof(hdr->WrapMode));
717 flip(&hdr->Reserved, sizeof(hdr->Reserved));
718 }
719
720 void hostorder_CSSM_KEY(CSSM_KEY *key, off_t offset)
721 {
722 if (!key) return;
723 hostorder_CSSM_KEYHEADER(&key->KeyHeader);
724 hostorder_CSSM_DATA(&key->KeyData, offset);
725 }
726
727 void hostorder_CSSM_DL_DB_HANDLE(CSSM_DL_DB_HANDLE *handle)
728 {
729 if (!handle) return;
730 /*
731 * XXX/gh offset is needed if these values are being treated as
732 * as pointers!
733 */
734 flip(&handle->DLHandle, sizeof(handle->DLHandle));
735 flip(&handle->DBHandle, sizeof(handle->DBHandle));
736 }
737
738 void hostorder_CSSM_RANGE(CSSM_RANGE *range)
739 {
740 if (!range) return;
741 flip(&range->Min, sizeof(range->Min));
742 flip(&range->Max, sizeof(range->Max));
743 }
744
745 void hostorder_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr,
746 off_t offset)
747 {
748 if (!attr) return;
749 flip(&attr->AttributeType, sizeof(attr->AttributeType));
750 flip(&attr->AttributeLength, sizeof(attr->AttributeLength));
751 if ((attr->AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) == CSSM_ATTRIBUTE_DATA_UINT32)
752 {
753 flip(&attr->Attribute.Uint32, sizeof(attr->Attribute.Uint32));
754 }
755 else
756 {
757 intptr_t newaddr; /* for readability */
758
759 /* any pointer accessor of the union will do */
760 if (attr->Attribute.String)
761 {
762 flip(&attr->Attribute.String, sizeof(attr->Attribute.String));
763 newaddr = reinterpret_cast<intptr_t>(attr->Attribute.String) + offset;
764 attr->Attribute.String = reinterpret_cast<char *>(newaddr);
765 }
766 switch (attr->AttributeType & CSSM_ATTRIBUTE_TYPE_MASK)
767 {
768 case CSSM_ATTRIBUTE_DATA_CSSM_DATA:
769 hostorder_CSSM_DATA(attr->Attribute.Data, offset);
770 break;
771 case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
772 hostorder_CSSM_CRYPTO_DATA(attr->Attribute.CryptoData, offset);
773 break;
774 case CSSM_ATTRIBUTE_DATA_KEY:
775 hostorder_CSSM_KEY(attr->Attribute.Key, offset);
776 break;
777 case CSSM_ATTRIBUTE_DATA_STRING:
778 case CSSM_ATTRIBUTE_DATA_DATE:
779 break;
780 case CSSM_ATTRIBUTE_DATA_RANGE:
781 hostorder_CSSM_RANGE(attr->Attribute.Range);
782 break;
783 case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS:
784 hostorder_CSSM_ACCESS_CREDENTIALS(attr->Attribute.AccessCredentials, offset);
785 break;
786 case CSSM_ATTRIBUTE_DATA_VERSION:
787 hostorder_CSSM_VERSION(attr->Attribute.Version);
788 break;
789 case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE:
790 hostorder_CSSM_DL_DB_HANDLE(attr->Attribute.DLDBHandle);
791 break;
792 /* _KR_PROFILE not supported? */
793 default:
794 fprintf(stderr, "hostorder_CSSM_CONTEXT_ATTRIBUTE(): unrecognized attribute type\n");
795 }
796 } /* end if (CSSM_ATTRIBUTE_DATA_UINT32 */
797 }
798
799 void hostorder_CSSM_CONTEXT(CSSM_CONTEXT *ctx, CSSM_CONTEXT_ATTRIBUTE *attrs)
800 {
801 off_t offset;
802 uint32_t i;
803
804 if (!ctx) return;
805 flip(&ctx->ContextType, sizeof(ctx->ContextType));
806 flip(&ctx->AlgorithmType, sizeof(ctx->AlgorithmType));
807 flip(&ctx->NumberOfAttributes, sizeof(ctx->NumberOfAttributes));
808 if (ctx->ContextAttributes)
809 {
810 flip(&ctx->ContextAttributes, sizeof(ctx->ContextAttributes));
811 offset = reinterpret_cast<intptr_t>(attrs) - reinterpret_cast<intptr_t>(ctx->ContextAttributes);
812 ctx->ContextAttributes = reinterpret_cast<CSSM_CONTEXT_ATTRIBUTE *>(attrs);
813 }
814 for (i = 0; i < ctx->NumberOfAttributes; ++i)
815 {
816 hostorder_CSSM_CONTEXT_ATTRIBUTE(&ctx->ContextAttributes[i], offset);
817 }
818 flip(&ctx->CSPHandle, sizeof(ctx->CSPHandle));
819 flip(&ctx->Privileged, sizeof(ctx->Privileged));
820 flip(&ctx->EncryptionProhibited, sizeof(ctx->EncryptionProhibited));
821 flip(&ctx->WorkFactor, sizeof(ctx->WorkFactor));
822 flip(&ctx->Reserved, sizeof(ctx->Reserved));
823 }
824
825 void hostorder_CSSM_OID(CSSM_OID *oid, off_t offset)
826 {
827 hostorder_CSSM_DATA(reinterpret_cast<CSSM_DATA *>(oid), offset);
828 }
829
830 void hostorder_CSSM_DB_ATTRIBUTE_INFO(CSSM_DB_ATTRIBUTE_INFO *attrinfo,
831 off_t offset)
832 {
833 if (!attrinfo) return;
834 flip(&attrinfo->AttributeNameFormat, sizeof(attrinfo->AttributeNameFormat));
835 switch(attrinfo->AttributeNameFormat)
836 {
837 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
838 {
839 intptr_t newaddr; /* for readability */
840 flip(&attrinfo->Label.AttributeName, sizeof(attrinfo->Label.AttributeName));
841 newaddr = reinterpret_cast<intptr_t>(attrinfo->Label.AttributeName) + offset;
842 attrinfo->Label.AttributeName = reinterpret_cast<char *>(newaddr);
843 break;
844 }
845 case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
846 hostorder_CSSM_OID(&attrinfo->Label.AttributeOID, offset);
847 break;
848 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
849 flip(&attrinfo->Label.AttributeID, sizeof(attrinfo->Label.AttributeID));
850 break;
851 default:
852 break; /* error, but no way to tell caller */
853 }
854 flip(&attrinfo->AttributeFormat, sizeof(attrinfo->AttributeFormat));
855 }
856
857 void hostorder_CSSM_DB_ATTRIBUTE_DATA(CSSM_DB_ATTRIBUTE_DATA *attrdata,
858 off_t offset)
859 {
860 uint32_t i;
861
862 if (!attrdata) return;
863 hostorder_CSSM_DB_ATTRIBUTE_INFO(&attrdata->Info, offset);
864 flip(&attrdata->NumberOfValues, sizeof(attrdata->NumberOfValues));
865 for (i = 0; i < attrdata->NumberOfValues; ++i)
866 {
867 hostorder_CSSM_DATA(&attrdata->Value[i], offset);
868 }
869 }
870
871 void hostorder_CSSM_SELECTION_PREDICATE(CSSM_SELECTION_PREDICATE *pred,
872 off_t offset)
873 {
874 if (!pred) return;
875 flip(&pred->DbOperator, sizeof(pred->DbOperator));
876 hostorder_CSSM_DB_ATTRIBUTE_DATA(&pred->Attribute, offset);
877 }
878
879 void hostorder_CSSM_QUERY_LIMITS(CSSM_QUERY_LIMITS *limits)
880 {
881 if (!limits) return;
882 flip(&limits->TimeLimit, sizeof(limits->TimeLimit));
883 flip(&limits->SizeLimit, sizeof(limits->SizeLimit));
884 }
885
886 void hostorder_CSSM_QUERY(CSSM_QUERY *query, off_t offset)
887 {
888 uint32_t i;
889
890 if (!query) return;
891 flip(&query->RecordType, sizeof(query->RecordType));
892 flip(&query->Conjunctive, sizeof(query->Conjunctive));
893 flip(&query->NumSelectionPredicates, sizeof(query->NumSelectionPredicates));
894 if (query->SelectionPredicate)
895 {
896 intptr_t newaddr; /* for readability */
897
898 flip(&query->SelectionPredicate, sizeof(query->SelectionPredicate));
899 newaddr = reinterpret_cast<intptr_t>(query->SelectionPredicate) + offset;
900 query->SelectionPredicate = reinterpret_cast<CSSM_SELECTION_PREDICATE *>(newaddr);
901 }
902 for (i = 0; i < query->NumSelectionPredicates; ++i)
903 {
904 hostorder_CSSM_SELECTION_PREDICATE(&query->SelectionPredicate[i], offset);
905 }
906 hostorder_CSSM_QUERY_LIMITS(&query->QueryLimits);
907 flip(&query->QueryFlags, sizeof(query->QueryFlags));
908 }
909
910
911 /**************************************************************************
912 * Comparators--data integrity checking routines.
913 *
914 * Each comparator compares two of the same high-level data structure, one
915 * of which is presumed to have been through at least one
916 * encoding/decoding cycle; these comparators check for errors introduced
917 * during that cycle.
918 *
919 * TODO/gh A hand-crafted function per type seems sloppy, not well thought
920 * out. I bet I could leverage part of the walker machinery to create a
921 * more elegant solution (a "comparison walker," anyone?). Whether the
922 * result would be maintainable is, of course, a different question....
923 **************************************************************************/
924
925 int compare_CSSM_DATA(CSSM_DATA *data1, CSSM_DATA *data2)
926 {
927 const char *func = "compare_CSSM_DATA()";
928
929 NULLCHECK(data1, data2, func);
930 if (data1->Length != data2->Length ||
931 memcmp(data1->Data, data2->Data, data1->Length))
932 {
933 fprintf(stderr, "%s (mismatch)\n", func);
934 return MISMATCH;
935 }
936 return OK;
937 }
938
939 int compare_CSSM_SUBSERVICE_UID(const CSSM_SUBSERVICE_UID *ssuid1,
940 const CSSM_SUBSERVICE_UID *ssuid2)
941 {
942 const char *func = "compare_CSSM_SUBSERVICE_UID()";
943
944 NULLCHECK(ssuid1, ssuid2, func);
945 if (memcmp(&ssuid1->Guid, &ssuid2->Guid, sizeof(CSSM_GUID)) ||
946 memcmp(&ssuid1->Version, &ssuid2->Version, sizeof(CSSM_VERSION)) ||
947 ssuid1->SubserviceId != ssuid2->SubserviceId ||
948 ssuid1->SubserviceType != ssuid2->SubserviceType)
949 {
950 fprintf(stderr, "%s (mismatch)\n", func);
951 return MISMATCH;
952 }
953 return OK;
954 }
955
956 int compare_CSSM_CRYPTO_DATA(CSSM_CRYPTO_DATA *data1, CSSM_CRYPTO_DATA *data2)
957 {
958 const char *func = "compare_CSSM_CRYPTO_DATA()";
959 int ret;
960
961 NULLCHECK(data1, data2, func);
962 if ((ret = compare_CSSM_DATA(&data1->Param, &data2->Param)) != OK)
963 {
964 fprintf(stderr, "%s\n", func);
965 return ret;
966 }
967 if (data1->Callback != data2->Callback ||
968 data1->CallerCtx != data2->CallerCtx)
969 {
970 fprintf(stderr, "%s (mismatch)\n", func);
971 return MISMATCH;
972 }
973 return OK;
974 }
975
976 int compare_CSSM_LIST(const CSSM_LIST *list1, const CSSM_LIST *list2)
977 {
978 const char *func = "compare_CSSM_LIST()";
979 CSSM_LIST_ELEMENT_PTR p1, p2;
980 int ret;
981
982 NULLCHECK(list1, list2, func);
983 if (list1->ListType != list2->ListType)
984 {
985 fprintf(stderr, "%s (ListType)\n", func);
986 return MISMATCH;
987 }
988 for (p1 = list1->Head, p2 = list2->Head;
989 p1 != NULL && p2 != NULL;
990 p1 = p1->NextElement, p2 = p2->NextElement)
991 {
992 if (p1->ElementType != p2->ElementType)
993 {
994 fprintf(stderr, "%s (ListElements' ElementType)\n", func);
995 return MISMATCH;
996 }
997 switch (p1->ElementType)
998 {
999 case CSSM_LIST_ELEMENT_DATUM:
1000 ret = compare_CSSM_DATA(&p1->Element.Word, &p2->Element.Word);
1001 if (ret != OK)
1002 {
1003 fprintf(stderr, "%s\n", func);
1004 return ret;
1005 }
1006 break;
1007 case CSSM_LIST_ELEMENT_SUBLIST:
1008 ret = compare_CSSM_LIST(&p1->Element.Sublist, &p2->Element.Sublist);
1009 if (ret != OK)
1010 {
1011 fprintf(stderr, "%s\n", func);
1012 return ret;
1013 }
1014 break;
1015 case CSSM_LIST_ELEMENT_WORDID:
1016 if (p1->WordID != p2->WordID)
1017 {
1018 fprintf(stderr, "%s (ListElements' WordID)\n", func);
1019 return MISMATCH;
1020 }
1021 break;
1022 default:
1023 fprintf(stderr, "%s (unknown ListElement type)\n", func);
1024 return UNKNOWN_TYPE;
1025 }
1026 if ((p1->NextElement == NULL && p1 != list1->Tail) ||
1027 (p2->NextElement == NULL && p2 != list2->Tail))
1028 {
1029 fprintf(stderr, "%s (tail mismatch)\n", func);
1030 return MISMATCH;
1031 }
1032 }
1033 if (p1 != NULL || p2 != NULL) /* lists didn't both terminate */
1034 {
1035 fprintf(stderr, "%s (unequal lists)\n", func);
1036 return MISMATCH;
1037 }
1038 return OK;
1039 }
1040
1041 int compare_CSSM_SAMPLE(const CSSM_SAMPLE *sample1, const CSSM_SAMPLE *sample2)
1042 {
1043 const char *func = "compare_CSSM_SAMPLE()";
1044 int ret;
1045
1046 NULLCHECK(sample1, sample2, func);
1047 ret = compare_CSSM_LIST(&sample1->TypedSample, &sample2->TypedSample);
1048 if (ret != OK)
1049 {
1050 fprintf(stderr, "%s\n", func);
1051 return ret;
1052 }
1053 if (sample1->Verifier && sample2->Verifier)
1054 {
1055 ret = compare_CSSM_SUBSERVICE_UID(sample1->Verifier, sample2->Verifier);
1056 if (ret != OK)
1057 {
1058 fprintf(stderr, "%s\n", func);
1059 return ret;
1060 }
1061 }
1062 else if (sample1->Verifier && !sample2->Verifier ||
1063 !sample1->Verifier && sample2->Verifier)
1064 {
1065 fprintf(stderr, "%s (Verifier mismatch)\n", func);
1066 return MISMATCH;
1067 }
1068 return OK;
1069 }
1070
1071 int compare_CSSM_SAMPLEGROUP(CSSM_SAMPLEGROUP *sgrp1, CSSM_SAMPLEGROUP *sgrp2)
1072 {
1073 const char *func = "compare_CSSM_SAMPLEGROUP()";
1074 int ret;
1075 u_int i;
1076
1077 NULLCHECK(sgrp1, sgrp2, func);
1078 if (sgrp1->NumberOfSamples != sgrp2->NumberOfSamples)
1079 {
1080 fprintf(stderr, "%s (NumberOfSamples mismatch)\n", func);
1081 return MISMATCH;
1082 }
1083 for (i = 0; i < sgrp1->NumberOfSamples; ++i)
1084 {
1085 ret = compare_CSSM_SAMPLE(&sgrp1->Samples[i], &sgrp2->Samples[i]);
1086 if (ret != OK)
1087 {
1088 fprintf(stderr, "%s\n", func);
1089 return ret;
1090 }
1091 }
1092 return OK;
1093 }
1094
1095 int compare_CSSM_ENCODED_CERT(CSSM_ENCODED_CERT *cert1,
1096 CSSM_ENCODED_CERT *cert2)
1097 {
1098 const char *func = "compare_CSSM_ENCODED_CERT()";
1099 int ret;
1100
1101 NULLCHECK(cert1, cert2, func);
1102 if (cert1->CertType != cert2->CertType ||
1103 cert1->CertEncoding != cert2->CertEncoding)
1104 {
1105 fprintf(stderr, "%s (mismatch)\n", func);
1106 return MISMATCH;
1107 }
1108 if ((ret = compare_CSSM_DATA(&cert1->CertBlob, &cert2->CertBlob)) != OK)
1109 fprintf(stderr, "%s\n", func);
1110 return ret;
1111 }
1112
1113 int compare_CSSM_CERTGROUP(CSSM_CERTGROUP *grp1, CSSM_CERTGROUP *grp2)
1114 {
1115 const char *func = "compare_CSSM_CERTGROUP()";
1116 int ret;
1117 u_int i;
1118
1119 NULLCHECK(grp1, grp2, func);
1120 if (grp1->CertType != grp2->CertType ||
1121 grp1->CertEncoding != grp2->CertEncoding ||
1122 grp1->NumCerts != grp2->NumCerts ||
1123 grp1->CertGroupType != grp2->CertGroupType ||
1124 grp1->Reserved != grp2->Reserved)
1125 {
1126 fprintf(stderr, "%s (mismatch)\n", func);
1127 return MISMATCH;
1128 }
1129 for (i = 0; i < grp1->NumCerts; ++i)
1130 {
1131 char *err = NULL;
1132
1133 switch (grp1->CertGroupType)
1134 {
1135 case CSSM_CERTGROUP_DATA:
1136 ret = compare_CSSM_DATA(&grp1->GroupList.CertList[i],
1137 &grp2->GroupList.CertList[i]);
1138 break;
1139 /* damned if I can find an example of the others */
1140 case CSSM_CERTGROUP_ENCODED_CERT:
1141 /*
1142 * This is apparently in use (see CertGroup in
1143 * cdsa_utilities, cssmcert.{cpp,h}), but it's just a
1144 * guess that it's implemented in the same way as
1145 * CSSM_CERTGROUP_DATA...
1146 */
1147 ret = compare_CSSM_ENCODED_CERT(&grp1->GroupList.EncodedCertList[i],
1148 &grp2->GroupList.EncodedCertList[i]);
1149 break;
1150 case CSSM_CERTGROUP_PARSED_CERT:
1151 err = "CSSM_CERTGROUP_PARSED_CERT unimplemented";
1152 ret = NOT_IMPLEMENTED;
1153 break;
1154 case CSSM_CERTGROUP_CERT_PAIR:
1155 err = "CSSM_CERTGROUP_CERT_PAIR unimplemented";
1156 ret = NOT_IMPLEMENTED;
1157 break;
1158 default:
1159 err = "unknown type";
1160 ret = UNKNOWN_TYPE;
1161 break;
1162 }
1163 if (ret != OK)
1164 {
1165 if (err)
1166 fprintf(stderr, "%s (%s)\n", func, err);
1167 else
1168 fprintf(stderr, "%s\n", func);
1169 return ret;
1170 }
1171 }
1172 return OK;
1173 }
1174
1175 int compare_CSSM_BASE_CERTS(CSSM_BASE_CERTS *bases1, CSSM_BASE_CERTS *bases2)
1176 {
1177 const char *func = "compare_CSSM_BASE_CERTS()";
1178 int ret;
1179
1180 NULLCHECK(bases1, bases2, func);
1181 if (bases1->TPHandle != bases2->TPHandle ||
1182 bases1->CLHandle != bases2->CLHandle)
1183 {
1184 fprintf(stderr, "%s (mismatch)\n", func);
1185 return MISMATCH;
1186 }
1187 ret = compare_CSSM_CERTGROUP(&bases1->Certs, &bases2->Certs);
1188 if (ret != OK)
1189 {
1190 fprintf(stderr, "%s\n", func);
1191 return ret;
1192 }
1193 return OK;
1194 }
1195
1196 int compare_CSSM_ACCESS_CREDENTIALS(CSSM_ACCESS_CREDENTIALS *creds1,
1197 CSSM_ACCESS_CREDENTIALS *creds2)
1198 {
1199 const char *func = "compare_CSSM_ACCESS_CREDENTIALS()";
1200 int ret;
1201
1202 NULLCHECK(creds1, creds2, func);
1203 if (memcmp(creds1->EntryTag, creds2->EntryTag, sizeof(CSSM_STRING)) ||
1204 creds1->Callback != creds2->Callback ||
1205 creds1->CallerCtx != creds2->CallerCtx)
1206 {
1207 fprintf(stderr, "%s (mismatch)\n", func);
1208 return MISMATCH;
1209 }
1210 ret = compare_CSSM_BASE_CERTS(&creds1->BaseCerts, &creds2->BaseCerts);
1211 if (ret != OK)
1212 {
1213 fprintf(stderr, "%s\n", func);
1214 return ret;
1215 }
1216 ret = compare_CSSM_SAMPLEGROUP(&creds1->Samples, &creds2->Samples);
1217 if (ret != OK)
1218 {
1219 fprintf(stderr, "%s\n", func);
1220 return ret;
1221 }
1222 return OK;
1223 }
1224
1225 int compare_CSSM_AUTHORIZATIONGROUP(CSSM_AUTHORIZATIONGROUP *grp1,
1226 CSSM_AUTHORIZATIONGROUP *grp2)
1227 {
1228 const char *func = "compare_CSSM_AUTHORIZATIONGROUP()";
1229
1230 NULLCHECK(grp1, grp2, func);
1231 if (grp1->NumberOfAuthTags != grp2->NumberOfAuthTags ||
1232 memcmp(grp1->AuthTags, grp2->AuthTags, grp1->NumberOfAuthTags*ALIGNSIZE(CSSM_ACL_AUTHORIZATION_TAG)))
1233 {
1234 fprintf(stderr, "%s (mismatch)\n", func);
1235 return MISMATCH;
1236 }
1237 return OK;
1238 }
1239
1240 int compare_CSSM_ACL_VALIDITY_PERIOD(CSSM_ACL_VALIDITY_PERIOD *period1,
1241 CSSM_ACL_VALIDITY_PERIOD *period2)
1242 {
1243 const char *func = "compare_CSSM_ACL_VALIDITY_PERIOD()";
1244 int ret;
1245
1246 NULLCHECK(period1, period2, func);
1247 ret = compare_CSSM_DATA(&period1->StartDate, &period1->StartDate);
1248 if (ret != OK)
1249 {
1250 fprintf(stderr, "%s (StartDate)\n", func);
1251 return ret;
1252 }
1253 ret = compare_CSSM_DATA(&period1->EndDate, &period1->EndDate);
1254 if (ret != OK)
1255 fprintf(stderr, "%s (EndDate)\n", func);
1256 return ret;
1257 }
1258
1259 int compare_CSSM_ACL_ENTRY_PROTOTYPE(CSSM_ACL_ENTRY_PROTOTYPE *proto1,
1260 CSSM_ACL_ENTRY_PROTOTYPE *proto2,
1261 int skipGarbage)
1262 {
1263 const char *func = "compare_CSSM_ACL_ENTRY_PROTOTYPE()";
1264 int ret;
1265
1266 NULLCHECK(proto1, proto2, func);
1267 ret = compare_CSSM_LIST(&proto1->TypedSubject, &proto2->TypedSubject);
1268 if (ret != OK)
1269 {
1270 fprintf(stderr, "%s\n", func);
1271 return ret;
1272 }
1273 if (!skipGarbage)
1274 {
1275 if (proto1->Delegate != proto2->Delegate)
1276 {
1277 fprintf(stderr, "%s (Delegate mismatch)\n", func);
1278 return MISMATCH;
1279 }
1280 }
1281 ret = compare_CSSM_AUTHORIZATIONGROUP(&proto1->Authorization, &proto2->Authorization);
1282 if (ret != OK)
1283 {
1284 fprintf(stderr, "%s\n", func);
1285 return ret;
1286 }
1287 if (!skipGarbage)
1288 {
1289 ret = compare_CSSM_ACL_VALIDITY_PERIOD(&proto1->TimeRange, &proto2->TimeRange);
1290 if (ret != OK)
1291 {
1292 fprintf(stderr, "%s\n", func);
1293 return ret;
1294 }
1295 }
1296 if (memcmp(proto1->EntryTag, proto2->EntryTag, sizeof(CSSM_STRING)))
1297 {
1298 fprintf(stderr, "%s (EntryTag mismatch)\n", func);
1299 return MISMATCH;
1300 }
1301 return OK;
1302 }
1303
1304 int compare_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *proto1,
1305 CSSM_ACL_OWNER_PROTOTYPE *proto2)
1306 {
1307 const char *func = "compare_CSSM_ACL_OWNER_PROTOTYPE()";
1308
1309 NULLCHECK(proto1, proto2, func);
1310 int ret = compare_CSSM_LIST(&proto1->TypedSubject, &proto2->TypedSubject);
1311 if (ret != OK)
1312 {
1313 fprintf(stderr, "%s\n", func);
1314 return ret;
1315 }
1316 if (proto1->Delegate != proto2->Delegate)
1317 {
1318 fprintf(stderr, "%s (Delegate mismatch)\n", func);
1319 return MISMATCH;
1320 }
1321 return OK;
1322 }
1323
1324 int compare_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *input1,
1325 CSSM_ACL_ENTRY_INPUT *input2)
1326 {
1327 const char *func = "compare_CSSM_ACL_ENTRY_INPUT()";
1328 int ret, skipGarbage = 0;
1329
1330 NULLCHECK(input1, input2, func);
1331 ret = compare_CSSM_ACL_ENTRY_PROTOTYPE(&input1->Prototype,
1332 &input2->Prototype,
1333 skipGarbage);
1334 if (ret != OK)
1335 {
1336 fprintf(stderr, "%s\n", func);
1337 return ret;
1338 }
1339 if (input1->Callback != input2->Callback ||
1340 input1->CallerContext != input2->CallerContext)
1341 {
1342 fprintf(stderr, "%s (mismatch)\n", func);
1343 return MISMATCH;
1344 }
1345 return OK;
1346 }
1347
1348 int compare_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *info1,
1349 CSSM_ACL_ENTRY_INFO *info2)
1350 {
1351 const char *func = "compare_CSSM_ACL_ENTRY_INFO()";
1352 int ret, skipGarbage = 0;
1353
1354 NULLCHECK(info1, info2, func);
1355 #if SECURITYD_SENDS_GARBAGE
1356 skipGarbage = 1;
1357 /* fprintf(stderr, "%s: skipping garbage\n", func); */
1358 #endif
1359 ret = compare_CSSM_ACL_ENTRY_PROTOTYPE(&info1->EntryPublicInfo,
1360 &info2->EntryPublicInfo,
1361 skipGarbage);
1362 if (ret != OK)
1363 {
1364 fprintf(stderr, "%s\n", func);
1365 return ret;
1366 }
1367 if (info1->EntryHandle != info2->EntryHandle)
1368 {
1369 fprintf(stderr, "%s (EntryHandle mismatch)\n", func);
1370 return MISMATCH;
1371 }
1372 return OK;
1373 }
1374
1375 int compare_CSSM_DATE(CSSM_DATE *date1, CSSM_DATE *date2)
1376 {
1377 const char *func = "compare_CSSM_DATE()";
1378
1379 NULLCHECK(date1, date2, func);
1380 if (memcmp(date1, date2, sizeof(CSSM_DATE)))
1381 {
1382 fprintf(stderr, "%s (mismatch)\n", func);
1383 return MISMATCH;
1384 }
1385 return OK;
1386 }
1387
1388 int compare_CSSM_KEYHEADER(CSSM_KEYHEADER *hdr1, CSSM_KEYHEADER *hdr2)
1389 {
1390 const char *func = "compare_CSSM_KEYHEADER()";
1391 int ret;
1392
1393 NULLCHECK(hdr1, hdr2, func);
1394 if (hdr1->HeaderVersion != hdr2->HeaderVersion ||
1395 memcmp(&hdr1->CspId, &hdr2->CspId, sizeof(CSSM_GUID)) ||
1396 hdr1->BlobType != hdr2->BlobType ||
1397 hdr1->Format != hdr2->Format ||
1398 hdr1->AlgorithmId != hdr2->AlgorithmId ||
1399 hdr1->KeyClass != hdr2->KeyClass ||
1400 hdr1->LogicalKeySizeInBits != hdr2->LogicalKeySizeInBits ||
1401 hdr1->KeyUsage != hdr2->KeyUsage ||
1402 hdr1->WrapAlgorithmId != hdr2->WrapAlgorithmId ||
1403 hdr1->WrapMode != hdr2->WrapMode ||
1404 hdr1->Reserved != hdr2->Reserved)
1405 {
1406 fprintf(stderr, "%s (mismatch)\n", func);
1407 return MISMATCH;
1408 }
1409 if ((ret = compare_CSSM_DATE(&hdr1->StartDate, &hdr2->StartDate)) != OK)
1410 {
1411 fprintf(stderr, "%s\n", func);
1412 return ret;
1413 }
1414 if ((ret = compare_CSSM_DATE(&hdr1->EndDate, &hdr2->EndDate)) != OK)
1415 {
1416 fprintf(stderr, "%s\n", func);
1417 return ret;
1418 }
1419 return OK;
1420 }
1421
1422 int compare_CSSM_KEY(CSSM_KEY *key1, CSSM_KEY *key2)
1423 {
1424 const char *func = "compare_CSSM_KEY()";
1425 int ret;
1426
1427 NULLCHECK(key1, key2, func);
1428 if ((ret = compare_CSSM_KEYHEADER(&key1->KeyHeader, &key1->KeyHeader)) != OK)
1429 {
1430 fprintf(stderr, "%s\n", func);
1431 return ret;
1432 }
1433 if ((ret = compare_CSSM_DATA(&key1->KeyData, &key2->KeyData)) != OK)
1434 {
1435 fprintf(stderr, "%s\n", func);
1436 return ret;
1437 }
1438 return OK;
1439 }
1440
1441 int compare_CSSM_RANGE(CSSM_RANGE *range1, CSSM_RANGE *range2)
1442 {
1443 const char *func = "compare_CSSM_RANGE()";
1444
1445 NULLCHECK(range1, range2, func);
1446 if (memcmp(range1, range2, sizeof(CSSM_RANGE)))
1447 {
1448 fprintf(stderr, "%s (mismatch)\n", func);
1449 return MISMATCH;
1450 }
1451 return OK;
1452 }
1453
1454 int compare_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr1,
1455 CSSM_CONTEXT_ATTRIBUTE *attr2)
1456 {
1457 const char *func = "compare_CSSM_CONTEXT_ATTRIBUTE()";
1458 char *err = NULL;
1459 int ret = OK;
1460
1461 NULLCHECK(attr1, attr2, func);
1462 if (attr1->AttributeType != attr2->AttributeType ||
1463 attr1->AttributeLength != attr2->AttributeLength)
1464 {
1465 fprintf(stderr, "%s (mismatch)\n", func);
1466 return MISMATCH;
1467 }
1468 switch (attr1->AttributeType & CSSM_ATTRIBUTE_TYPE_MASK)
1469 {
1470 case CSSM_ATTRIBUTE_DATA_UINT32:
1471 if (attr1->Attribute.Uint32 != attr2->Attribute.Uint32)
1472 {
1473 err = "Uint32 mismatch";
1474 ret = MISMATCH;
1475 }
1476 break;
1477 case CSSM_ATTRIBUTE_DATA_CSSM_DATA:
1478 ret = compare_CSSM_DATA(attr1->Attribute.Data, attr2->Attribute.Data);
1479 break;
1480 case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA:
1481 ret = compare_CSSM_CRYPTO_DATA(attr1->Attribute.CryptoData, attr2->Attribute.CryptoData);
1482 break;
1483 case CSSM_ATTRIBUTE_DATA_KEY:
1484 ret = compare_CSSM_KEY(attr1->Attribute.Key, attr2->Attribute.Key);
1485 break;
1486 case CSSM_ATTRIBUTE_DATA_STRING:
1487 if (memcmp(attr1->Attribute.String, attr2->Attribute.String, attr1->AttributeLength))
1488 {
1489 err = "String mismatch";
1490 ret = MISMATCH;
1491 }
1492 break;
1493 case CSSM_ATTRIBUTE_DATA_DATE:
1494 ret = compare_CSSM_DATE(attr1->Attribute.Date, attr2->Attribute.Date);
1495 break;
1496 case CSSM_ATTRIBUTE_DATA_RANGE:
1497 ret = compare_CSSM_RANGE(attr1->Attribute.Range, attr2->Attribute.Range);
1498 break;
1499 case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS:
1500 ret = compare_CSSM_ACCESS_CREDENTIALS(attr1->Attribute.AccessCredentials,
1501 attr2->Attribute.AccessCredentials);
1502 break;
1503 case CSSM_ATTRIBUTE_DATA_VERSION:
1504 if (memcmp(&attr1->Attribute.Version, &attr2->Attribute.Version, sizeof(CSSM_VERSION)))
1505 {
1506 err = "Version mismatch";
1507 ret = MISMATCH;
1508 }
1509 break;
1510 case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE:
1511 if (memcmp(&attr1->Attribute.DLDBHandle, &attr2->Attribute.DLDBHandle, sizeof(CSSM_DL_DB_HANDLE)))
1512 {
1513 err = "DLDBHandle mismatch";
1514 ret = MISMATCH;
1515 }
1516 break;
1517 /* _PADDING and _KR_PROFILE not supported? */
1518 default:
1519 err = "unknown type";
1520 ret = UNKNOWN_TYPE;
1521 break;
1522 }
1523 if (ret != OK)
1524 {
1525 if (err)
1526 fprintf(stderr, "%s (%s)\n", func, err);
1527 else
1528 fprintf(stderr, "%s\n", func);
1529 return ret;
1530 }
1531 return OK;
1532 }
1533
1534 int compare_CSSM_CONTEXT(CSSM_CONTEXT *ctx1, CSSM_CONTEXT *ctx2)
1535 {
1536 const char *func = "compare_CSSM_CONTEXT()";
1537 u_int i, ret;
1538
1539 NULLCHECK(ctx1, ctx2, func);
1540 if (ctx1->ContextType != ctx2->ContextType ||
1541 ctx1->AlgorithmType != ctx2->AlgorithmType ||
1542 ctx1->NumberOfAttributes != ctx2->NumberOfAttributes ||
1543 ctx1->CSPHandle != ctx2->CSPHandle ||
1544 ctx1->Privileged != ctx2->Privileged ||
1545 ctx1->EncryptionProhibited != ctx2->EncryptionProhibited ||
1546 ctx1->WorkFactor != ctx2->WorkFactor ||
1547 ctx1->Reserved != ctx2->Reserved)
1548 {
1549 fprintf(stderr, "%s (mismatch)\n", func);
1550 return MISMATCH;
1551 }
1552 for (i = 0; i < ctx1->NumberOfAttributes; ++i)
1553 {
1554 ret = compare_CSSM_CONTEXT_ATTRIBUTE(&ctx1->ContextAttributes[i],
1555 &ctx2->ContextAttributes[i]);
1556 if (ret != OK)
1557 {
1558 fprintf(stderr, "%s\n", func);
1559 return ret;
1560 }
1561 }
1562 return OK;
1563 }
1564
1565 int compare_CSSM_OID(CSSM_OID *oid1, CSSM_OID *oid2)
1566 {
1567 return compare_CSSM_DATA(reinterpret_cast<CSSM_DATA *>(oid1),
1568 reinterpret_cast<CSSM_DATA *>(oid2));
1569 }
1570
1571 /* oy -- see cdsa_utilities, cssmdb.cpp: CompareAttributeInfos() */
1572 int compare_CSSM_DB_ATTRIBUTE_INFO(CSSM_DB_ATTRIBUTE_INFO *attrinfo1,
1573 CSSM_DB_ATTRIBUTE_INFO *attrinfo2)
1574 {
1575 const char *func = "compare_CSSM_DB_ATTRIBUTE_INFO()";
1576
1577 NULLCHECK(attrinfo1, attrinfo2, func);
1578 if (attrinfo1->AttributeNameFormat != attrinfo2->AttributeNameFormat ||
1579 attrinfo1->AttributeFormat != attrinfo2->AttributeFormat)
1580 {
1581 fprintf(stderr, "%s (mismatch)\n", func);
1582 return MISMATCH;
1583 }
1584 switch(attrinfo1->AttributeNameFormat)
1585 {
1586 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
1587 if (strcmp(attrinfo1->Label.AttributeName, attrinfo2->Label.AttributeName))
1588 {
1589 fprintf(stderr, "%s (string mismatch)\n", func);
1590 return MISMATCH;
1591 }
1592 break;
1593 case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
1594 return compare_CSSM_OID(&attrinfo1->Label.AttributeOID,
1595 &attrinfo2->Label.AttributeOID);
1596 break;
1597 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
1598 if (attrinfo1->Label.AttributeID != attrinfo2->Label.AttributeID)
1599 {
1600 fprintf(stderr, "%s (integer mismatch)\n", func);
1601 return MISMATCH;
1602 }
1603 break;
1604 default:
1605 fprintf(stderr, "%s (unknown type)\n", func);
1606 return UNKNOWN_TYPE;
1607 }
1608 return OK;
1609 }
1610
1611 int compare_CSSM_DB_ATTRIBUTE_DATA(CSSM_DB_ATTRIBUTE_DATA *attrdata1,
1612 CSSM_DB_ATTRIBUTE_DATA *attrdata2)
1613 {
1614 const char *func = "compare_CSSM_DB_ATTRIBUTE_DATA()";
1615 int ret;
1616 uint32_t i;
1617
1618 NULLCHECK(attrdata1, attrdata2, func);
1619 ret = compare_CSSM_DB_ATTRIBUTE_INFO(&attrdata1->Info, &attrdata2->Info);
1620 if (ret != OK)
1621 {
1622 fprintf(stderr, "%s\n", func);
1623 return ret;
1624 }
1625 if (attrdata1->NumberOfValues != attrdata2->NumberOfValues)
1626 {
1627 fprintf(stderr, "%s (mismatch)\n", func);
1628 return MISMATCH;
1629 }
1630 for (i = 0; i < attrdata1->NumberOfValues; ++i)
1631 {
1632 ret = compare_CSSM_DATA(&attrdata1->Value[i], &attrdata2->Value[i]);
1633 if (ret != OK)
1634 {
1635 fprintf(stderr, "%s (Value %d)\n", func, i+1);
1636 return ret;
1637 }
1638 }
1639 return OK;
1640 }
1641
1642 int compare_CSSM_SELECTION_PREDICATE(CSSM_SELECTION_PREDICATE *pred1,
1643 CSSM_SELECTION_PREDICATE *pred2)
1644 {
1645 const char *func = "compare_CSSM_SELECTION_PREDICATE()";
1646 int ret;
1647
1648 NULLCHECK(pred1, pred2, func);
1649 if (pred1->DbOperator != pred2->DbOperator)
1650 {
1651 fprintf(stderr, "%s (mismatch)\n", func);
1652 return MISMATCH;
1653 }
1654 ret = compare_CSSM_DB_ATTRIBUTE_DATA(&pred1->Attribute, &pred2->Attribute);
1655 if (ret != OK)
1656 fprintf(stderr, "%s\n", func);
1657 return ret;
1658 }
1659
1660 int compare_CSSM_QUERY_LIMITS(CSSM_QUERY_LIMITS *limits1,
1661 CSSM_QUERY_LIMITS *limits2)
1662 {
1663 const char *func = "compare_CSSM_QUERY_LIMITS()";
1664
1665 NULLCHECK(limits1, limits2, func);
1666 if (limits1->TimeLimit != limits2->TimeLimit ||
1667 limits1->SizeLimit != limits2->SizeLimit)
1668 {
1669 fprintf(stderr, "%s (mismatch)\n", func);
1670 return MISMATCH;
1671 }
1672 return OK;
1673 }
1674
1675 int compare_CSSM_QUERY(CSSM_QUERY *query1, CSSM_QUERY *query2)
1676 {
1677 const char *func = "compare_CSSM_QUERY()";
1678 int ret;
1679 uint32_t i;
1680
1681 NULLCHECK(query1, query2, func);
1682 if (query1->RecordType != query2->RecordType ||
1683 query1->Conjunctive != query2->Conjunctive ||
1684 query1->NumSelectionPredicates != query2->NumSelectionPredicates ||
1685 query1->QueryFlags != query2->QueryFlags)
1686 {
1687 fprintf(stderr, "%s (mismatch)\n", func);
1688 return MISMATCH;
1689 }
1690 for (i = 0; i < query1->NumSelectionPredicates; ++i)
1691 {
1692 ret = compare_CSSM_SELECTION_PREDICATE(&query1->SelectionPredicate[i],
1693 &query2->SelectionPredicate[i]);
1694 }
1695 ret = compare_CSSM_QUERY_LIMITS(&query1->QueryLimits, &query2->QueryLimits);
1696 if (ret != OK)
1697 fprintf(stderr, "%s\n", func);
1698 return ret;
1699 }
1700
1701 /**************************************************************************
1702 * Support routines for test_...() functions.
1703 **************************************************************************/
1704
1705 CSSM_RETURN dummyACLSubjectCallback(const CSSM_LIST *subjectRequest,
1706 void *callerContext,
1707 const CSSM_MEMORY_FUNCS *MemFuncs)
1708 {
1709 return CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED; /* XXX/gh */
1710 }
1711
1712 /*
1713 * Dummy func to make sure CSSM_CRYPTO_DATA isn't being corrupted. Kindly
1714 * note the requirement that "context" be a CSSM_CRYPTO_DATA.
1715 */
1716 CSSM_RETURN dummyCSSMCallback(CSSM_DATA *data, void *context)
1717 {
1718 CSSM_CRYPTO_DATA_PTR crypto = (CSSM_CRYPTO_DATA *)context;
1719 data->Length = crypto->Param.Length;
1720 data->Data = (uint8 *)malloc(data->Length); /* XXX/gh leaked */
1721 /* XXX/gh yeah, should check if the malloc() failed */
1722 memcpy(data->Data, crypto->Param.Data, data->Length);
1723 return CSSM_OK;
1724 }
1725
1726 /**************************************************************************
1727 * test_CSSM_...() routines read sample data from disk (obtained from
1728 * securityd via the SecuritydDataSave class), set up the named
1729 * top-level structure by byte-reordering (if needed) and pointer
1730 * relocating (using libsecurity_utilities walkers), and let the
1731 * corresponding test_xdrwalk_...() routine test the XDR encoding/decoding
1732 * routines against themselves and against the equivalent walker-generated
1733 * output.
1734 *
1735 * General test methodology:
1736 *
1737 * encode/decode x 3, then compare (1) the encoded original vs. the decoded
1738 * copy, and (2) the flattened encoded version with the equivalent walker's
1739 * flattened output.
1740 **************************************************************************/
1741
1742 /* TODO/gh don't worry about this until we get smart cards working */
1743 int test_CSSM_DB_RECORD_ATTRIBUTE_DATA(const char *srcfile)
1744 {
1745 CSSM_DB_RECORD_ATTRIBUTE_DATA *data = NULL;
1746
1747 if (srcfile)
1748 {
1749 /* read binary data from disk */
1750 }
1751 else
1752 {
1753 /* dummy something up */
1754 data = (CSSM_DB_RECORD_ATTRIBUTE_DATA *)malloc(sizeof(CSSM_DB_RECORD_ATTRIBUTE_DATA));
1755 if (!data)
1756 return MEM_ERROR;
1757 data->DataRecordType = CSSM_DL_DB_RECORD_CERT;
1758 /* TODO/gh pick up from here */
1759 }
1760 if (data)
1761 free(data);
1762 return NOT_IMPLEMENTED; /* TODO/gh */
1763 }
1764
1765 int test_xdrwalk_CSSM_CONTEXT(CSSM_CONTEXT *ctx, int dbglvl)
1766 {
1767 const char *func = "test_xdrwalk_CSSM_CONTEXT()";
1768 CSSM_CONTEXT *walkcopy, *xdrctxcopy = NULL;
1769 CSSM_CONTEXT_ATTRIBUTE *attrs;
1770 void *flattenedCtxPtr = NULL;
1771 u_int flattenedCtxLen = 0, i;
1772 int ret, iter;
1773 size_t attrsSize, walkedAttrsSize;
1774
1775 /*
1776 * Reimplement Context::Builder so we control where the memory is
1777 * allocated, thus what pointer values are.
1778 */
1779 SizeWalker sizer;
1780 for (i = 0; i < ctx->NumberOfAttributes; ++i)
1781 {
1782 walk(sizer, ctx->ContextAttributes[i]);
1783 }
1784 attrsSize = ALIGNUP(ctx->NumberOfAttributes * sizeof(CSSM_CONTEXT_ATTRIBUTE));
1785 walkedAttrsSize = attrsSize + ALIGNUP(sizer);
1786
1787 /* create a *flat* copy of ctx for direct memcmp() w/ XDR copy */
1788 walkcopy = reinterpret_cast<CSSM_CONTEXT *>(calloc(1, sizeof(CSSM_CONTEXT) + walkedAttrsSize));
1789 if (walkcopy == NULL)
1790 {
1791 fprintf(stderr, "%s: error allocating walked context\n", func);
1792 return MEM_ERROR;
1793 }
1794 memcpy(walkcopy, ctx, sizeof(CSSM_CONTEXT));
1795 attrs = reinterpret_cast<CSSM_CONTEXT_ATTRIBUTE *>(reinterpret_cast<char *>(walkcopy) + sizeof(CSSM_CONTEXT));
1796 CopyWalker copier = LowLevelMemoryUtilities::increment(attrs, attrsSize);
1797 for (i = 0; i < ctx->NumberOfAttributes; ++i)
1798 {
1799 attrs[i] = ctx->ContextAttributes[i]; /* shallow copy */
1800 walk(copier, attrs[i]); /* deep copy */
1801 }
1802 walkcopy->ContextAttributes = attrs;
1803
1804 for (iter = 0; iter < N_ITERS; ++iter)
1805 {
1806 if (!xdr_mem_encode(ctx, &flattenedCtxPtr, &flattenedCtxLen,
1807 (xdrproc_t)xdr_CSSM_CONTEXT))
1808 {
1809 fprintf(stderr, "%s, round %d (encode error)\n", func, iter+1);
1810 return XDR_ENCODE_ERROR;
1811 }
1812 /* always zero out memory before attempting a decode */
1813 if ((xdrctxcopy = (CSSM_CONTEXT *)calloc(1, sizeof(CSSM_CONTEXT))) == NULL)
1814 {
1815 fprintf(stderr, "%s, round %d (allocation error)\n", func, iter+1);
1816 return MEM_ERROR;
1817 }
1818 if (!xdr_mem_decode(flattenedCtxPtr, xdrctxcopy, flattenedCtxLen,
1819 (xdrproc_t)xdr_CSSM_CONTEXT))
1820 {
1821 fprintf(stderr, "%s, round %d (decode error)\n", func, iter+1);
1822 return XDR_DECODE_ERROR;
1823 }
1824 if (dbglvl >= 3)
1825 printf("comparing XDR-generated structs...\n");
1826 if ((ret = compare_CSSM_CONTEXT(ctx, xdrctxcopy)) != OK)
1827 {
1828 fprintf(stderr, "%s: CSSM_CONTEXT old/new XDR comparison, round %d, failed\n",
1829 func, iter+1);
1830 return ret;
1831 }
1832 if (dbglvl >= 3)
1833 printf("comparing walked- and XDR-generated structs...\n");
1834 if ((ret = compare_CSSM_CONTEXT(xdrctxcopy, walkcopy)) != OK)
1835 {
1836 fprintf(stderr, "%s: CSSM_CONTEXT XDR/walker comparison, round %d, failed\n",
1837 func, iter+1);
1838 return ret;
1839 }
1840 if (dbglvl >= 2)
1841 printf("CSSM_CONTEXT compared OK, round %d\n", iter+1);
1842 #if 0
1843 if (dbglvl >= 3)
1844 printf("Starting XDR/walker comparison...\n");
1845 /*
1846 * XXX/gh xdrctxcopy and walkcopy should be identical except for
1847 * pointer offsets. However, xdrctxcopy has extra bytes following
1848 * CSSM_CONTEXT's Reserved field; still investigating why.
1849 */
1850 /* XXX/gh relocate somebody's pointers */
1851 if (memcmp(walkcopy, xdrctxcopy, walkedAttrsSize+sizeof(CSSM_CONTEXT)))
1852 {
1853 fprintf(stderr, "%s, round %d (comparison failed)\n", func, iter+1);
1854 return MISMATCH;
1855 }
1856 #endif
1857 if (iter > 0)
1858 free(ctx);
1859 ctx = xdrctxcopy;
1860 free(flattenedCtxPtr);
1861 flattenedCtxPtr = NULL;
1862 flattenedCtxLen = 0;
1863 }
1864 if (dbglvl >= 1)
1865 printf("Successfully finished CSSM_CONTEXT check\n");
1866 return OK;
1867 }
1868
1869 int test_CSSM_CONTEXT(int fd, int doflip, int dbglvl)
1870 {
1871 const char *func = "test_CSSM_CONTEXT()";
1872 CSSM_CONTEXT ctx;
1873 CSSM_CONTEXT_ATTRIBUTE *attrs;
1874 int ret;
1875 CSSM_CRYPTO_DATA crypto;
1876
1877 if (fd > -1) /* cheesy hack, but what ya gonna do? */
1878 {
1879 int csize, attrSize;
1880 u_int i;
1881 intptr_t attraddr;
1882 off_t offset;
1883 /*
1884 * Saved format:
1885 * - size (of CSSM_CONTEXT)
1886 * - CSSM_CONTEXT
1887 * - size (of starting address for attributes)
1888 * - starting address for CSSM_CONTEXT_ATTRIBUTEs
1889 * - total size of CSSM_CONTEXT_ATTRIBUTEs
1890 * - CSSM_CONTEXT_ATTRIBUTEs (contiguous)
1891 */
1892
1893 /* context size; not really needed */
1894 if (read(fd, &csize, sizeof(csize)) != static_cast<ssize_t>(sizeof(csize)))
1895 {
1896 fprintf(stderr, "%s: Error reading context size\n", func);
1897 return BAD_READ;
1898 }
1899 if (doflip) flip(&csize, sizeof(csize));
1900 if (read(fd, &ctx, csize) != static_cast<ssize_t>(csize))
1901 {
1902 fprintf(stderr, "Error reading context\n");
1903 return BAD_READ;
1904 }
1905 /* Defer reorder of CSSM_CONTEXT until attributes have been read */
1906 /* attribute array starting address */
1907 if (read(fd, &csize, sizeof(csize)) != static_cast<ssize_t>(sizeof(csize)))
1908 {
1909 fprintf(stderr, "Error reading attribute address size\n");
1910 return BAD_READ;
1911 }
1912 if (doflip) flip(&csize, sizeof(csize));
1913 if (read(fd, &attraddr, csize) != csize)
1914 {
1915 fprintf(stderr, "Error reading attribute address\n");
1916 return BAD_READ;
1917 }
1918 /*
1919 * byte reorder of old attribute address, if needed, handled in
1920 * hostorder_CSSM_CONTEXT()
1921 */
1922 /* size of attributes */
1923 if (read(fd, &attrSize, sizeof(attrSize)) != static_cast<ssize_t>(sizeof(attrSize)))
1924 {
1925 fprintf(stderr, "Error reading attribute size\n");
1926 return BAD_READ;
1927 }
1928 if (doflip) flip(&attrSize, sizeof(attrSize));
1929 if ((attrs = (CSSM_CONTEXT_ATTRIBUTE *)malloc(attrSize)) == NULL)
1930 return MEM_ERROR;
1931 /* attributes */
1932 if (read(fd, attrs, attrSize) != attrSize)
1933 {
1934 fprintf(stderr, "Error reading attributes\n");
1935 return BAD_READ;
1936 }
1937 if (doflip)
1938 {
1939 ctx.ContextAttributes = reinterpret_cast<CSSM_CONTEXT_ATTRIBUTE *>(attraddr);
1940 hostorder_CSSM_CONTEXT(&ctx, attrs);
1941 }
1942 else
1943 {
1944 /* NB: this was the working code before byte-reordering */
1945 offset = reinterpret_cast<intptr_t>(attrs) - attraddr;
1946 ReconstituteWalker relocator(offset);
1947 for (i = 0; i < ctx.NumberOfAttributes; ++i)
1948 {
1949 walk(relocator, attrs[i]);
1950 }
1951 ctx.ContextAttributes = attrs;
1952 }
1953 (void)close(fd);
1954 }
1955 else
1956 {
1957 int err;
1958 uint32_t intattr;
1959
1960 /*
1961 * dummy something up; this is from FakeContext usages in
1962 * securityd/tests/
1963 */
1964 ctx.ContextType = CSSM_ALGCLASS_KEYGEN;
1965 ctx.AlgorithmType = CSSM_ALGID_DES;
1966 #define N_TEST_ATTRS 2
1967 ctx.NumberOfAttributes = N_TEST_ATTRS;
1968 attrs = (CSSM_CONTEXT_ATTRIBUTE *)malloc(N_TEST_ATTRS*sizeof(CSSM_CONTEXT_ATTRIBUTE));
1969 if (!attrs)
1970 return MEM_ERROR;
1971 ctx.ContextAttributes = attrs;
1972 intattr = 64;
1973 err = fill_CSSM_CONTEXT_ATTRIBUTE(&ctx.ContextAttributes[0],
1974 CSSM_ATTRIBUTE_KEY_LENGTH,
1975 sizeof(uint32_t),
1976 &intattr);
1977 if (err != OK)
1978 return err;
1979 crypto.Param.Length = strlen(testString);
1980 crypto.Param.Data = (uint8 *)testString;
1981 #if 0
1982 crypto.Callback = dummyCSSMCallback;
1983 crypto.CallerCtx = &crypto; /* dummy cb needs crypto.Param */
1984 #endif
1985 crypto.Callback = NULL;
1986 crypto.CallerCtx = NULL; /* dummy cb needs crypto.Param */
1987 err = fill_CSSM_CONTEXT_ATTRIBUTE(&ctx.ContextAttributes[1],
1988 CSSM_ATTRIBUTE_SEED,
1989 sizeof(CSSM_CRYPTO_DATA),
1990 (void *)&crypto);
1991 if (err != OK)
1992 return err;
1993 ctx.CSPHandle = 13;
1994 ctx.Privileged = CSSM_TRUE; /* ! 0 */
1995 ctx.EncryptionProhibited = CSSM_TRUE;
1996 ctx.WorkFactor = 41;
1997 ctx.Reserved = 0xfeefee; /* sentry value */
1998 }
1999
2000 if ((ret = test_xdrwalk_CSSM_CONTEXT(&ctx, dbglvl)) != OK)
2001 {
2002 fprintf(stderr, "%s\n", func);
2003 return ret;
2004 }
2005 return OK;
2006 }
2007
2008 int test_xdrwalk_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *aclOwnerPrototype,
2009 int dbglvl)
2010 {
2011 const char *func = "test_xdrwalk_CSSM_ACL_OWNER_PROTOTYPE()";
2012 CSSM_ACL_OWNER_PROTOTYPE *walkcopy, *xdrcopy;
2013 void *flattenedAclOwnerPtr = NULL;
2014 u_int flattenedAclOwnerLen = 0;
2015 int ret, iter;
2016
2017 /* save off aclOwnerPrototype because we're going to reuse the pointer */
2018 walkcopy = reinterpret_cast<CSSM_ACL_OWNER_PROTOTYPE *>(calloc(1, sizeof(CSSM_ACL_OWNER_PROTOTYPE)));
2019 if (walkcopy == NULL)
2020 {
2021 fprintf(stderr, "%s: error allocating walked CSSM_ACL_OWNER_PROTOTYPE\n", func);
2022 return MEM_ERROR;
2023 }
2024 memcpy(walkcopy, aclOwnerPrototype, sizeof(CSSM_ACL_OWNER_PROTOTYPE));
2025 /* aclOwnerPrototype *is* a walked copy, so no need to re-walk it */
2026
2027 for (iter = 0; iter < N_ITERS; ++iter)
2028 {
2029 if (!xdr_mem_encode(aclOwnerPrototype, &flattenedAclOwnerPtr,
2030 &flattenedAclOwnerLen,
2031 reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE)))
2032 {
2033 fprintf(stderr, "%s, round %d (encode error)\n", func, iter+1);
2034 return XDR_ENCODE_ERROR;
2035 }
2036 /* always zero out memory before attempting a decode */
2037 if ((xdrcopy = (CSSM_ACL_OWNER_PROTOTYPE *)calloc(1, sizeof(CSSM_ACL_OWNER_PROTOTYPE))) == NULL)
2038 {
2039 fprintf(stderr, "%s, round %d (allocation error)\n", func, iter+1);
2040 return MEM_ERROR;
2041 }
2042 if (!xdr_mem_decode(flattenedAclOwnerPtr, xdrcopy, flattenedAclOwnerLen,
2043 (xdrproc_t)xdr_CSSM_ACL_OWNER_PROTOTYPE))
2044 {
2045 fprintf(stderr, "%s, round %d (decode error)\n", func, iter+1);
2046 return XDR_DECODE_ERROR;
2047 }
2048 if (dbglvl >= 3)
2049 printf("comparing XDR-generated structs...\n");
2050 if ((ret = compare_CSSM_ACL_OWNER_PROTOTYPE(aclOwnerPrototype, xdrcopy)) != OK)
2051 {
2052 fprintf(stderr, "%s: CSSM_ACL_OWNER_PROTOTYPE old/new XDR comparison, round %d, failed\n",
2053 func, iter+1);
2054 return ret;
2055 }
2056 if (dbglvl >= 3)
2057 printf("comparing walked- and XDR-generated structs...\n");
2058 if ((ret = compare_CSSM_ACL_OWNER_PROTOTYPE(xdrcopy, walkcopy)) != OK)
2059 {
2060 fprintf(stderr, "%s: CSSM_ACL_OWNER_PROTOTYPE XDR/walker comparison, round %d, failed\n",
2061 func, iter+1);
2062 return ret;
2063 }
2064 if (dbglvl >= 2)
2065 printf("CSSM_ACL_OWNER_PROTOTYPE compared OK, round %d\n", iter+1);
2066 if (iter > 0)
2067 free(aclOwnerPrototype);
2068 aclOwnerPrototype = xdrcopy;
2069 free(flattenedAclOwnerPtr);
2070 flattenedAclOwnerPtr = NULL;
2071 flattenedAclOwnerLen = 0;
2072 }
2073
2074 if (dbglvl >= 1)
2075 printf("Successfully finished CSSM_ACL_OWNER_PROTOTYPE check\n");
2076 return OK;
2077 }
2078
2079 int test_CSSM_ACL_OWNER_PROTOTYPE(int fd, int doflip, int dbglvl)
2080 {
2081 const char *func = "test_CSSM_ACL_OWNER_PROTOTYPE()";
2082 CSSM_ACL_OWNER_PROTOTYPE *aclOwnerPrototype;
2083 int ret;
2084
2085 if (fd > -1) /* cheesy hack, but what ya gonna do? */
2086 {
2087 int aclsize;
2088 uint32_t ptrsize; /* AKA mach_msg_type_number_t, AKA natural_t */
2089 intptr_t baseptr;
2090 off_t offset;
2091 /*
2092 * Saved format:
2093 * - sizeof(base pointer)
2094 * - base pointer
2095 * - length
2096 * - CSSM_ACL_OWNER_PROTOTYPE
2097 */
2098 if (read(fd, &ptrsize, sizeof(ptrsize)) < static_cast<ssize_t>(sizeof(ptrsize)))
2099 {
2100 fprintf(stderr, "%s: Error reading base pointer size\n", func);
2101 return BAD_READ;
2102 }
2103 if (doflip) flip(&ptrsize, sizeof(ptrsize));
2104 if (read(fd, &baseptr, ptrsize) < static_cast<ssize_t>(ptrsize))
2105 {
2106 fprintf(stderr, "%s: Error reading base pointer\n", func);
2107 return BAD_READ;
2108 }
2109 if (doflip) flip(&baseptr, sizeof(baseptr));
2110 if (read(fd, &aclsize, sizeof(aclsize)) < static_cast<ssize_t>(sizeof(aclsize)))
2111 {
2112 fprintf(stderr, "%s: Error reading AclOwnerPrototype size\n", func);
2113 return BAD_READ;
2114 }
2115 if (doflip) flip(&aclsize, sizeof(aclsize));
2116 aclOwnerPrototype = (CSSM_ACL_OWNER_PROTOTYPE *)malloc(aclsize);
2117 if (aclOwnerPrototype == NULL)
2118 return MEM_ERROR;
2119 if (read(fd, aclOwnerPrototype, aclsize) < aclsize)
2120 {
2121 fprintf(stderr, "Error reading CSSM_ACL_OWNER_PROTOTYPE\n");
2122 return BAD_READ;
2123 }
2124 offset = reinterpret_cast<intptr_t>(aclOwnerPrototype) - baseptr;
2125 if (doflip)
2126 {
2127 hostorder_CSSM_ACL_OWNER_PROTOTYPE(aclOwnerPrototype, offset);
2128 }
2129 else
2130 {
2131 ReconstituteWalker relocator(offset);
2132 walk(relocator, reinterpret_cast<AclOwnerPrototype *&>(baseptr));
2133 }
2134 (void)close(fd);
2135 }
2136 else
2137 {
2138 /* TODO/gh cobble something up */
2139 return NOT_IMPLEMENTED;
2140 }
2141
2142 ret = test_xdrwalk_CSSM_ACL_OWNER_PROTOTYPE(aclOwnerPrototype, dbglvl);
2143 if (ret != OK)
2144 fprintf(stderr, "%s\n", func);
2145 free(aclOwnerPrototype);
2146 return ret;
2147 }
2148
2149 int test_xdrwalk_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *aclEntryInput,
2150 int dbglvl)
2151 {
2152 const char *func = "test_xdrwalk_CSSM_ACL_ENTRY_INPUT()";
2153 CSSM_ACL_ENTRY_INPUT *walkcopy, *xdrcopy;
2154 void *flattenedAclEIPtr = NULL;
2155 u_int flattenedAclEILen = 0;
2156 int ret, iter;
2157
2158 /* save off aclEntryInput because we're going to reuse the pointer */
2159 walkcopy = reinterpret_cast<CSSM_ACL_ENTRY_INPUT *>(calloc(1, sizeof(CSSM_ACL_ENTRY_INPUT)));
2160 if (walkcopy == NULL)
2161 {
2162 fprintf(stderr, "%s: error allocating walked CSSM_ACL_ENTRY_INPUT\n", func);
2163 return MEM_ERROR;
2164 }
2165 memcpy(walkcopy, aclEntryInput, sizeof(CSSM_ACL_ENTRY_INPUT));
2166 /* aclEntryInput *is* a walked copy, so no need to re-walk it */
2167
2168 for (iter = 0; iter < N_ITERS; ++iter)
2169 {
2170 if (!xdr_mem_encode(aclEntryInput, &flattenedAclEIPtr, &flattenedAclEILen,
2171 (xdrproc_t)xdr_CSSM_ACL_ENTRY_INPUT))
2172 {
2173 fprintf(stderr, "%s, round %d\n", func, iter+1);
2174 return XDR_ENCODE_ERROR;
2175 }
2176 /* always zero out memory before attempting a decode */
2177 if ((xdrcopy = (CSSM_ACL_ENTRY_INPUT *)calloc(1, sizeof(CSSM_ACL_ENTRY_INPUT))) == NULL)
2178 {
2179 fprintf(stderr, "%s, round %d (allocation error)\n", func, iter+1);
2180 return MEM_ERROR;
2181 }
2182 if (!xdr_mem_decode(flattenedAclEIPtr, xdrcopy, flattenedAclEILen,
2183 (xdrproc_t)xdr_CSSM_ACL_ENTRY_INPUT))
2184 {
2185 fprintf(stderr, "%s, round %d\n", func, iter+1);
2186 return XDR_DECODE_ERROR;
2187 }
2188 if (dbglvl >= 3)
2189 printf("comparing XDR-generated structs...\n");
2190 if ((ret = compare_CSSM_ACL_ENTRY_INPUT(aclEntryInput, xdrcopy)) != OK)
2191 {
2192 fprintf(stderr, "%s: CSSM_ACL_ENTRY_INPUT old/new XDR comparison, round %d, failed\n",
2193 func, iter+1);
2194 return ret;
2195 }
2196 if (dbglvl >= 3)
2197 printf("comparing walked- and XDR-generated structs...\n");
2198 if ((ret = compare_CSSM_ACL_ENTRY_INPUT(xdrcopy, walkcopy)) != OK)
2199 {
2200 fprintf(stderr, "%s: CSSM_ACL_ENTRY_INPUT XDR/walker comparison, round %d, failed\n",
2201 func, iter+1);
2202 return ret;
2203 }
2204 if (dbglvl >= 2)
2205 printf("CSSM_ACL_ENTRY_INPUT compared OK, round %d\n", iter+1);
2206 if (iter > 0)
2207 free(aclEntryInput);
2208 aclEntryInput = xdrcopy;
2209 free(flattenedAclEIPtr);
2210 flattenedAclEIPtr = NULL;
2211 flattenedAclEILen = 0;
2212 }
2213
2214 if (dbglvl >= 1)
2215 printf("Successfully finished CSSM_ACL_ENTRY_INPUT check\n");
2216 return OK;
2217 }
2218
2219 int test_CSSM_ACL_ENTRY_INPUT(int fd, int doflip, int dbglvl)
2220 {
2221 const char *func = "test_CSSM_ACL_ENTRY_INPUT()";
2222 CSSM_ACL_ENTRY_INPUT *aclEntryInput;
2223 int ret;
2224
2225 if (fd > -1) /* cheesy hack, but what ya gonna do? */
2226 {
2227 int aclsize;
2228 uint32_t ptrsize; /* AKA mach_msg_type_number_t, AKA natural_t */
2229 intptr_t baseptr;
2230 off_t offset;
2231 /*
2232 * Saved format:
2233 * - sizeof(base pointer)
2234 * - base pointer
2235 * - length
2236 * - CSSM_ACL_ENTRY_INPUT
2237 */
2238 if (read(fd, &ptrsize, sizeof(ptrsize)) < static_cast<ssize_t>(sizeof(ptrsize)))
2239 {
2240 fprintf(stderr, "%s: Error reading base pointer size\n", func);
2241 return BAD_READ;
2242 }
2243 if (doflip) flip(&ptrsize, sizeof(ptrsize));
2244 if (read(fd, &baseptr, ptrsize) < static_cast<ssize_t>(ptrsize))
2245 {
2246 fprintf(stderr, "%s: Error reading base pointer\n", func);
2247 return BAD_READ;
2248 }
2249 if (doflip) flip(&baseptr, sizeof(baseptr));
2250 if (read(fd, &aclsize, sizeof(aclsize)) < static_cast<ssize_t>(sizeof(aclsize)))
2251 {
2252 fprintf(stderr, "%s: Error reading AclEntryInput size\n", func);
2253 return BAD_READ;
2254 }
2255 if (doflip) flip(&aclsize, sizeof(aclsize));
2256 aclEntryInput = (CSSM_ACL_ENTRY_INPUT *)malloc(aclsize);
2257 if (aclEntryInput == NULL)
2258 return MEM_ERROR;
2259 if (read(fd, aclEntryInput, aclsize) < aclsize)
2260 {
2261 fprintf(stderr, "Error reading CSSM_ACL_ENTRY_INPUT\n");
2262 return BAD_READ;
2263 }
2264 offset = reinterpret_cast<intptr_t>(aclEntryInput) - baseptr;
2265 if (doflip)
2266 {
2267 hostorder_CSSM_ACL_ENTRY_INPUT(aclEntryInput, offset);
2268 }
2269 else
2270 {
2271 ReconstituteWalker relocator(offset);
2272 walk(relocator, reinterpret_cast<AclEntryInput *&>(baseptr));
2273 }
2274 (void)close(fd);
2275 }
2276 else
2277 {
2278 /* TODO/gh cobble something up */
2279 fprintf(stderr, "%s: hard-coded test not implemented yet\n", func);
2280 return NOT_IMPLEMENTED;
2281 }
2282
2283 if ((ret = test_xdrwalk_CSSM_ACL_ENTRY_INPUT(aclEntryInput, dbglvl)) != OK)
2284 fprintf(stderr, "%s\n", func);
2285 free(aclEntryInput);
2286 return ret;
2287 }
2288
2289 int test_xdrwalk_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *aclEntryInfo,
2290 int dbglvl)
2291 {
2292 const char *func = "test_xdrwalk_CSSM_ACL_ENTRY_INFO()";
2293
2294 CSSM_ACL_ENTRY_INFO *walkcopy, *xdrcopy;
2295 void *flattenedAclEIPtr = NULL;
2296 u_int flattenedAclEILen = 0;
2297 int ret, iter;
2298
2299 /* save off aclEntryInfo because we're going to reuse the pointer */
2300 walkcopy = reinterpret_cast<CSSM_ACL_ENTRY_INFO *>(calloc(1, sizeof(CSSM_ACL_ENTRY_INFO)));
2301 if (walkcopy == NULL)
2302 {
2303 fprintf(stderr, "%s: error allocating walked CSSM_ACL_ENTRY_INFO\n", func);
2304 return MEM_ERROR;
2305 }
2306 memcpy(walkcopy, aclEntryInfo, sizeof(CSSM_ACL_ENTRY_INFO));
2307 /* right now aclEntryInfo *is* a walked copy, so no need to re-walk it */
2308 for (iter = 0; iter < N_ITERS; ++iter)
2309 {
2310 if (!xdr_mem_encode(aclEntryInfo, &flattenedAclEIPtr, &flattenedAclEILen,
2311 (xdrproc_t)xdr_CSSM_ACL_ENTRY_INFO))
2312 {
2313 fprintf(stderr, "%s, round %d\n", func, iter+1);
2314 return XDR_ENCODE_ERROR;
2315 }
2316 /* always zero out memory before attempting a decode */
2317 if ((xdrcopy = (CSSM_ACL_ENTRY_INFO *)calloc(1, sizeof(CSSM_ACL_ENTRY_INFO))) == NULL)
2318 {
2319 fprintf(stderr, "%s, round %d (allocation error)\n", func, iter+1);
2320 return MEM_ERROR;
2321 }
2322 if (!xdr_mem_decode(flattenedAclEIPtr, xdrcopy, flattenedAclEILen,
2323 (xdrproc_t)xdr_CSSM_ACL_ENTRY_INFO))
2324 {
2325 fprintf(stderr, "%s, round %d\n", func, iter+1);
2326 return XDR_DECODE_ERROR;
2327 }
2328 if (dbglvl >= 3)
2329 printf("comparing XDR-generated structs...\n");
2330 if ((ret = compare_CSSM_ACL_ENTRY_INFO(aclEntryInfo, xdrcopy)) != OK)
2331 {
2332 fprintf(stderr, "%s: CSSM_ACL_ENTRY_INFO old/new XDR comparison, round %d, failed\n",
2333 func, iter+1);
2334 return ret;
2335 }
2336 if (dbglvl >= 3)
2337 printf("comparing walked- and XDR-generated structs...\n");
2338 if ((ret = compare_CSSM_ACL_ENTRY_INFO(xdrcopy, walkcopy)) != OK)
2339 {
2340 fprintf(stderr, "%s: CSSM_ACL_ENTRY_INFO XDR/walker comparison, round %d, failed\n",
2341 func, iter+1);
2342 return ret;
2343 }
2344 if (dbglvl >= 2)
2345 printf("CSSM_ACL_ENTRY_INFO compared OK, round %d\n", iter+1);
2346 if (iter > 0)
2347 free(aclEntryInfo);
2348 aclEntryInfo = xdrcopy;
2349 free(flattenedAclEIPtr);
2350 flattenedAclEIPtr = NULL;
2351 flattenedAclEILen = 0;
2352 }
2353 if (dbglvl >= 1)
2354 printf("Successfully finished CSSM_ACL_ENTRY_INFO check\n");
2355 return OK;
2356 }
2357
2358 int test_CSSM_ACL_ENTRY_INFO(int fd, int doflip, int dbglvl)
2359 {
2360 const char *func = "test_CSSM_ACL_ENTRY_INFO()";
2361 CSSM_ACL_ENTRY_INFO *aclEntryInfo;
2362 int ret, aclsize;
2363
2364 if (fd > -1) /* cheesy hack, but what ya gonna do? */
2365 {
2366 uint32_t ptrsize; /* AKA mach_msg_type_number_t, AKA natural_t */
2367 intptr_t baseptr;
2368 off_t offset;
2369 /*
2370 * Saved format (v. 1 of saved-data protocol):
2371 * - preamble
2372 * - sizeof(base pointer)
2373 * - base pointer
2374 * - length
2375 * - CSSM_ACL_ENTRY_INFO
2376 */
2377
2378 if (read(fd, &ptrsize, sizeof(ptrsize)) < static_cast<ssize_t>(sizeof(ptrsize)))
2379 {
2380 fprintf(stderr, "%s: Error reading base pointer size\n", func);
2381 return BAD_READ;
2382 }
2383 if (doflip) flip(&ptrsize, sizeof(ptrsize));
2384 if (read(fd, &baseptr, ptrsize) < static_cast<ssize_t>(ptrsize))
2385 {
2386 fprintf(stderr, "%s: Error reading base pointer\n", func);
2387 return BAD_READ;
2388 }
2389 if (doflip) flip(&baseptr, sizeof(baseptr));
2390 if (read(fd, &aclsize, sizeof(aclsize)) < static_cast<ssize_t>(sizeof(aclsize)))
2391 {
2392 fprintf(stderr, "%s: Error reading AclEntryInput size\n", func);
2393 return BAD_READ;
2394 }
2395 if (doflip) flip(&aclsize, sizeof(aclsize));
2396 aclEntryInfo = (CSSM_ACL_ENTRY_INFO *)malloc(aclsize);
2397 if (aclEntryInfo == NULL)
2398 return MEM_ERROR;
2399 if (read(fd, aclEntryInfo, aclsize) < aclsize)
2400 {
2401 fprintf(stderr, "Error reading CSSM_ACL_ENTRY_INFO\n");
2402 return BAD_READ;
2403 }
2404 offset = reinterpret_cast<intptr_t>(aclEntryInfo) - baseptr;
2405 if (doflip)
2406 {
2407 hostorder_CSSM_ACL_ENTRY_INFO(aclEntryInfo, offset);
2408 }
2409 else
2410 {
2411 ReconstituteWalker relocator(offset);
2412 walk(relocator, reinterpret_cast<AclEntryInput *&>(baseptr));
2413 }
2414 (void)close(fd);
2415 }
2416 else
2417 {
2418 /* TODO/gh cobble something up */
2419 fprintf(stderr, "%s: hard-coded test not implemented yet\n", func);
2420 return NOT_IMPLEMENTED;
2421 }
2422 if ((ret = test_xdrwalk_CSSM_ACL_ENTRY_INFO(aclEntryInfo, dbglvl)) != OK)
2423 fprintf(stderr, "%s\n", func);
2424 free(aclEntryInfo);
2425 return ret;
2426 }
2427
2428 int test_xdrwalk_CSSM_QUERY(CSSM_QUERY *query, int dbglvl)
2429 {
2430 const char *func = "test_xdrwalk_CSSM_QUERY()";
2431
2432 CSSM_QUERY *walkcopy, *xdrcopy;
2433 void *flattenedQueryPtr = NULL;
2434 u_int flattenedQueryLen = 0;
2435 int ret, iter;
2436
2437 /* save off query because we're going to reuse the pointer */
2438 walkcopy = reinterpret_cast<CSSM_QUERY *>(calloc(1, sizeof(CSSM_QUERY)));
2439 if (walkcopy == NULL)
2440 {
2441 fprintf(stderr, "%s: error allocating walked CSSM_QUERY\n", func);
2442 return MEM_ERROR;
2443 }
2444 memcpy(walkcopy, query, sizeof(CSSM_QUERY));
2445 /* right now query *is* a walked copy, so no need to re-walk it */
2446 for (iter = 0; iter < N_ITERS; ++iter)
2447 {
2448 if (!xdr_mem_encode(query, &flattenedQueryPtr, &flattenedQueryLen,
2449 (xdrproc_t)xdr_CSSM_QUERY))
2450 {
2451 fprintf(stderr, "%s, round %d\n", func, iter+1);
2452 return XDR_ENCODE_ERROR;
2453 }
2454 /* always zero out memory before attempting a decode */
2455 if ((xdrcopy = (CSSM_QUERY *)calloc(1, sizeof(CSSM_QUERY))) == NULL)
2456 {
2457 fprintf(stderr, "%s, round %d (allocation error)\n", func, iter+1);
2458 return MEM_ERROR;
2459 }
2460 if (!xdr_mem_decode(flattenedQueryPtr, xdrcopy, flattenedQueryLen,
2461 (xdrproc_t)xdr_CSSM_QUERY))
2462 {
2463 fprintf(stderr, "%s, round %d\n", func, iter+1);
2464 return XDR_DECODE_ERROR;
2465 }
2466 if (dbglvl >= 3)
2467 printf("comparing XDR-generated structs...\n");
2468 if ((ret = compare_CSSM_QUERY(query, xdrcopy)) != OK)
2469 {
2470 fprintf(stderr, "%s: CSSM_QUERY old/new XDR comparison, round %d, failed\n",
2471 func, iter+1);
2472 return ret;
2473 }
2474 if (dbglvl >= 3)
2475 printf("comparing walked- and XDR-generated structs...\n");
2476 if ((ret = compare_CSSM_QUERY(xdrcopy, walkcopy)) != OK)
2477 {
2478 fprintf(stderr, "%s: CSSM_QUERY XDR/walker comparison, round %d, failed\n",
2479 func, iter+1);
2480 return ret;
2481 }
2482 if (dbglvl >= 2)
2483 printf("CSSM_QUERY compared OK, round %d\n", iter+1);
2484 if (iter > 0)
2485 free(query);
2486 query = xdrcopy;
2487 free(flattenedQueryPtr);
2488 flattenedQueryPtr = NULL;
2489 flattenedQueryLen = 0;
2490 }
2491 if (dbglvl >= 1)
2492 printf("Successfully finished CSSM_QUERY check\n");
2493 return OK;
2494 }
2495
2496 int test_CSSM_QUERY(int fd, int doflip, int dbglvl)
2497 {
2498 const char *func = "test_CSSM_QUERY()";
2499 CSSM_QUERY *query;
2500 int ret, querysize;
2501
2502 if (fd > -1) /* cheesy hack, but what ya gonna do? */
2503 {
2504 uint32_t ptrsize; /* AKA mach_msg_type_number_t, AKA natural_t */
2505 intptr_t baseptr;
2506 off_t offset;
2507 ssize_t readPtr;
2508 int nq = 0; /* # of queries */
2509 /*
2510 * Saved format (v. 1 of saved-data protocol):
2511 * - preamble
2512 * - sizeof(base pointer)
2513 * - base pointer
2514 * - length
2515 * - CSSM_QUERY
2516 */
2517 do
2518 {
2519 if (nq) /* first readPreamble() was in main() */
2520 {
2521 /* dummy vars -- let the func params govern */
2522 uint32_t d1, d2, d3 = 0;
2523 if ((ret = readPreamble(fd, &d1, &d2, &d3)) != OK)
2524 {
2525 if (ret == READ_EOF)
2526 {
2527 readPtr = -1;
2528 continue;
2529 }
2530 return ret;
2531 }
2532 }
2533 readPtr = read(fd, &ptrsize, sizeof(ptrsize));
2534 if (readPtr == 0) break; /* we're done */
2535 if (readPtr < static_cast<ssize_t>(sizeof(ptrsize)))
2536 {
2537 fprintf(stderr, "%s: Error reading base pointer size\n", func);
2538 return BAD_READ;
2539 }
2540 if (doflip) flip(&ptrsize, sizeof(ptrsize));
2541 if (read(fd, &baseptr, ptrsize) < static_cast<ssize_t>(ptrsize))
2542 {
2543 fprintf(stderr, "%s: Error reading base pointer\n", func);
2544 return BAD_READ;
2545 }
2546 if (doflip) flip(&baseptr, sizeof(baseptr));
2547 if (read(fd, &querysize, sizeof(querysize)) < static_cast<ssize_t>(sizeof(querysize)))
2548 {
2549 fprintf(stderr, "%s: Error reading CSSM_QUERY size\n", func);
2550 return BAD_READ;
2551 }
2552 if (doflip) flip(&querysize, sizeof(querysize));
2553 query = (CSSM_QUERY *)malloc(querysize);
2554 if (query == NULL)
2555 return MEM_ERROR;
2556 if (read(fd, query, querysize) < querysize)
2557 {
2558 fprintf(stderr, "Error reading CSSM_QUERY\n");
2559 return BAD_READ;
2560 }
2561 offset = reinterpret_cast<intptr_t>(query) - baseptr;
2562 if (doflip)
2563 {
2564 hostorder_CSSM_QUERY(query, offset);
2565 }
2566 else
2567 {
2568 ReconstituteWalker relocator(offset);
2569 walk(relocator, reinterpret_cast<CssmQuery *&>(baseptr));
2570 }
2571 ++nq;
2572 if (dbglvl >= 2)
2573 printf("%s: read a new CSSM_QUERY (%d)\n", func, nq);
2574 if ((ret = test_xdrwalk_CSSM_QUERY(query, dbglvl)) != OK)
2575 fprintf(stderr, "%s\n", func);
2576 free(query);
2577 }
2578 while (readPtr != -1);
2579 (void)close(fd);
2580 }
2581 else
2582 {
2583 /* TODO/gh cobble something up */
2584 fprintf(stderr, "%s: hard-coded test not implemented yet\n", func);
2585 return NOT_IMPLEMENTED;
2586 }
2587 return OK;
2588 }
2589
2590 void usage(const char *progname)
2591 {
2592 fprintf(stderr, "Usage: %s [-c|-I|-i] <FILE>\n", progname);
2593 fprintf(stderr, " FILE is binary data saved from securityd\n");
2594 fprintf(stderr, " -c\trun hard-coded CSSM_CONTEXT test\n");
2595 fprintf(stderr, " -i\trun hard-coded CSSM_ACL_ENTRY_INFO test\n");
2596 fprintf(stderr, " -I\trun hard-coded CSSM_ACL_ENTRY_INPUT test\n");
2597 fprintf(stderr, " -v\tverbose (more -v options mean more output\n");
2598 fprintf(stderr, " If FILE is not provided, %s will try to run any requested hard-coded test\n", progname);
2599 }
2600
2601 int main(int ac, char **av)
2602 {
2603 const char *optstring = "chIiv";
2604 char *infile = NULL;
2605 int c, fd, ret = OK, debuglevel = 0;
2606 uint32_t doflip, version, type = 0;
2607
2608 while ((c = getopt(ac, av, optstring)) != EOF)
2609 {
2610 switch(c)
2611 {
2612 case 'c':
2613 type = SecuritydDataSave::CONTEXT;
2614 break;
2615 case 'I':
2616 type = SecuritydDataSave::ACL_ENTRY_INPUT;
2617 break;
2618 case 'i':
2619 type = SecuritydDataSave::ACL_ENTRY_INFO;
2620 break;
2621 case 'h':
2622 usage(av[0]);
2623 exit(0);
2624 break;
2625 case 'v':
2626 debuglevel++;
2627 break;
2628 default:
2629 break;
2630 }
2631 }
2632 ac -= optind;
2633 av += optind;
2634 if (ac >= 1)
2635 {
2636 infile = av[0]; /* XXX/gh need to validate av[0]? */
2637 if ((fd = open(infile, O_RDONLY, 0)) < 0)
2638 {
2639 fprintf(stderr, "Couldn't open %s (%s)\n", infile, strerror(errno));
2640 return 2;
2641 }
2642 if ((ret = readPreamble(fd, &doflip, &version, &type)) != OK)
2643 return ret;
2644 }
2645 else
2646 {
2647 fd = -1; /* use a hard-coded test */
2648 if (!type)
2649 {
2650 type = SecuritydDataSave::CONTEXT; /* the only test that has hard-coded data...*/
2651 fprintf(stderr, "*** running hard-coded CSSM_CONTEXT test\n");
2652 }
2653 }
2654 switch (type)
2655 {
2656 case SecuritydDataSave::CONTEXT:
2657 ret = test_CSSM_CONTEXT(fd, doflip, debuglevel);
2658 break;
2659 case SecuritydDataSave::ACL_OWNER_PROTOTYPE:
2660 ret = test_CSSM_ACL_OWNER_PROTOTYPE(fd, doflip, debuglevel);
2661 break;
2662 case SecuritydDataSave::ACL_ENTRY_INPUT:
2663 ret = test_CSSM_ACL_ENTRY_INPUT(fd, doflip, debuglevel);
2664 break;
2665 case SecuritydDataSave::ACL_ENTRY_INFO:
2666 ret = test_CSSM_ACL_ENTRY_INFO(fd, doflip, debuglevel);
2667 break;
2668 case SecuritydDataSave::QUERY:
2669 ret = test_CSSM_QUERY(fd, doflip, debuglevel);
2670 break;
2671 default:
2672 fprintf(stderr, "Unrecognized test\n");
2673 ret = NOT_IMPLEMENTED;
2674 }
2675 return ret;
2676 }