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
recodeDbToVersion(uint32 newVersion
, DbHandle srcDb
);
187 DbHandle
authenticateDbsForSync(const CssmData
&dbHandleArray
, const CssmData
&agentData
);
188 void commitDbForSync(DbHandle srcDb
, DbHandle cloneDb
, CssmData
&blob
, Allocator
&alloc
);
189 DbHandle
decodeDb(const DLDbIdentifier
&dbId
,
190 const AccessCredentials
*cred
, const CssmData
&blob
);
191 void encodeDb(DbHandle db
, CssmData
&blob
, Allocator
&alloc
);
192 void encodeDb(DbHandle db
, CssmData
&blob
) { return encodeDb(db
, blob
, returnAllocator
); }
193 void setDbParameters(DbHandle db
, const DBParameters
¶ms
);
194 void getDbParameters(DbHandle db
, DBParameters
¶ms
);
195 void changePassphrase(DbHandle db
, const AccessCredentials
*cred
);
196 void lock(DbHandle db
);
197 void lockAll(bool forSleep
);
198 void unlock(DbHandle db
);
199 void unlock(DbHandle db
, const CssmData
&passPhrase
);
200 void stashDb(DbHandle db
);
201 void stashDbCheck(DbHandle db
);
202 bool isLocked(DbHandle db
);
203 void verifyKeyStorePassphrase(uint32_t retries
);
204 void resetKeyStorePassphrase(const CssmData
&passphrase
);
205 void changeKeyStorePassphrase();
211 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
, Allocator
&alloc
);
212 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
= NULL
)
213 { return encodeKey(key
, blob
, uid
, returnAllocator
); }
214 KeyHandle
decodeKey(DbHandle db
, const CssmData
&blob
, CssmKey::Header
&header
);
215 void recodeKey(DbHandle oldDb
, KeyHandle key
, DbHandle newDb
, CssmData
&blob
);
216 void releaseKey(KeyHandle key
);
218 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
219 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
220 uint32 inputSize
, bool encrypt
= true);
222 void getKeyDigest(KeyHandle key
, CssmData
&digest
, Allocator
&alloc
);
223 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
224 { return getKeyDigest(key
, digest
, returnAllocator
); }
227 // key wrapping and unwrapping
228 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
229 const AccessCredentials
*cred
,
230 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
, Allocator
&alloc
);
231 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
232 const AccessCredentials
*cred
,
233 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
)
234 { return wrapKey(context
, key
, keyToBeWrapped
, cred
,
235 descriptiveData
, wrappedKey
, returnAllocator
); }
237 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
238 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
239 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
240 CssmData
&data
, KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
, Allocator
&alloc
);
241 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
242 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
243 const AccessCredentials
*cred
, const AclEntryInput
*owner
, CssmData
&data
,
244 KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
)
245 { return unwrapKey(db
, context
, key
, publicKey
, wrappedKey
, keyUsage
, keyAttr
,
246 cred
, owner
, data
, newKey
, newKeyHeader
, returnAllocator
); }
248 // key generation and derivation
249 void generateKey(DbHandle db
, const Security::Context
&context
, uint32 keyUsage
, uint32 keyAttr
,
250 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
251 KeyHandle
&newKey
, CssmKey::Header
&newHeader
);
252 void generateKey(DbHandle db
, const Security::Context
&context
,
253 uint32 pubKeyUsage
, uint32 pubKeyAttr
,
254 uint32 privKeyUsage
, uint32 privKeyAttr
,
255 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
256 KeyHandle
&pubKey
, CssmKey::Header
&pubHeader
,
257 KeyHandle
&privKey
, CssmKey::Header
&privHeader
);
258 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
259 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
260 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
261 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, Allocator
&alloc
);
262 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
263 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
264 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
265 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
266 { return deriveKey(db
, context
, baseKey
, keyUsage
, keyAttr
, param
, cred
, owner
, newKey
, newHeader
, returnAllocator
); }
267 //void generateAlgorithmParameters(); // not implemented
269 void generateRandom(const Security::Context
&context
, CssmData
&data
, Allocator
&alloc
);
270 void generateRandom(const Security::Context
&context
, CssmData
&data
)
271 { return generateRandom(context
, data
, returnAllocator
); }
274 void encrypt(const Security::Context
&context
, KeyHandle key
,
275 const CssmData
&in
, CssmData
&out
, Allocator
&alloc
);
276 void encrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
277 { return encrypt(context
, key
, in
, out
, returnAllocator
); }
278 void decrypt(const Security::Context
&context
, KeyHandle key
,
279 const CssmData
&in
, CssmData
&out
, Allocator
&alloc
);
280 void decrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
281 { return decrypt(context
, key
, in
, out
, returnAllocator
); }
284 void generateSignature(const Security::Context
&context
, KeyHandle key
,
285 const CssmData
&data
, CssmData
&signature
, Allocator
&alloc
,
286 CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
);
287 void generateSignature(const Security::Context
&context
, KeyHandle key
,
288 const CssmData
&data
, CssmData
&signature
, CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
)
289 { return generateSignature(context
, key
, data
, signature
, returnAllocator
, signOnlyAlgorithm
); }
290 void verifySignature(const Security::Context
&context
, KeyHandle key
,
291 const CssmData
&data
, const CssmData
&signature
,
292 CSSM_ALGORITHMS verifyOnlyAlgorithm
= CSSM_ALGID_NONE
);
295 void generateMac(const Security::Context
&context
, KeyHandle key
,
296 const CssmData
&data
, CssmData
&mac
, Allocator
&alloc
);
297 void generateMac(const Security::Context
&context
, KeyHandle key
,
298 const CssmData
&data
, CssmData
&mac
)
299 { return generateMac(context
, key
, data
, mac
, returnAllocator
); }
300 void verifyMac(const Security::Context
&context
, KeyHandle key
,
301 const CssmData
&data
, const CssmData
&mac
);
303 // key ACL management
304 void getKeyAcl(KeyHandle key
, const char *tag
,
305 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
306 void getKeyAcl(KeyHandle key
, const char *tag
,
307 uint32
&count
, AclEntryInfo
* &info
)
308 { return getKeyAcl(key
, tag
, count
, info
, returnAllocator
); }
309 void changeKeyAcl(KeyHandle key
, const AccessCredentials
&cred
, const AclEdit
&edit
);
310 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
, Allocator
&alloc
);
311 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
)
312 { return getKeyOwner(key
, owner
, returnAllocator
); }
313 void changeKeyOwner(KeyHandle key
, const AccessCredentials
&cred
,
314 const AclOwnerPrototype
&edit
);
316 // database ACL management
317 void getDbAcl(DbHandle db
, const char *tag
,
318 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
319 void getDbAcl(DbHandle db
, const char *tag
,
320 uint32
&count
, AclEntryInfo
* &info
)
321 { return getDbAcl(db
, tag
, count
, info
, returnAllocator
); }
322 void changeDbAcl(DbHandle db
, const AccessCredentials
&cred
, const AclEdit
&edit
);
323 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
, Allocator
&alloc
);
324 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
)
325 { return getDbOwner(db
, owner
, returnAllocator
); }
326 void changeDbOwner(DbHandle db
, const AccessCredentials
&cred
,
327 const AclOwnerPrototype
&edit
);
329 // database key manipulations
330 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
331 uint32 keyUsage
, uint32 keyAttr
,
332 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
333 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, Allocator
&alloc
);
334 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
335 uint32 keyUsage
, uint32 keyAttr
,
336 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
337 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
338 { return extractMasterKey(db
, context
, sourceDb
, keyUsage
, keyAttr
, cred
, owner
,
339 newKey
, newHeader
, returnAllocator
); }
342 // Authorization API support
343 void authCreate(const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
344 AuthorizationFlags flags
,AuthorizationBlob
&result
);
345 void authRelease(const AuthorizationBlob
&auth
, AuthorizationFlags flags
);
346 void authCopyRights(const AuthorizationBlob
&auth
,
347 const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
348 AuthorizationFlags flags
, AuthorizationItemSet
**result
);
349 void authCopyInfo(const AuthorizationBlob
&auth
, const char *tag
, AuthorizationItemSet
* &info
);
350 void authExternalize(const AuthorizationBlob
&auth
, AuthorizationExternalForm
&extForm
);
351 void authInternalize(const AuthorizationExternalForm
&extForm
, AuthorizationBlob
&auth
);
354 // Session API support
355 void setSessionUserPrefs(SecuritySessionId sessionId
, uint32_t userPreferencesLength
, const void *userPreferences
);
358 // Notification core support
359 void postNotification(NotificationDomain domain
, NotificationEvent event
, const CssmData
&data
);
361 // low-level callback (C form)
362 typedef OSStatus
ConsumeNotification(NotificationDomain domain
, NotificationEvent event
,
363 const void *data
, size_t dataLength
, void *context
);
366 // AuthorizationDB API
367 void authorizationdbGet(const AuthorizationString rightname
, CssmData
&rightDefinition
, Allocator
&alloc
);
368 void authorizationdbSet(const AuthorizationBlob
&auth
, const AuthorizationString rightname
, uint32_t rightdefinitionLength
, const void *rightdefinition
);
369 void authorizationdbRemove(const AuthorizationBlob
&auth
, const AuthorizationString rightname
);
372 // securityd helper support
373 void childCheckIn(Port serverPort
, Port taskPort
);
376 // temporary hack to deal with "edit acl" pseudo-error returns
377 typedef void DidChangeKeyAclCallback(void *context
, ClientSession
&clientSession
,
378 KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
379 void registerForAclEdits(DidChangeKeyAclCallback
*callback
, void *context
);
382 // Code Signing hosting interface
383 void registerHosting(mach_port_t hostingPort
, SecCSFlags flags
);
384 mach_port_t
hostingPort(pid_t pid
);
386 SecGuestRef
createGuest(SecGuestRef host
,
387 uint32_t status
, const char *path
, const CssmData
&cdhash
, const CssmData
&attributes
, SecCSFlags flags
);
388 void setGuestStatus(SecGuestRef guest
, uint32 status
, const CssmData
&attributes
);
389 void removeGuest(SecGuestRef host
, SecGuestRef guest
);
391 void selectGuest(SecGuestRef guest
);
392 SecGuestRef
selectedGuest() const;
395 static Port
findSecurityd();
396 void getAcl(AclKind kind
, GenericHandle key
, const char *tag
,
397 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
398 void changeAcl(AclKind kind
, GenericHandle key
,
399 const AccessCredentials
&cred
, const AclEdit
&edit
);
400 void getOwner(AclKind kind
, GenericHandle key
,
401 AclOwnerPrototype
&owner
, Allocator
&alloc
);
402 void changeOwner(AclKind kind
, GenericHandle key
,
403 const AccessCredentials
&cred
, const AclOwnerPrototype
&edit
);
405 static OSStatus
consumerDispatch(NotificationDomain domain
, NotificationEvent event
,
406 const void *data
, size_t dataLength
, void *context
);
408 void notifyAclChange(KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
410 void returnAttrsAndData(CssmDbRecordAttributeData
*inOutAttributes
,
411 CssmDbRecordAttributeData
*attrs
, CssmDbRecordAttributeData
*attrsBase
, mach_msg_type_number_t attrsLength
,
412 CssmData
*inOutData
, void *dataPtr
, mach_msg_type_number_t dataLength
);
414 DidChangeKeyAclCallback
*mCallback
;
415 void *mCallbackContext
;
417 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
420 Thread() : registered(false), notifySeq(0),
421 currentGuest(kSecNoGuest
), lastGuest(kSecNoGuest
) { }
422 operator bool() const { return registered
; }
424 ReceivePort replyPort
; // dedicated reply port (send right held by SecurityServer)
425 bool registered
; // has been registered with SecurityServer
426 uint32 notifySeq
; // notification sequence number
428 SecGuestRef currentGuest
; // last set guest path
429 SecGuestRef lastGuest
; // last transmitted guest path
435 RefPointer
<OSXCode
> myself
;
436 ThreadNexus
<Thread
> thread
;
439 static ModuleNexus
<Global
> mGlobal
;
440 static const char *mContactName
;
441 static SecGuestRef mDedicatedGuest
;
445 } // end namespace SecurityServer
446 } // end namespace Security