]> git.saurik.com Git - apple/security.git/blob - libsecurityd/lib/transition.cpp
063193039c20f748581af0131938f0b64293a8f5
[apple/security.git] / libsecurityd / lib / transition.cpp
1 /*
2 * Copyright (c) 2000-2008 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 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
53
54 #include <securityd_client/xdr_auth.h>
55 #include <securityd_client/xdr_cssm.h>
56 #include <securityd_client/xdr_dldb.h>
57
58 namespace Security {
59 namespace SecurityServer {
60
61 using MachPlusPlus::check;
62 using MachPlusPlus::VMGuard;
63
64 //
65 // Common database interface
66 //
67 void ClientSession::authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type,
68 const AccessCredentials *cred)
69 {
70 // XXX/cs Leave it up to DatabaseAccessCredentials to rewrite it for now
71 DatabaseAccessCredentials creds(cred, internalAllocator);
72 CopyIn copy(creds.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
73 IPC(ucsp_client_authenticateDb(UCSP_ARGS, db, type, copy.data(), copy.length()));
74 }
75
76
77 void ClientSession::releaseDb(DbHandle db)
78 {
79 IPC(ucsp_client_releaseDb(UCSP_ARGS, db));
80 }
81
82
83 //
84 // External database interface
85 //
86 DbHandle ClientSession::openToken(uint32 ssid, const AccessCredentials *cred,
87 const char *name)
88 {
89 DbHandle db;
90 DatabaseAccessCredentials creds(cred, internalAllocator);
91 CopyIn copycreds(creds.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
92
93 IPC(ucsp_client_openToken(UCSP_ARGS, ssid, name ? name : "", copycreds.data(), copycreds.length(), &db));
94
95 return db;
96 }
97
98
99 RecordHandle ClientSession::insertRecord(DbHandle db,
100 CSSM_DB_RECORDTYPE recordType,
101 const CssmDbRecordAttributeData *attributes,
102 const CssmData *data)
103 {
104 RecordHandle record;
105 CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
106
107 IPC(ucsp_client_insertRecord(UCSP_ARGS, db, recordType, db_record_attr_data.data(), db_record_attr_data.length(), OPTIONALDATA(data), &record));
108
109 return record;
110 }
111
112
113 void ClientSession::deleteRecord(DbHandle db, RecordHandle record)
114 {
115 IPC(ucsp_client_deleteRecord(UCSP_ARGS, db, record));
116 }
117
118
119 void ClientSession::modifyRecord(DbHandle db, RecordHandle &record,
120 CSSM_DB_RECORDTYPE recordType,
121 const CssmDbRecordAttributeData *attributes,
122 const CssmData *data,
123 CSSM_DB_MODIFY_MODE modifyMode)
124 {
125 CopyIn db_record_attr_data(attributes, reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA));
126
127 IPC(ucsp_client_modifyRecord(UCSP_ARGS, db, &record, recordType, db_record_attr_data.data(), db_record_attr_data.length(),
128 data != NULL, OPTIONALDATA(data), modifyMode));
129 }
130
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::authenticateDbsForSync(const CssmData &dbHandleArray,
279 const CssmData &agentData)
280 {
281 DbHandle newDb;
282
283 IPC(ucsp_client_authenticateDbsForSync(UCSP_ARGS, DATA(dbHandleArray), DATA(agentData), &newDb));
284
285 return newDb;
286 }
287
288 void ClientSession::commitDbForSync(DbHandle srcDb, DbHandle cloneDb,
289 CssmData &blob, Allocator &alloc)
290 {
291 DataOutput outBlob(blob, alloc);
292 IPC(ucsp_client_commitDbForSync(UCSP_ARGS, srcDb, cloneDb, DATA(outBlob)));
293 }
294
295 DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
296 const AccessCredentials *cred, const CssmData &blob)
297 {
298 // XXX/64 fold into one translation
299 DatabaseAccessCredentials credentials(cred, internalAllocator);
300 CopyIn creds(credentials.value(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
301 // XXX/64 fold into one translation
302 DataWalkers::DLDbFlatIdentifier ident(dbId);
303 CopyIn id(&ident, reinterpret_cast<xdrproc_t>(xdr_DLDbFlatIdentifier));
304 DbHandle db;
305
306 IPC(ucsp_client_decodeDb(UCSP_ARGS, &db, id.data(), id.length(), creds.data(), creds.length(), DATA(blob)));
307
308 return db;
309 }
310
311 void ClientSession::encodeDb(DbHandle db, CssmData &blob, Allocator &alloc)
312 {
313 DataOutput outBlob(blob, alloc);
314 IPC(ucsp_client_encodeDb(UCSP_ARGS, db, DATA(outBlob)));
315 }
316
317 void ClientSession::setDbParameters(DbHandle db, const DBParameters &params)
318 {
319 IPC(ucsp_client_setDbParameters(UCSP_ARGS, db, params));
320 }
321
322 void ClientSession::getDbParameters(DbHandle db, DBParameters &params)
323 {
324 IPC(ucsp_client_getDbParameters(UCSP_ARGS, db, &params));
325 }
326
327 void ClientSession::changePassphrase(DbHandle db, const AccessCredentials *cred)
328 {
329 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
330 IPC(ucsp_client_changePassphrase(UCSP_ARGS, db, creds.data(), creds.length()));
331 }
332
333
334 void ClientSession::lock(DbHandle db)
335 {
336 IPC(ucsp_client_authenticateDb(UCSP_ARGS, db, CSSM_DB_ACCESS_RESET, NULL, 0));
337 //@@@VIRTUAL IPC(ucsp_client_lockDb(UCSP_ARGS, db));
338 }
339
340 void ClientSession::lockAll (bool forSleep)
341 {
342 IPC(ucsp_client_lockAll (UCSP_ARGS, forSleep));
343 }
344
345 void ClientSession::unlock(DbHandle db)
346 {
347 IPC(ucsp_client_unlockDb(UCSP_ARGS, db));
348 }
349
350 void ClientSession::unlock(DbHandle db, const CssmData &passphrase)
351 {
352 IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS, db, DATA(passphrase)));
353 }
354
355 bool ClientSession::isLocked(DbHandle db)
356 {
357 boolean_t locked;
358 IPC(ucsp_client_isLocked(UCSP_ARGS, db, &locked));
359 return locked;
360 }
361
362
363 //
364 // Key control
365 //
366 void ClientSession::encodeKey(KeyHandle key, CssmData &blob,
367 KeyUID *uid, Allocator &alloc)
368 {
369 // Not really used as output
370 DataOutput oBlob(blob, alloc);
371 void *uidp;
372 mach_msg_type_number_t uidLength;
373
374 IPC(ucsp_client_encodeKey(UCSP_ARGS, key, oBlob.data(), oBlob.length(),
375 (uid != NULL), &uidp, &uidLength));
376
377 // return key uid if requested
378 if (uid) {
379 assert(uidLength == sizeof(KeyUID));
380 memcpy(uid, uidp, sizeof(KeyUID));
381 }
382 }
383
384 KeyHandle ClientSession::decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header)
385 {
386 KeyHandle key;
387 void *keyHeaderData;
388 mach_msg_type_number_t keyHeaderDataLength;
389
390 IPC(ucsp_client_decodeKey(UCSP_ARGS, &key, &keyHeaderData, &keyHeaderDataLength, db, blob.data(), blob.length()));
391
392 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
393 header = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
394
395 return key;
396 }
397
398 // keychain synchronization
399 void ClientSession::recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb,
400 CssmData &blob)
401 {
402 DataOutput outBlob(blob, returnAllocator);
403 IPC(ucsp_client_recodeKey(UCSP_ARGS, oldDb, key, newDb, DATA(outBlob)));
404 }
405
406 void ClientSession::releaseKey(KeyHandle key)
407 {
408 IPC(ucsp_client_releaseKey(UCSP_ARGS, key));
409 }
410
411
412 CssmKeySize ClientSession::queryKeySizeInBits(KeyHandle key)
413 {
414 CssmKeySize length;
415 IPC(ucsp_client_queryKeySizeInBits(UCSP_ARGS, key, &length));
416 return length;
417 }
418
419
420 uint32 ClientSession::getOutputSize(const Context &context, KeyHandle key,
421 uint32 inputSize, bool encrypt)
422 {
423 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
424 uint32 outputSize;
425
426 IPC(ucsp_client_getOutputSize(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, inputSize, encrypt, &outputSize));
427 return outputSize;
428 }
429
430
431 //
432 // Random number generation.
433 // This interfaces to the secure RNG inside the SecurityServer; it does not access
434 // a PRNG in its CSP. If you need a reproducible PRNG, attach a local CSP and use it.
435 // Note that this function does not allocate a buffer; it always fills the buffer provided.
436 //
437 void ClientSession::generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc)
438 {
439 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
440 DataOutput result(data, alloc);
441
442 IPC(ucsp_client_generateRandom(UCSP_ARGS, 0, ctxcopy.data(), ctxcopy.length(), DATA(result)));
443 }
444
445
446 //
447 // Signatures and MACs
448 //
449 void ClientSession::generateSignature(const Context &context, KeyHandle key,
450 const CssmData &data, CssmData &signature, Allocator &alloc, CSSM_ALGORITHMS signOnlyAlgorithm)
451 {
452 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
453 DataOutput sig(signature, alloc);
454
455 IPCKEY(ucsp_client_generateSignature(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, signOnlyAlgorithm,
456 DATA(data), DATA(sig)),
457 key, CSSM_ACL_AUTHORIZATION_SIGN);
458 }
459
460 void ClientSession::verifySignature(const Context &context, KeyHandle key,
461 const CssmData &data, const CssmData &signature, CSSM_ALGORITHMS verifyOnlyAlgorithm)
462 {
463 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
464
465 IPC(ucsp_client_verifySignature(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, verifyOnlyAlgorithm, DATA(data), DATA(signature)));
466 }
467
468
469 void ClientSession::generateMac(const Context &context, KeyHandle key,
470 const CssmData &data, CssmData &signature, Allocator &alloc)
471 {
472 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
473 DataOutput sig(signature, alloc);
474
475 IPCKEY(ucsp_client_generateMac(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(data), DATA(sig)),
476 key, CSSM_ACL_AUTHORIZATION_MAC);
477 }
478
479 void ClientSession::verifyMac(const Context &context, KeyHandle key,
480 const CssmData &data, const CssmData &signature)
481 {
482 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
483
484 IPCKEY(ucsp_client_verifyMac(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key,
485 DATA(data), DATA(signature)),
486 key, CSSM_ACL_AUTHORIZATION_MAC);
487 }
488
489
490 //
491 // Encryption/Decryption
492 //
493
494 void ClientSession::encrypt(const Context &context, KeyHandle key,
495 const CssmData &clear, CssmData &cipher, Allocator &alloc)
496 {
497 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
498 DataOutput cipherOut(cipher, alloc);
499 IPCKEY(ucsp_client_encrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(clear), DATA(cipherOut)),
500 key, CSSM_ACL_AUTHORIZATION_ENCRYPT);
501 }
502
503 void ClientSession::decrypt(const Context &context, KeyHandle key,
504 const CssmData &cipher, CssmData &clear, Allocator &alloc)
505 {
506 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
507 DataOutput clearOut(clear, alloc);
508
509 IPCKEY(ucsp_client_decrypt(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), key, DATA(cipher), DATA(clearOut)),
510 key, CSSM_ACL_AUTHORIZATION_DECRYPT);
511 }
512
513
514 //
515 // Key generation
516 //
517 void ClientSession::generateKey(DbHandle db, const Context &context, uint32 keyUsage, uint32 keyAttr,
518 const AccessCredentials *cred, const AclEntryInput *owner,
519 KeyHandle &newKey, CssmKey::Header &newHeader)
520 {
521 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
522 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
523 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
524 void *keyHeaderData;
525 mach_msg_type_number_t keyHeaderDataLength;
526
527 IPC(ucsp_client_generateKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(),
528 creds.data(), creds.length(), proto.data(), proto.length(),
529 keyUsage, keyAttr, &newKey, &keyHeaderData, &keyHeaderDataLength));
530
531 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
532 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
533 }
534
535 void ClientSession::generateKey(DbHandle db, const Context &context,
536 uint32 pubKeyUsage, uint32 pubKeyAttr,
537 uint32 privKeyUsage, uint32 privKeyAttr,
538 const AccessCredentials *cred, const AclEntryInput *owner,
539 KeyHandle &pubKey, CssmKey::Header &pubHeader,
540 KeyHandle &privKey, CssmKey::Header &privHeader)
541 {
542 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
543 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
544 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
545 void *pubKeyHeaderData, *privKeyHeaderData;
546 mach_msg_type_number_t pubKeyHeaderDataLength, privKeyHeaderDataLength;
547
548 IPC(ucsp_client_generateKeyPair(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(),
549 creds.data(), creds.length(), proto.data(), proto.length(),
550 pubKeyUsage, pubKeyAttr, privKeyUsage, privKeyAttr,
551 &pubKey, &pubKeyHeaderData, &pubKeyHeaderDataLength,
552 &privKey, &privKeyHeaderData, &privKeyHeaderDataLength));
553
554 CopyOut wrappedPubKeyHeaderXDR(pubKeyHeaderData, pubKeyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
555 pubHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedPubKeyHeaderXDR.data()));
556 CopyOut wrappedPrivKeyHeaderXDR(privKeyHeaderData, privKeyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
557 privHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedPrivKeyHeaderXDR.data()));
558
559 }
560
561
562 //
563 // Key derivation
564 // This is a bit strained; the incoming 'param' value may have structure,
565 // and we use a synthetic CssmDeriveData structure (with ad-hoc walker) to
566 // handle that. Param also is input/output, which is always a pain (not to mention
567 // ill-defined by the CDSA standard).
568 //
569 // If you're here because an algorithm of yours requires structured parameter
570 // input, go to security_cdsa_utilities/cssmwalkers.h and add a case to the
571 // CssmDeriveData walker.
572 //
573 void ClientSession::deriveKey(DbHandle db, const Context &context, KeyHandle baseKey,
574 CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, CssmData &param,
575 const AccessCredentials *cred, const AclEntryInput *owner,
576 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &allocator)
577 {
578 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
579 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
580 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
581 CSSM_DERIVE_DATA inParamForm = { context.algorithm(), param };
582 CopyIn inParam(&inParamForm, reinterpret_cast<xdrproc_t>(xdr_CSSM_DERIVE_DATA));
583
584 try
585 {
586 DataOutput paramOutput(param, allocator);
587 void *keyHeaderData;
588 mach_msg_type_number_t keyHeaderDataLength;
589
590 IPCKEY(ucsp_client_deriveKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), baseKey,
591 creds.data(), creds.length(), proto.data(), proto.length(),
592 inParam.data(), inParam.length(), DATA(paramOutput),
593 usage, attrs, &newKey, &keyHeaderData, &keyHeaderDataLength),
594 baseKey, CSSM_ACL_AUTHORIZATION_DERIVE);
595
596 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
597 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
598 }
599 catch (CssmError& e)
600 {
601 // filter out errors for CSSM_ALGID_PKCS5_PBKDF2
602 if (context.algorithm() != CSSM_ALGID_PKCS5_PBKDF2 && e.error != CSSMERR_CSP_OUTPUT_LENGTH_ERROR)
603 {
604 throw;
605 }
606 }
607 }
608
609
610 //
611 // Digest generation
612 //
613 void ClientSession::getKeyDigest(KeyHandle key, CssmData &digest, Allocator &allocator)
614 {
615 DataOutput dig(digest, allocator);
616 IPC(ucsp_client_getKeyDigest(UCSP_ARGS, key, DATA(dig)));
617 }
618
619
620 //
621 // Key wrapping and unwrapping
622 //
623 void ClientSession::wrapKey(const Context &context, KeyHandle wrappingKey,
624 KeyHandle keyToBeWrapped, const AccessCredentials *cred,
625 const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, Allocator &alloc)
626 {
627 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
628 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
629 void *keyData;
630 mach_msg_type_number_t keyDataLength;
631
632 IPCKEY(ucsp_client_wrapKey(UCSP_ARGS, ctxcopy.data(), ctxcopy.length(), wrappingKey,
633 creds.data(), creds.length(),
634 keyToBeWrapped, OPTIONALDATA(descriptiveData),
635 &keyData, &keyDataLength),
636 keyToBeWrapped,
637 context.algorithm() == CSSM_ALGID_NONE
638 ? CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR : CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED);
639
640 CopyOut wrappedKeyXDR(keyData, keyDataLength + sizeof(CSSM_KEY), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY_PTR), true);
641 CssmWrappedKey *wrappedKeyIPC = reinterpret_cast<CssmWrappedKey*>(wrappedKeyXDR.data());
642 wrappedKey.header() = wrappedKeyIPC->header();
643 wrappedKey.keyData() = CssmData(alloc.malloc(wrappedKeyIPC->keyData().length()), wrappedKeyIPC->keyData().length());
644 memcpy(wrappedKey.keyData().data(), wrappedKeyIPC->keyData(), wrappedKeyIPC->keyData().length());
645 }
646
647 void ClientSession::unwrapKey(DbHandle db, const Context &context, KeyHandle key,
648 KeyHandle publicKey, const CssmWrappedKey &wrappedKey,
649 uint32 usage, uint32 attr,
650 const AccessCredentials *cred, const AclEntryInput *acl,
651 CssmData &descriptiveData,
652 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc)
653 {
654 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
655 DataOutput descriptor(descriptiveData, alloc);
656 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
657 CopyIn proto(acl ? &acl->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
658 CopyIn wrappedKeyXDR(&wrappedKey, reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY));
659 void *keyHeaderData;
660 mach_msg_type_number_t keyHeaderDataLength;
661
662 IPCKEY(ucsp_client_unwrapKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), key,
663 creds.data(), creds.length(), proto.data(), proto.length(),
664 publicKey, wrappedKeyXDR.data(), wrappedKeyXDR.length(), usage, attr, DATA(descriptor),
665 &newKey, &keyHeaderData, &keyHeaderDataLength),
666 key, CSSM_ACL_AUTHORIZATION_DECRYPT);
667
668 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
669 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
670 }
671
672
673 //
674 // ACL management
675 //
676 void ClientSession::getAcl(AclKind kind, GenericHandle key, const char *tag,
677 uint32 &infoCount, AclEntryInfo * &infoArray, Allocator &alloc)
678 {
679 uint32 count;
680 void* info; mach_msg_type_number_t infoLength;
681 IPC(ucsp_client_getAcl(UCSP_ARGS, kind, key,
682 (tag != NULL), tag ? tag : "",
683 &count, &info, &infoLength));
684
685 CSSM_ACL_ENTRY_INFO_ARRAY_PTR aclsArray;
686 if (!::copyout_chunked(info, infoLength, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_INFO_ARRAY_PTR), reinterpret_cast<void**>(&aclsArray)))
687 CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);
688
689 infoCount = aclsArray->count;
690 infoArray = reinterpret_cast<AclEntryInfo*>(aclsArray->acls);
691 free(aclsArray);
692 }
693
694 void ClientSession::changeAcl(AclKind kind, GenericHandle key, const AccessCredentials &cred,
695 const AclEdit &edit)
696 {
697 CopyIn creds(&cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
698 //@@@ ignoring callback
699 CopyIn newEntry(edit.newEntry(), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_INPUT));
700
701 IPCKEY(ucsp_client_changeAcl(UCSP_ARGS, kind, key, creds.data(), creds.length(),
702 edit.mode(), toIPCHandle(edit.handle()), newEntry.data(), newEntry.length()),
703 key, CSSM_ACL_AUTHORIZATION_CHANGE_ACL);
704 }
705
706 void ClientSession::getOwner(AclKind kind, GenericHandle key, AclOwnerPrototype &owner,
707 Allocator &alloc)
708 {
709 void* proto; mach_msg_type_number_t protoLength;
710 IPC(ucsp_client_getOwner(UCSP_ARGS, kind, key, &proto, &protoLength));
711
712 CSSM_ACL_OWNER_PROTOTYPE_PTR tmpOwner;
713 if (!::copyout_chunked(proto, protoLength, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE_PTR), reinterpret_cast<void **>(&tmpOwner)))
714 CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);
715 owner = *static_cast<AclOwnerPrototypePtr>(tmpOwner);
716 free(tmpOwner);
717 }
718
719 void ClientSession::changeOwner(AclKind kind, GenericHandle key,
720 const AccessCredentials &cred, const AclOwnerPrototype &proto)
721 {
722 CopyIn creds(&cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
723 CopyIn protos(&proto, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE));
724 IPCKEY(ucsp_client_setOwner(UCSP_ARGS, kind, key, creds.data(), creds.length(), protos.data(), protos.length()),
725 key, CSSM_ACL_AUTHORIZATION_CHANGE_OWNER);
726 }
727
728
729 void ClientSession::getKeyAcl(DbHandle db, const char *tag,
730 uint32 &count, AclEntryInfo * &info, Allocator &alloc)
731 { getAcl(keyAcl, db, tag, count, info, alloc); }
732
733 void ClientSession::changeKeyAcl(DbHandle db, const AccessCredentials &cred,
734 const AclEdit &edit)
735 { changeAcl(keyAcl, db, cred, edit); }
736
737 void ClientSession::getKeyOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc)
738 { getOwner(keyAcl, db, owner, alloc); }
739
740 void ClientSession::changeKeyOwner(DbHandle db, const AccessCredentials &cred,
741 const AclOwnerPrototype &edit)
742 { changeOwner(keyAcl, db, cred, edit); }
743
744 void ClientSession::getDbAcl(DbHandle db, const char *tag,
745 uint32 &count, AclEntryInfo * &info, Allocator &alloc)
746 { getAcl(dbAcl, db, tag, count, info, alloc); }
747
748 void ClientSession::changeDbAcl(DbHandle db, const AccessCredentials &cred,
749 const AclEdit &edit)
750 { changeAcl(dbAcl, db, cred, edit); }
751
752 void ClientSession::getDbOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc)
753 { getOwner(dbAcl, db, owner, alloc); }
754
755 void ClientSession::changeDbOwner(DbHandle db, const AccessCredentials &cred,
756 const AclOwnerPrototype &edit)
757 { changeOwner(dbAcl, db, cred, edit); }
758
759
760 //
761 // Database key management
762 //
763 void ClientSession::extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb,
764 uint32 keyUsage, uint32 keyAttr,
765 const AccessCredentials *cred, const AclEntryInput *owner,
766 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc)
767 {
768 CopyIn ctxcopy(&context, reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT));
769 CopyIn creds(cred, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS));
770 CopyIn proto(owner ? &owner->proto() : NULL, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE));
771 void *keyHeaderData;
772 mach_msg_type_number_t keyHeaderDataLength;
773
774 IPC(ucsp_client_extractMasterKey(UCSP_ARGS, db, ctxcopy.data(), ctxcopy.length(), sourceDb,
775 creds.data(), creds.length(), proto.data(), proto.length(),
776 keyUsage, keyAttr, &newKey, &keyHeaderData, &keyHeaderDataLength));
777
778 CopyOut wrappedKeyHeaderXDR(keyHeaderData, keyHeaderDataLength + sizeof(CSSM_KEYHEADER), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEYHEADER_PTR), true);
779 newHeader = *static_cast<CssmKey::Header *>(reinterpret_cast<CSSM_KEYHEADER*>(wrappedKeyHeaderXDR.data()));
780 }
781
782
783 //
784 // Authorization subsystem entry
785 //
786 void ClientSession::authCreate(const AuthorizationItemSet *rights,
787 const AuthorizationItemSet *environment, AuthorizationFlags flags,
788 AuthorizationBlob &result)
789 {
790 void *rightSet = NULL; mach_msg_size_t rightSet_size = 0;
791 void *environ = NULL; mach_msg_size_t environ_size = 0;
792
793 if ((rights &&
794 !copyin_AuthorizationItemSet(rights, &rightSet, &rightSet_size)) ||
795 (environment &&
796 !copyin_AuthorizationItemSet(environment, &environ, &environ_size)))
797 CssmError::throwMe(errAuthorizationInternal);
798
799 activate();
800 IPCSTART(ucsp_client_authorizationCreate(UCSP_ARGS,
801 rightSet, rightSet_size,
802 flags,
803 environ, environ_size,
804 &result));
805
806 free(rightSet);
807 free(environ);
808
809 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
810 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
811 IPCEND_CHECK;
812 }
813
814 void ClientSession::authRelease(const AuthorizationBlob &auth,
815 AuthorizationFlags flags)
816 {
817 activate();
818 IPCSTART(ucsp_client_authorizationRelease(UCSP_ARGS, auth, flags));
819 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
820 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
821 IPCEND_CHECK;
822 }
823
824 void ClientSession::authCopyRights(const AuthorizationBlob &auth,
825 const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
826 AuthorizationFlags flags,
827 AuthorizationItemSet **grantedRights)
828 {
829 void *rightSet = NULL; mach_msg_size_t rightSet_size = 0;
830 void *environ = NULL; mach_msg_size_t environ_size = 0;
831 void *result = NULL; mach_msg_type_number_t resultLength = 0;
832
833 if ((rights && !copyin_AuthorizationItemSet(rights, &rightSet, &rightSet_size)) ||
834 (environment && !copyin_AuthorizationItemSet(environment, &environ, &environ_size)))
835 CssmError::throwMe(errAuthorizationInternal); // allocation error probably
836
837 activate();
838 IPCSTART(ucsp_client_authorizationCopyRights(UCSP_ARGS,
839 auth,
840 rightSet, rightSet_size,
841 flags | (grantedRights ? 0 : kAuthorizationFlagNoData),
842 environ, environ_size,
843 &result, &resultLength));
844
845 free(rightSet);
846 free(environ);
847
848 // XXX/cs return error when copyout returns false
849 if (rcode == CSSM_OK && grantedRights)
850 copyout_AuthorizationItemSet(result, resultLength, grantedRights);
851
852 if (result)
853 mig_deallocate(reinterpret_cast<vm_address_t>(result), resultLength);
854 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
855 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
856 IPCEND_CHECK;
857 }
858
859 void ClientSession::authCopyInfo(const AuthorizationBlob &auth,
860 const char *tag,
861 AuthorizationItemSet * &info)
862 {
863 if (tag == NULL)
864 tag = "";
865 else if (tag[0] == '\0')
866 MacOSError::throwMe(errAuthorizationInvalidTag);
867
868 activate();
869 void *result; mach_msg_type_number_t resultLength;
870 IPCSTART(ucsp_client_authorizationCopyInfo(UCSP_ARGS, auth, tag, &result, &resultLength));
871
872 // XXX/cs return error when copyout returns false
873 if (rcode == CSSM_OK)
874 copyout_AuthorizationItemSet(result, resultLength, &info);
875
876 if (result)
877 mig_deallocate(reinterpret_cast<vm_address_t>(result), resultLength);
878
879 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
880 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
881 IPCEND_CHECK;
882 }
883
884 void ClientSession::authExternalize(const AuthorizationBlob &auth,
885 AuthorizationExternalForm &extForm)
886 {
887 activate();
888 IPCSTART(ucsp_client_authorizationExternalize(UCSP_ARGS, auth, &extForm));
889 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
890 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
891 IPCEND_CHECK;
892 }
893
894 void ClientSession::authInternalize(const AuthorizationExternalForm &extForm,
895 AuthorizationBlob &auth)
896 {
897 activate();
898 IPCSTART(ucsp_client_authorizationInternalize(UCSP_ARGS, extForm, &auth));
899 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
900 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
901 IPCEND_CHECK;
902 }
903
904
905 //
906 // Push user preferences from an app in user space to securityd
907 //
908 void ClientSession::setSessionUserPrefs(SecuritySessionId sessionId, uint32_t userPreferencesLength, const void *userPreferences)
909 {
910 IPC(ucsp_client_setSessionUserPrefs(UCSP_ARGS, sessionId, const_cast<void *>(userPreferences), userPreferencesLength));
911 }
912
913
914 void ClientSession::postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data)
915 {
916 uint32 seq = ++mGlobal().thread().notifySeq;
917 #if !defined(NDEBUG)
918 if (getenv("NOTIFYJITTER")) {
919 // artificially reverse odd/even sequences to test securityd's jitter buffer
920 seq += 2 * (seq % 2) - 1;
921 secdebug("notify", "POSTING FAKE SEQUENCE %d NOTIFICATION", seq);
922 }
923 #endif //NDEBUG
924 secdebug("notify", "posting domain 0x%x event %d sequence %d",
925 domain, event, seq);
926 IPC(ucsp_client_postNotification(UCSP_ARGS, domain, event, DATA(data), seq));
927 }
928
929 //
930 // authorizationdbGet/Set/Remove
931 //
932 void ClientSession::authorizationdbGet(const AuthorizationString rightname, CssmData &rightDefinition, Allocator &alloc)
933 {
934 DataOutput definition(rightDefinition, alloc);
935 activate();
936 IPCSTART(ucsp_client_authorizationdbGet(UCSP_ARGS, rightname, DATA(definition)));
937 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
938 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
939 IPCEND_CHECK;
940 }
941
942 void ClientSession::authorizationdbSet(const AuthorizationBlob &auth, const AuthorizationString rightname, uint32_t rightDefinitionLength, const void *rightDefinition)
943 {
944 // @@@ DATA_IN in transition.cpp is not const void *
945 activate();
946 IPCSTART(ucsp_client_authorizationdbSet(UCSP_ARGS, auth, rightname, const_cast<void *>(rightDefinition), rightDefinitionLength));
947 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
948 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
949 IPCEND_CHECK;
950 }
951
952 void ClientSession::authorizationdbRemove(const AuthorizationBlob &auth, const AuthorizationString rightname)
953 {
954 activate();
955 IPCSTART(ucsp_client_authorizationdbRemove(UCSP_ARGS, auth, rightname));
956 if (rcode == CSSMERR_CSSM_NO_USER_INTERACTION)
957 CssmError::throwMe(errAuthorizationInteractionNotAllowed);
958 IPCEND_CHECK;
959 }
960
961
962 //
963 // Miscellaneous administrative calls
964 //
965 void ClientSession::addCodeEquivalence(const CssmData &oldHash, const CssmData &newHash,
966 const char *name, bool forSystem /* = false */)
967 {
968 IPC(ucsp_client_addCodeEquivalence(UCSP_ARGS, DATA(oldHash), DATA(newHash),
969 name, forSystem));
970 }
971
972 void ClientSession::removeCodeEquivalence(const CssmData &hash, const char *name, bool forSystem /* = false */)
973 {
974 IPC(ucsp_client_removeCodeEquivalence(UCSP_ARGS, DATA(hash), name, forSystem));
975 }
976
977 void ClientSession::setAlternateSystemRoot(const char *path)
978 {
979 IPC(ucsp_client_setAlternateSystemRoot(UCSP_ARGS, path));
980 }
981
982
983 //
984 // Code Signing related
985 //
986 void ClientSession::registerHosting(mach_port_t hostingPort, SecCSFlags flags)
987 {
988 IPC(ucsp_client_registerHosting(UCSP_ARGS, hostingPort, flags));
989 }
990
991 mach_port_t ClientSession::hostingPort(pid_t pid)
992 {
993 mach_port_t result;
994 IPC(ucsp_client_hostingPort(UCSP_ARGS, pid, &result));
995 return result;
996 }
997
998 SecGuestRef ClientSession::createGuest(SecGuestRef host,
999 uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags)
1000 {
1001 SecGuestRef newGuest;
1002 IPC(ucsp_client_createGuest(UCSP_ARGS, host, status, path, DATA(cdhash), DATA(attributes), flags, &newGuest));
1003 if (flags & kSecCSDedicatedHost) {
1004 secdebug("ssclient", "setting dedicated guest to 0x%x (was 0x%x)",
1005 mDedicatedGuest, newGuest);
1006 mDedicatedGuest = newGuest;
1007 }
1008 return newGuest;
1009 }
1010
1011 void ClientSession::setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes)
1012 {
1013 IPC(ucsp_client_setGuestStatus(UCSP_ARGS, guest, status, DATA(attributes)));
1014 }
1015
1016 void ClientSession::removeGuest(SecGuestRef host, SecGuestRef guest)
1017 {
1018 IPC(ucsp_client_removeGuest(UCSP_ARGS, host, guest));
1019 }
1020
1021 void ClientSession::selectGuest(SecGuestRef newGuest)
1022 {
1023 if (mDedicatedGuest) {
1024 secdebug("ssclient", "ignoring selectGuest(0x%x) because dedicated guest=0x%x",
1025 newGuest, mDedicatedGuest);
1026 } else {
1027 secdebug("ssclient", "switching to guest 0x%x", newGuest);
1028 mGlobal().thread().currentGuest = newGuest;
1029 }
1030 }
1031
1032 SecGuestRef ClientSession::selectedGuest() const
1033 {
1034 if (mDedicatedGuest)
1035 return mDedicatedGuest;
1036 else
1037 return mGlobal().thread().currentGuest;
1038 }
1039
1040
1041 } // end namespace SecurityServer
1042 } // end namespace Security