2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // ssclient - SecurityServer client interface library
22 // This interface is private to the Security system. It is not a public interface,
23 // and it may change at any time. You have been warned.
29 #include <Security/cssm.h>
30 #include <Security/utilities.h>
31 #include <Security/cssmalloc.h>
32 #include <Security/cssmacl.h>
33 #include <Security/context.h>
34 #include <Security/globalizer.h>
35 #include <Security/unix++.h>
36 #include <Security/mach++.h>
37 #include <Security/cssmdb.h>
38 #include <Security/osxsigning.h>
39 #include <Security/Authorization.h>
40 #include <Security/AuthSession.h>
41 #include <Security/notifications.h>
42 #include <Security/context.h>
45 namespace SecurityServer
{
47 using MachPlusPlus::Port
;
48 using MachPlusPlus::ReceivePort
;
52 // The default Mach bootstrap registration name for SecurityServer,
53 // and the environment variable to override it
55 #define SECURITYSERVER_BOOTSTRAP_NAME "com.apple.SecurityServer"
56 #define SECURITYSERVER_BOOTSTRAP_ENV "SECURITYSERVER"
62 typedef CSSM_HANDLE KeyHandle
;
63 typedef CSSM_HANDLE DbHandle
;
65 static const CSSM_HANDLE noDb
= 0;
66 static const CSSM_HANDLE noKey
= 0;
72 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;
86 struct ClientSetupInfo
{
89 #define SSPROTOVERSION 4
91 enum AclKind
{ dbAcl
, keyAcl
, loginAcl
};
95 // Database parameter structure
99 uint32 idleTimeout
; // seconds idle timout lock
100 uint8 lockOnSleep
; // lock keychain when system sleeps
105 // A client connection (session)
107 class ClientSession
{
108 NOCOPY(ClientSession
)
110 typedef void DidChangeKeyAclCallback(void *context
, ClientSession
&clientSession
,
111 KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
113 ClientSession(CssmAllocator
&standard
, CssmAllocator
&returning
);
114 virtual ~ClientSession();
116 void registerForAclEdits(DidChangeKeyAclCallback
*callback
, void *context
);
118 CssmAllocator
&internalAllocator
;
119 CssmAllocator
&returnAllocator
;
122 typedef CSSM_DB_ACCESS_TYPE DBAccessType
;
123 typedef Security::Context Context
;
130 // use this only if you know what you're doing...
131 void contactName(const char *name
);
132 const char *contactName() const;
136 DbHandle
createDb(const DLDbIdentifier
&dbId
,
137 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
138 const DBParameters
¶ms
);
139 DbHandle
decodeDb(const DLDbIdentifier
&dbId
,
140 const AccessCredentials
*cred
, const CssmData
&blob
);
141 void encodeDb(DbHandle db
, CssmData
&blob
, CssmAllocator
&alloc
);
142 void encodeDb(DbHandle db
, CssmData
&blob
) { return encodeDb(db
, blob
, returnAllocator
); }
143 void releaseDb(DbHandle db
);
144 void authenticateDb(DbHandle db
, DBAccessType type
, const AccessCredentials
*cred
);
145 void setDbParameters(DbHandle db
, const DBParameters
¶ms
);
146 void getDbParameters(DbHandle db
, DBParameters
¶ms
);
147 void getDbSuggestedIndex(DbHandle db
, CssmData
&index
, CssmAllocator
&alloc
);
148 void getDbSuggestedIndex(DbHandle db
, CssmData
&index
)
149 { return getDbSuggestedIndex(db
, index
, returnAllocator
); }
150 void changePassphrase(DbHandle db
, const AccessCredentials
*cred
);
151 void lock(DbHandle db
);
152 void lockAll(bool forSleep
);
153 void unlock(DbHandle db
);
154 void unlock(DbHandle db
, const CssmData
&passPhrase
);
155 bool isLocked(DbHandle db
);
158 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
, CssmAllocator
&alloc
);
159 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
= NULL
)
160 { return encodeKey(key
, blob
, uid
, returnAllocator
); }
161 KeyHandle
decodeKey(DbHandle db
, const CssmData
&blob
, CssmKey::Header
&header
);
162 void releaseKey(KeyHandle key
);
164 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
165 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
166 uint32 inputSize
, bool encrypt
= true);
168 void getKeyDigest(KeyHandle key
, CssmData
&digest
, CssmAllocator
&alloc
);
169 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
170 { return getKeyDigest(key
, digest
, returnAllocator
); }
174 // key wrapping and unwrapping
175 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
176 const AccessCredentials
*cred
,
177 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
, CssmAllocator
&alloc
);
178 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
179 const AccessCredentials
*cred
,
180 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
)
181 { return wrapKey(context
, key
, keyToBeWrapped
, cred
,
182 descriptiveData
, wrappedKey
, returnAllocator
); }
184 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
185 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
186 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
187 CssmData
&data
, KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
, CssmAllocator
&alloc
);
188 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
189 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
190 const AccessCredentials
*cred
, const AclEntryInput
*owner
, CssmData
&data
,
191 KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
)
192 { return unwrapKey(db
, context
, key
, publicKey
, wrappedKey
, keyUsage
, keyAttr
,
193 cred
, owner
, data
, newKey
, newKeyHeader
, returnAllocator
); }
195 // key generation and derivation
196 void generateKey(DbHandle db
, const Security::Context
&context
, uint32 keyUsage
, uint32 keyAttr
,
197 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
198 KeyHandle
&newKey
, CssmKey::Header
&newHeader
);
199 void generateKey(DbHandle db
, const Security::Context
&context
,
200 uint32 pubKeyUsage
, uint32 pubKeyAttr
,
201 uint32 privKeyUsage
, uint32 privKeyAttr
,
202 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
203 KeyHandle
&pubKey
, CssmKey::Header
&pubHeader
,
204 KeyHandle
&privKey
, CssmKey::Header
&privHeader
);
205 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
206 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
207 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
208 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, CssmAllocator
&alloc
);
209 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
210 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
211 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
212 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
213 { return deriveKey(db
, context
, baseKey
, keyUsage
, keyAttr
, param
, cred
, owner
, newKey
, newHeader
, returnAllocator
); }
214 //void generateAlgorithmParameters(); // not implemented
216 void generateRandom(CssmData
&data
);
219 void encrypt(const Security::Context
&context
, KeyHandle key
,
220 const CssmData
&in
, CssmData
&out
, CssmAllocator
&alloc
);
221 void encrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
222 { return encrypt(context
, key
, in
, out
, returnAllocator
); }
223 void decrypt(const Security::Context
&context
, KeyHandle key
,
224 const CssmData
&in
, CssmData
&out
, CssmAllocator
&alloc
);
225 void decrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
226 { return decrypt(context
, key
, in
, out
, returnAllocator
); }
229 void generateSignature(const Security::Context
&context
, KeyHandle key
,
230 const CssmData
&data
, CssmData
&signature
, CssmAllocator
&alloc
,
231 CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
);
232 void generateSignature(const Security::Context
&context
, KeyHandle key
,
233 const CssmData
&data
, CssmData
&signature
, CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
)
234 { return generateSignature(context
, key
, data
, signature
, returnAllocator
, signOnlyAlgorithm
); }
235 void verifySignature(const Security::Context
&context
, KeyHandle key
,
236 const CssmData
&data
, const CssmData
&signature
,
237 CSSM_ALGORITHMS verifyOnlyAlgorithm
= CSSM_ALGID_NONE
);
240 void generateMac(const Security::Context
&context
, KeyHandle key
,
241 const CssmData
&data
, CssmData
&mac
, CssmAllocator
&alloc
);
242 void generateMac(const Security::Context
&context
, KeyHandle key
,
243 const CssmData
&data
, CssmData
&mac
)
244 { return generateMac(context
, key
, data
, mac
, returnAllocator
); }
245 void verifyMac(const Security::Context
&context
, KeyHandle key
,
246 const CssmData
&data
, const CssmData
&mac
);
248 // key ACL management
249 void getKeyAcl(KeyHandle key
, const char *tag
,
250 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
);
251 void getKeyAcl(KeyHandle key
, const char *tag
,
252 uint32
&count
, AclEntryInfo
* &info
)
253 { return getKeyAcl(key
, tag
, count
, info
, returnAllocator
); }
254 void changeKeyAcl(KeyHandle key
, const AccessCredentials
&cred
, const AclEdit
&edit
);
255 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
);
256 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
)
257 { return getKeyOwner(key
, owner
, returnAllocator
); }
258 void changeKeyOwner(KeyHandle key
, const AccessCredentials
&cred
,
259 const AclOwnerPrototype
&edit
);
261 // database ACL management
262 void getDbAcl(DbHandle db
, const char *tag
,
263 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
);
264 void getDbAcl(DbHandle db
, const char *tag
,
265 uint32
&count
, AclEntryInfo
* &info
)
266 { return getDbAcl(db
, tag
, count
, info
, returnAllocator
); }
267 void changeDbAcl(DbHandle db
, const AccessCredentials
&cred
, const AclEdit
&edit
);
268 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
);
269 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
)
270 { return getDbOwner(db
, owner
, returnAllocator
); }
271 void changeDbOwner(DbHandle db
, const AccessCredentials
&cred
,
272 const AclOwnerPrototype
&edit
);
274 // database key manipulations
275 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
276 uint32 keyUsage
, uint32 keyAttr
,
277 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
278 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, CssmAllocator
&alloc
);
279 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
280 uint32 keyUsage
, uint32 keyAttr
,
281 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
282 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
283 { return extractMasterKey(db
, context
, sourceDb
, keyUsage
, keyAttr
, cred
, owner
,
284 newKey
, newHeader
, returnAllocator
); }
287 // Authorization API support
288 void authCreate(const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
289 AuthorizationFlags flags
,AuthorizationBlob
&result
);
290 void authRelease(const AuthorizationBlob
&auth
, AuthorizationFlags flags
);
291 void authCopyRights(const AuthorizationBlob
&auth
,
292 const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
293 AuthorizationFlags flags
, AuthorizationItemSet
**result
);
294 void authCopyInfo(const AuthorizationBlob
&auth
, const char *tag
, AuthorizationItemSet
* &info
);
295 void authExternalize(const AuthorizationBlob
&auth
, AuthorizationExternalForm
&extForm
);
296 void authInternalize(const AuthorizationExternalForm
&extForm
, AuthorizationBlob
&auth
);
299 // Session API support
300 void getSessionInfo(SecuritySessionId
&sessionId
, SessionAttributeBits
&attrs
);
301 void setupSession(SessionCreationFlags flags
, SessionAttributeBits attrs
);
304 // Notification core support
305 void requestNotification(Port receiver
, Listener::Domain domain
, Listener::EventMask events
);
306 void stopNotification(Port receiver
);
307 void postNotification(Listener::Domain domain
, Listener::Event event
, const CssmData
&data
);
309 typedef OSStatus
ConsumeNotification(Listener::Domain domain
, Listener::Event event
,
310 const void *data
, size_t dataLength
, void *context
);
311 OSStatus
dispatchNotification(const mach_msg_header_t
*message
,
312 ConsumeNotification
*consumer
, void *context
) throw();
315 // AuthorizationDB API
316 void authorizationdbGet(const AuthorizationString rightname
, CssmData
&rightDefinition
, CssmAllocator
&alloc
);
317 void authorizationdbSet(const AuthorizationBlob
&auth
, const AuthorizationString rightname
, uint32_t rightdefinitionLength
, const void *rightdefinition
);
318 void authorizationdbRemove(const AuthorizationBlob
&auth
, const AuthorizationString rightname
);
321 // miscellaneous administrative calls
322 void addCodeEquivalence(const CssmData
&oldCode
, const CssmData
&newCode
,
323 const char *name
, bool forSystem
= false);
324 void removeCodeEquivalence(const CssmData
&code
, const char *name
, bool forSystem
= false);
325 void setAlternateSystemRoot(const char *path
);
328 void getAcl(AclKind kind
, KeyHandle key
, const char *tag
,
329 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
);
330 void changeAcl(AclKind kind
, KeyHandle key
,
331 const AccessCredentials
&cred
, const AclEdit
&edit
);
332 void getOwner(AclKind kind
, KeyHandle key
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
);
333 void changeOwner(AclKind kind
, KeyHandle key
, const AccessCredentials
&cred
,
334 const AclOwnerPrototype
&edit
);
336 void addApplicationAclSubject(KeyHandle key
, CSSM_ACL_AUTHORIZATION_TAG tag
);
339 static DidChangeKeyAclCallback
*mCallback
;
340 static void *mCallbackContext
;
342 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
345 Thread() : registered(false) { }
346 operator bool() const { return registered
; }
348 ReceivePort replyPort
; // dedicated reply port (send right held by SecurityServer)
349 bool registered
; // has been registered with SecurityServer
355 RefPointer
<CodeSigning::OSXCode
> myself
;
356 ThreadNexus
<Thread
> thread
;
359 static ModuleNexus
<Global
> mGlobal
;
360 static bool mSetupSession
;
361 static const char *mContactName
;
365 } // end namespace SecurityServer
366 } // end namespace Security