]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2008,2011-2013 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // ssclient - SecurityServer client interface library | |
27 | // | |
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. | |
30 | // | |
31 | #ifndef _H_SSCLIENT | |
32 | #define _H_SSCLIENT | |
33 | ||
34 | #include "sscommon.h" | |
35 | #include <Security/Authorization.h> | |
36 | #include <Security/AuthSession.h> | |
37 | #include <Security/SecCodeHost.h> | |
38 | ||
39 | #ifdef __cplusplus | |
40 | ||
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> | |
45 | #include "ssnotify.h" | |
46 | ||
47 | ||
48 | namespace Security { | |
49 | namespace SecurityServer { | |
50 | ||
51 | #endif //__cplusplus | |
52 | ||
53 | ||
54 | // | |
55 | // Unique-identifier blobs for key objects | |
56 | // | |
57 | typedef struct KeyUID { | |
58 | uint8 signature[20]; | |
59 | } KeyUID; | |
60 | ||
61 | ||
62 | // | |
63 | // Maximum length of hash (digest) arguments (bytes) | |
64 | // | |
65 | #define maxUcspHashLength 64 | |
66 | ||
67 | ||
68 | // | |
69 | // Authorization blobs | |
70 | // | |
71 | typedef struct AuthorizationBlob { | |
72 | uint32 data[2]; | |
73 | ||
74 | #ifdef __cplusplus | |
75 | bool operator < (const AuthorizationBlob &other) const | |
76 | { return memcmp(data, other.data, sizeof(data)) < 0; } | |
77 | ||
78 | bool operator == (const AuthorizationBlob &other) const | |
79 | { return memcmp(data, other.data, sizeof(data)) == 0; } | |
80 | ||
81 | size_t hash() const { //@@@ revisit this hash | |
82 | return data[0] ^ data[1] << 3; | |
83 | } | |
84 | #endif | |
85 | } AuthorizationBlob; | |
86 | ||
87 | ||
88 | // | |
89 | // Initial-setup data for versioning etc. | |
90 | // | |
91 | typedef struct { | |
92 | uint32_t order; | |
93 | uint32_t version; | |
94 | } ClientSetupInfo; | |
95 | ||
96 | #define SSPROTOVERSION 20000 | |
97 | ||
98 | ||
99 | // | |
100 | // Database parameter structure | |
101 | // | |
102 | typedef struct { | |
103 | uint32_t idleTimeout; // seconds idle timout lock | |
104 | uint8_t lockOnSleep; // lock keychain when system sleeps | |
105 | } DBParameters; | |
106 | ||
107 | ||
108 | #ifdef __cplusplus | |
109 | ||
110 | ||
111 | // | |
112 | // A client connection (session) | |
113 | // | |
114 | class ClientSession : public ClientCommon { | |
115 | public: | |
116 | ClientSession(Allocator &standard = Allocator::standard(), | |
117 | Allocator &returning = Allocator::standard()); | |
118 | virtual ~ClientSession(); | |
119 | ||
120 | public: | |
121 | void activate(); | |
122 | void reset(); | |
123 | ||
124 | public: | |
125 | // use this only if you know what you're doing... | |
126 | void contactName(const char *name); | |
127 | const char *contactName() const; | |
128 | ||
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); | |
134 | } | |
135 | ||
136 | ||
137 | public: | |
138 | // | |
139 | // common database interface | |
140 | // | |
141 | void authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type, const AccessCredentials *cred); | |
142 | void releaseDb(DbHandle db); | |
143 | ||
144 | // | |
145 | // External database interface | |
146 | // | |
147 | DbHandle openToken(uint32 ssid, const AccessCredentials *cred, const char *name = NULL); | |
148 | ||
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); | |
159 | ||
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); | |
173 | ||
174 | void getDbName(DbHandle db, std::string &name); | |
175 | void setDbName(DbHandle db, const std::string &name); | |
176 | ||
177 | // | |
178 | // Internal database interface | |
179 | // | |
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); | |
427c49bc A |
199 | void stashDb(DbHandle db); |
200 | void stashDbCheck(DbHandle db); | |
b1ab9ed8 | 201 | bool isLocked(DbHandle db); |
427c49bc A |
202 | void verifyKeyStorePassphrase(uint32_t retries); |
203 | void resetKeyStorePassphrase(const CssmData &passphrase); | |
204 | void changeKeyStorePassphrase(); | |
b1ab9ed8 A |
205 | |
206 | public: | |
207 | // | |
208 | // Key objects | |
209 | // | |
210 | void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid, Allocator &alloc); | |
211 | void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid = NULL) | |
212 | { return encodeKey(key, blob, uid, returnAllocator); } | |
213 | KeyHandle decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header); | |
214 | void recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb, CssmData &blob); | |
215 | void releaseKey(KeyHandle key); | |
216 | ||
217 | CssmKeySize queryKeySizeInBits(KeyHandle key); | |
218 | uint32 getOutputSize(const Security::Context &context, KeyHandle key, | |
219 | uint32 inputSize, bool encrypt = true); | |
220 | ||
221 | void getKeyDigest(KeyHandle key, CssmData &digest, Allocator &alloc); | |
222 | void getKeyDigest(KeyHandle key, CssmData &digest) | |
223 | { return getKeyDigest(key, digest, returnAllocator); } | |
224 | ||
225 | ||
226 | // key wrapping and unwrapping | |
227 | void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped, | |
228 | const AccessCredentials *cred, | |
229 | const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, Allocator &alloc); | |
230 | void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped, | |
231 | const AccessCredentials *cred, | |
232 | const CssmData *descriptiveData, CssmWrappedKey &wrappedKey) | |
233 | { return wrapKey(context, key, keyToBeWrapped, cred, | |
234 | descriptiveData, wrappedKey, returnAllocator); } | |
235 | ||
236 | void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey, | |
237 | const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr, | |
238 | const AccessCredentials *cred, const AclEntryInput *owner, | |
239 | CssmData &data, KeyHandle &newKey, CssmKey::Header &newKeyHeader, Allocator &alloc); | |
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, CssmData &data, | |
243 | KeyHandle &newKey, CssmKey::Header &newKeyHeader) | |
244 | { return unwrapKey(db, context, key, publicKey, wrappedKey, keyUsage, keyAttr, | |
245 | cred, owner, data, newKey, newKeyHeader, returnAllocator); } | |
246 | ||
247 | // key generation and derivation | |
248 | void generateKey(DbHandle db, const Security::Context &context, uint32 keyUsage, uint32 keyAttr, | |
249 | const AccessCredentials *cred, const AclEntryInput *owner, | |
250 | KeyHandle &newKey, CssmKey::Header &newHeader); | |
251 | void generateKey(DbHandle db, const Security::Context &context, | |
252 | uint32 pubKeyUsage, uint32 pubKeyAttr, | |
253 | uint32 privKeyUsage, uint32 privKeyAttr, | |
254 | const AccessCredentials *cred, const AclEntryInput *owner, | |
255 | KeyHandle &pubKey, CssmKey::Header &pubHeader, | |
256 | KeyHandle &privKey, CssmKey::Header &privHeader); | |
257 | void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey, | |
258 | uint32 keyUsage, uint32 keyAttr, CssmData ¶m, | |
259 | const AccessCredentials *cred, const AclEntryInput *owner, | |
260 | KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc); | |
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) | |
265 | { return deriveKey(db, context, baseKey, keyUsage, keyAttr, param, cred, owner, newKey, newHeader, returnAllocator); } | |
266 | //void generateAlgorithmParameters(); // not implemented | |
267 | ||
268 | void generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc); | |
269 | void generateRandom(const Security::Context &context, CssmData &data) | |
270 | { return generateRandom(context, data, returnAllocator); } | |
271 | ||
272 | // encrypt/decrypt | |
273 | void encrypt(const Security::Context &context, KeyHandle key, | |
274 | const CssmData &in, CssmData &out, Allocator &alloc); | |
275 | void encrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out) | |
276 | { return encrypt(context, key, in, out, returnAllocator); } | |
277 | void decrypt(const Security::Context &context, KeyHandle key, | |
278 | const CssmData &in, CssmData &out, Allocator &alloc); | |
279 | void decrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out) | |
280 | { return decrypt(context, key, in, out, returnAllocator); } | |
281 | ||
282 | // signatures | |
283 | void generateSignature(const Security::Context &context, KeyHandle key, | |
284 | const CssmData &data, CssmData &signature, Allocator &alloc, | |
285 | CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE); | |
286 | void generateSignature(const Security::Context &context, KeyHandle key, | |
287 | const CssmData &data, CssmData &signature, CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE) | |
288 | { return generateSignature(context, key, data, signature, returnAllocator, signOnlyAlgorithm); } | |
289 | void verifySignature(const Security::Context &context, KeyHandle key, | |
290 | const CssmData &data, const CssmData &signature, | |
291 | CSSM_ALGORITHMS verifyOnlyAlgorithm = CSSM_ALGID_NONE); | |
292 | ||
293 | // MACs | |
294 | void generateMac(const Security::Context &context, KeyHandle key, | |
295 | const CssmData &data, CssmData &mac, Allocator &alloc); | |
296 | void generateMac(const Security::Context &context, KeyHandle key, | |
297 | const CssmData &data, CssmData &mac) | |
298 | { return generateMac(context, key, data, mac, returnAllocator); } | |
299 | void verifyMac(const Security::Context &context, KeyHandle key, | |
300 | const CssmData &data, const CssmData &mac); | |
301 | ||
302 | // key ACL management | |
303 | void getKeyAcl(KeyHandle key, const char *tag, | |
304 | uint32 &count, AclEntryInfo * &info, Allocator &alloc); | |
305 | void getKeyAcl(KeyHandle key, const char *tag, | |
306 | uint32 &count, AclEntryInfo * &info) | |
307 | { return getKeyAcl(key, tag, count, info, returnAllocator); } | |
308 | void changeKeyAcl(KeyHandle key, const AccessCredentials &cred, const AclEdit &edit); | |
309 | void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner, Allocator &alloc); | |
310 | void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner) | |
311 | { return getKeyOwner(key, owner, returnAllocator); } | |
312 | void changeKeyOwner(KeyHandle key, const AccessCredentials &cred, | |
313 | const AclOwnerPrototype &edit); | |
314 | ||
315 | // database ACL management | |
316 | void getDbAcl(DbHandle db, const char *tag, | |
317 | uint32 &count, AclEntryInfo * &info, Allocator &alloc); | |
318 | void getDbAcl(DbHandle db, const char *tag, | |
319 | uint32 &count, AclEntryInfo * &info) | |
320 | { return getDbAcl(db, tag, count, info, returnAllocator); } | |
321 | void changeDbAcl(DbHandle db, const AccessCredentials &cred, const AclEdit &edit); | |
322 | void getDbOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc); | |
323 | void getDbOwner(DbHandle db, AclOwnerPrototype &owner) | |
324 | { return getDbOwner(db, owner, returnAllocator); } | |
325 | void changeDbOwner(DbHandle db, const AccessCredentials &cred, | |
326 | const AclOwnerPrototype &edit); | |
327 | ||
328 | // database key manipulations | |
329 | void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb, | |
330 | uint32 keyUsage, uint32 keyAttr, | |
331 | const AccessCredentials *cred, const AclEntryInput *owner, | |
332 | KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc); | |
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) | |
337 | { return extractMasterKey(db, context, sourceDb, keyUsage, keyAttr, cred, owner, | |
338 | newKey, newHeader, returnAllocator); } | |
339 | ||
340 | public: | |
341 | // Authorization API support | |
342 | void authCreate(const AuthorizationItemSet *rights, const AuthorizationItemSet *environment, | |
343 | AuthorizationFlags flags,AuthorizationBlob &result); | |
344 | void authRelease(const AuthorizationBlob &auth, AuthorizationFlags flags); | |
345 | void authCopyRights(const AuthorizationBlob &auth, | |
346 | const AuthorizationItemSet *rights, const AuthorizationItemSet *environment, | |
347 | AuthorizationFlags flags, AuthorizationItemSet **result); | |
348 | void authCopyInfo(const AuthorizationBlob &auth, const char *tag, AuthorizationItemSet * &info); | |
349 | void authExternalize(const AuthorizationBlob &auth, AuthorizationExternalForm &extForm); | |
350 | void authInternalize(const AuthorizationExternalForm &extForm, AuthorizationBlob &auth); | |
351 | ||
352 | public: | |
353 | // Session API support | |
354 | void setSessionUserPrefs(SecuritySessionId sessionId, uint32_t userPreferencesLength, const void *userPreferences); | |
355 | ||
356 | public: | |
357 | // Notification core support | |
358 | void postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data); | |
359 | ||
360 | // low-level callback (C form) | |
361 | typedef OSStatus ConsumeNotification(NotificationDomain domain, NotificationEvent event, | |
362 | const void *data, size_t dataLength, void *context); | |
363 | ||
364 | public: | |
365 | // AuthorizationDB API | |
366 | void authorizationdbGet(const AuthorizationString rightname, CssmData &rightDefinition, Allocator &alloc); | |
367 | void authorizationdbSet(const AuthorizationBlob &auth, const AuthorizationString rightname, uint32_t rightdefinitionLength, const void *rightdefinition); | |
368 | void authorizationdbRemove(const AuthorizationBlob &auth, const AuthorizationString rightname); | |
369 | ||
370 | public: | |
371 | // securityd helper support | |
372 | void childCheckIn(Port serverPort, Port taskPort); | |
373 | ||
b1ab9ed8 A |
374 | public: |
375 | // temporary hack to deal with "edit acl" pseudo-error returns | |
376 | typedef void DidChangeKeyAclCallback(void *context, ClientSession &clientSession, | |
377 | KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); | |
378 | void registerForAclEdits(DidChangeKeyAclCallback *callback, void *context); | |
379 | ||
380 | public: | |
381 | // Code Signing hosting interface | |
382 | void registerHosting(mach_port_t hostingPort, SecCSFlags flags); | |
383 | mach_port_t hostingPort(pid_t pid); | |
384 | ||
385 | SecGuestRef createGuest(SecGuestRef host, | |
386 | uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags); | |
387 | void setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes); | |
388 | void removeGuest(SecGuestRef host, SecGuestRef guest); | |
389 | ||
390 | void selectGuest(SecGuestRef guest); | |
391 | SecGuestRef selectedGuest() const; | |
392 | ||
393 | private: | |
394 | static Port findSecurityd(); | |
395 | void getAcl(AclKind kind, GenericHandle key, const char *tag, | |
396 | uint32 &count, AclEntryInfo * &info, Allocator &alloc); | |
397 | void changeAcl(AclKind kind, GenericHandle key, | |
398 | const AccessCredentials &cred, const AclEdit &edit); | |
399 | void getOwner(AclKind kind, GenericHandle key, | |
400 | AclOwnerPrototype &owner, Allocator &alloc); | |
401 | void changeOwner(AclKind kind, GenericHandle key, | |
402 | const AccessCredentials &cred, const AclOwnerPrototype &edit); | |
403 | ||
404 | static OSStatus consumerDispatch(NotificationDomain domain, NotificationEvent event, | |
405 | const void *data, size_t dataLength, void *context); | |
406 | ||
407 | void notifyAclChange(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); | |
408 | ||
409 | void returnAttrsAndData(CssmDbRecordAttributeData *inOutAttributes, | |
410 | CssmDbRecordAttributeData *attrs, CssmDbRecordAttributeData *attrsBase, mach_msg_type_number_t attrsLength, | |
411 | CssmData *inOutData, void *dataPtr, mach_msg_type_number_t dataLength); | |
412 | private: | |
413 | DidChangeKeyAclCallback *mCallback; | |
414 | void *mCallbackContext; | |
415 | ||
416 | static UnixPlusPlus::StaticForkMonitor mHasForked; // global fork indicator | |
417 | ||
418 | struct Thread { | |
419 | Thread() : registered(false), notifySeq(0), | |
420 | currentGuest(kSecNoGuest), lastGuest(kSecNoGuest) { } | |
421 | operator bool() const { return registered; } | |
422 | ||
423 | ReceivePort replyPort; // dedicated reply port (send right held by SecurityServer) | |
424 | bool registered; // has been registered with SecurityServer | |
425 | uint32 notifySeq; // notification sequence number | |
426 | ||
427 | SecGuestRef currentGuest; // last set guest path | |
428 | SecGuestRef lastGuest; // last transmitted guest path | |
429 | }; | |
430 | ||
431 | struct Global { | |
432 | Global(); | |
433 | Port serverPort; | |
434 | RefPointer<OSXCode> myself; | |
435 | ThreadNexus<Thread> thread; | |
436 | }; | |
437 | ||
438 | static ModuleNexus<Global> mGlobal; | |
439 | static const char *mContactName; | |
440 | static SecGuestRef mDedicatedGuest; | |
441 | }; | |
442 | ||
443 | ||
444 | } // end namespace SecurityServer | |
445 | } // end namespace Security | |
446 | ||
447 | #endif //__cplusplus | |
448 | ||
449 | ||
450 | #endif //_H_SSCLIENT |