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 23using Security::DataWalkers::Copier; 24 25const 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 82extern "C" { 83extern 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 */ 112bool_t xdr_stdio(void *data, xdrproc_t proc, enum xdr_op op); /* XXX/gh needed? */ 113bool_t xdr_mem_encode(void *input, void **output, u_int *outlen, 114 xdrproc_t proc); 115bool_t xdr_mem_decode(void *input, void *output, u_int bytesNeeded, 116 xdrproc_t proc); 117void flip(uint8_t *addr, size_t size); 118int readPreamble(int fd, uint32_t *doflip, uint32_t *vers, uint32_t *type); 119int 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 */ 125void hostorder_CSSM_DATA(CSSM_DATA *data, off_t offset); 126void hostorder_CSSM_GUID(CSSM_GUID *guid); 127void hostorder_CSSM_VERSION(CSSM_VERSION *version); 128void hostorder_CSSM_SUBSERVICE_UID(CSSM_SUBSERVICE_UID *ssuid); 129void hostorder_CSSM_CRYPTO_DATA(CSSM_CRYPTO_DATA *crypto, off_t offset); 130void hostorder_CSSM_LIST(CSSM_LIST *list, off_t offset); 131void hostorder_CSSM_LIST_ELEMENT(CSSM_LIST_ELEMENT *element, off_t offset); 132void hostorder_CSSM_SAMPLE(CSSM_SAMPLE *sample, off_t offset); 133void hostorder_CSSM_SAMPLEGROUP(CSSM_SAMPLEGROUP *sgrp, off_t offset); 134void hostorder_CSSM_ENCODED_CERT(CSSM_ENCODED_CERT *cert, off_t offset); 135void hostorder_CSSM_CERTGROUP(CSSM_CERTGROUP *grp, off_t offset); 136void hostorder_CSSM_BASE_CERTS(CSSM_BASE_CERTS *certs, off_t offset); 137void hostorder_CSSM_ACCESS_CREDENTIALS(CSSM_ACCESS_CREDENTIALS *creds, 138 off_t offset); 139void hostorder_CSSM_AUTHORIZATIONGROUP(CSSM_AUTHORIZATIONGROUP *grp, 140 off_t offset); 141void hostorder_CSSM_ACL_VALIDITY_PERIOD(CSSM_ACL_VALIDITY_PERIOD *period, 142 off_t offset); 143void hostorder_CSSM_ACL_ENTRY_PROTOTYPE(CSSM_ACL_ENTRY_PROTOTYPE *proto, 144 off_t offset); 145void hostorder_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *proto, 146 off_t offset); 147void hostorder_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *input, off_t offset); 148void hostorder_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *info, off_t offset); 149void hostorder_CSSM_KEYHEADER(CSSM_KEYHEADER *key); 150void hostorder_CSSM_KEY(CSSM_KEY *key, off_t offset); 151void hostorder_CSSM_DL_DB_HANDLE(CSSM_DL_DB_HANDLE *handle); 152void hostorder_CSSM_RANGE(CSSM_RANGE *range); 153void hostorder_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr, 154 off_t offset); 155void hostorder_CSSM_CONTEXT(CSSM_CONTEXT *ctx, CSSM_CONTEXT_ATTRIBUTE *attrs); 156void hostorder_CSSM_OID(CSSM_OID *oid, off_t offset); 157void hostorder_CSSM_DB_ATTRIBUTE_INFO(CSSM_DB_ATTRIBUTE_INFO *attrinfo, 158 off_t offset); 159void hostorder_CSSM_DB_ATTRIBUTE_DATA(CSSM_DB_ATTRIBUTE_DATA *attrdata, 160 off_t offset); 161void hostorder_CSSM_SELECTION_PREDICATE(CSSM_SELECTION_PREDICATE *pred, 162 off_t offset); 163void hostorder_CSSM_QUERY_LIMITS(CSSM_QUERY_LIMITS *limits); 164void hostorder_CSSM_QUERY(CSSM_QUERY *range, off_t offset); 165 166/* comparators */ 167int compare_CSSM_DATA(CSSM_DATA *data1, CSSM_DATA *data2); 168int compare_CSSM_SUBSERVICE_UID(const CSSM_SUBSERVICE_UID *ssuid1, 169 const CSSM_SUBSERVICE_UID *ssuid2); 170int compare_CSSM_CRYPTO_DATA(CSSM_CRYPTO_DATA *data1, CSSM_CRYPTO_DATA *data2); 171int compare_CSSM_LIST(const CSSM_LIST *list1, const CSSM_LIST *list2); 172int compare_CSSM_SAMPLE(const CSSM_SAMPLE *sample1, const CSSM_SAMPLE *sample2); 173int compare_CSSM_SAMPLEGROUP(CSSM_SAMPLEGROUP *sgrp1, CSSM_SAMPLEGROUP *sgrp2); 174int compare_CSSM_ENCODED_CERT(CSSM_ENCODED_CERT *cert1, 175 CSSM_ENCODED_CERT *cert2); 176int compare_CSSM_CERTGROUP(CSSM_CERTGROUP *grp1, CSSM_CERTGROUP *grp2); 177int compare_CSSM_BASE_CERTS(CSSM_BASE_CERTS *bases1, CSSM_BASE_CERTS *bases2); 178int compare_CSSM_ACCESS_CREDENTIALS(CSSM_ACCESS_CREDENTIALS *creds1, 179 CSSM_ACCESS_CREDENTIALS *creds2); 180int compare_CSSM_AUTHORIZATIONGROUP(CSSM_AUTHORIZATIONGROUP *grp1, 181 CSSM_AUTHORIZATIONGROUP *grp2); 182int compare_CSSM_ACL_VALIDITY_PERIOD(CSSM_ACL_VALIDITY_PERIOD *period1, 183 CSSM_ACL_VALIDITY_PERIOD *period2); 184int compare_CSSM_ACL_ENTRY_PROTOTYPE(CSSM_ACL_ENTRY_PROTOTYPE *proto1, 185 CSSM_ACL_ENTRY_PROTOTYPE *proto2, 186 int skipGarbage); 187int compare_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *proto1, 188 CSSM_ACL_OWNER_PROTOTYPE *proto2); 189int compare_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *input1, 190 CSSM_ACL_ENTRY_INPUT *input2); 191int compare_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *info1, 192 CSSM_ACL_ENTRY_INFO *info2); 193int compare_CSSM_DATE(CSSM_DATE *date1, CSSM_DATE *date2); 194int compare_CSSM_KEYHEADER(CSSM_KEYHEADER *hdr1, CSSM_KEYHEADER *hdr2); 195int compare_CSSM_KEY(CSSM_KEY *key1, CSSM_KEY *key2); 196int compare_CSSM_RANGE(CSSM_RANGE *range1, CSSM_RANGE *range2); 197int compare_CSSM_CONTEXT_ATTRIBUTE(CSSM_CONTEXT_ATTRIBUTE *attr1, 198 CSSM_CONTEXT_ATTRIBUTE *attr2); 199int compare_CSSM_OID(CSSM_OID *oid1, CSSM_OID *oid2); 200int compare_CSSM_CONTEXT(CSSM_CONTEXT *ctx1, CSSM_CONTEXT *ctx2); 201int compare_CSSM_DB_ATTRIBUTE_INFO(CSSM_DB_ATTRIBUTE_INFO *attrinfo1, 202 CSSM_DB_ATTRIBUTE_INFO *attrinfo2); 203int compare_CSSM_DB_ATTRIBUTE_DATA(CSSM_DB_ATTRIBUTE_DATA *attrdata1, 204 CSSM_DB_ATTRIBUTE_DATA *attrdata2); 205int compare_CSSM_SELECTION_PREDICATE(CSSM_SELECTION_PREDICATE *pred1, 206 CSSM_SELECTION_PREDICATE *pred2); 207int compare_CSSM_QUERY_LIMITS(CSSM_QUERY_LIMITS *limits1, 208 CSSM_QUERY_LIMITS *limits2); 209int compare_CSSM_QUERY(CSSM_QUERY *query1, CSSM_QUERY *query2); 210 211CSSM_RETURN dummyCSSMCallback(CSSM_DATA *data, void *context); 212CSSM_RETURN dummyACLSubjectCallback(const CSSM_LIST *subjectRequest, 213 void *callerContext, 214 const CSSM_MEMORY_FUNCS *MemFuncs); 215 216/* the actual test functions */ 217int test_CSSM_DB_RECORD_ATTRIBUTE_DATA(const char *srcfile); /* TODO/gh */ 218int test_xdrwalk_CSSM_CONTEXT(CSSM_CONTEXT *ctx, int dbglvl); 219int test_CSSM_CONTEXT(int fd, int doflip, int dbglvl); 220int test_xdrwalk_CSSM_ACL_OWNER_PROTOTYPE(CSSM_ACL_OWNER_PROTOTYPE *aclOwnerPrototype, int dbglvl); 221int test_CSSM_ACL_OWNER_PROTOTYPE(int fd, int doflip, int dbglvl); 222int test_xdrwalk_CSSM_ACL_ENTRY_INPUT(CSSM_ACL_ENTRY_INPUT *aclEntryInput, 223 int dbglvl); 224int test_CSSM_ACL_ENTRY_INPUT(int fd, int doflip, int dbglvl); 225int test_xdrwalk_CSSM_ACL_ENTRY_INFO(CSSM_ACL_ENTRY_INFO *aclEntryInfo, 226 int dbglvl); 227int test_CSSM_ACL_ENTRY_INFO(int fd, int doflip, int dbglvl); 228int test_xdrwalk_CSSM_QUERY(CSSM_QUERY *query, int dbglvl); 229int 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 *? */ 238bool_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 */ 249bool_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 */ 276bool_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 */ 291void 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 */ 310int 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 366int 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 424void 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 438void 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 446void 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 453void 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 462void 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 470void 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 499void 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 529void 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 545void 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 564void 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 572void 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 631void 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 639void 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 658void 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 665void 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 672void 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 681void 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 688void 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 694void 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 704void 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 720void 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 727void 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 738void 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 745void 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 799void 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 825void hostorder_CSSM_OID(CSSM_OID *oid, off_t offset) 826{ 827 hostorder_CSSM_DATA(reinterpret_cast<CSSM_DATA *>(oid), offset); 828} 829 830void 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 857void 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 871void 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 879void 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 886void 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 925int 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 939int 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 956int 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 976int 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 1041int 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 1071int 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 1095int 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 1113int 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 1175int 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 1196int 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 1225int 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 1240int 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 1259int 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 1304int 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 1324int 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 1348int 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 1375int 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 1388int 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 1422int 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 1441int 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 1454int 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 1534int 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 1565int 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() */ 1572int 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 1611int 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 1642int 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 1660int 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 1675int 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 1705CSSM_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 */ 1716CSSM_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 */ 1743int 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 1765int 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 1869int 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 2008int 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 2079int 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 2149int 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 2219int 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 2289int 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 2358int 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 2428int 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 2496int 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 2590void 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 2601int 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} 2677