2 * Copyright (c) 2000-2008,2011-2013 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // ssclient - SecurityServer client interface library
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.
35 #include <Security/Authorization.h>
36 #include <Security/AuthSession.h>
37 #include <Security/SecCodeHost.h>
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>
49 namespace SecurityServer
{
55 // Unique-identifier blobs for key objects
57 typedef struct KeyUID
{
63 // Maximum length of hash (digest) arguments (bytes)
65 #define maxUcspHashLength 64
69 // Authorization blobs
71 typedef struct AuthorizationBlob
{
75 bool operator < (const AuthorizationBlob
&other
) const
76 { return memcmp(data
, other
.data
, sizeof(data
)) < 0; }
78 bool operator == (const AuthorizationBlob
&other
) const
79 { return memcmp(data
, other
.data
, sizeof(data
)) == 0; }
81 size_t hash() const { //@@@ revisit this hash
82 return data
[0] ^ data
[1] << 3;
89 // Initial-setup data for versioning etc.
96 #define SSPROTOVERSION 20000
100 // Database parameter structure
103 uint32_t idleTimeout
; // seconds idle timout lock
104 uint8_t lockOnSleep
; // lock keychain when system sleeps
112 // A client connection (session)
114 class ClientSession
: public ClientCommon
{
116 ClientSession(Allocator
&standard
= Allocator::standard(),
117 Allocator
&returning
= Allocator::standard());
118 virtual ~ClientSession();
125 // use this only if you know what you're doing...
126 void contactName(const char *name
);
127 const char *contactName() const;
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);
139 // common database interface
141 void authenticateDb(DbHandle db
, CSSM_DB_ACCESS_TYPE type
, const AccessCredentials
*cred
);
142 void releaseDb(DbHandle db
);
145 // External database interface
147 DbHandle
openToken(uint32 ssid
, const AccessCredentials
*cred
, const char *name
= NULL
);
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
);
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
);
174 void getDbName(DbHandle db
, std::string
&name
);
175 void setDbName(DbHandle db
, const std::string
&name
);
178 // Internal database interface
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();
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
);
217 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
218 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
219 uint32 inputSize
, bool encrypt
= true);
221 void getKeyDigest(KeyHandle key
, CssmData
&digest
, Allocator
&alloc
);
222 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
223 { return getKeyDigest(key
, digest
, returnAllocator
); }
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
); }
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
); }
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
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
); }
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
); }
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
);
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
);
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
);
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
);
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
); }
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
);
353 // Session API support
354 void setSessionUserPrefs(SecuritySessionId sessionId
, uint32_t userPreferencesLength
, const void *userPreferences
);
357 // Notification core support
358 void postNotification(NotificationDomain domain
, NotificationEvent event
, const CssmData
&data
);
360 // low-level callback (C form)
361 typedef OSStatus
ConsumeNotification(NotificationDomain domain
, NotificationEvent event
,
362 const void *data
, size_t dataLength
, void *context
);
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
);
371 // securityd helper support
372 void childCheckIn(Port serverPort
, Port taskPort
);
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
);
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
);
388 // Code Signing hosting interface
389 void registerHosting(mach_port_t hostingPort
, SecCSFlags flags
);
390 mach_port_t
hostingPort(pid_t pid
);
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
);
397 void selectGuest(SecGuestRef guest
);
398 SecGuestRef
selectedGuest() const;
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
);
411 static OSStatus
consumerDispatch(NotificationDomain domain
, NotificationEvent event
,
412 const void *data
, size_t dataLength
, void *context
);
414 void notifyAclChange(KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
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
);
420 DidChangeKeyAclCallback
*mCallback
;
421 void *mCallbackContext
;
423 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
426 Thread() : registered(false), notifySeq(0),
427 currentGuest(kSecNoGuest
), lastGuest(kSecNoGuest
) { }
428 operator bool() const { return registered
; }
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
434 SecGuestRef currentGuest
; // last set guest path
435 SecGuestRef lastGuest
; // last transmitted guest path
441 RefPointer
<OSXCode
> myself
;
442 ThreadNexus
<Thread
> thread
;
445 static ModuleNexus
<Global
> mGlobal
;
446 static const char *mContactName
;
447 static SecGuestRef mDedicatedGuest
;
451 } // end namespace SecurityServer
452 } // end namespace Security