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 ClientSession(CssmAllocator
&standard
, CssmAllocator
&returning
);
111 virtual ~ClientSession();
113 CssmAllocator
&internalAllocator
;
114 CssmAllocator
&returnAllocator
;
117 typedef CSSM_DB_ACCESS_TYPE DBAccessType
;
118 typedef Security::Context Context
;
125 // use this only if you know what you're doing...
126 void contactName(const char *name
);
127 const char *contactName() const;
131 DbHandle
createDb(const DLDbIdentifier
&dbId
,
132 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
133 const DBParameters
¶ms
);
134 DbHandle
decodeDb(const DLDbIdentifier
&dbId
,
135 const AccessCredentials
*cred
, const CssmData
&blob
);
136 void encodeDb(DbHandle db
, CssmData
&blob
, CssmAllocator
&alloc
);
137 void encodeDb(DbHandle db
, CssmData
&blob
) { return encodeDb(db
, blob
, returnAllocator
); }
138 void releaseDb(DbHandle db
);
139 void authenticateDb(DbHandle db
, DBAccessType type
, const AccessCredentials
*cred
);
140 void setDbParameters(DbHandle db
, const DBParameters
¶ms
);
141 void getDbParameters(DbHandle db
, DBParameters
¶ms
);
142 void getDbSuggestedIndex(DbHandle db
, CssmData
&index
, CssmAllocator
&alloc
);
143 void getDbSuggestedIndex(DbHandle db
, CssmData
&index
)
144 { return getDbSuggestedIndex(db
, index
, returnAllocator
); }
145 void changePassphrase(DbHandle db
, const AccessCredentials
*cred
);
146 void lock(DbHandle db
);
147 void lockAll(bool forSleep
);
148 void unlock(DbHandle db
);
149 void unlock(DbHandle db
, const CssmData
&passPhrase
);
150 bool isLocked(DbHandle db
);
153 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
, CssmAllocator
&alloc
);
154 void encodeKey(KeyHandle key
, CssmData
&blob
, KeyUID
*uid
= NULL
)
155 { return encodeKey(key
, blob
, uid
, returnAllocator
); }
156 KeyHandle
decodeKey(DbHandle db
, const CssmData
&blob
, CssmKey::Header
&header
);
157 void releaseKey(KeyHandle key
);
159 CssmKeySize
queryKeySizeInBits(KeyHandle key
);
160 uint32
getOutputSize(const Security::Context
&context
, KeyHandle key
,
161 uint32 inputSize
, bool encrypt
= true);
163 void getKeyDigest(KeyHandle key
, CssmData
&digest
, CssmAllocator
&alloc
);
164 void getKeyDigest(KeyHandle key
, CssmData
&digest
)
165 { return getKeyDigest(key
, digest
, returnAllocator
); }
169 // key wrapping and unwrapping
170 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
171 const AccessCredentials
*cred
,
172 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
, CssmAllocator
&alloc
);
173 void wrapKey(const Security::Context
&context
, KeyHandle key
, KeyHandle keyToBeWrapped
,
174 const AccessCredentials
*cred
,
175 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
)
176 { return wrapKey(context
, key
, keyToBeWrapped
, cred
,
177 descriptiveData
, wrappedKey
, returnAllocator
); }
179 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
180 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
181 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
182 CssmData
&data
, KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
, CssmAllocator
&alloc
);
183 void unwrapKey(DbHandle db
, const Security::Context
&context
, KeyHandle key
, KeyHandle publicKey
,
184 const CssmWrappedKey
&wrappedKey
, uint32 keyUsage
, uint32 keyAttr
,
185 const AccessCredentials
*cred
, const AclEntryInput
*owner
, CssmData
&data
,
186 KeyHandle
&newKey
, CssmKey::Header
&newKeyHeader
)
187 { return unwrapKey(db
, context
, key
, publicKey
, wrappedKey
, keyUsage
, keyAttr
,
188 cred
, owner
, data
, newKey
, newKeyHeader
, returnAllocator
); }
190 // key generation and derivation
191 void generateKey(DbHandle db
, const Security::Context
&context
, uint32 keyUsage
, uint32 keyAttr
,
192 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
193 KeyHandle
&newKey
, CssmKey::Header
&newHeader
);
194 void generateKey(DbHandle db
, const Security::Context
&context
,
195 uint32 pubKeyUsage
, uint32 pubKeyAttr
,
196 uint32 privKeyUsage
, uint32 privKeyAttr
,
197 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
198 KeyHandle
&pubKey
, CssmKey::Header
&pubHeader
,
199 KeyHandle
&privKey
, CssmKey::Header
&privHeader
);
200 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
201 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
202 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
203 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, CssmAllocator
&alloc
);
204 void deriveKey(DbHandle db
, const Security::Context
&context
, KeyHandle baseKey
,
205 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
206 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
207 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
208 { return deriveKey(db
, context
, baseKey
, keyUsage
, keyAttr
, param
, cred
, owner
, newKey
, newHeader
, returnAllocator
); }
209 //void generateAlgorithmParameters(); // not implemented
211 void generateRandom(CssmData
&data
);
214 void encrypt(const Security::Context
&context
, KeyHandle key
,
215 const CssmData
&in
, CssmData
&out
, CssmAllocator
&alloc
);
216 void encrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
217 { return encrypt(context
, key
, in
, out
, returnAllocator
); }
218 void decrypt(const Security::Context
&context
, KeyHandle key
,
219 const CssmData
&in
, CssmData
&out
, CssmAllocator
&alloc
);
220 void decrypt(const Security::Context
&context
, KeyHandle key
, const CssmData
&in
, CssmData
&out
)
221 { return decrypt(context
, key
, in
, out
, returnAllocator
); }
224 void generateSignature(const Security::Context
&context
, KeyHandle key
,
225 const CssmData
&data
, CssmData
&signature
, CssmAllocator
&alloc
,
226 CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
);
227 void generateSignature(const Security::Context
&context
, KeyHandle key
,
228 const CssmData
&data
, CssmData
&signature
, CSSM_ALGORITHMS signOnlyAlgorithm
= CSSM_ALGID_NONE
)
229 { return generateSignature(context
, key
, data
, signature
, returnAllocator
, signOnlyAlgorithm
); }
230 void verifySignature(const Security::Context
&context
, KeyHandle key
,
231 const CssmData
&data
, const CssmData
&signature
,
232 CSSM_ALGORITHMS verifyOnlyAlgorithm
= CSSM_ALGID_NONE
);
235 void generateMac(const Security::Context
&context
, KeyHandle key
,
236 const CssmData
&data
, CssmData
&mac
, CssmAllocator
&alloc
);
237 void generateMac(const Security::Context
&context
, KeyHandle key
,
238 const CssmData
&data
, CssmData
&mac
)
239 { return generateMac(context
, key
, data
, mac
, returnAllocator
); }
240 void verifyMac(const Security::Context
&context
, KeyHandle key
,
241 const CssmData
&data
, const CssmData
&mac
);
243 // key ACL management
244 void getKeyAcl(KeyHandle key
, const char *tag
,
245 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
);
246 void getKeyAcl(KeyHandle key
, const char *tag
,
247 uint32
&count
, AclEntryInfo
* &info
)
248 { return getKeyAcl(key
, tag
, count
, info
, returnAllocator
); }
249 void changeKeyAcl(KeyHandle key
, const AccessCredentials
&cred
, const AclEdit
&edit
);
250 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
);
251 void getKeyOwner(KeyHandle key
, AclOwnerPrototype
&owner
)
252 { return getKeyOwner(key
, owner
, returnAllocator
); }
253 void changeKeyOwner(KeyHandle key
, const AccessCredentials
&cred
,
254 const AclOwnerPrototype
&edit
);
256 // database ACL management
257 void getDbAcl(DbHandle db
, const char *tag
,
258 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
);
259 void getDbAcl(DbHandle db
, const char *tag
,
260 uint32
&count
, AclEntryInfo
* &info
)
261 { return getDbAcl(db
, tag
, count
, info
, returnAllocator
); }
262 void changeDbAcl(DbHandle db
, const AccessCredentials
&cred
, const AclEdit
&edit
);
263 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
);
264 void getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
)
265 { return getDbOwner(db
, owner
, returnAllocator
); }
266 void changeDbOwner(DbHandle db
, const AccessCredentials
&cred
,
267 const AclOwnerPrototype
&edit
);
269 // database key manipulations
270 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
271 uint32 keyUsage
, uint32 keyAttr
,
272 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
273 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, CssmAllocator
&alloc
);
274 void extractMasterKey(DbHandle db
, const Context
&context
, DbHandle sourceDb
,
275 uint32 keyUsage
, uint32 keyAttr
,
276 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
277 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
278 { return extractMasterKey(db
, context
, sourceDb
, keyUsage
, keyAttr
, cred
, owner
,
279 newKey
, newHeader
, returnAllocator
); }
282 // Authorization API support
283 void authCreate(const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
284 AuthorizationFlags flags
,AuthorizationBlob
&result
);
285 void authRelease(const AuthorizationBlob
&auth
, AuthorizationFlags flags
);
286 void authCopyRights(const AuthorizationBlob
&auth
,
287 const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
288 AuthorizationFlags flags
, AuthorizationItemSet
**result
);
289 void authCopyInfo(const AuthorizationBlob
&auth
, const char *tag
, AuthorizationItemSet
* &info
);
290 void authExternalize(const AuthorizationBlob
&auth
, AuthorizationExternalForm
&extForm
);
291 void authInternalize(const AuthorizationExternalForm
&extForm
, AuthorizationBlob
&auth
);
294 // Session API support
295 void getSessionInfo(SecuritySessionId
&sessionId
, SessionAttributeBits
&attrs
);
296 void setupSession(SessionCreationFlags flags
, SessionAttributeBits attrs
);
299 // Notification core support
300 void requestNotification(Port receiver
, Listener::Domain domain
, Listener::EventMask events
);
301 void stopNotification(Port receiver
);
302 void postNotification(Listener::Domain domain
, Listener::Event event
, const CssmData
&data
);
304 typedef OSStatus
ConsumeNotification(Listener::Domain domain
, Listener::Event event
,
305 const void *data
, size_t dataLength
, void *context
);
306 OSStatus
dispatchNotification(const mach_msg_header_t
*message
,
307 ConsumeNotification
*consumer
, void *context
) throw();
310 // AuthorizationDB API
311 void authorizationdbGet(const AuthorizationString rightname
, CssmData
&rightDefinition
, CssmAllocator
&alloc
);
312 void authorizationdbSet(const AuthorizationBlob
&auth
, const AuthorizationString rightname
, uint32_t rightdefinitionLength
, const void *rightdefinition
);
313 void authorizationdbRemove(const AuthorizationBlob
&auth
, const AuthorizationString rightname
);
316 // miscellaneous administrative calls
317 void addCodeEquivalence(const CssmData
&oldCode
, const CssmData
&newCode
,
318 const char *name
, bool forSystem
= false);
319 void removeCodeEquivalence(const CssmData
&code
, const char *name
, bool forSystem
= false);
320 void setAlternateSystemRoot(const char *path
);
323 void getAcl(AclKind kind
, KeyHandle key
, const char *tag
,
324 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
);
325 void changeAcl(AclKind kind
, KeyHandle key
,
326 const AccessCredentials
&cred
, const AclEdit
&edit
);
327 void getOwner(AclKind kind
, KeyHandle key
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
);
328 void changeOwner(AclKind kind
, KeyHandle key
, const AccessCredentials
&cred
,
329 const AclOwnerPrototype
&edit
);
332 static UnixPlusPlus::StaticForkMonitor mHasForked
; // global fork indicator
335 Thread() : registered(false) { }
336 operator bool() const { return registered
; }
338 ReceivePort replyPort
; // dedicated reply port (send right held by SecurityServer)
339 bool registered
; // has been registered with SecurityServer
345 RefPointer
<CodeSigning::OSXCode
> myself
;
346 ThreadNexus
<Thread
> thread
;
349 static ModuleNexus
<Global
> mGlobal
;
350 static bool mSetupSession
;
351 static const char *mContactName
;
355 } // end namespace SecurityServer
356 } // end namespace Security