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