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