2 * Copyright (c) 2000-2008 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 bool isLocked(DbHandle db
);
205 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
, Allocator
&alloc
);
206 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
= NULL
)
207 { return encodeKey(key
, blob
, uid
, returnAllocator
); }
208 KeyHandle
decodeKey(DbHandle db
, const CssmData
&blob
, CssmKey::Header
&header
);
209 void recodeKey(DbHandle oldDb
, KeyHandle key
, DbHandle newDb
, CssmData
&blob
);
210 void releaseKey(KeyHandle key
);
212 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
213 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
214 uint32 inputSize
, bool encrypt
= true);
216 void getKeyDigest(KeyHandle key
, CssmData
&digest
, Allocator
&alloc
);
217 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
218 { return getKeyDigest(key
, digest
, returnAllocator
); }
221 // key wrapping and unwrapping
222 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
223 const AccessCredentials
*cred
,
224 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
, Allocator
&alloc
);
225 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
226 const AccessCredentials
*cred
,
227 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
)
228 { return wrapKey(context
, key
, keyToBeWrapped
, cred
,
229 descriptiveData
, wrappedKey
, returnAllocator
); }
231 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
232 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
233 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
234 CssmData
&data
, KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
, Allocator
&alloc
);
235 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
236 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
237 const AccessCredentials
*cred
, const AclEntryInput
*owner
, CssmData
&data
,
238 KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
)
239 { return unwrapKey(db
, context
, key
, publicKey
, wrappedKey
, keyUsage
, keyAttr
,
240 cred
, owner
, data
, newKey
, newKeyHeader
, returnAllocator
); }
242 // key generation and derivation
243 void generateKey(DbHandle db
, const Security::Context
&context
, uint32 keyUsage
, uint32 keyAttr
,
244 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
245 KeyHandle
&newKey
, CssmKey::Header
&newHeader
);
246 void generateKey(DbHandle db
, const Security::Context
&context
,
247 uint32 pubKeyUsage
, uint32 pubKeyAttr
,
248 uint32 privKeyUsage
, uint32 privKeyAttr
,
249 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
250 KeyHandle
&pubKey
, CssmKey::Header
&pubHeader
,
251 KeyHandle
&privKey
, CssmKey::Header
&privHeader
);
252 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
253 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
254 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
255 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, Allocator
&alloc
);
256 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
257 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
258 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
259 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
260 { return deriveKey(db
, context
, baseKey
, keyUsage
, keyAttr
, param
, cred
, owner
, newKey
, newHeader
, returnAllocator
); }
261 //void generateAlgorithmParameters(); // not implemented
263 void generateRandom(const Security::Context
&context
, CssmData
&data
, Allocator
&alloc
);
264 void generateRandom(const Security::Context
&context
, CssmData
&data
)
265 { return generateRandom(context
, data
, returnAllocator
); }
268 void encrypt(const Security::Context
&context
, KeyHandle key
,
269 const CssmData
&in
, CssmData
&out
, Allocator
&alloc
);
270 void encrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
271 { return encrypt(context
, key
, in
, out
, returnAllocator
); }
272 void decrypt(const Security::Context
&context
, KeyHandle key
,
273 const CssmData
&in
, CssmData
&out
, Allocator
&alloc
);
274 void decrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
275 { return decrypt(context
, key
, in
, out
, returnAllocator
); }
278 void generateSignature(const Security::Context
&context
, KeyHandle key
,
279 const CssmData
&data
, CssmData
&signature
, Allocator
&alloc
,
280 CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
);
281 void generateSignature(const Security::Context
&context
, KeyHandle key
,
282 const CssmData
&data
, CssmData
&signature
, CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
)
283 { return generateSignature(context
, key
, data
, signature
, returnAllocator
, signOnlyAlgorithm
); }
284 void verifySignature(const Security::Context
&context
, KeyHandle key
,
285 const CssmData
&data
, const CssmData
&signature
,
286 CSSM_ALGORITHMS verifyOnlyAlgorithm
= CSSM_ALGID_NONE
);
289 void generateMac(const Security::Context
&context
, KeyHandle key
,
290 const CssmData
&data
, CssmData
&mac
, Allocator
&alloc
);
291 void generateMac(const Security::Context
&context
, KeyHandle key
,
292 const CssmData
&data
, CssmData
&mac
)
293 { return generateMac(context
, key
, data
, mac
, returnAllocator
); }
294 void verifyMac(const Security::Context
&context
, KeyHandle key
,
295 const CssmData
&data
, const CssmData
&mac
);
297 // key ACL management
298 void getKeyAcl(KeyHandle key
, const char *tag
,
299 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
300 void getKeyAcl(KeyHandle key
, const char *tag
,
301 uint32
&count
, AclEntryInfo
* &info
)
302 { return getKeyAcl(key
, tag
, count
, info
, returnAllocator
); }
303 void changeKeyAcl(KeyHandle key
, const AccessCredentials
&cred
, const AclEdit
&edit
);
304 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
, Allocator
&alloc
);
305 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
)
306 { return getKeyOwner(key
, owner
, returnAllocator
); }
307 void changeKeyOwner(KeyHandle key
, const AccessCredentials
&cred
,
308 const AclOwnerPrototype
&edit
);
310 // database ACL management
311 void getDbAcl(DbHandle db
, const char *tag
,
312 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
313 void getDbAcl(DbHandle db
, const char *tag
,
314 uint32
&count
, AclEntryInfo
* &info
)
315 { return getDbAcl(db
, tag
, count
, info
, returnAllocator
); }
316 void changeDbAcl(DbHandle db
, const AccessCredentials
&cred
, const AclEdit
&edit
);
317 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
, Allocator
&alloc
);
318 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
)
319 { return getDbOwner(db
, owner
, returnAllocator
); }
320 void changeDbOwner(DbHandle db
, const AccessCredentials
&cred
,
321 const AclOwnerPrototype
&edit
);
323 // database key manipulations
324 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
325 uint32 keyUsage
, uint32 keyAttr
,
326 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
327 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, Allocator
&alloc
);
328 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
329 uint32 keyUsage
, uint32 keyAttr
,
330 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
331 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
332 { return extractMasterKey(db
, context
, sourceDb
, keyUsage
, keyAttr
, cred
, owner
,
333 newKey
, newHeader
, returnAllocator
); }
336 // Authorization API support
337 void authCreate(const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
338 AuthorizationFlags flags
,AuthorizationBlob
&result
);
339 void authRelease(const AuthorizationBlob
&auth
, AuthorizationFlags flags
);
340 void authCopyRights(const AuthorizationBlob
&auth
,
341 const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
342 AuthorizationFlags flags
, AuthorizationItemSet
**result
);
343 void authCopyInfo(const AuthorizationBlob
&auth
, const char *tag
, AuthorizationItemSet
* &info
);
344 void authExternalize(const AuthorizationBlob
&auth
, AuthorizationExternalForm
&extForm
);
345 void authInternalize(const AuthorizationExternalForm
&extForm
, AuthorizationBlob
&auth
);
348 // Session API support
349 void setSessionUserPrefs(SecuritySessionId sessionId
, uint32_t userPreferencesLength
, const void *userPreferences
);
352 // Notification core support
353 void postNotification(NotificationDomain domain
, NotificationEvent event
, const CssmData
&data
);
355 // low-level callback (C form)
356 typedef OSStatus
ConsumeNotification(NotificationDomain domain
, NotificationEvent event
,
357 const void *data
, size_t dataLength
, void *context
);
360 // AuthorizationDB API
361 void authorizationdbGet(const AuthorizationString rightname
, CssmData
&rightDefinition
, Allocator
&alloc
);
362 void authorizationdbSet(const AuthorizationBlob
&auth
, const AuthorizationString rightname
, uint32_t rightdefinitionLength
, const void *rightdefinition
);
363 void authorizationdbRemove(const AuthorizationBlob
&auth
, const AuthorizationString rightname
);
366 // securityd helper support
367 void childCheckIn(Port serverPort
, Port taskPort
);
370 // miscellaneous administrative calls
371 void addCodeEquivalence(const CssmData
&oldCode
, const CssmData
&newCode
,
372 const char *name
, bool forSystem
= false);
373 void removeCodeEquivalence(const CssmData
&code
, const char *name
, bool forSystem
= false);
374 void setAlternateSystemRoot(const char *path
);
377 // temporary hack to deal with "edit acl" pseudo-error returns
378 typedef void DidChangeKeyAclCallback(void *context
, ClientSession
&clientSession
,
379 KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
380 void registerForAclEdits(DidChangeKeyAclCallback
*callback
, void *context
);
383 // Code Signing hosting interface
384 void registerHosting(mach_port_t hostingPort
, SecCSFlags flags
);
385 mach_port_t
hostingPort(pid_t pid
);
387 SecGuestRef
createGuest(SecGuestRef host
,
388 uint32_t status
, const char *path
, const CssmData
&cdhash
, const CssmData
&attributes
, SecCSFlags flags
);
389 void setGuestStatus(SecGuestRef guest
, uint32 status
, const CssmData
&attributes
);
390 void removeGuest(SecGuestRef host
, SecGuestRef guest
);
392 void selectGuest(SecGuestRef guest
);
393 SecGuestRef
selectedGuest() const;
396 static Port
findSecurityd();
397 void getAcl(AclKind kind
, GenericHandle key
, const char *tag
,
398 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
399 void changeAcl(AclKind kind
, GenericHandle key
,
400 const AccessCredentials
&cred
, const AclEdit
&edit
);
401 void getOwner(AclKind kind
, GenericHandle key
,
402 AclOwnerPrototype
&owner
, Allocator
&alloc
);
403 void changeOwner(AclKind kind
, GenericHandle key
,
404 const AccessCredentials
&cred
, const AclOwnerPrototype
&edit
);
406 static OSStatus
consumerDispatch(NotificationDomain domain
, NotificationEvent event
,
407 const void *data
, size_t dataLength
, void *context
);
409 void notifyAclChange(KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
411 void returnAttrsAndData(CssmDbRecordAttributeData
*inOutAttributes
,
412 CssmDbRecordAttributeData
*attrs
, CssmDbRecordAttributeData
*attrsBase
, mach_msg_type_number_t attrsLength
,
413 CssmData
*inOutData
, void *dataPtr
, mach_msg_type_number_t dataLength
);
415 DidChangeKeyAclCallback
*mCallback
;
416 void *mCallbackContext
;
418 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
421 Thread() : registered(false), notifySeq(0),
422 currentGuest(kSecNoGuest
), lastGuest(kSecNoGuest
) { }
423 operator bool() const { return registered
; }
425 ReceivePort replyPort
; // dedicated reply port (send right held by SecurityServer)
426 bool registered
; // has been registered with SecurityServer
427 uint32 notifySeq
; // notification sequence number
429 SecGuestRef currentGuest
; // last set guest path
430 SecGuestRef lastGuest
; // last transmitted guest path
436 RefPointer
<OSXCode
> myself
;
437 ThreadNexus
<Thread
> thread
;
440 static ModuleNexus
<Global
> mGlobal
;
441 static const char *mContactName
;
442 static SecGuestRef mDedicatedGuest
;
446 } // end namespace SecurityServer
447 } // end namespace Security