1/* 2 * Copyright (c) 2006-2008,2011-2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <architecture/byte_order.h> 25#include <string.h> /* bzero() */ 26#include <stdlib.h> /* exit() */ 27#include <assert.h> /* assert() */ 28#include <stdio.h> /* XXX/gh because utilities/debugging.h doesn't */ 29#include <security_utilities/debugging.h> 30 31#include "xdr_cssm.h" 32 33// All functions with the "writes" comment write to memory without regard for size only operation. This is okay as long as they aren't used "naked", ie. as toplevel encoders. For our purposes they're always in a struct or array, or with a pointer pointing at them. 34 35// XXX/cs writes 36bool_t sec_xdr_clip_long(XDR *xdrs, long *objp) 37{ 38 uint32_t clip = 0; 39 40 if (objp && xdrs->x_op == XDR_ENCODE) 41 clip = *objp & UINT32_MAX; 42 if (!xdr_uint32(xdrs, &clip)) 43 return (FALSE); 44 if (objp && xdrs->x_op == XDR_DECODE) 45 *objp = clip; 46 return (TRUE); 47} 48 49// XXX/cs writes 50bool_t xdr_voidptr(XDR *xdrs, void **objp) 51{ 52 long ptr = 0; 53 54 if (*objp) 55 ptr = (intptr_t)*objp; 56 if (!sec_xdr_clip_long(xdrs, &ptr)) 57 return (FALSE); 58 // not returned 59 60 return (TRUE); 61} 62 63bool_t xdr_CSSM_DATA(XDR *xdrs, CSSM_DATA *objp) 64{ 65 u_int valueLength; // objp->Length is a size_t 66 if (xdrs->x_op == XDR_ENCODE) { 67 if (objp->Length > (u_int)~0) 68 return (FALSE); 69 valueLength = (u_int)objp->Length; 70 } 71 if (!sec_xdr_bytes(xdrs, &objp->Data, &valueLength, ~0)) 72 return (FALSE); 73 if (xdrs->x_op == XDR_DECODE) 74 objp->Length = valueLength; 75 return (TRUE); 76} 77 78bool_t xdr_CSSM_GUID(XDR *xdrs, CSSM_GUID *objp) 79{ 80 return xdr_opaque(xdrs, (char *)objp, sizeof(CSSM_GUID)); 81} 82 83bool_t xdr_CSSM_VERSION(XDR *xdrs, CSSM_VERSION *objp) 84{ 85 if (!xdr_uint32(xdrs, &objp->Major)) 86 return (FALSE); 87 if (!xdr_uint32(xdrs, &objp->Minor)) 88 return (FALSE); 89 return (TRUE); 90} 91 92bool_t xdr_CSSM_SUBSERVICE_UID(XDR *xdrs, CSSM_SUBSERVICE_UID *objp) 93{ 94 if (!xdr_CSSM_GUID(xdrs, &objp->Guid)) 95 return (FALSE); 96 if (!xdr_CSSM_VERSION(xdrs, &objp->Version)) 97 return (FALSE); 98 if (!xdr_uint32(xdrs, &objp->SubserviceId)) 99 return (FALSE); 100 if (!xdr_CSSM_SERVICE_TYPE(xdrs, &objp->SubserviceType)) 101 return (FALSE); 102 return (TRUE); 103} 104 105bool_t xdr_CSSM_NET_ADDRESS(XDR *xdrs, CSSM_NET_ADDRESS *objp) 106{ 107 if (!xdr_CSSM_NET_ADDRESS_TYPE(xdrs, &objp->AddressType)) 108 return (FALSE); 109 if (!xdr_CSSM_DATA(xdrs, &objp->Address)) 110 return (FALSE); 111 return (TRUE); 112} 113 114// XXX/cs crypto_data will automagically send callback data when necessary, on the pass out it will reappear in Param, which is also the alternative data sent. So Callback!=NULL means Param is crypto callback data, otherwise it is param data. 115bool_t xdr_CSSM_CRYPTO_DATA(XDR *xdrs, CSSM_CRYPTO_DATA *objp) 116{ 117 void *cb = (void *)objp->Callback; 118 if (!xdr_voidptr(xdrs, &cb)) 119 return (FALSE); 120 if (!xdr_voidptr(xdrs, &objp->CallerCtx)) 121 return (FALSE); 122 123 // Encode callback result if existing, otherwise just param 124 // Result comes back in Param 125 if (xdrs->x_op == XDR_ENCODE && objp->Callback) 126 { 127 CSSM_CALLBACK func = objp->Callback; 128 CSSM_DATA data; 129 CSSM_RETURN err; 130 if ((err = func(&data, objp->CallerCtx))) 131 return (FALSE); // XXX/cs meaningfully return err 132 if (!xdr_CSSM_DATA(xdrs, &data)) 133 return (FALSE); 134 } 135 else 136 { 137 if (!xdr_CSSM_DATA(xdrs, &objp->Param)) 138 return (FALSE); 139 } 140 return (TRUE); 141} 142 143bool_t inline xdr_CSSM_LIST_ELEMENT(XDR *xdrs, CSSM_LIST_ELEMENT *objp) 144{ 145 if (!xdr_CSSM_WORDID_TYPE(xdrs, &objp->WordID)) 146 return (FALSE); 147 if (!xdr_CSSM_LIST_ELEMENT_TYPE(xdrs, &objp->ElementType)) 148 return (FALSE); 149 switch(objp->ElementType) { 150 case CSSM_LIST_ELEMENT_DATUM: 151 if (!xdr_CSSM_DATA(xdrs, &objp->Element.Word)) return (FALSE); break; 152 case CSSM_LIST_ELEMENT_SUBLIST: 153 if (!xdr_CSSM_LIST(xdrs, &objp->Element.Sublist)) return (FALSE); break; 154 case CSSM_LIST_ELEMENT_WORDID: 155 break; 156 default: 157 secdebug("secxdr", "Illegal CSSM_LIST_ELEMENT type: %u", objp->ElementType); return (FALSE); 158 } 159 160 if (!sec_xdr_pointer(xdrs, (uint8_t**)&objp->NextElement, sizeof(CSSM_LIST_ELEMENT), (xdrproc_t)xdr_CSSM_LIST_ELEMENT)) 161 return (FALSE); 162 163 return (TRUE); 164} 165 166bool_t xdr_CSSM_LIST(XDR *xdrs, CSSM_LIST *objp) 167{ 168 if (!xdr_CSSM_LIST_TYPE(xdrs, &objp->ListType)) 169 return (FALSE); 170 if (!sec_xdr_pointer(xdrs, (uint8_t**)&objp->Head, sizeof(CSSM_LIST_ELEMENT), (xdrproc_t)xdr_CSSM_LIST_ELEMENT)) 171 return (FALSE); 172 // if we're restoring things, make sure to fix up Tail to point 173 // to the right place 174 if (xdrs->x_op == XDR_DECODE) 175 { 176 bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs); 177 if (!size_alloc) 178 for (objp->Tail = objp->Head; objp->Tail && objp->Tail->NextElement; objp->Tail = objp->Tail->NextElement); 179 } 180 return (TRUE); 181} 182 183bool_t xdr_CSSM_SAMPLE(XDR *xdrs, CSSM_SAMPLE *objp) 184{ 185 if (!xdr_CSSM_LIST(xdrs, &objp->TypedSample)) 186 return (FALSE); 187 if (!sec_xdr_pointer(xdrs, (uint8_t**)&objp->Verifier, sizeof(CSSM_SUBSERVICE_UID), (xdrproc_t)xdr_CSSM_SUBSERVICE_UID)) 188 return (FALSE); 189 return (TRUE); 190} 191 192bool_t xdr_CSSM_SAMPLEGROUP(XDR *xdrs, CSSM_SAMPLEGROUP *objp) 193{ 194 assert(sizeof(objp->NumberOfSamples) == sizeof(int)); 195 if (!sec_xdr_array(xdrs, (uint8_t**)&objp->Samples, (u_int *)&objp->NumberOfSamples, ~0, sizeof(CSSM_SAMPLE), (xdrproc_t)xdr_CSSM_SAMPLE)) 196 return (FALSE); 197 return (TRUE); 198} 199 200bool_t xdr_CSSM_ENCODED_CERT(XDR *xdrs, CSSM_ENCODED_CERT *objp) 201{ 202 203 if (!xdr_CSSM_CERT_TYPE(xdrs, &objp->CertType)) 204 return (FALSE); 205 if (!xdr_CSSM_CERT_ENCODING(xdrs, &objp->CertEncoding)) 206 return (FALSE); 207 if (!xdr_CSSM_DATA(xdrs, &objp->CertBlob)) 208 return (FALSE); 209 return (TRUE); 210} 211 212bool_t xdr_CSSM_CERTGROUP(XDR *xdrs, CSSM_CERTGROUP *objp) 213{ 214 if (!xdr_CSSM_CERT_TYPE(xdrs, &objp->CertType)) 215 return (FALSE); 216 if (!xdr_CSSM_CERT_ENCODING(xdrs, &objp->CertEncoding)) 217 return (FALSE); 218 219 // NumCerts encoded as part of sec_xdr_array below (we need it 220 // before the switch on decode) 221 if (!xdr_CSSM_CERTGROUP_TYPE(xdrs, &objp->CertGroupType)) 222 return (FALSE); 223 224 switch (objp->CertGroupType) { 225 case CSSM_CERTGROUP_DATA: 226 if (!sec_xdr_array(xdrs, (uint8_t**)&objp->GroupList.CertList, &objp->NumCerts, ~0, sizeof(CSSM_DATA), (xdrproc_t)xdr_CSSM_DATA)) 227 return (FALSE); 228 break; 229 case CSSM_CERTGROUP_ENCODED_CERT: 230 if (!sec_xdr_array(xdrs, (uint8_t**)&objp->GroupList.EncodedCertList, 231 &objp->NumCerts, ~0, 232 sizeof(CSSM_ENCODED_CERT), (xdrproc_t)xdr_CSSM_ENCODED_CERT)) 233 return (FALSE); 234 break; 235 case CSSM_CERTGROUP_PARSED_CERT: // unimplemented -> there are no walkers for it 236 case CSSM_CERTGROUP_CERT_PAIR: // unimplemented -> there are no walkers for it 237 assert(FALSE); 238 default: 239 return (FALSE); 240 } 241 242 if (!xdr_voidptr(xdrs, &objp->Reserved)) 243 return (FALSE); 244 return (TRUE); 245} 246 247bool_t xdr_CSSM_BASE_CERTS(XDR *xdrs, CSSM_BASE_CERTS *objp) 248{ 249 if (!xdr_CSSM_TP_HANDLE(xdrs, &objp->TPHandle)) 250 return (FALSE); 251 if (!xdr_CSSM_CL_HANDLE(xdrs, &objp->CLHandle)) 252 return (FALSE); 253 if (!xdr_CSSM_CERTGROUP(xdrs, &objp->Certs)) 254 return (FALSE); 255 return (TRUE); 256} 257 258bool_t xdr_CSSM_ACCESS_CREDENTIALS(XDR *xdrs, CSSM_ACCESS_CREDENTIALS *objp) 259{ 260 // XXX/cs this was for executing the callback but we're not doing that apparently void *cb = (void *)objp->Callback; 261 262 if (!xdr_CSSM_STRING(xdrs, objp->EntryTag)) 263 return (FALSE); 264 if (!xdr_CSSM_BASE_CERTS(xdrs, &objp->BaseCerts)) 265 return (FALSE); 266 if (!xdr_CSSM_SAMPLEGROUP(xdrs, &objp->Samples)) 267 return (FALSE); 268 // @@@ treating both Callback and CallerCtx like intptr_t 269 // in case it ever turns into a magic cookie 270 if (!xdr_voidptr(xdrs, (void *)&objp->Callback)) 271 return (FALSE); 272 if (!xdr_voidptr(xdrs, &objp->CallerCtx)) 273 return (FALSE); 274 275 return (TRUE); 276} 277 278bool_t xdr_CSSM_ACCESS_CREDENTIALS_PTR(XDR *xdrs, CSSM_ACCESS_CREDENTIALS_PTR *objp) 279{ 280 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_ACCESS_CREDENTIALS), (xdrproc_t)xdr_CSSM_ACCESS_CREDENTIALS); 281} 282 283bool_t xdr_CSSM_AUTHORIZATIONGROUP(XDR *xdrs, CSSM_AUTHORIZATIONGROUP *objp) 284{ 285 assert(sizeof(objp->NumberOfAuthTags) == sizeof(int)); 286 if (!sec_xdr_array(xdrs, (uint8_t **)&objp->AuthTags, (u_int *)&objp->NumberOfAuthTags, ~0, sizeof(CSSM_ACL_AUTHORIZATION_TAG), (xdrproc_t)xdr_CSSM_ACL_AUTHORIZATION_TAG)) 287 return (FALSE); 288 return (TRUE); 289} 290 291bool_t xdr_CSSM_ACL_VALIDITY_PERIOD(XDR *xdrs, CSSM_ACL_VALIDITY_PERIOD *objp) 292{ 293 if (!xdr_CSSM_DATA(xdrs, &objp->StartDate)) 294 return (FALSE); 295 if (!xdr_CSSM_DATA(xdrs, &objp->EndDate)) 296 return (FALSE); 297 return (TRUE); 298} 299 300bool_t xdr_CSSM_ACL_ENTRY_PROTOTYPE(XDR *xdrs, CSSM_ACL_ENTRY_PROTOTYPE *objp) 301{ 302 if (!xdr_CSSM_LIST(xdrs, &objp->TypedSubject)) 303 return (FALSE); 304 // if (!xdr_CSSM_BOOL(xdrs, &objp->Delegate)) 305 // return (FALSE); 306 if (!xdr_CSSM_AUTHORIZATIONGROUP(xdrs, &objp->Authorization)) 307 return (FALSE); 308 // XXX/cs enable once securityd stops leaving garbage in here 309 // if (!xdr_CSSM_ACL_VALIDITY_PERIOD(xdrs, &objp->TimeRange)) 310 // return (FALSE); 311 if (!xdr_CSSM_STRING(xdrs, objp->EntryTag)) 312 return (FALSE); 313 return (TRUE); 314} 315 316bool_t xdr_CSSM_ACL_ENTRY_PROTOTYPE_PTR(XDR *xdrs, CSSM_ACL_ENTRY_PROTOTYPE_PTR *objp) 317{ 318 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_ACL_ENTRY_PROTOTYPE), (xdrproc_t)xdr_CSSM_ACL_ENTRY_PROTOTYPE); 319} 320 321bool_t xdr_CSSM_ACL_OWNER_PROTOTYPE(XDR *xdrs, CSSM_ACL_OWNER_PROTOTYPE *objp) 322{ 323 if (!xdr_CSSM_LIST(xdrs, &objp->TypedSubject)) 324 return (FALSE); 325 if (!xdr_CSSM_BOOL(xdrs, &objp->Delegate)) 326 return (FALSE); 327 return (TRUE); 328} 329 330bool_t xdr_CSSM_ACL_OWNER_PROTOTYPE_PTR(XDR *xdrs, CSSM_ACL_OWNER_PROTOTYPE_PTR *objp) 331{ 332 return sec_xdr_reference(xdrs, (uint8_t **)objp,sizeof(CSSM_ACL_OWNER_PROTOTYPE), (xdrproc_t)xdr_CSSM_ACL_OWNER_PROTOTYPE); 333} 334 335bool_t xdr_CSSM_ACL_ENTRY_INPUT(XDR *xdrs, CSSM_ACL_ENTRY_INPUT *objp) 336{ 337 if (!xdr_CSSM_ACL_ENTRY_PROTOTYPE(xdrs, &objp->Prototype)) 338 return (FALSE); 339 // XXX/cs not currently using this 340 // @@@ treating both Callback and CallerCtx like intptr_t 341 // in case it ever turns into a magic cookie 342 // if (!xdr_voidptr(xdrs, &cb)) 343 // return (FALSE); 344 // if (!xdr_voidptr(xdrs, &objp->CallerContext)) 345 // return (FALSE); 346 return (TRUE); 347} 348 349bool_t xdr_CSSM_ACL_ENTRY_INPUT_PTR(XDR *xdrs, CSSM_ACL_ENTRY_INPUT_PTR *objp) 350{ 351 return sec_xdr_reference(xdrs, (uint8_t **)objp,sizeof(CSSM_ACL_ENTRY_INPUT), (xdrproc_t)xdr_CSSM_ACL_ENTRY_INPUT); 352} 353 354bool_t xdr_CSSM_ACL_ENTRY_INFO(XDR *xdrs, CSSM_ACL_ENTRY_INFO *objp) 355{ 356 357 if (!xdr_CSSM_ACL_ENTRY_PROTOTYPE(xdrs, &objp->EntryPublicInfo)) 358 return (FALSE); 359 if (!xdr_CSSM_ACL_HANDLE(xdrs, &objp->EntryHandle)) 360 return (FALSE); 361 return (TRUE); 362} 363 364bool_t xdr_CSSM_ACL_ENTRY_INFO_ARRAY(XDR *xdrs, CSSM_ACL_ENTRY_INFO_ARRAY *objp) 365{ 366 return sec_xdr_array(xdrs, (uint8_t **)&objp->acls, (u_int *)&objp->count, ~0, sizeof(CSSM_ACL_ENTRY_INFO), (xdrproc_t)xdr_CSSM_ACL_ENTRY_INFO); 367} 368 369bool_t xdr_CSSM_ACL_ENTRY_INFO_ARRAY_PTR(XDR *xdrs, CSSM_ACL_ENTRY_INFO_ARRAY_PTR *objp) 370{ 371 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_ACL_ENTRY_INFO_ARRAY), (xdrproc_t)xdr_CSSM_ACL_ENTRY_INFO_ARRAY); 372} 373 374 375bool_t xdr_CSSM_DATE(XDR *xdrs, CSSM_DATE *objp) 376{ 377 return xdr_opaque(xdrs, (char *)objp, sizeof(CSSM_DATE)); 378} 379 380bool_t xdr_CSSM_RANGE(XDR *xdrs, CSSM_RANGE *objp) 381{ 382 383 if (!xdr_uint32(xdrs, &objp->Min)) 384 return (FALSE); 385 if (!xdr_uint32(xdrs, &objp->Max)) 386 return (FALSE); 387 return (TRUE); 388} 389 390bool_t xdr_CSSM_KEYHEADER(XDR *xdrs, CSSM_KEYHEADER *objp) 391{ 392 393 if (!xdr_CSSM_HEADERVERSION(xdrs, &objp->HeaderVersion)) 394 return (FALSE); 395 if (!xdr_CSSM_GUID(xdrs, &objp->CspId)) 396 return (FALSE); 397 if (!xdr_CSSM_KEYBLOB_TYPE(xdrs, &objp->BlobType)) 398 return (FALSE); 399 if (!xdr_CSSM_KEYBLOB_FORMAT(xdrs, &objp->Format)) 400 return (FALSE); 401 if (!xdr_CSSM_ALGORITHMS(xdrs, &objp->AlgorithmId)) 402 return (FALSE); 403 if (!xdr_CSSM_KEYCLASS(xdrs, &objp->KeyClass)) 404 return (FALSE); 405 if (!xdr_uint32(xdrs, &objp->LogicalKeySizeInBits)) 406 return (FALSE); 407 if (!xdr_CSSM_KEYATTR_FLAGS(xdrs, &objp->KeyAttr)) 408 return (FALSE); 409 if (!xdr_CSSM_KEYUSE(xdrs, &objp->KeyUsage)) 410 return (FALSE); 411 if (!xdr_CSSM_DATE(xdrs, &objp->StartDate)) 412 return (FALSE); 413 if (!xdr_CSSM_DATE(xdrs, &objp->EndDate)) 414 return (FALSE); 415 if (!xdr_CSSM_ALGORITHMS(xdrs, &objp->WrapAlgorithmId)) 416 return (FALSE); 417 if (!xdr_CSSM_ENCRYPT_MODE(xdrs, &objp->WrapMode)) 418 return (FALSE); 419 if (!xdr_uint32(xdrs, &objp->Reserved)) 420 return (FALSE); 421 return (TRUE); 422} 423 424bool_t xdr_CSSM_KEYHEADER_PTR(XDR *xdrs, CSSM_KEYHEADER_PTR *objp) 425{ 426 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_KEYHEADER), (xdrproc_t)xdr_CSSM_KEYHEADER); 427} 428 429bool_t xdr_CSSM_KEY(XDR *xdrs, CSSM_KEY *objp) 430{ 431 if (!xdr_CSSM_KEYHEADER(xdrs, &objp->KeyHeader)) 432 return (FALSE); 433 if (!xdr_CSSM_DATA(xdrs, &objp->KeyData)) 434 return (FALSE); 435 return (TRUE); 436} 437 438bool_t xdr_CSSM_KEY_PTR(XDR *xdrs, CSSM_KEY_PTR *objp) 439{ 440 if (!sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_KEY), (xdrproc_t)xdr_CSSM_KEY)) 441 return (FALSE); 442 return (TRUE); 443} 444 445// CSSM_DATA passed through in the following calls: findFirst, findNext and 446// findRecordHandle actually contains a CSSM_KEY if the item is a key. 447// Since a key has byte order sensitive bits it needs to be encoded. 448// At this level we can only guess based on the length of the CSSM_DATA passed in 449// during encode, whether it's a CSSM_KEY, so we're currently letting securityd 450// call xdr_CSSM_KEY_IN_DATA or xdr_CSSM_NO_KEY_IN_DATA to let us know. 451bool_t xdr_CSSM_POSSIBLY_KEY_IN_DATA_WITH_BOOL(XDR *xdrs, CSSM_DATA *objp, bool_t in_iskey) 452{ 453 bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs); 454 bool_t is_key = FALSE; /* shut compiler up */ 455 if (xdrs->x_op == XDR_ENCODE) 456 is_key = (in_iskey && objp->Length == sizeof(CSSM_KEY)); 457 if (!xdr_CSSM_BOOL(xdrs, &is_key)) 458 return (FALSE); 459 if (is_key) { 460 if (!xdr_CSSM_KEY_PTR(xdrs, (CSSM_KEY_PTR*)&objp->Data)) 461 return (FALSE); 462 if (!size_alloc && (xdrs->x_op == XDR_DECODE)) 463 objp->Length = sizeof(CSSM_KEY); 464 } else { 465 if (!xdr_CSSM_DATA(xdrs, objp)) 466 return (FALSE); 467 } 468 return (TRUE); 469} 470 471bool_t xdr_CSSM_POSSIBLY_KEY_IN_DATA(XDR *xdrs, CSSM_DATA *objp) 472{ 473 return xdr_CSSM_POSSIBLY_KEY_IN_DATA_WITH_BOOL(xdrs, objp, FALSE); 474} 475 476bool_t xdr_CSSM_POSSIBLY_KEY_IN_DATA_PTR(XDR *xdrs, CSSM_DATA_PTR *objp) 477{ 478 if (!sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_DATA), (xdrproc_t)xdr_CSSM_POSSIBLY_KEY_IN_DATA)) 479 return (FALSE); 480 return (TRUE); 481} 482 483bool_t xdr_CSSM_KEY_IN_DATA(XDR *xdrs, CSSM_DATA *objp) 484{ 485 return xdr_CSSM_POSSIBLY_KEY_IN_DATA_WITH_BOOL(xdrs, objp, TRUE); 486} 487 488bool_t xdr_CSSM_NO_KEY_IN_DATA(XDR *xdrs, CSSM_DATA *objp) 489{ 490 return xdr_CSSM_POSSIBLY_KEY_IN_DATA_WITH_BOOL(xdrs, objp, FALSE); 491} 492 493bool_t xdr_CSSM_DB_ATTRIBUTE_INFO(XDR *xdrs, CSSM_DB_ATTRIBUTE_INFO *objp) 494{ 495 if (!xdr_CSSM_DB_ATTRIBUTE_NAME_FORMAT(xdrs, &objp->AttributeNameFormat)) 496 return (FALSE); 497 switch (objp->AttributeNameFormat) 498 { 499 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING: 500 if (!sec_xdr_charp(xdrs, &objp->Label.AttributeName, ~0)) 501 return (FALSE); 502 break; 503 case CSSM_DB_ATTRIBUTE_NAME_AS_OID: 504 if (!xdr_CSSM_OID(xdrs, &objp->Label.AttributeOID)) 505 return (FALSE); 506 break; 507 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER: // @@@ apparently unused 508 if (!xdr_uint32(xdrs, &objp->Label.AttributeID)) 509 return (FALSE); 510 break; 511 default: 512 return (FALSE); 513 } 514 if (!xdr_CSSM_DB_ATTRIBUTE_FORMAT(xdrs, &objp->AttributeFormat)) 515 return (FALSE); 516 return (TRUE); 517} 518 519static 520bool_t xdr_CSSM_DATA_FLIPPED(XDR *xdrs, CSSM_DATA *objp) 521{ 522 bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs); 523 if ((xdrs->x_op == XDR_ENCODE) && !size_alloc) { 524 switch (objp->Length) { 525 case sizeof(uint32_t): *(uint32_t*)objp->Data = htonl(*(uint32_t*)objp->Data); break; 526 case sizeof(uint64_t): *(uint64_t*)objp->Data = OSSwapHostToBigInt64(*(uint64_t*)objp->Data); break; 527 case sizeof(uint8_t): break; 528 default: assert(FALSE); break; 529 } 530 } 531 if (!xdr_CSSM_DATA(xdrs, objp)) 532 return (FALSE); 533 if ((xdrs->x_op == XDR_DECODE) && !size_alloc) { 534 switch (objp->Length) { 535 case sizeof(uint32_t): *(uint32_t*)objp->Data = ntohl(*(uint32_t*)objp->Data); break; 536 case sizeof(uint64_t): *(uint64_t*)objp->Data = OSSwapBigToHostInt64(*(uint64_t*)objp->Data); break; 537 case sizeof(uint8_t): break; 538 default: assert(FALSE); break; 539 } 540 } 541 return (TRUE); 542} 543 544bool_t xdr_CSSM_DB_ATTRIBUTE_DATA(XDR *xdrs, CSSM_DB_ATTRIBUTE_DATA *objp) 545{ 546 if (!xdr_CSSM_DB_ATTRIBUTE_INFO(xdrs, &objp->Info)) 547 return (FALSE); 548 assert(sizeof(objp->NumberOfValues) == sizeof(int)); 549 CSSM_DB_ATTRIBUTE_FORMAT format = objp->Info.AttributeFormat; 550 xdrproc_t proc = (xdrproc_t)xdr_CSSM_DATA; // fallback 551 switch(format) { 552 case CSSM_DB_ATTRIBUTE_FORMAT_STRING: 553 case CSSM_DB_ATTRIBUTE_FORMAT_BLOB: 554 case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE: // all byte strings 555 break; 556 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32: 557 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32: 558 case CSSM_DB_ATTRIBUTE_FORMAT_REAL: 559 proc = (xdrproc_t)xdr_CSSM_DATA_FLIPPED; 560 break; 561 /* XXX/cs unhandled: 562 Note that in case of values being passed from CopyIn, it will be normal 563 for the format to be set to CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX, as that 564 is the "not-yet-filled-in" value in the CssmDbAttributeInfo constructor 565 (see Record::addAttributes for where this is called). 566 */ 567 case CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM: 568 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32: 569 case CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX: 570 assert(objp->NumberOfValues == 0); 571 break; 572 default: 573 assert(FALSE); 574 } 575 if (!sec_xdr_array(xdrs, (uint8_t **)&objp->Value, (u_int *)&objp->NumberOfValues, ~0, sizeof(CSSM_DATA), proc)) 576 return (FALSE); 577 return (TRUE); 578} 579 580bool_t xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA(XDR *xdrs, CSSM_DB_RECORD_ATTRIBUTE_DATA *objp) 581{ 582 if (!xdr_CSSM_DB_RECORDTYPE(xdrs, &objp->DataRecordType)) 583 return (FALSE); 584 if (!xdr_uint32(xdrs, &objp->SemanticInformation)) 585 return (FALSE); 586 assert(sizeof(objp->NumberOfAttributes) == sizeof(int)); 587 if (!sec_xdr_array(xdrs, (uint8_t **)&objp->AttributeData, (u_int *)&objp->NumberOfAttributes, ~0, sizeof(CSSM_DB_ATTRIBUTE_DATA), (xdrproc_t)xdr_CSSM_DB_ATTRIBUTE_DATA)) 588 return (FALSE); 589 return (TRUE); 590} 591 592bool_t xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR(XDR *xdrs, CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR *objp) 593{ 594 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_DB_RECORD_ATTRIBUTE_DATA), (xdrproc_t)xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA); 595} 596 597bool_t xdr_CSSM_SELECTION_PREDICATE(XDR *xdrs, CSSM_SELECTION_PREDICATE *objp) 598{ 599 600 if (!xdr_CSSM_DB_OPERATOR(xdrs, &objp->DbOperator)) 601 return (FALSE); 602 if (!xdr_CSSM_DB_ATTRIBUTE_DATA(xdrs, &objp->Attribute)) 603 return (FALSE); 604 return (TRUE); 605} 606 607bool_t xdr_CSSM_QUERY_LIMITS(XDR *xdrs, CSSM_QUERY_LIMITS *objp) 608{ 609 610 if (!xdr_uint32(xdrs, &objp->TimeLimit)) 611 return (FALSE); 612 if (!xdr_uint32(xdrs, &objp->SizeLimit)) 613 return (FALSE); 614 return (TRUE); 615} 616 617bool_t xdr_CSSM_QUERY(XDR *xdrs, CSSM_QUERY *objp) 618{ 619 620 if (!xdr_CSSM_DB_RECORDTYPE(xdrs, &objp->RecordType)) 621 return (FALSE); 622 if (!xdr_CSSM_DB_CONJUNCTIVE(xdrs, &objp->Conjunctive)) 623 return (FALSE); 624 assert(sizeof(objp->NumSelectionPredicates) == sizeof(int)); 625 if (!sec_xdr_array(xdrs, (uint8_t **)&objp->SelectionPredicate, (u_int *)&objp->NumSelectionPredicates, ~0, sizeof(CSSM_SELECTION_PREDICATE), (xdrproc_t)xdr_CSSM_SELECTION_PREDICATE)) 626 return (FALSE); 627 if (!xdr_CSSM_QUERY_LIMITS(xdrs, &objp->QueryLimits)) 628 return (FALSE); 629 if (!xdr_CSSM_QUERY_FLAGS(xdrs, &objp->QueryFlags)) 630 return (FALSE); 631 return (TRUE); 632} 633 634bool_t xdr_CSSM_QUERY_PTR(XDR *xdrs, CSSM_QUERY_PTR *objp) 635{ 636 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_QUERY), (xdrproc_t)xdr_CSSM_QUERY); 637} 638 639bool_t xdr_CSSM_CONTEXT_ATTRIBUTE(XDR *xdrs, CSSM_CONTEXT_ATTRIBUTE *objp) 640{ 641 if (!xdr_CSSM_ATTRIBUTE_TYPE(xdrs, &objp->AttributeType)) 642 return (FALSE); 643 // @@@ original walkers skirt the issue: set to 0 on copyin, set to sizeof(attr) on copyout - all attrs do have internal size or null termination. 644 if (!xdr_uint32(xdrs, &objp->AttributeLength)) 645 return (FALSE); 646 switch(objp->AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) 647 { 648 case CSSM_ATTRIBUTE_DATA_CSSM_DATA: 649 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.Data, sizeof(CSSM_DATA), (xdrproc_t)xdr_CSSM_DATA)) return (FALSE); break; 650 case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA: 651 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.CryptoData, sizeof(CSSM_CRYPTO_DATA), (xdrproc_t)xdr_CSSM_CRYPTO_DATA)) return (FALSE); break; 652 case CSSM_ATTRIBUTE_DATA_KEY: 653 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.Key, sizeof(CSSM_KEY), (xdrproc_t)xdr_CSSM_KEY)) return (FALSE); break; 654 case CSSM_ATTRIBUTE_DATA_STRING: 655 if (!sec_xdr_charp(xdrs, &objp->Attribute.String, ~0)) return (FALSE); break; 656 case CSSM_ATTRIBUTE_DATA_DATE: 657 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.Date, sizeof(CSSM_DATE), (xdrproc_t)xdr_CSSM_DATE)) return (FALSE); break; 658 case CSSM_ATTRIBUTE_DATA_RANGE: 659 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.Range, sizeof(CSSM_RANGE), (xdrproc_t)xdr_CSSM_RANGE)) return (FALSE); break; 660 case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS: 661 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.AccessCredentials, sizeof(CSSM_ACCESS_CREDENTIALS), (xdrproc_t)xdr_CSSM_ACCESS_CREDENTIALS)) return (FALSE); break; 662 case CSSM_ATTRIBUTE_DATA_VERSION: 663 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.Version, sizeof(CSSM_VERSION), (xdrproc_t)xdr_CSSM_VERSION)) return (FALSE); break; 664 case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE: 665 if (!sec_xdr_reference(xdrs, (uint8_t **)&objp->Attribute.DLDBHandle, sizeof(CSSM_DL_DB_HANDLE), (xdrproc_t)xdr_CSSM_DL_DB_HANDLE)) return (FALSE); break; 666 case CSSM_ATTRIBUTE_NONE: 667 break; 668 case CSSM_ATTRIBUTE_DATA_UINT32: 669 if (!xdr_uint32(xdrs, &objp->Attribute.Uint32)) 670 return (FALSE); 671 break; 672 default: 673 return (FALSE); 674 } 675 676 return (TRUE); 677} 678 679bool_t xdr_CSSM_CONTEXT(XDR *xdrs, CSSM_CONTEXT *objp) 680{ 681 if (!xdr_CSSM_CONTEXT_TYPE(xdrs, &objp->ContextType)) 682 return (FALSE); 683 if (!xdr_CSSM_ALGORITHMS(xdrs, &objp->AlgorithmType)) 684 return (FALSE); 685 if (!sec_xdr_array(xdrs, (uint8_t **)&objp->ContextAttributes, (u_int *)&objp->NumberOfAttributes, ~0, sizeof(CSSM_CONTEXT_ATTRIBUTE), (xdrproc_t)xdr_CSSM_CONTEXT_ATTRIBUTE)) 686 return (FALSE); 687 if (!xdr_CSSM_CSP_HANDLE(xdrs, &objp->CSPHandle)) 688 return (FALSE); 689 if (!xdr_CSSM_BOOL(xdrs, &objp->Privileged)) 690 return (FALSE); 691 if (!xdr_uint32(xdrs, &objp->EncryptionProhibited)) 692 return (FALSE); 693 if (!xdr_uint32(xdrs, &objp->WorkFactor)) 694 return (FALSE); 695 if (!xdr_uint32(xdrs, &objp->Reserved)) 696 return (FALSE); 697 return (TRUE); 698} 699 700bool_t xdr_CSSM_CONTEXT_PTR(XDR *xdrs, CSSM_CONTEXT_PTR *objp) 701{ 702 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_CONTEXT), (xdrproc_t)xdr_CSSM_CONTEXT); 703} 704 705// this is possibly not actually used in favor of the flatidentifier 706bool_t xdr_CSSM_DL_DB_HANDLE(XDR *xdrs, CSSM_DL_DB_HANDLE *objp) 707{ 708 if (!xdr_CSSM_DL_HANDLE(xdrs, &objp->DLHandle)) 709 return (FALSE); 710 if (!xdr_CSSM_DB_HANDLE(xdrs, &objp->DBHandle)) 711 return (FALSE); 712 return (TRUE); 713} 714 715bool_t xdr_CSSM_PKCS5_PBKDF2_PARAMS(XDR *xdrs, CSSM_PKCS5_PBKDF2_PARAMS *objp) 716{ 717 if (!xdr_CSSM_DATA(xdrs, &objp->Passphrase)) 718 return (FALSE); 719 if (!xdr_CSSM_PKCS5_PBKDF2_PRF(xdrs, &objp->PseudoRandomFunction)) 720 return (FALSE); 721 return (TRUE); 722} 723 724bool_t xdr_CSSM_DERIVE_DATA(XDR *xdrs, CSSM_DERIVE_DATA *objp) 725{ 726 if (!xdr_CSSM_ALGORITHMS(xdrs,&objp->algorithm)) 727 return (FALSE); 728 switch (objp->algorithm) { 729 case CSSM_ALGID_PKCS5_PBKDF2: 730 if ((xdrs->x_op == XDR_ENCODE) && 731 (!objp->baseData.Data) && 732 (objp->baseData.Length != sizeof(CSSM_PKCS5_PBKDF2_PARAMS))) 733 return (FALSE); //CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS); 734 if (!sec_xdr_reference(xdrs, &(objp->baseData.Data), sizeof(CSSM_PKCS5_PBKDF2_PARAMS), (xdrproc_t)xdr_CSSM_PKCS5_PBKDF2_PARAMS)) 735 return (FALSE); 736 objp->baseData.Length = sizeof(CSSM_PKCS5_PBKDF2_PARAMS); 737 break; 738 default: 739 if (!xdr_CSSM_DATA(xdrs, &objp->baseData)) 740 return (FALSE); 741 break; 742 } 743 return (TRUE); 744} 745 746bool_t xdr_CSSM_DERIVE_DATA_PTR(XDR *xdrs, CSSM_DERIVE_DATA **objp) 747{ 748 return sec_xdr_reference(xdrs, (uint8_t **)objp, sizeof(CSSM_DERIVE_DATA), (xdrproc_t)xdr_CSSM_DERIVE_DATA); 749} 750 751bool_t xdr_CSSM_ACL_OWNER_PROTOTYPE_ARRAY(XDR *xdrs, CSSM_ACL_OWNER_PROTOTYPE_ARRAY *objp) 752{ 753 if (!sec_xdr_array(xdrs, (uint8_t **)&objp->acls, (u_int *)&objp->count, ~0, sizeof(CSSM_ACL_OWNER_PROTOTYPE), (xdrproc_t)xdr_CSSM_ACL_OWNER_PROTOTYPE)) 754 return (FALSE); 755 return (TRUE); 756} 757 758 759#if 0 /* unimplemented in current stack */ 760 761bool_t xdr_CSSM_FIELD(XDR *xdrs, CSSM_FIELD *objp) 762{ 763 764 if (!xdr_CSSM_OID(xdrs, &objp->FieldOid)) 765 return (FALSE); 766 if (!xdr_CSSM_DATA(xdrs, &objp->FieldValue)) 767 return (FALSE); 768 return (TRUE); 769} 770 771bool_t xdr_CSSM_FIELDGROUP(XDR *xdrs, CSSM_FIELDGROUP *objp) 772{ 773 assert(sizeof(objp->NumberOfFields) == sizeof(int)); 774 if (!sec_xdr_array(xdrs, (uint8_t**)&objp->Fields, (u_int *)&objp->NumberOfFields, ~0, sizeof(CSSM_FIELD), (xdrproc_t)xdr_CSSM_FIELD)) 775 return (FALSE); 776 return (TRUE); 777} 778 779bool_t xdr_CSSM_TUPLE(XDR *xdrs, CSSM_TUPLE *objp) 780{ 781 if (!xdr_CSSM_LIST(xdrs, &objp->Issuer)) 782 return (FALSE); 783 if (!xdr_CSSM_LIST(xdrs, &objp->Subject)) 784 return (FALSE); 785 if (!xdr_CSSM_BOOL(xdrs, &objp->Delegate)) 786 return (FALSE); 787 if (!xdr_CSSM_LIST(xdrs, &objp->AuthorizationTag)) 788 return (FALSE); 789 if (!xdr_CSSM_LIST(xdrs, &objp->ValidityPeriod)) 790 return (FALSE); 791 return (TRUE); 792} 793 794bool_t xdr_CSSM_PARSED_CERT(XDR *xdrs, CSSM_PARSED_CERT *objp) 795{ 796 if (!xdr_CSSM_CERT_TYPE(xdrs, &objp->CertType)) 797 return (FALSE); 798 switch (objp->ParsedCertFormat) 799 { 800 case CSSM_CERT_PARSE_FORMAT_NONE: 801 case CSSM_CERT_PARSE_FORMAT_CUSTOM: /* void* */ 802 /* XXX/gh SOL? */ 803 break; 804 case CSSM_CERT_PARSE_FORMAT_SEXPR: 805 if (!xdr_CSSM_LIST(xdrs, (CSSM_LIST *)objp->ParsedCert)) 806 return (FALSE); 807 break; 808 case CSSM_CERT_PARSE_FORMAT_COMPLEX: /* void* */ 809 /* XXX/gh SOL? */ 810 break; 811 case CSSM_CERT_PARSE_FORMAT_OID_NAMED: 812 if (!xdr_CSSM_FIELDGROUP(xdrs, (CSSM_FIELDGROUP *)objp->ParsedCert)) 813 return (FALSE); 814 break; 815 case CSSM_CERT_PARSE_FORMAT_TUPLE: 816 if (!xdr_CSSM_TUPLE(xdrs, (CSSM_TUPLE *)objp->ParsedCert)) 817 return (FALSE); 818 break; 819 case CSSM_CERT_PARSE_FORMAT_MULTIPLE: 820 /* multiple forms; each cert carries a parse format indicator */ 821 /* XXX/gh ??? */ 822 break; 823 case CSSM_CERT_PARSE_FORMAT_LAST: 824 /* XXX/gh ??? */ 825 break; 826 case CSSM_CL_CUSTOM_CERT_PARSE_FORMAT: 827 /* XXX/gh ??? */ 828 break; 829 default: 830 return (FALSE); 831 } 832 return (TRUE); 833} 834 835bool_t xdr_CSSM_CERT_PAIR(XDR *xdrs, CSSM_CERT_PAIR *objp) 836{ 837 838 if (!xdr_CSSM_ENCODED_CERT(xdrs, &objp->EncodedCert)) 839 return (FALSE); 840 if (!xdr_CSSM_PARSED_CERT(xdrs, &objp->ParsedCert)) 841 return (FALSE); 842 return (TRUE); 843} 844 845#endif /* unimplemented in current stack */ 846 847