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
cloneDb(const DLDbIdentifier
&newDbId
, DbHandle srcDb
);
185 DbHandle
cloneDbForSync(const CssmData
&secretsBlob
, DbHandle srcDb
,
186 const CssmData
&agentData
);
187 DbHandle
recodeDbForSync(DbHandle dbToClone
, DbHandle srcDb
);
188 DbHandle
recodeDbToVersion(uint32 newVersion
, DbHandle srcDb
);
189 void recodeFinished(DbHandle db
);
190 DbHandle
authenticateDbsForSync(const CssmData
&dbHandleArray
, const CssmData
&agentData
);
191 void commitDbForSync(DbHandle srcDb
, DbHandle cloneDb
, CssmData
&blob
, Allocator
&alloc
);
192 DbHandle
decodeDb(const DLDbIdentifier
&dbId
,
193 const AccessCredentials
*cred
, const CssmData
&blob
);
194 void encodeDb(DbHandle db
, CssmData
&blob
, Allocator
&alloc
);
195 void encodeDb(DbHandle db
, CssmData
&blob
) { return encodeDb(db
, blob
, returnAllocator
); }
196 void setDbParameters(DbHandle db
, const DBParameters
¶ms
);
197 void getDbParameters(DbHandle db
, DBParameters
¶ms
);
198 void changePassphrase(DbHandle db
, const AccessCredentials
*cred
);
199 void lock(DbHandle db
);
200 void lockAll(bool forSleep
);
201 void unlock(DbHandle db
);
202 void unlock(DbHandle db
, const CssmData
&passPhrase
);
203 void stashDb(DbHandle db
);
204 void stashDbCheck(DbHandle db
);
205 bool isLocked(DbHandle db
);
206 void verifyKeyStorePassphrase(uint32_t retries
);
207 void resetKeyStorePassphrase(const CssmData
&passphrase
);
208 void changeKeyStorePassphrase();
214 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
, Allocator
&alloc
);
215 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
= NULL
)
216 { return encodeKey(key
, blob
, uid
, returnAllocator
); }
217 KeyHandle
decodeKey(DbHandle db
, const CssmData
&blob
, CssmKey::Header
&header
);
218 void recodeKey(DbHandle oldDb
, KeyHandle key
, DbHandle newDb
, CssmData
&blob
);
219 void releaseKey(KeyHandle key
);
221 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
222 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
223 uint32 inputSize
, bool encrypt
= true);
225 void getKeyDigest(KeyHandle key
, CssmData
&digest
, Allocator
&alloc
);
226 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
227 { return getKeyDigest(key
, digest
, returnAllocator
); }
230 // key wrapping and unwrapping
231 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
232 const AccessCredentials
*cred
,
233 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
, Allocator
&alloc
);
234 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
235 const AccessCredentials
*cred
,
236 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
)
237 { return wrapKey(context
, key
, keyToBeWrapped
, cred
,
238 descriptiveData
, wrappedKey
, returnAllocator
); }
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
,
243 CssmData
&data
, KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
, Allocator
&alloc
);
244 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
245 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
246 const AccessCredentials
*cred
, const AclEntryInput
*owner
, CssmData
&data
,
247 KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
)
248 { return unwrapKey(db
, context
, key
, publicKey
, wrappedKey
, keyUsage
, keyAttr
,
249 cred
, owner
, data
, newKey
, newKeyHeader
, returnAllocator
); }
251 // key generation and derivation
252 void generateKey(DbHandle db
, const Security::Context
&context
, uint32 keyUsage
, uint32 keyAttr
,
253 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
254 KeyHandle
&newKey
, CssmKey::Header
&newHeader
);
255 void generateKey(DbHandle db
, const Security::Context
&context
,
256 uint32 pubKeyUsage
, uint32 pubKeyAttr
,
257 uint32 privKeyUsage
, uint32 privKeyAttr
,
258 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
259 KeyHandle
&pubKey
, CssmKey::Header
&pubHeader
,
260 KeyHandle
&privKey
, CssmKey::Header
&privHeader
);
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
, Allocator
&alloc
);
265 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
266 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
267 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
268 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
269 { return deriveKey(db
, context
, baseKey
, keyUsage
, keyAttr
, param
, cred
, owner
, newKey
, newHeader
, returnAllocator
); }
270 //void generateAlgorithmParameters(); // not implemented
272 void generateRandom(const Security::Context
&context
, CssmData
&data
, Allocator
&alloc
);
273 void generateRandom(const Security::Context
&context
, CssmData
&data
)
274 { return generateRandom(context
, data
, returnAllocator
); }
277 void encrypt(const Security::Context
&context
, KeyHandle key
,
278 const CssmData
&in
, CssmData
&out
, Allocator
&alloc
);
279 void encrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
280 { return encrypt(context
, key
, in
, out
, returnAllocator
); }
281 void decrypt(const Security::Context
&context
, KeyHandle key
,
282 const CssmData
&in
, CssmData
&out
, Allocator
&alloc
);
283 void decrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
284 { return decrypt(context
, key
, in
, out
, returnAllocator
); }
287 void generateSignature(const Security::Context
&context
, KeyHandle key
,
288 const CssmData
&data
, CssmData
&signature
, Allocator
&alloc
,
289 CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
);
290 void generateSignature(const Security::Context
&context
, KeyHandle key
,
291 const CssmData
&data
, CssmData
&signature
, CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
)
292 { return generateSignature(context
, key
, data
, signature
, returnAllocator
, signOnlyAlgorithm
); }
293 void verifySignature(const Security::Context
&context
, KeyHandle key
,
294 const CssmData
&data
, const CssmData
&signature
,
295 CSSM_ALGORITHMS verifyOnlyAlgorithm
= CSSM_ALGID_NONE
);
298 void generateMac(const Security::Context
&context
, KeyHandle key
,
299 const CssmData
&data
, CssmData
&mac
, Allocator
&alloc
);
300 void generateMac(const Security::Context
&context
, KeyHandle key
,
301 const CssmData
&data
, CssmData
&mac
)
302 { return generateMac(context
, key
, data
, mac
, returnAllocator
); }
303 void verifyMac(const Security::Context
&context
, KeyHandle key
,
304 const CssmData
&data
, const CssmData
&mac
);
306 // key ACL management
307 void getKeyAcl(KeyHandle key
, const char *tag
,
308 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
309 void getKeyAcl(KeyHandle key
, const char *tag
,
310 uint32
&count
, AclEntryInfo
* &info
)
311 { return getKeyAcl(key
, tag
, count
, info
, returnAllocator
); }
312 void changeKeyAcl(KeyHandle key
, const AccessCredentials
&cred
, const AclEdit
&edit
);
313 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
, Allocator
&alloc
);
314 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
)
315 { return getKeyOwner(key
, owner
, returnAllocator
); }
316 void changeKeyOwner(KeyHandle key
, const AccessCredentials
&cred
,
317 const AclOwnerPrototype
&edit
);
319 // database ACL management
320 void getDbAcl(DbHandle db
, const char *tag
,
321 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
322 void getDbAcl(DbHandle db
, const char *tag
,
323 uint32
&count
, AclEntryInfo
* &info
)
324 { return getDbAcl(db
, tag
, count
, info
, returnAllocator
); }
325 void changeDbAcl(DbHandle db
, const AccessCredentials
&cred
, const AclEdit
&edit
);
326 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
, Allocator
&alloc
);
327 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
)
328 { return getDbOwner(db
, owner
, returnAllocator
); }
329 void changeDbOwner(DbHandle db
, const AccessCredentials
&cred
,
330 const AclOwnerPrototype
&edit
);
332 // database key manipulations
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
, Allocator
&alloc
);
337 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
338 uint32 keyUsage
, uint32 keyAttr
,
339 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
340 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
341 { return extractMasterKey(db
, context
, sourceDb
, keyUsage
, keyAttr
, cred
, owner
,
342 newKey
, newHeader
, returnAllocator
); }
345 // Testing support calls
346 void getUserPromptAttempts(uint32_t& attempts
);
349 // Notification core support
350 void postNotification(NotificationDomain domain
, NotificationEvent event
, const CssmData
&data
);
352 // low-level callback (C form)
353 typedef OSStatus
ConsumeNotification(NotificationDomain domain
, NotificationEvent event
,
354 const void *data
, size_t dataLength
, void *context
);
357 // securityd helper support
358 void childCheckIn(Port serverPort
, Port taskPort
);
361 // temporary hack to deal with "edit acl" pseudo-error returns
362 typedef void DidChangeKeyAclCallback(void *context
, ClientSession
&clientSession
,
363 KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
364 void registerForAclEdits(DidChangeKeyAclCallback
*callback
, void *context
);
367 // Code Signing hosting interface
368 void registerHosting(mach_port_t hostingPort
, SecCSFlags flags
);
369 mach_port_t
hostingPort(pid_t pid
);
371 SecGuestRef
createGuest(SecGuestRef host
,
372 uint32_t status
, const char *path
, const CssmData
&cdhash
, const CssmData
&attributes
, SecCSFlags flags
);
373 void setGuestStatus(SecGuestRef guest
, uint32 status
, const CssmData
&attributes
);
374 void removeGuest(SecGuestRef host
, SecGuestRef guest
);
376 void selectGuest(SecGuestRef guest
);
377 SecGuestRef
selectedGuest() const;
380 static Port
findSecurityd();
381 void getAcl(AclKind kind
, GenericHandle key
, const char *tag
,
382 uint32
&count
, AclEntryInfo
* &info
, Allocator
&alloc
);
383 void changeAcl(AclKind kind
, GenericHandle key
,
384 const AccessCredentials
&cred
, const AclEdit
&edit
);
385 void getOwner(AclKind kind
, GenericHandle key
,
386 AclOwnerPrototype
&owner
, Allocator
&alloc
);
387 void changeOwner(AclKind kind
, GenericHandle key
,
388 const AccessCredentials
&cred
, const AclOwnerPrototype
&edit
);
390 static OSStatus
consumerDispatch(NotificationDomain domain
, NotificationEvent event
,
391 const void *data
, size_t dataLength
, void *context
);
393 void notifyAclChange(KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
395 void returnAttrsAndData(CssmDbRecordAttributeData
*inOutAttributes
,
396 CssmDbRecordAttributeData
*attrs
, CssmDbRecordAttributeData
*attrsBase
, mach_msg_type_number_t attrsLength
,
397 CssmData
*inOutData
, void *dataPtr
, mach_msg_type_number_t dataLength
);
399 DidChangeKeyAclCallback
*mCallback
;
400 void *mCallbackContext
;
402 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
405 Thread() : registered(false), notifySeq(0),
406 currentGuest(kSecNoGuest
), lastGuest(kSecNoGuest
) { }
407 operator bool() const { return registered
; }
409 ReceivePort replyPort
; // dedicated reply port (send right held by SecurityServer)
410 bool registered
; // has been registered with SecurityServer
411 uint32 notifySeq
; // notification sequence number
413 SecGuestRef currentGuest
; // last set guest path
414 SecGuestRef lastGuest
; // last transmitted guest path
420 RefPointer
<OSXCode
> myself
;
421 ThreadNexus
<Thread
> thread
;
424 static ModuleNexus
<Global
> mGlobal
;
425 static const char *mContactName
;
426 static SecGuestRef mDedicatedGuest
;
430 } // end namespace SecurityServer
431 } // end namespace Security