]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurityd/lib/transition.cpp
Security-57337.50.23.tar.gz
[apple/security.git] / OSX / libsecurityd / lib / transition.cpp
1 /*
2 * Copyright (c) 2000-2008,2011-2013 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
25 //
26 // transition - SecurityServer client library transition code.
27 //
28 // These are the functions that implement CssmClient methods in terms of
29 // MIG IPC client calls, plus their supporting machinery.
30 //
31 // WARNING! HERE BE DRAGONS!
32 // This code involves moderately arcane magic including (but not limited to)
33 // dancing macros paired off with self-maintaining stack objects. Don't take
34 // anything for granted! Be very afraid of ALL-CAPS names. Your best bet is
35 // probably to stick with the existing patterns.
36 //
37 // Dragons, the sequel. You just don't go killing of that kind of prose, so
38 // we'll continue the saga here with a bit of an update. In transitioning
39 // into securityd there are a couple of steps. The current setup is there
40 // to allow Security.framework to have 32 and 64 bit clients and either
41 // big or little endian. Data is packaged up as hand-generated XDR, which
42 // means it's also in network byte-order.
43 //
44 // CSSM_HANDLEs have remained longs in the 64 bit transition to keep the
45 // optimization option open to allow cssm modules to hand back pointers as
46 // handles. Since we don't identify the client, handles across ipc will
47 // remain 32 bit. Handles you see here are passed out by securityd, and
48 // are clipped and expanded in this layer (high bits always zero).
49 //
50 #include "sstransit.h"
51 #include <security_cdsa_client/cspclient.h>
52
53 #include <securityd_client/xdr_auth.h>
54 #include <securityd_client/xdr_cssm.h>
55 #include <securityd_client/xdr_dldb.h>
56
57 namespace Security {
58 namespace SecurityServer {
59
60 using MachPlusPlus::check;
61 using MachPlusPlus::VMGuard;
62
63 //
64 // Common database interface
65 //
66 void ClientSession::authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type,
67 const AccessCredentials *cred)
68 {
69 // XXX/cs Leave it up to DatabaseAccessCredentials to rewrite it for now
70 DatabaseAccessCredentials creds(cred, internalAllocator);
71 CopyIn copy(creds.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
72 IPC(ucsp_client_authenticateDb(UCSP_ARGS, db, type, copy.data(), copy.length()));
73 }
74
75
76 void ClientSession::releaseDb(DbHandle db)
77 {
78 IPC(ucsp_client_releaseDb(UCSP_ARGS, db));
79 }
80
81
82 //
83 // External database interface
84 //
85 DbHandle ClientSession::openToken(uint32 ssid, const AccessCredentials *cred,
86 const char *name)
87 {
88 DbHandle db;
89 DatabaseAccessCredentials creds(cred, internalAllocator);
90 CopyIn copycreds(creds.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
91
92 IPC(ucsp_client_openToken(UCSP_ARGS, ssid, name ? name : "", copycreds.data(), copycreds.length(), &db));
93
94 return db;
95 }
96
97
98 RecordHandle ClientSession::insertRecord(DbHandle db,
99 CSSM_DB_RECORDTYPE recordType,
100 const CssmDbRecordAttributeData *attributes,
101 const CssmData *data)
102 {
103 RecordHandle record;
104 CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
105
106 IPC(ucsp_client_insertRecord(UCSP_ARGS, db, recordType, db_record_attr_data.data(), (mach_msg_type_number_t)db_record_attr_data.length(), OPTIONALDATA(data), &record));
107
108 return record;
109 }
110
111
112 void ClientSession::deleteRecord(DbHandle db, RecordHandle record)
113 {
114 IPC(ucsp_client_deleteRecord(UCSP_ARGS, db, record));
115 }
116
117
118 void ClientSession::modifyRecord(DbHandle db, RecordHandle &record,
119 CSSM_DB_RECORDTYPE recordType,
120 const CssmDbRecordAttributeData *attributes,
121 const CssmData *data,
122 CSSM_DB_MODIFY_MODE modifyMode)
123 {
124 CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
125
126 IPC(ucsp_client_modifyRecord(UCSP_ARGS, db, &record, recordType, db_record_attr_data.data(), (mach_msg_type_number_t)db_record_attr_data.length(),
127 data != NULL, OPTIONALDATA(data), modifyMode));
128 }
129
130 static
131 void copy_back_attribute_return_data(CssmDbRecordAttributeData *dest_attrs, CssmDbRecordAttributeData *source_attrs, Allocator &returnAllocator)
132 {
133 assert(dest_attrs->size() == source_attrs->size());
134 // global (per-record) fields
135 dest_attrs->recordType(source_attrs->recordType());
136 dest_attrs->semanticInformation(source_attrs->semanticInformation());
137
138 // transfer data values (but not infos, which we keep in the original vector)
139 for (uint32 n = 0; n < dest_attrs->size(); n++)
140 dest_attrs->at(n).copyValues(source_attrs->at(n), returnAllocator);
141 }
142
143 RecordHandle ClientSession::findFirst(DbHandle db,
144 const CssmQuery &inQuery,
145 SearchHandle &hSearch,
146 CssmDbRecordAttributeData *attributes,
147 CssmData *data, KeyHandle &hKey)
148 {
149 CopyIn query(&inQuery, reinterpret_cast<xdrproc_t>(xdr_CSSM_QUERY));
150 CopyIn in_attr(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
151 void *out_attr_data = NULL, *out_data = NULL;
152 mach_msg_size_t out_attr_length = 0, out_data_length = 0;
153 RecordHandle ipcHRecord = 0;
154
155 IPC(ucsp_client_findFirst(UCSP_ARGS, db,
156 query.data(), query.length(), in_attr.data(), in_attr.length(),
157 &out_attr_data, &out_attr_length, (data != NULL), &out_data, &out_data_length,
158 &hKey, &hSearch, &ipcHRecord));
159
160 if (ipcHRecord != 0)
161 {
162 CopyOut out_attrs(out_attr_data, out_attr_length, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR), true);
163 copy_back_attribute_return_data(attributes, reinterpret_cast<CssmDbRecordAttributeData*>(out_attrs.data()), returnAllocator);
164 }
165
166 // decode data from server as cssm_data or cssm_key (get data on keys returns cssm_key in data)
167 CopyOut possible_key_in_data(out_data, out_data_length, reinterpret_cast<xdrproc_t>(xdr_CSSM_POSSIBLY_KEY_IN_DATA_PTR), true, data);
168
169 return ipcHRecord;
170 }
171
172
173 RecordHandle ClientSession::findNext(SearchHandle hSearch,
174 CssmDbRecordAttributeData *attributes,
175 CssmData *data, KeyHandle &hKey)
176 {
177 CopyIn in_attr(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
178 void *out_attr_data = NULL, *out_data = NULL;
179 mach_msg_size_t out_attr_length = 0, out_data_length = 0;
180 //DataOutput out_data(data, returnAllocator);
181 RecordHandle ipcHRecord = 0;
182
183 IPC(ucsp_client_findNext(UCSP_ARGS, hSearch,
184 in_attr.data(), in_attr.length(), &out_attr_data, &out_attr_length,
185 (data != NULL), &out_data, &out_data_length, &hKey, &ipcHRecord));
186
187 if (ipcHRecord != 0)
188 {
189 CopyOut out_attrs(out_attr_data, out_attr_length, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR), true);
190 copy_back_attribute_return_data(attributes, reinterpret_cast<CssmDbRecordAttributeData*>(out_attrs.data()), returnAllocator);
191 }
192
193 // decode data from server as cssm_data or cssm_key (get data on keys returns cssm_key in data)
194 CopyOut possible_key_in_data(out_data, out_data_length, reinterpret_cast<xdrproc_t>(xdr_CSSM_POSSIBLY_KEY_IN_DATA_PTR), true, data);
195
196 return ipcHRecord;
197 }
198
199
200 void ClientSession::findRecordHandle(RecordHandle hRecord,
201 CssmDbRecordAttributeData *attributes,
202 CssmData *data, KeyHandle &hKey)
203 {
204 CopyIn in_attr(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
205 void *out_attr_data = NULL, *out_data = NULL;
206 mach_msg_size_t out_attr_length = 0, out_data_length = 0;
207 IPC(ucsp_client_findRecordHandle(UCSP_ARGS, hRecord,
208 in_attr.data(), in_attr.length(), &out_attr_data, &out_attr_length,
209 data != NULL, &out_data, &out_data_length, &hKey));
210
211 if (hRecord != 0)
212 {
213 CopyOut out_attrs(out_attr_data, out_attr_length, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR), true);
214 copy_back_attribute_return_data(attributes, reinterpret_cast<CssmDbRecordAttributeData*>(out_attrs.data()), returnAllocator);
215 }
216
217 // decode data from server as cssm_data or cssm_key (get data on keys returns cssm_key in data)
218 CopyOut possible_key_in_data(out_data, out_data_length, reinterpret_cast<xdrproc_t>(xdr_CSSM_POSSIBLY_KEY_IN_DATA_PTR), true, data);
219 }
220
221
222 void ClientSession::releaseSearch(SearchHandle searchHandle)
223 {
224 IPC(ucsp_client_releaseSearch(UCSP_ARGS, searchHandle));
225 }
226
227
228 void ClientSession::releaseRecord(RecordHandle record)
229 {
230 IPC(ucsp_client_releaseRecord(UCSP_ARGS, record));
231 }
232
233 void ClientSession::getDbName(DbHandle db, string &name)
234 {
235 char result[PATH_MAX];
236
237 IPC(ucsp_client_getDbName(UCSP_ARGS, db, result));
238
239 name = result;
240 }
241
242 void ClientSession::setDbName(DbHandle db, const string &name)
243 {
244 IPC(ucsp_client_setDbName(UCSP_ARGS, db, name.c_str()));
245 }
246
247
248 //
249 // Internal database management
250 //
251 DbHandle ClientSession::createDb(const DLDbIdentifier &dbId,
252 const AccessCredentials *cred, const AclEntryInput *owner,
253 const DBParameters &params)
254 {
255 DatabaseAccessCredentials creds(cred, internalAllocator);
256 CopyIn copycreds(creds.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
257 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
258 // XXX/64 make xdr routines translate directly between dldbident and flat rep
259 DataWalkers::DLDbFlatIdentifier ident(dbId);
260 CopyIn id(&ident, reinterpret_cast<xdrproc_t>(xdr_DLDbFlatIdentifier));
261 DbHandle db;
262
263 IPC(ucsp_client_createDb(UCSP_ARGS, &db, id.data(), id.length(), copycreds.data(), copycreds.length(), proto.data(), proto.length(), params));
264
265 return db;
266 }
267
268 DbHandle ClientSession::recodeDbForSync(DbHandle dbToClone,
269 DbHandle srcDb)
270 {
271 DbHandle newDb;
272
273 IPC(ucsp_client_recodeDbForSync(UCSP_ARGS, dbToClone, srcDb, &newDb));
274
275 return newDb;
276 }
277
278 DbHandle ClientSession::recodeDbToVersion(uint32 newVersion, DbHandle srcDb)
279 {
280 DbHandle newDb;
281
282 IPC(ucsp_client_recodeDbToVersion(UCSP_ARGS, newVersion, srcDb, &newDb));
283
284 return newDb;
285 }
286
287 DbHandle ClientSession::authenticateDbsForSync(const CssmData &dbHandleArray,
288 const CssmData &agentData)
289 {
290 DbHandle newDb;
291
292 IPC(ucsp_client_authenticateDbsForSync(UCSP_ARGS, DATA(dbHandleArray), DATA(agentData), &newDb));
293
294 return newDb;
295 }
296
297 void ClientSession::commitDbForSync(DbHandle srcDb, DbHandle cloneDb,
298 CssmData &blob, Allocator &alloc)
299 {
300 DataOutput outBlob(blob, alloc);
301 IPC(ucsp_client_commitDbForSync(UCSP_ARGS, srcDb, cloneDb, DATA_OUT(outBlob)));
302 }
303
304 DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
305 const AccessCredentials *cred, const CssmData &blob)
306 {
307 // XXX/64 fold into one translation
308 DatabaseAccessCredentials credentials(cred, internalAllocator);
309 CopyIn creds(credentials.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
310 // XXX/64 fold into one translation
311 DataWalkers::DLDbFlatIdentifier ident(dbId);
312 CopyIn id(&ident, reinterpret_cast<xdrproc_t>(xdr_DLDbFlatIdentifier));
313 DbHandle db;
314
315 IPC(ucsp_client_decodeDb(UCSP_ARGS, &db, id.data(), id.length(), creds.data(), creds.length(), DATA(blob)));
316
317 return db;
318 }
319
320 void ClientSession::encodeDb(DbHandle db, CssmData &blob, Allocator &alloc)
321 {
322 DataOutput outBlob(blob, alloc);
323 IPC(ucsp_client_encodeDb(UCSP_ARGS, db, DATA_OUT(outBlob)));
324 }
325
326 void ClientSession::setDbParameters(DbHandle db, const DBParameters &params)
327 {
328 IPC(ucsp_client_setDbParameters(UCSP_ARGS, db, params));
329 }
330
331 void ClientSession::getDbParameters(DbHandle db, DBParameters &params)
332 {
333 IPC(ucsp_client_getDbParameters(UCSP_ARGS, db, &params));
334 }
335
336 void ClientSession::changePassphrase(DbHandle db, const AccessCredentials *cred)
337 {
338 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
339 IPC(ucsp_client_changePassphrase(UCSP_ARGS, db, creds.data(), creds.length()));
340 }
341
342
343 void ClientSession::lock(DbHandle db)
344 {
345 IPC(ucsp_client_authenticateDb(UCSP_ARGS, db, CSSM_DB_ACCESS_RESET, NULL, 0));
346 //@@@VIRTUAL IPC(ucsp_client_lockDb(UCSP_ARGS, db));
347 }
348
349 void ClientSession::lockAll (bool forSleep)
350 {
351 IPC(ucsp_client_lockAll (UCSP_ARGS, forSleep));
352 }
353
354 void ClientSession::unlock(DbHandle db)
355 {
356 IPC(ucsp_client_unlockDb(UCSP_ARGS, db));
357 }
358
359 void ClientSession::unlock(DbHandle db, const CssmData &passphrase)
360 {
361 IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS, db, DATA(passphrase)));
362 }
363
364 void ClientSession::stashDb(DbHandle db)
365 {
366 IPC(ucsp_client_stashDb(UCSP_ARGS, db));
367 }
368
369 void ClientSession::stashDbCheck(DbHandle db)
370 {
371 IPC(ucsp_client_stashDbCheck(UCSP_ARGS, db));
372 }
373
374 bool ClientSession::isLocked(DbHandle db)
375 {
376 boolean_t locked;
377 IPC(ucsp_client_isLocked(UCSP_ARGS, db, &locked));
378 return locked;
379 }
380
381 void ClientSession::verifyKeyStorePassphrase(uint32_t retries)
382 {
383 IPC(ucsp_client_verifyKeyStorePassphrase(UCSP_ARGS, retries));
384 }
385
386 void ClientSession::resetKeyStorePassphrase(const CssmData &passphrase)
387 {
388 IPC(ucsp_client_resetKeyStorePassphrase(UCSP_ARGS, DATA(passphrase)));
389 }
390
391 void ClientSession::changeKeyStorePassphrase()
392 {
393 IPC(ucsp_client_changeKeyStorePassphrase(UCSP_ARGS));
394 }
395
396 //
397 // Key control
398 //
399 void ClientSession::encodeKey(KeyHandle key, CssmData &blob,
400 KeyUID *uid, Allocator &alloc)
401 {
402 // Not really used as output
403 DataOutput oBlob(blob, alloc);
404 void *uidp;
405 mach_msg_type_number_t uidLength;
406
407 IPC(ucsp_client_encodeKey(UCSP_ARGS, key, oBlob.data(), oBlob.length(),
408 (uid != NULL), &uidp, &uidLength));
409
410 // return key uid if requested
411 if (uid) {
412 assert(uidLength == sizeof(KeyUID));
413 memcpy(uid, uidp, sizeof(KeyUID));
414 }
415 }
416
417 KeyHandle ClientSession::decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header)
418 {
419 KeyHandle key;
420 void *keyHeaderData;
421 mach_msg_type_number_t keyHeaderDataLength;
422
423 IPC(ucsp_client_decodeKey(UCSP_ARGS, &key, &keyHeaderData, &keyHeaderDataLength, db, blob.data(), (mach_msg_type_number_t)blob.length()));
424
425 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
426 header = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
427
428 return key;
429 }
430
431 // keychain synchronization
432 void ClientSession::recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb,
433 CssmData &blob)
434 {
435 DataOutput outBlob(blob, returnAllocator);
436 IPC(ucsp_client_recodeKey(UCSP_ARGS, oldDb, key, newDb, DATA_OUT(outBlob)));
437 }
438
439 void ClientSession::releaseKey(KeyHandle key)
440 {
441 IPC(ucsp_client_releaseKey(UCSP_ARGS, key));
442 }
443
444
445 CssmKeySize ClientSession::queryKeySizeInBits(KeyHandle key)
446 {
447 CssmKeySize length;
448 IPC(ucsp_client_queryKeySizeInBits(UCSP_ARGS, key, &length));
449 return length;
450 }
451
452
453 uint32 ClientSession::getOutputSize(const Context &context, KeyHandle key,
454 uint32 inputSize, bool encrypt)
455 {
456 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
457 uint32 outputSize;
458
459 IPC(ucsp_client_getOutputSize(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, inputSize, encrypt, &outputSize));
460 return outputSize;
461 }
462
463
464 //
465 // Random number generation.
466 // This interfaces to the secure RNG inside the SecurityServer; it does not access
467 // a PRNG in its CSP. If you need a reproducible PRNG, attach a local CSP and use it.
468 // Note that this function does not allocate a buffer; it always fills the buffer provided.
469 //
470 void ClientSession::generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc)
471 {
472 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
473 DataOutput result(data, alloc);
474
475 IPC(ucsp_client_generateRandom(UCSP_ARGS, 0, ctxcopy.data(), ctxcopy.length(), DATA_OUT(result)));
476 }
477
478
479 //
480 // Signatures and MACs
481 //
482 void ClientSession::generateSignature(const Context &context, KeyHandle key,
483 const CssmData &data, CssmData &signature, Allocator &alloc, CSSM_ALGORITHMS signOnlyAlgorithm)
484 {
485 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
486 DataOutput sig(signature, alloc);
487
488 IPCKEY(ucsp_client_generateSignature(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, signOnlyAlgorithm,
489 DATA(data), DATA_OUT(sig)),
490 key, CSSM_ACL_AUTHORIZATION_SIGN);
491 }
492
493 void ClientSession::verifySignature(const Context &context, KeyHandle key,
494 const CssmData &data, const CssmData &signature, CSSM_ALGORITHMS verifyOnlyAlgorithm)
495 {
496 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
497
498 IPC(ucsp_client_verifySignature(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, verifyOnlyAlgorithm, DATA(data), DATA(signature)));
499 }
500
501
502 void ClientSession::generateMac(const Context &context, KeyHandle key,
503 const CssmData &data, CssmData &signature, Allocator &alloc)
504 {
505 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
506 DataOutput sig(signature, alloc);
507
508 IPCKEY(ucsp_client_generateMac(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(data), DATA_OUT(sig)),
509 key, CSSM_ACL_AUTHORIZATION_MAC);
510 }
511
512 void ClientSession::verifyMac(const Context &context, KeyHandle key,
513 const CssmData &data, const CssmData &signature)
514 {
515 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
516
517 IPCKEY(ucsp_client_verifyMac(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key,
518 DATA(data), DATA(signature)),
519 key, CSSM_ACL_AUTHORIZATION_MAC);
520 }
521
522
523 //
524 // Encryption/Decryption
525 //
526
527 void ClientSession::encrypt(const Context &context, KeyHandle key,
528 const CssmData &clear, CssmData &cipher, Allocator &alloc)
529 {
530 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
531 DataOutput cipherOut(cipher, alloc);
532 IPCKEY(ucsp_client_encrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(clear), DATA_OUT(cipherOut)),
533 key, CSSM_ACL_AUTHORIZATION_ENCRYPT);
534 }
535
536 void ClientSession::decrypt(const Context &context, KeyHandle key,
537 const CssmData &cipher, CssmData &clear, Allocator &alloc)
538 {
539 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
540 DataOutput clearOut(clear, alloc);
541
542 IPCKEY(ucsp_client_decrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(cipher), DATA_OUT(clearOut)),
543 key, CSSM_ACL_AUTHORIZATION_DECRYPT);
544 }
545
546
547 //
548 // Key generation
549 //
550 void ClientSession::generateKey(DbHandle db, const Context &context, uint32 keyUsage, uint32 keyAttr,
551 const AccessCredentials *cred, const AclEntryInput *owner,
552 KeyHandle &newKey, CssmKey::Header &newHeader)
553 {
554 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
555 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
556 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
557 void *keyHeaderData;
558 mach_msg_type_number_t keyHeaderDataLength;
559
560 IPC(ucsp_client_generateKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(),
561 creds.data(), creds.length(), proto.data(), proto.length(),
562 keyUsage, keyAttr, &newKey, &keyHeaderData, &keyHeaderDataLength));
563
564 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
565 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
566 }
567
568 void ClientSession::generateKey(DbHandle db, const Context &context,
569 uint32 pubKeyUsage, uint32 pubKeyAttr,
570 uint32 privKeyUsage, uint32 privKeyAttr,
571 const AccessCredentials *cred, const AclEntryInput *owner,
572 KeyHandle &pubKey, CssmKey::Header &pubHeader,
573 KeyHandle &privKey, CssmKey::Header &privHeader)
574 {
575 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
576 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
577 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
578 void *pubKeyHeaderData, *privKeyHeaderData;
579 mach_msg_type_number_t pubKeyHeaderDataLength, privKeyHeaderDataLength;
580
581 IPC(ucsp_client_generateKeyPair(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(),
582 creds.data(), creds.length(), proto.data(), proto.length(),
583 pubKeyUsage, pubKeyAttr, privKeyUsage, privKeyAttr,
584 &pubKey, &pubKeyHeaderData, &pubKeyHeaderDataLength,
585 &privKey, &privKeyHeaderData, &privKeyHeaderDataLength));
586
587 CopyOut wrappedPubKeyHeaderXDR(pubKeyHeaderData, pubKeyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
588 pubHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedPubKeyHeaderXDR.data()));
589 CopyOut wrappedPrivKeyHeaderXDR(privKeyHeaderData, privKeyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
590 privHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedPrivKeyHeaderXDR.data()));
591
592 }
593
594
595 //
596 // Key derivation
597 // This is a bit strained; the incoming 'param' value may have structure,
598 // and we use a synthetic CssmDeriveData structure (with ad-hoc walker) to
599 // handle that. Param also is input/output, which is always a pain (not to mention
600 // ill-defined by the CDSA standard).
601 //
602 // If you're here because an algorithm of yours requires structured parameter
603 // input, go to security_cdsa_utilities/cssmwalkers.h and add a case to the
604 // CssmDeriveData walker.
605 //
606 void ClientSession::deriveKey(DbHandle db, const Context &context, KeyHandle baseKey,
607 CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, CssmData &param,
608 const AccessCredentials *cred, const AclEntryInput *owner,
609 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &allocator)
610 {
611 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
612 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
613 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
614 CSSM_DERIVE_DATA inParamForm = { context.algorithm(), param };
615 CopyIn inParam(&inParamForm, reinterpret_cast<xdrproc_t>(xdr_CSSM_DERIVE_DATA));
616
617 try
618 {
619 DataOutput paramOutput(param, allocator);
620 void *keyHeaderData;
621 mach_msg_type_number_t keyHeaderDataLength;
622
623 IPCKEY(ucsp_client_deriveKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), baseKey,
624 creds.data(), creds.length(), proto.data(), proto.length(),
625 inParam.data(), inParam.length(), DATA_OUT(paramOutput),
626 usage, attrs, &newKey, &keyHeaderData, &keyHeaderDataLength),
627 baseKey, CSSM_ACL_AUTHORIZATION_DERIVE);
628
629 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
630 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
631 }
632 catch (CssmError& e)
633 {
634 // filter out errors for CSSM_ALGID_PKCS5_PBKDF2
635 if (context.algorithm() != CSSM_ALGID_PKCS5_PBKDF2 && e.error != CSSMERR_CSP_OUTPUT_LENGTH_ERROR)
636 {
637 throw;
638 }
639 }
640 }
641
642
643 //
644 // Digest generation
645 //
646 void ClientSession::getKeyDigest(KeyHandle key, CssmData &digest, Allocator &allocator)
647 {
648 DataOutput dig(digest, allocator);
649 IPC(ucsp_client_getKeyDigest(UCSP_ARGS, key, DATA_OUT(dig)));
650 }
651
652
653 //
654 // Key wrapping and unwrapping
655 //
656 void ClientSession::wrapKey(const Context &context, KeyHandle wrappingKey,
657 KeyHandle keyToBeWrapped, const AccessCredentials *cred,
658 const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, Allocator &alloc)
659 {
660 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
661 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
662 void *keyData;
663 mach_msg_type_number_t keyDataLength;
664
665 IPCKEY(ucsp_client_wrapKey(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), wrappingKey,
666 creds.data(), creds.length(),
667 keyToBeWrapped, OPTIONALDATA(descriptiveData),
668 &keyData, &keyDataLength),
669 keyToBeWrapped,
670 context.algorithm() == CSSM_ALGID_NONE
671 ? CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR : CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED);
672
673 CopyOut wrappedKeyXDR(keyData, keyDataLength + sizeof(CSSM_KEY), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY_PTR), true);
674 CssmWrappedKey *wrappedKeyIPC = reinterpret_cast<CssmWrappedKey*>(wrappedKeyXDR.data());
675 wrappedKey.header() = wrappedKeyIPC->header();
676 wrappedKey.keyData() = CssmData(alloc.malloc(wrappedKeyIPC->keyData().length()), wrappedKeyIPC->keyData().length());
677 memcpy(wrappedKey.keyData().data(), wrappedKeyIPC->keyData(), wrappedKeyIPC->keyData().length());
678 }
679
680 void ClientSession::unwrapKey(DbHandle db, const Context &context, KeyHandle key,
681 KeyHandle publicKey, const CssmWrappedKey &wrappedKey,
682 uint32 usage, uint32 attr,
683 const AccessCredentials *cred, const AclEntryInput *acl,
684 CssmData &descriptiveData,
685 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc)
686 {
687 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
688 DataOutput descriptor(descriptiveData, alloc);
689 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
690 CopyIn proto(acl ? &acl->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
691 CopyIn wrappedKeyXDR(&wrappedKey, reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY));
692 void *keyHeaderData;
693 mach_msg_type_number_t keyHeaderDataLength;
694
695 IPCKEY(ucsp_client_unwrapKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), key,
696 creds.data(), creds.length(), proto.data(), proto.length(),
697 publicKey, wrappedKeyXDR.data(), wrappedKeyXDR.length(), usage, attr, DATA_OUT(descriptor),
698 &newKey, &keyHeaderData, &keyHeaderDataLength),
699 key, CSSM_ACL_AUTHORIZATION_DECRYPT);
700
701 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
702 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
703 }
704
705
706 //
707 // ACL management
708 //
709 void ClientSession::getAcl(AclKind kind, GenericHandle key, const char *tag,
710 uint32 &infoCount, AclEntryInfo * &infoArray, Allocator &alloc)
711 {
712 uint32 count;
713 void* info; mach_msg_type_number_t infoLength;
714 IPC(ucsp_client_getAcl(UCSP_ARGS, kind, key,
715 (tag != NULL), tag ? tag : "",
716 &count, &info, &infoLength));
717
718 CSSM_ACL_ENTRY_INFO_ARRAY_PTR aclsArray;
719 if (!::copyout_chunked(info, infoLength, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_INFO_ARRAY_PTR), reinterpret_cast<void**>(&aclsArray)))
720 CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);
721
722 infoCount = aclsArray->count;
723 infoArray = reinterpret_cast<AclEntryInfo*>(aclsArray->acls);
724 free(aclsArray);
725 }
726
727 void ClientSession::changeAcl(AclKind kind, GenericHandle key, const AccessCredentials &cred,
728 const AclEdit &edit)
729 {
730 CopyIn creds(&cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
731 //@@@ ignoring callback
732 CopyIn newEntry(edit.newEntry(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_INPUT));
733
734 IPCKEY(ucsp_client_changeAcl(UCSP_ARGS, kind, key, creds.data(), creds.length(),
735 edit.mode(), toIPCHandle(edit.handle()), newEntry.data(), newEntry.length()),
736 key, CSSM_ACL_AUTHORIZATION_CHANGE_ACL);
737 }
738
739 void ClientSession::getOwner(AclKind kind, GenericHandle key, AclOwnerPrototype &owner,
740 Allocator &alloc)
741 {
742 void* proto; mach_msg_type_number_t protoLength;
743 IPC(ucsp_client_getOwner(UCSP_ARGS, kind, key, &proto, &protoLength));
744
745 CSSM_ACL_OWNER_PROTOTYPE_PTR tmpOwner;
746 if (!::copyout_chunked(proto, protoLength, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE_PTR), reinterpret_cast<void **>(&tmpOwner)))
747 CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);
748 owner = *static_cast<AclOwnerPrototypePtr>(tmpOwner);
749 free(tmpOwner);
750 }
751
752 void ClientSession::changeOwner(AclKind kind, GenericHandle key,
753 const AccessCredentials &cred, const AclOwnerPrototype &proto)
754 {
755 CopyIn creds(&cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
756 CopyIn protos(&proto, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE));
757 IPCKEY(ucsp_client_setOwner(UCSP_ARGS, kind, key, creds.data(), creds.length(), protos.data(), protos.length()),
758 key, CSSM_ACL_AUTHORIZATION_CHANGE_OWNER);
759 }
760
761
762 void ClientSession::getKeyAcl(DbHandle db, const char *tag,
763 uint32 &count, AclEntryInfo * &info, Allocator &alloc)
764 { getAcl(keyAcl, db, tag, count, info, alloc); }
765
766 void ClientSession::changeKeyAcl(DbHandle db, const AccessCredentials &cred,
767 const AclEdit &edit)
768 { changeAcl(keyAcl, db, cred, edit); }
769
770 void ClientSession::getKeyOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc)
771 { getOwner(keyAcl, db, owner, alloc); }
772
773 void ClientSession::changeKeyOwner(DbHandle db, const AccessCredentials &cred,
774 const AclOwnerPrototype &edit)
775 { changeOwner(keyAcl, db, cred, edit); }
776
777 void ClientSession::getDbAcl(DbHandle db, const char *tag,
778 uint32 &count, AclEntryInfo * &info, Allocator &alloc)
779 { getAcl(dbAcl, db, tag, count, info, alloc); }
780
781 void ClientSession::changeDbAcl(DbHandle db, const AccessCredentials &cred,
782 const AclEdit &edit)
783 { changeAcl(dbAcl, db, cred, edit); }
784
785 void ClientSession::getDbOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc)
786 { getOwner(dbAcl, db, owner, alloc); }
787
788 void ClientSession::changeDbOwner(DbHandle db, const AccessCredentials &cred,
789 const AclOwnerPrototype &edit)
790 { changeOwner(dbAcl, db, cred, edit); }
791
792
793 //
794 // Database key management
795 //
796 void ClientSession::extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb,
797 uint32 keyUsage, uint32 keyAttr,
798 const AccessCredentials *cred, const AclEntryInput *owner,
799 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc)
800 {
801 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
802 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
803 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
804 void *keyHeaderData;
805 mach_msg_type_number_t keyHeaderDataLength;
806
807 IPC(ucsp_client_extractMasterKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), sourceDb,
808 creds.data(), creds.length(), proto.data(), proto.length(),
809 keyUsage, keyAttr, &newKey, &keyHeaderData, &keyHeaderDataLength));
810
811 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
812 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
813 }
814
815
816 //
817 // Authorization subsystem entry
818 //
819 void ClientSession::authCreate(const AuthorizationItemSet *rights,
820 const AuthorizationItemSet *environment, AuthorizationFlags flags,
821 AuthorizationBlob &result)
822 {
823 void *rightSet = NULL; mach_msg_size_t rightSet_size = 0;
824 void *environ = NULL; mach_msg_size_t environ_size = 0;
825
826 if ((rights &&
827 !copyin_AuthorizationItemSet(rights, &rightSet, &rightSet_size)) ||
828 (environment &&
829 !copyin_AuthorizationItemSet(environment, &environ, &environ_size)))
830 CssmError::throwMe(errAuthorizationInternal);
831
832 activate();
833 IPCSTART(ucsp_client_authorizationCreate(UCSP_ARGS,
834 rightSet, rightSet_size,
835 flags,
836 environ, environ_size,
837 &result));
838
839 free(rightSet);
840 free(environ);
841
842 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
843 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
844 IPCEND_CHECK;
845 }
846
847 void ClientSession::authRelease(const AuthorizationBlob &auth,
848 AuthorizationFlags flags)
849 {
850 activate();
851 IPCSTART(ucsp_client_authorizationRelease(UCSP_ARGS, auth, flags));
852 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
853 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
854 IPCEND_CHECK;
855 }
856
857 void ClientSession::authCopyRights(const AuthorizationBlob &auth,
858 const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
859 AuthorizationFlags flags,
860 AuthorizationItemSet **grantedRights)
861 {
862 void *rightSet = NULL; mach_msg_size_t rightSet_size = 0;
863 void *environ = NULL; mach_msg_size_t environ_size = 0;
864 void *result = NULL; mach_msg_type_number_t resultLength = 0;
865
866 if ((rights && !copyin_AuthorizationItemSet(rights, &rightSet, &rightSet_size)) ||
867 (environment && !copyin_AuthorizationItemSet(environment, &environ, &environ_size)))
868 CssmError::throwMe(errAuthorizationInternal); // allocation error probably
869
870 activate();
871 IPCSTART(ucsp_client_authorizationCopyRights(UCSP_ARGS,
872 auth,
873 rightSet, rightSet_size,
874 flags | (grantedRights ? 0 : kAuthorizationFlagNoData),
875 environ, environ_size,
876 &result, &resultLength));
877
878 free(rightSet);
879 free(environ);
880
881 // XXX/cs return error when copyout returns false
882 if (rcode == CSSM_OK && grantedRights)
883 copyout_AuthorizationItemSet(result, resultLength, grantedRights);
884
885 if (result)
886 mig_deallocate(reinterpret_cast<vm_address_t>(result), resultLength);
887 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
888 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
889 IPCEND_CHECK;
890 }
891
892 void ClientSession::authCopyInfo(const AuthorizationBlob &auth,
893 const char *tag,
894 AuthorizationItemSet * &info)
895 {
896 if (tag == NULL)
897 tag = "";
898 else if (tag[0] == '\0')
899 MacOSError::throwMe(errAuthorizationInvalidTag);
900
901 activate();
902 void *result; mach_msg_type_number_t resultLength;
903 IPCSTART(ucsp_client_authorizationCopyInfo(UCSP_ARGS, auth, tag, &result, &resultLength));
904
905 // XXX/cs return error when copyout returns false
906 if (rcode == CSSM_OK)
907 copyout_AuthorizationItemSet(result, resultLength, &info);
908
909 if (result)
910 mig_deallocate(reinterpret_cast<vm_address_t>(result), resultLength);
911
912 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
913 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
914 IPCEND_CHECK;
915 }
916
917 void ClientSession::authExternalize(const AuthorizationBlob &auth,
918 AuthorizationExternalForm &extForm)
919 {
920 activate();
921 IPCSTART(ucsp_client_authorizationExternalize(UCSP_ARGS, auth, &extForm));
922 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
923 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
924 IPCEND_CHECK;
925 }
926
927 void ClientSession::authInternalize(const AuthorizationExternalForm &extForm,
928 AuthorizationBlob &auth)
929 {
930 activate();
931 IPCSTART(ucsp_client_authorizationInternalize(UCSP_ARGS, extForm, &auth));
932 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
933 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
934 IPCEND_CHECK;
935 }
936
937
938 //
939 // Push user preferences from an app in user space to securityd
940 //
941 void ClientSession::setSessionUserPrefs(SecuritySessionId sessionId, uint32_t userPreferencesLength, const void *userPreferences)
942 {
943 IPC(ucsp_client_setSessionUserPrefs(UCSP_ARGS, sessionId, const_cast<void *>(userPreferences), userPreferencesLength));
944 }
945
946
947 void ClientSession::postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data)
948 {
949 uint32 seq = ++mGlobal().thread().notifySeq;
950 #if !defined(NDEBUG)
951 if (getenv("NOTIFYJITTER")) {
952 // artificially reverse odd/even sequences to test securityd's jitter buffer
953 seq += 2 * (seq % 2) - 1;
954 secdebug("notify", "POSTING FAKE SEQUENCE %d NOTIFICATION", seq);
955 }
956 #endif //NDEBUG
957 secdebug("notify", "posting domain 0x%x event %d sequence %d",
958 domain, event, seq);
959 IPC(ucsp_client_postNotification(UCSP_ARGS, domain, event, DATA(data), seq));
960 }
961
962 //
963 // authorizationdbGet/Set/Remove
964 //
965 void ClientSession::authorizationdbGet(const AuthorizationString rightname, CssmData &rightDefinition, Allocator &alloc)
966 {
967 DataOutput definition(rightDefinition, alloc);
968 activate();
969 IPCSTART(ucsp_client_authorizationdbGet(UCSP_ARGS, rightname, DATA_OUT(definition)));
970 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
971 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
972 IPCEND_CHECK;
973 }
974
975 void ClientSession::authorizationdbSet(const AuthorizationBlob &auth, const AuthorizationString rightname, uint32_t rightDefinitionLength, const void *rightDefinition)
976 {
977 // @@@ DATA_IN in transition.cpp is not const void *
978 activate();
979 IPCSTART(ucsp_client_authorizationdbSet(UCSP_ARGS, auth, rightname, const_cast<void *>(rightDefinition), rightDefinitionLength));
980 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
981 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
982 IPCEND_CHECK;
983 }
984
985 void ClientSession::authorizationdbRemove(const AuthorizationBlob &auth, const AuthorizationString rightname)
986 {
987 activate();
988 IPCSTART(ucsp_client_authorizationdbRemove(UCSP_ARGS, auth, rightname));
989 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
990 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
991 IPCEND_CHECK;
992 }
993
994
995 //
996 // Code Signing related
997 //
998 void ClientSession::registerHosting(mach_port_t hostingPort, SecCSFlags flags)
999 {
1000 IPC(ucsp_client_registerHosting(UCSP_ARGS, hostingPort, flags));
1001 }
1002
1003 mach_port_t ClientSession::hostingPort(pid_t pid)
1004 {
1005 mach_port_t result;
1006 IPC(ucsp_client_hostingPort(UCSP_ARGS, pid, &result));
1007 return result;
1008 }
1009
1010 SecGuestRef ClientSession::createGuest(SecGuestRef host,
1011 uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags)
1012 {
1013 SecGuestRef newGuest;
1014 IPC(ucsp_client_createGuest(UCSP_ARGS, host, status, path, DATA(cdhash), DATA(attributes), flags, &newGuest));
1015 if (flags & kSecCSDedicatedHost) {
1016 secdebug("ssclient", "setting dedicated guest to 0x%x (was 0x%x)",
1017 mDedicatedGuest, newGuest);
1018 mDedicatedGuest = newGuest;
1019 }
1020 return newGuest;
1021 }
1022
1023 void ClientSession::setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes)
1024 {
1025 IPC(ucsp_client_setGuestStatus(UCSP_ARGS, guest, status, DATA(attributes)));
1026 }
1027
1028 void ClientSession::removeGuest(SecGuestRef host, SecGuestRef guest)
1029 {
1030 IPC(ucsp_client_removeGuest(UCSP_ARGS, host, guest));
1031 }
1032
1033 void ClientSession::selectGuest(SecGuestRef newGuest)
1034 {
1035 if (mDedicatedGuest) {
1036 secdebug("ssclient", "ignoring selectGuest(0x%x) because dedicated guest=0x%x",
1037 newGuest, mDedicatedGuest);
1038 } else {
1039 secdebug("ssclient", "switching to guest 0x%x", newGuest);
1040 mGlobal().thread().currentGuest = newGuest;
1041 }
1042 }
1043
1044 SecGuestRef ClientSession::selectedGuest() const
1045 {
1046 if (mDedicatedGuest)
1047 return mDedicatedGuest;
1048 else
1049 return mGlobal().thread().currentGuest;
1050 }
1051
1052
1053 } // end namespace SecurityServer
1054 } // end namespace Security