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// ssclient - SecurityServer client interface library 27// 28// This interface is private to the Security system. It is not a public interface, 29// and it may change at any time. You have been warned. 30// 31#ifndef _H_SSCLIENT 32#define _H_SSCLIENT 33 34#include "sscommon.h" 35#include <Security/Authorization.h> 36#include <Security/AuthSession.h> 37#include <Security/SecCodeHost.h> 38 39#ifdef __cplusplus 40 41#include <security_utilities/osxcode.h> 42#include <security_utilities/unix++.h> 43#include <security_utilities/globalizer.h> 44#include <security_cdsa_utilities/cssmerrors.h> 45#include "ssnotify.h" 46 47 48namespace Security { 49namespace SecurityServer { 50 51#endif //__cplusplus 52 53 54// 55// Unique-identifier blobs for key objects 56// 57typedef struct KeyUID { 58 uint8 signature[20]; 59} KeyUID; 60 61 62// 63// Maximum length of hash (digest) arguments (bytes) 64// 65#define maxUcspHashLength 64 66 67 68// 69// Authorization blobs 70// 71typedef struct AuthorizationBlob { 72 uint32 data[2]; 73 74#ifdef __cplusplus 75 bool operator < (const AuthorizationBlob &other) const 76 { return memcmp(data, other.data, sizeof(data)) < 0; } 77 78 bool operator == (const AuthorizationBlob &other) const 79 { return memcmp(data, other.data, sizeof(data)) == 0; } 80 81 size_t hash() const { //@@@ revisit this hash 82 return data[0] ^ data[1] << 3; 83 } 84#endif 85} AuthorizationBlob; 86 87 88// 89// Initial-setup data for versioning etc. 90// 91typedef struct { 92 uint32_t order; 93 uint32_t version; 94} ClientSetupInfo; 95 96#define SSPROTOVERSION 20000 97 98 99// 100// Database parameter structure 101// 102typedef struct { 103 uint32_t idleTimeout; // seconds idle timout lock 104 uint8_t lockOnSleep; // lock keychain when system sleeps 105} DBParameters; 106 107 108#ifdef __cplusplus 109 110 111// 112// A client connection (session) 113// 114class ClientSession : public ClientCommon { 115public: 116 ClientSession(Allocator &standard = Allocator::standard(), 117 Allocator &returning = Allocator::standard()); 118 virtual ~ClientSession(); 119 120public: 121 void activate(); 122 void reset(); 123 124public: 125 // use this only if you know what you're doing... 126 void contactName(const char *name); 127 const char *contactName() const; 128 129 static GenericHandle toIPCHandle(CSSM_HANDLE h) { 130 // implementation subject to change 131 if (h & (CSSM_HANDLE(~0) ^ GenericHandle(~0))) 132 CssmError::throwMe(CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); 133 return h & GenericHandle(~0); 134 } 135 136 137public: 138 // 139 // common database interface 140 // 141 void authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type, const AccessCredentials *cred); 142 void releaseDb(DbHandle db); 143 144 // 145 // External database interface 146 // 147 DbHandle openToken(uint32 ssid, const AccessCredentials *cred, const char *name = NULL); 148 149 RecordHandle insertRecord(DbHandle db, 150 CSSM_DB_RECORDTYPE recordType, 151 const CssmDbRecordAttributeData *attributes, 152 const CssmData *data); 153 void deleteRecord(DbHandle db, RecordHandle record); 154 void modifyRecord(DbHandle db, RecordHandle &record, 155 CSSM_DB_RECORDTYPE recordType, 156 const CssmDbRecordAttributeData *attributesToBeModified, 157 const CssmData *dataToBeModified, 158 CSSM_DB_MODIFY_MODE modifyMode); 159 160 RecordHandle findFirst(DbHandle db, 161 const CssmQuery &query, 162 SearchHandle &outSearchHandle, 163 CssmDbRecordAttributeData *inOutAttributes, 164 CssmData *outData, KeyHandle &key); 165 RecordHandle findNext(SearchHandle searchHandle, 166 CssmDbRecordAttributeData *inOutAttributes, 167 CssmData *inOutData, KeyHandle &key); 168 void findRecordHandle(RecordHandle record, 169 CssmDbRecordAttributeData *inOutAttributes, 170 CssmData *inOutData, KeyHandle &key); 171 void releaseSearch(SearchHandle searchHandle); 172 void releaseRecord(RecordHandle record); 173 174 void getDbName(DbHandle db, std::string &name); 175 void setDbName(DbHandle db, const std::string &name); 176 177 // 178 // Internal database interface 179 // 180 DbHandle createDb(const DLDbIdentifier &dbId, 181 const AccessCredentials *cred, const AclEntryInput *owner, 182 const DBParameters ¶ms); 183 DbHandle cloneDbForSync(const CssmData &secretsBlob, DbHandle srcDb, 184 const CssmData &agentData); 185 DbHandle recodeDbForSync(DbHandle dbToClone, DbHandle srcDb); 186 DbHandle authenticateDbsForSync(const CssmData &dbHandleArray, const CssmData &agentData); 187 void commitDbForSync(DbHandle srcDb, DbHandle cloneDb, CssmData &blob, Allocator &alloc); 188 DbHandle decodeDb(const DLDbIdentifier &dbId, 189 const AccessCredentials *cred, const CssmData &blob); 190 void encodeDb(DbHandle db, CssmData &blob, Allocator &alloc); 191 void encodeDb(DbHandle db, CssmData &blob) { return encodeDb(db, blob, returnAllocator); } 192 void setDbParameters(DbHandle db, const DBParameters ¶ms); 193 void getDbParameters(DbHandle db, DBParameters ¶ms); 194 void changePassphrase(DbHandle db, const AccessCredentials *cred); 195 void lock(DbHandle db); 196 void lockAll(bool forSleep); 197 void unlock(DbHandle db); 198 void unlock(DbHandle db, const CssmData &passPhrase); 199 void stashDb(DbHandle db); 200 void stashDbCheck(DbHandle db); 201 bool isLocked(DbHandle db); 202 void verifyKeyStorePassphrase(uint32_t retries); 203 void resetKeyStorePassphrase(const CssmData &passphrase); 204 void changeKeyStorePassphrase(); 205 206public: 207 // 208 // Key objects 209 // 210 void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid, Allocator &alloc); 211 void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid = NULL) 212 { return encodeKey(key, blob, uid, returnAllocator); } 213 KeyHandle decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header); 214 void recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb, CssmData &blob); 215 void releaseKey(KeyHandle key); 216 217 CssmKeySize queryKeySizeInBits(KeyHandle key); 218 uint32 getOutputSize(const Security::Context &context, KeyHandle key, 219 uint32 inputSize, bool encrypt = true); 220 221 void getKeyDigest(KeyHandle key, CssmData &digest, Allocator &alloc); 222 void getKeyDigest(KeyHandle key, CssmData &digest) 223 { return getKeyDigest(key, digest, returnAllocator); } 224 225 226 // key wrapping and unwrapping 227 void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped, 228 const AccessCredentials *cred, 229 const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, Allocator &alloc); 230 void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped, 231 const AccessCredentials *cred, 232 const CssmData *descriptiveData, CssmWrappedKey &wrappedKey) 233 { return wrapKey(context, key, keyToBeWrapped, cred, 234 descriptiveData, wrappedKey, returnAllocator); } 235 236 void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey, 237 const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr, 238 const AccessCredentials *cred, const AclEntryInput *owner, 239 CssmData &data, KeyHandle &newKey, CssmKey::Header &newKeyHeader, Allocator &alloc); 240 void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey, 241 const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr, 242 const AccessCredentials *cred, const AclEntryInput *owner, CssmData &data, 243 KeyHandle &newKey, CssmKey::Header &newKeyHeader) 244 { return unwrapKey(db, context, key, publicKey, wrappedKey, keyUsage, keyAttr, 245 cred, owner, data, newKey, newKeyHeader, returnAllocator); } 246 247 // key generation and derivation 248 void generateKey(DbHandle db, const Security::Context &context, uint32 keyUsage, uint32 keyAttr, 249 const AccessCredentials *cred, const AclEntryInput *owner, 250 KeyHandle &newKey, CssmKey::Header &newHeader); 251 void generateKey(DbHandle db, const Security::Context &context, 252 uint32 pubKeyUsage, uint32 pubKeyAttr, 253 uint32 privKeyUsage, uint32 privKeyAttr, 254 const AccessCredentials *cred, const AclEntryInput *owner, 255 KeyHandle &pubKey, CssmKey::Header &pubHeader, 256 KeyHandle &privKey, CssmKey::Header &privHeader); 257 void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey, 258 uint32 keyUsage, uint32 keyAttr, CssmData ¶m, 259 const AccessCredentials *cred, const AclEntryInput *owner, 260 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc); 261 void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey, 262 uint32 keyUsage, uint32 keyAttr, CssmData ¶m, 263 const AccessCredentials *cred, const AclEntryInput *owner, 264 KeyHandle &newKey, CssmKey::Header &newHeader) 265 { return deriveKey(db, context, baseKey, keyUsage, keyAttr, param, cred, owner, newKey, newHeader, returnAllocator); } 266 //void generateAlgorithmParameters(); // not implemented 267 268 void generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc); 269 void generateRandom(const Security::Context &context, CssmData &data) 270 { return generateRandom(context, data, returnAllocator); } 271 272 // encrypt/decrypt 273 void encrypt(const Security::Context &context, KeyHandle key, 274 const CssmData &in, CssmData &out, Allocator &alloc); 275 void encrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out) 276 { return encrypt(context, key, in, out, returnAllocator); } 277 void decrypt(const Security::Context &context, KeyHandle key, 278 const CssmData &in, CssmData &out, Allocator &alloc); 279 void decrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out) 280 { return decrypt(context, key, in, out, returnAllocator); } 281 282 // signatures 283 void generateSignature(const Security::Context &context, KeyHandle key, 284 const CssmData &data, CssmData &signature, Allocator &alloc, 285 CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE); 286 void generateSignature(const Security::Context &context, KeyHandle key, 287 const CssmData &data, CssmData &signature, CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE) 288 { return generateSignature(context, key, data, signature, returnAllocator, signOnlyAlgorithm); } 289 void verifySignature(const Security::Context &context, KeyHandle key, 290 const CssmData &data, const CssmData &signature, 291 CSSM_ALGORITHMS verifyOnlyAlgorithm = CSSM_ALGID_NONE); 292 293 // MACs 294 void generateMac(const Security::Context &context, KeyHandle key, 295 const CssmData &data, CssmData &mac, Allocator &alloc); 296 void generateMac(const Security::Context &context, KeyHandle key, 297 const CssmData &data, CssmData &mac) 298 { return generateMac(context, key, data, mac, returnAllocator); } 299 void verifyMac(const Security::Context &context, KeyHandle key, 300 const CssmData &data, const CssmData &mac); 301 302 // key ACL management 303 void getKeyAcl(KeyHandle key, const char *tag, 304 uint32 &count, AclEntryInfo * &info, Allocator &alloc); 305 void getKeyAcl(KeyHandle key, const char *tag, 306 uint32 &count, AclEntryInfo * &info) 307 { return getKeyAcl(key, tag, count, info, returnAllocator); } 308 void changeKeyAcl(KeyHandle key, const AccessCredentials &cred, const AclEdit &edit); 309 void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner, Allocator &alloc); 310 void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner) 311 { return getKeyOwner(key, owner, returnAllocator); } 312 void changeKeyOwner(KeyHandle key, const AccessCredentials &cred, 313 const AclOwnerPrototype &edit); 314 315 // database ACL management 316 void getDbAcl(DbHandle db, const char *tag, 317 uint32 &count, AclEntryInfo * &info, Allocator &alloc); 318 void getDbAcl(DbHandle db, const char *tag, 319 uint32 &count, AclEntryInfo * &info) 320 { return getDbAcl(db, tag, count, info, returnAllocator); } 321 void changeDbAcl(DbHandle db, const AccessCredentials &cred, const AclEdit &edit); 322 void getDbOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc); 323 void getDbOwner(DbHandle db, AclOwnerPrototype &owner) 324 { return getDbOwner(db, owner, returnAllocator); } 325 void changeDbOwner(DbHandle db, const AccessCredentials &cred, 326 const AclOwnerPrototype &edit); 327 328 // database key manipulations 329 void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb, 330 uint32 keyUsage, uint32 keyAttr, 331 const AccessCredentials *cred, const AclEntryInput *owner, 332 KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc); 333 void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb, 334 uint32 keyUsage, uint32 keyAttr, 335 const AccessCredentials *cred, const AclEntryInput *owner, 336 KeyHandle &newKey, CssmKey::Header &newHeader) 337 { return extractMasterKey(db, context, sourceDb, keyUsage, keyAttr, cred, owner, 338 newKey, newHeader, returnAllocator); } 339 340public: 341 // Authorization API support 342 void authCreate(const AuthorizationItemSet *rights, const AuthorizationItemSet *environment, 343 AuthorizationFlags flags,AuthorizationBlob &result); 344 void authRelease(const AuthorizationBlob &auth, AuthorizationFlags flags); 345 void authCopyRights(const AuthorizationBlob &auth, 346 const AuthorizationItemSet *rights, const AuthorizationItemSet *environment, 347 AuthorizationFlags flags, AuthorizationItemSet **result); 348 void authCopyInfo(const AuthorizationBlob &auth, const char *tag, AuthorizationItemSet * &info); 349 void authExternalize(const AuthorizationBlob &auth, AuthorizationExternalForm &extForm); 350 void authInternalize(const AuthorizationExternalForm &extForm, AuthorizationBlob &auth); 351 352public: 353 // Session API support 354 void setSessionUserPrefs(SecuritySessionId sessionId, uint32_t userPreferencesLength, const void *userPreferences); 355 356public: 357 // Notification core support 358 void postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data); 359 360 // low-level callback (C form) 361 typedef OSStatus ConsumeNotification(NotificationDomain domain, NotificationEvent event, 362 const void *data, size_t dataLength, void *context); 363 364public: 365 // AuthorizationDB API 366 void authorizationdbGet(const AuthorizationString rightname, CssmData &rightDefinition, Allocator &alloc); 367 void authorizationdbSet(const AuthorizationBlob &auth, const AuthorizationString rightname, uint32_t rightdefinitionLength, const void *rightdefinition); 368 void authorizationdbRemove(const AuthorizationBlob &auth, const AuthorizationString rightname); 369 370public: 371 // securityd helper support 372 void childCheckIn(Port serverPort, Port taskPort); 373 374public: 375 // miscellaneous administrative calls 376 void addCodeEquivalence(const CssmData &oldCode, const CssmData &newCode, 377 const char *name, bool forSystem = false); 378 void removeCodeEquivalence(const CssmData &code, const char *name, bool forSystem = false); 379 void setAlternateSystemRoot(const char *path); 380 381public: 382 // temporary hack to deal with "edit acl" pseudo-error returns 383 typedef void DidChangeKeyAclCallback(void *context, ClientSession &clientSession, 384 KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); 385 void registerForAclEdits(DidChangeKeyAclCallback *callback, void *context); 386 387public: 388 // Code Signing hosting interface 389 void registerHosting(mach_port_t hostingPort, SecCSFlags flags); 390 mach_port_t hostingPort(pid_t pid); 391 392 SecGuestRef createGuest(SecGuestRef host, 393 uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags); 394 void setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes); 395 void removeGuest(SecGuestRef host, SecGuestRef guest); 396 397 void selectGuest(SecGuestRef guest); 398 SecGuestRef selectedGuest() const; 399 400private: 401 static Port findSecurityd(); 402 void getAcl(AclKind kind, GenericHandle key, const char *tag, 403 uint32 &count, AclEntryInfo * &info, Allocator &alloc); 404 void changeAcl(AclKind kind, GenericHandle key, 405 const AccessCredentials &cred, const AclEdit &edit); 406 void getOwner(AclKind kind, GenericHandle key, 407 AclOwnerPrototype &owner, Allocator &alloc); 408 void changeOwner(AclKind kind, GenericHandle key, 409 const AccessCredentials &cred, const AclOwnerPrototype &edit); 410 411 static OSStatus consumerDispatch(NotificationDomain domain, NotificationEvent event, 412 const void *data, size_t dataLength, void *context); 413 414 void notifyAclChange(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); 415 416 void returnAttrsAndData(CssmDbRecordAttributeData *inOutAttributes, 417 CssmDbRecordAttributeData *attrs, CssmDbRecordAttributeData *attrsBase, mach_msg_type_number_t attrsLength, 418 CssmData *inOutData, void *dataPtr, mach_msg_type_number_t dataLength); 419private: 420 DidChangeKeyAclCallback *mCallback; 421 void *mCallbackContext; 422 423 static UnixPlusPlus::StaticForkMonitor mHasForked; // global fork indicator 424 425 struct Thread { 426 Thread() : registered(false), notifySeq(0), 427 currentGuest(kSecNoGuest), lastGuest(kSecNoGuest) { } 428 operator bool() const { return registered; } 429 430 ReceivePort replyPort; // dedicated reply port (send right held by SecurityServer) 431 bool registered; // has been registered with SecurityServer 432 uint32 notifySeq; // notification sequence number 433 434 SecGuestRef currentGuest; // last set guest path 435 SecGuestRef lastGuest; // last transmitted guest path 436 }; 437 438 struct Global { 439 Global(); 440 Port serverPort; 441 RefPointer<OSXCode> myself; 442 ThreadNexus<Thread> thread; 443 }; 444 445 static ModuleNexus<Global> mGlobal; 446 static const char *mContactName; 447 static SecGuestRef mDedicatedGuest; 448}; 449 450 451} // end namespace SecurityServer 452} // end namespace Security 453 454#endif //__cplusplus 455 456 457#endif //_H_SSCLIENT 458