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>
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>
48 namespace SecurityServer
{
54 // Unique-identifier blobs for key objects
56 typedef struct KeyUID
{
62 // Maximum length of hash (digest) arguments (bytes)
64 #define maxUcspHashLength 64
68 // Authorization blobs
70 typedef struct AuthorizationBlob
{
74 bool operator < (const AuthorizationBlob
&other
) const
75 { return memcmp(data
, other
.data
, sizeof(data
)) < 0; }
77 bool operator == (const AuthorizationBlob
&other
) const
78 { return memcmp(data
, other
.data
, sizeof(data
)) == 0; }
80 size_t hash() const { //@@@ revisit this hash
81 return data
[0] ^ data
[1] << 3;
88 // Initial-setup data for versioning etc.
95 #define SSPROTOVERSION 20000
99 // Database parameter structure
102 uint32_t idleTimeout
; // seconds idle timout lock
103 uint8_t lockOnSleep
; // lock keychain when system sleeps
111 // A client connection (session)
113 class ClientSession
: public ClientCommon
{
115 ClientSession(Allocator
&standard
= Allocator::standard(),
116 Allocator
&returning
= Allocator::standard());
117 virtual ~ClientSession();
124 // use this only if you know what you're doing...
125 void contactName(const char *name
);
126 const char *contactName() const;
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);
138 // common database interface
140 void authenticateDb(DbHandle db
, CSSM_DB_ACCESS_TYPE type
, const AccessCredentials
*cred
);
141 void releaseDb(DbHandle db
);
144 // External database interface
146 DbHandle
openToken(uint32 ssid
, const AccessCredentials
*cred
, const char *name
= NULL
);
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
);
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
);
173 void getDbName(DbHandle db
, std::string
&name
);
174 void setDbName(DbHandle db
, const std::string
&name
);
177 // Internal database interface
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
);
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();
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
);
220 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
221 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
222 uint32 inputSize
, bool encrypt
= true);
224 void getKeyDigest(KeyHandle key
, CssmData
&digest
, Allocator
&alloc
);
225 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
226 { return getKeyDigest(key
, digest
, returnAllocator
); }
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
); }
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
); }
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
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
); }
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
); }
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
);
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
);
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
);
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
);
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
); }
344 // Testing support calls
345 void getUserPromptAttempts(uint32_t& attempts
);
348 // Notification core support
349 void postNotification(NotificationDomain domain
, NotificationEvent event
, const CssmData
&data
);
351 // low-level callback (C form)
352 typedef OSStatus
ConsumeNotification(NotificationDomain domain
, NotificationEvent event
,
353 const void *data
, size_t dataLength
, void *context
);
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
);
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
);
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
);
376 static OSStatus
consumerDispatch(NotificationDomain domain
, NotificationEvent event
,
377 const void *data
, size_t dataLength
, void *context
);
379 void notifyAclChange(KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
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
);
385 DidChangeKeyAclCallback
*mCallback
;
386 void *mCallbackContext
;
388 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
391 Thread() : registered(false), notifySeq(0) { }
392 operator bool() const { return registered
; }
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
402 RefPointer
<OSXCode
> myself
;
403 ThreadNexus
<Thread
> thread
;
406 static ModuleNexus
<Global
> mGlobal
;
407 static const char *mContactName
;
411 } // end namespace SecurityServer
412 } // end namespace Security