/ OSX / libsecurityd / lib / xdr_cssm.c
xdr_cssm.c
  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 <security_utilities/simulatecrash_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
 36  bool_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
 50  bool_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  
 63  bool_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  
 78  bool_t xdr_CSSM_GUID(XDR *xdrs, CSSM_GUID *objp)
 79  {
 80      return xdr_opaque(xdrs, (char *)objp, sizeof(CSSM_GUID));
 81  }
 82  
 83  bool_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  
 92  bool_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  
105  bool_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.
115  bool_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  
143  bool_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          secinfo("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  
166  bool_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  
183  bool_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  
192  bool_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  
200  bool_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  
212  bool_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  
247  bool_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  
258  bool_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  
278  bool_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  
283  bool_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  
291  bool_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  
300  bool_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  
316  bool_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  
321  bool_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  
330  bool_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  
335  bool_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  
349  bool_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  
354  bool_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  
364  bool_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  
369  bool_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  
375  bool_t xdr_CSSM_DATE(XDR *xdrs, CSSM_DATE *objp)
376  {
377      return xdr_opaque(xdrs, (char *)objp, sizeof(CSSM_DATE));
378  }
379  
380  bool_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  
390  bool_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  
424  bool_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  
429  bool_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  
438  bool_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.
451  bool_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  
471  bool_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  
476  bool_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  
483  bool_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  
488  bool_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  
493  bool_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  
519  static
520  bool_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  
544  bool_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  
580  bool_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  
592  bool_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  
597  bool_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  
607  bool_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  
617  bool_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  
634  bool_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  
639  bool_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  
679  bool_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  
700  bool_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
706  bool_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  
715  bool_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  
724  bool_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  
746  bool_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  
751  bool_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  
761  bool_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  
771  bool_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  
779  bool_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  
794  bool_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  
835  bool_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