/ OSX / libsecurityd / lib / ssclient.h
ssclient.h
  1  /*
  2   * Copyright (c) 2000-2008,2011-2013 Apple Inc. All Rights Reserved.
  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  
 38  #ifdef __cplusplus
 39  
 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>
 44  #include "ssnotify.h"
 45  
 46  
 47  namespace Security {
 48  namespace SecurityServer {
 49  
 50  #endif //__cplusplus
 51  
 52  
 53  //
 54  // Unique-identifier blobs for key objects
 55  //
 56  typedef struct KeyUID {
 57      uint8 signature[20];
 58  } KeyUID;
 59  
 60  
 61  //
 62  // Maximum length of hash (digest) arguments (bytes)
 63  //
 64  #define maxUcspHashLength 64
 65  
 66  
 67  //
 68  // Authorization blobs
 69  //
 70  typedef struct AuthorizationBlob {
 71      uint32 data[2];
 72  	
 73  #ifdef __cplusplus
 74  	bool operator < (const AuthorizationBlob &other) const
 75  	{ return memcmp(data, other.data, sizeof(data)) < 0; }
 76  	
 77  	bool operator == (const AuthorizationBlob &other) const
 78  	{ return memcmp(data, other.data, sizeof(data)) == 0; }
 79      
 80      size_t hash() const {	//@@@ revisit this hash
 81          return data[0] ^ data[1] << 3;
 82      }
 83  #endif
 84  } AuthorizationBlob;
 85  
 86  
 87  //
 88  // Initial-setup data for versioning etc.
 89  //
 90  typedef struct {
 91  	uint32_t order;
 92  	uint32_t version;
 93  } ClientSetupInfo;
 94  
 95  #define SSPROTOVERSION 20000
 96  
 97  
 98  //
 99  // Database parameter structure
100  //
101  typedef struct {
102  	uint32_t idleTimeout;				// seconds idle timout lock
103  	uint8_t lockOnSleep;				// lock keychain when system sleeps
104  } DBParameters;
105  
106  
107  #ifdef __cplusplus
108  
109  
110  //
111  // A client connection (session)
112  //
113  class ClientSession : public ClientCommon {
114  public:
115  	ClientSession(Allocator &standard = Allocator::standard(),
116  		Allocator &returning = Allocator::standard());
117  	virtual ~ClientSession();
118  
119  public:
120  	void activate();
121  	void reset();
122  	
123  public:
124  	// use this only if you know what you're doing...
125  	void contactName(const char *name);
126  	const char *contactName() const;
127  
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);
133      }
134  
135  
136  public:
137  	//
138  	// common database interface
139  	//
140  	void authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type, const AccessCredentials *cred);
141  	void releaseDb(DbHandle db);
142  	
143  	//
144  	// External database interface
145  	//
146  	DbHandle openToken(uint32 ssid, const AccessCredentials *cred, const char *name = NULL);
147  
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);
158  
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);
172  	
173  	void getDbName(DbHandle db, std::string &name);
174  	void setDbName(DbHandle db, const std::string &name);
175  
176  	//
177  	// Internal database interface
178  	//
179  	DbHandle createDb(const DLDbIdentifier &dbId,
180          const AccessCredentials *cred, const AclEntryInput *owner,
181          const DBParameters &params);
182      DbHandle cloneDb(const DLDbIdentifier &newDbId, DbHandle srcDb);
183  
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 &params);
196  	void getDbParameters(DbHandle db, DBParameters &params);
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();
208  	
209  public:
210  	//
211  	// Key objects
212  	//
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);
219  
220  	CssmKeySize queryKeySizeInBits(KeyHandle key);
221      uint32 getOutputSize(const Security::Context &context, KeyHandle key,
222          uint32 inputSize, bool encrypt = true);
223  		
224  	void getKeyDigest(KeyHandle key, CssmData &digest, Allocator &alloc);
225  	void getKeyDigest(KeyHandle key, CssmData &digest)
226  	{ return getKeyDigest(key, digest, returnAllocator); }
227  
228  
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); }
238      
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); }
249  
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 &param,
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 &param,
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
270  
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); }
274  	
275      // encrypt/decrypt
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); }
284  
285      // signatures
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);
295  		
296      // MACs
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);
304  	
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);
317  	
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);
330  	
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); }
342  
343  public:
344      // Testing support calls
345      void getUserPromptAttempts(uint32_t& attempts);
346  		
347  public:
348      // Notification core support
349      void postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data);
350      
351  	// low-level callback (C form)
352      typedef OSStatus ConsumeNotification(NotificationDomain domain, NotificationEvent event,
353          const void *data, size_t dataLength, void *context);
354  	
355  public:
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);
358  	
359  public:
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);
364  	
365  private:
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);
375  	
376  	static OSStatus consumerDispatch(NotificationDomain domain, NotificationEvent event,
377  		const void *data, size_t dataLength, void *context);
378  
379  	void notifyAclChange(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag);
380  
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);
384  private:
385  	DidChangeKeyAclCallback *mCallback;
386  	void *mCallbackContext;
387  
388  	static UnixPlusPlus::StaticForkMonitor mHasForked;	// global fork indicator
389  
390  	struct Thread {
391  		Thread() : registered(false), notifySeq(0) { }
392  		operator bool() const { return registered; }
393  		
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
397  	};
398  
399  	struct Global {
400          Global();
401  		Port serverPort;
402  		RefPointer<OSXCode> myself;
403  		ThreadNexus<Thread> thread;
404  	};
405  
406  	static ModuleNexus<Global> mGlobal;
407  	static const char *mContactName;
408  };
409  
410  
411  } // end namespace SecurityServer
412  } // end namespace Security
413  
414  #endif //__cplusplus
415  
416  
417  #endif //_H_SSCLIENT