]> git.saurik.com Git - apple/security.git/blob - Security/libsecurityd/lib/xdr_cssm.c
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurityd / lib / 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 <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 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
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