/ OSX / libsecurity_cdsa_client / lib / securestorage.h
securestorage.h
  1  /*
  2   * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
  3   * 
  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
  8   * using this file.
  9   * 
 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.
 16   */
 17  
 18  
 19  //
 20  // securestorage - client interface to CSP DLs and their operations
 21  //
 22  #ifndef _H_CDSA_CLIENT_SECURESTORAGE
 23  #define _H_CDSA_CLIENT_SECURESTORAGE  1
 24  
 25  #include <security_cdsa_client/cspclient.h>
 26  #include <security_cdsa_client/dlclient.h>
 27  #include <security_cdsa_client/keyclient.h>
 28  
 29  namespace Security
 30  {
 31  
 32  namespace CssmClient
 33  {
 34  
 35  //
 36  // A CSP and a DL attachment of the same subservice
 37  //
 38  // This gives us 2 Object instances, but we make sure that have the same
 39  // mImpl.  Currently this class has no behaviour, but it will get some in
 40  // the future.
 41  //
 42  class CSPDLImpl : public CSPImpl, public DLImpl
 43  {
 44  public:
 45  	CSPDLImpl(const Guid &guid);
 46  	CSPDLImpl(const Module &module);
 47  	virtual ~CSPDLImpl();
 48  
 49  	// Object methods.
 50  	bool isActive() const { return CSPImpl::isActive() || DLImpl::isActive(); }
 51  
 52  	virtual Allocator &allocator() const;
 53  	virtual void allocator(Allocator &alloc);
 54  
 55  	virtual bool operator <(const CSPDLImpl &other) const;
 56  	virtual bool operator ==(const CSPDLImpl &other) const;
 57  
 58  	// Attachment methods.
 59  	virtual CSSM_SERVICE_MASK subserviceMask() const;
 60  	virtual void subserviceId(uint32 id);
 61  
 62  	uint32 subserviceId() const { return CSPImpl::subserviceId(); }
 63  	CSSM_ATTACH_FLAGS cspFlags() const { return CSPImpl::flags(); }
 64  	void cspFlags(CSSM_ATTACH_FLAGS f) { CSPImpl::flags(f); }
 65  	CSSM_ATTACH_FLAGS dlFlags() const { return DLImpl::flags(); }
 66  	void dlFlags(CSSM_ATTACH_FLAGS f) { DLImpl::flags(f); }
 67  
 68  	void attach() { CSPImpl::attach(); DLImpl::attach(); }
 69  	void detach() { CSPImpl::detach(); DLImpl::detach(); }
 70  	bool attached() const { return CSPImpl::attached() || DLImpl::attached(); }
 71  
 72  	Module module() const { return CSPImpl::module(); }
 73  	const Guid &guid() const { return CSPImpl::guid(); }
 74  	CSSM_MODULE_HANDLE cspHandle() { return CSPImpl::handle(); }
 75  	CSSM_MODULE_HANDLE dlHandle() { return DLImpl::handle(); }
 76  
 77  	CssmSubserviceUid subserviceUid() const
 78  	{ return CSPImpl::subserviceUid(); }
 79  
 80  private:
 81  };
 82  
 83  
 84  class CSPDL : public CSP, public DL
 85  {
 86  public:
 87  	typedef CSPDLImpl Impl;
 88  
 89  	explicit CSPDL(Impl *impl) : CSP(impl), DL(impl) {}
 90  	CSPDL(const Guid &guid) : CSP(new Impl(guid)), DL(&CSP::impl<Impl>()) {}
 91  	CSPDL(const Module &module)
 92  		: CSP(new Impl(module)), DL(&CSP::impl<Impl>()) {}
 93  
 94  	//template <class _Impl> _Impl &impl() const
 95  	//{ return CSP::impl<_Impl>(); }
 96  
 97  	Impl *get() const { return &CSP::impl<Impl>(); }
 98  	Impl *operator ->() const { return &CSP::impl<Impl>(); }
 99  	Impl &operator *() const { return CSP::impl<Impl>(); }
100  
101  	// Conversion operators must be here
102  	bool operator !() const { return !get(); }
103  	operator bool() const { return get(); }
104  
105  	bool operator <(const CSPDL &other) const
106  	{ return *this && other ? **this < *other : get() < other.get(); }
107  	bool operator ==(const CSPDL &other) const
108  	{ return *this && other ? **this == *other : get() == other.get(); }
109  };
110  
111  
112  //
113  // SSCSPDL -- Secure storage class
114  //
115  class SSCSPDLImpl : public CSPDLImpl
116  {
117  public:
118  	SSCSPDLImpl(const Guid &guid);
119  	SSCSPDLImpl(const Module &module);
120  	virtual ~SSCSPDLImpl();
121  
122  	// DbMaker
123  	DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
124  private:
125  };
126  
127  class SSCSPDL : public CSPDL 
128  {
129  public:
130  	typedef SSCSPDLImpl Impl;
131  
132  	explicit SSCSPDL(Impl *impl) : CSPDL(impl) {}
133  	SSCSPDL(const Guid &guid) : CSPDL(new Impl(guid)) {}
134  	SSCSPDL(const Module &module) : CSPDL(new Impl(module)) {}
135  
136  	Impl *operator ->() const { return &CSP::impl<Impl>(); }
137  	Impl &operator *() const { return CSP::impl<Impl>(); }
138  };
139  
140  
141  //
142  // SSDbImpl --  A Security Storage Db object.
143  //
144  class SSGroup;
145  class SSDbUniqueRecord;
146  
147  class SSDbImpl : public DbImpl
148  {
149  public:
150  	SSDbImpl(const SSCSPDL &cspdl,
151  			 const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
152  	virtual ~SSDbImpl();
153  
154  	void create();
155  	void open();
156  
157      // This insert is here to explicitly catch calls to DbImpl's insert. You probably want the ssInsert calls below.
158      DbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
159                                const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
160                                const CSSM_DATA *data);
161  
162  	SSDbUniqueRecord ssInsert(CSSM_DB_RECORDTYPE recordType,
163  							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
164  							const CSSM_DATA *data,
165  							const CSSM_RESOURCE_CONTROL_CONTEXT *rc = NULL);
166  
167  	SSDbUniqueRecord ssInsert(CSSM_DB_RECORDTYPE recordType,
168  							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
169  							const CSSM_DATA *data, const SSGroup &group,
170  							const CSSM_ACCESS_CREDENTIALS *cred);
171  
172  	// DbCursorMaker
173  	DbCursorImpl *newDbCursor(const CSSM_QUERY &query,
174  							  Allocator &allocator);
175  	DbCursorImpl *newDbCursor(uint32 capacity, Allocator &allocator);
176  
177  	// SSDbUniqueRecordMaker
178  	DbUniqueRecordImpl *newDbUniqueRecord();
179  
180  	CSP csp() { return parent<CSP>(); }
181  };
182  
183  class SSDb : public Db
184  {
185  public:
186  	typedef SSDbImpl Impl;
187  
188  	explicit SSDb(Impl *impl) : Db(impl) {}
189  	SSDb(const SSCSPDL &cspdl, const char *inDbName,
190  		 const CSSM_NET_ADDRESS *inDbLocation = NULL)
191  		: Db(cspdl->newDb(inDbName, inDbLocation)) {}
192  
193  	Impl *operator ->() const { return &impl<Impl>(); }
194  	Impl &operator *() const { return impl<Impl>(); }
195  };
196  
197  
198  //
199  // SSGroup -- Group key with acl, used to protect a group of items.
200  //
201  class SSGroupImpl : public KeyImpl
202  {
203  public:
204  	SSGroupImpl(const SSDb &ssDb, const CSSM_DATA &dataBlob);
205  	SSGroupImpl(const SSDb &ssDb,
206  				const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry);
207  
208  	static bool isGroup(const CSSM_DATA &dataBlob);
209  
210  	const CssmData label() const;
211  	void decodeDataBlob(const CSSM_DATA &dataBlob,
212  						const CSSM_ACCESS_CREDENTIALS *cred,
213  						Allocator &allocator, CSSM_DATA &data);
214  	void encodeDataBlob(const CSSM_DATA *data,
215  						const CSSM_ACCESS_CREDENTIALS *cred,
216  						CssmDataContainer &dataBlob);
217  
218  private:
219  	// Constants
220  	enum
221  	{
222  		// Label prefix for a secure storage group
223  		kGroupMagic = FOUR_CHAR_CODE('ssgp'),
224  
225  		// Size of label (including prefix)
226  		kLabelSize = 20,
227  
228  		// Size of IV
229  		kIVSize = 8
230  	};
231  
232  	CSSM_DB_ATTR_DECL(kLabel);
233  
234  	CssmDataContainer mLabel;
235  };
236  
237  class SSGroup : public Key
238  {
239  public:
240  	typedef SSGroupImpl Impl;
241  	explicit SSGroup(Impl *impl) : Key(impl) {}
242  
243  	SSGroup() : Key(NULL) {}
244  
245  	// Create a new group.
246  	SSGroup(const SSDb &ssDb,
247  			const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry)
248  	: Key(new Impl(ssDb, credAndAclEntry)) {}
249  
250  	// Lookup an existing group based on a dataBlob.
251  	SSGroup(const SSDb &ssDb, const CSSM_DATA &dataBlob)
252  	: Key(new Impl(ssDb, dataBlob)) {}
253  
254  	Impl *operator ->() const { return &impl<Impl>(); }
255  	Impl &operator *() const { return impl<Impl>(); }
256  };
257  
258  
259  //
260  // SSDbCursor -- Cursor for iterating over Securely Stored records (or keys)
261  //
262  class SSDbCursorImpl : public DbDbCursorImpl
263  {
264  public:
265  	SSDbCursorImpl(const Db &db, const CSSM_QUERY &query,
266  				   Allocator &allocator);
267  	SSDbCursorImpl(const Db &db, uint32 capacity,
268  				   Allocator &allocator);
269  
270  	bool next(DbAttributes *attributes, ::CssmDataContainer *data,
271  			  DbUniqueRecord &uniqueId);
272  	bool next(DbAttributes *attributes, ::CssmDataContainer *data,
273  			  DbUniqueRecord &uniqueId, const CSSM_ACCESS_CREDENTIALS *cred);
274  	bool nextKey(DbAttributes *attributes, Key &key, DbUniqueRecord &uniqueId);
275  	//bool nextGroup(DbAttributes *attributes, SSGroup &group, DbUniqueRecord &uniqueId);
276  
277  	SSDb database() { return parent<SSDb>(); }
278  protected:
279  	void activate();
280  	void deactivate();
281  };
282  
283  class SSDbCursor : public DbCursor
284  {
285  public:
286  	typedef SSDbCursorImpl Impl;
287  
288  	explicit SSDbCursor(Impl *impl) : DbCursor(impl) {}
289  	SSDbCursor(const SSDb &ssDb, const CSSM_QUERY &query,
290  			   Allocator &allocator = Allocator::standard())
291  		: DbCursor(ssDb->newDbCursor(query, allocator)) {}
292  	SSDbCursor(const SSDb &ssDb, const uint32 capacity = 0,
293  			   Allocator &allocator = Allocator::standard())
294  		: DbCursor(ssDb->newDbCursor(capacity, allocator)) {}
295  
296  	Impl *operator ->() const { return &impl<Impl>(); }
297  	Impl &operator *() const { return impl<Impl>(); }
298  };
299  
300  
301  //
302  // SSDbUniqueRecord
303  //
304  class SSDbUniqueRecordImpl : public DbUniqueRecordImpl
305  {
306  public:
307  	SSDbUniqueRecordImpl(const Db &db);
308  	virtual ~SSDbUniqueRecordImpl();
309  
310  	void deleteRecord();
311  	void deleteRecord(const CSSM_ACCESS_CREDENTIALS *cred);
312  	void modify(CSSM_DB_RECORDTYPE recordType,
313  				const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
314  				const CSSM_DATA *data,
315  				CSSM_DB_MODIFY_MODE modifyMode);
316  	void modify(CSSM_DB_RECORDTYPE recordType,
317  				const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
318  				const CSSM_DATA *data,
319  				CSSM_DB_MODIFY_MODE modifyMode,
320  				const CSSM_ACCESS_CREDENTIALS *cred);
321  	void get(DbAttributes *attributes, ::CssmDataContainer *data);
322  	void get(DbAttributes *attributes, ::CssmDataContainer *data,
323  			 const CSSM_ACCESS_CREDENTIALS *cred);
324  
325  	SSDb database() { return parent<SSDb>(); }
326  
327  	// Return the group that this record is in.
328  	SSGroup group();
329  };
330  
331  class SSDbUniqueRecord : public DbUniqueRecord
332  {
333  public:
334  	typedef SSDbUniqueRecordImpl Impl;
335  
336  	explicit SSDbUniqueRecord(Impl *impl) : DbUniqueRecord(impl) {}
337  	SSDbUniqueRecord(const SSDb &ssDb)
338  		: DbUniqueRecord(ssDb->newDbUniqueRecord()) {}
339  
340  	Impl *operator ->() const { return &impl<Impl>(); }
341  	Impl &operator *() const { return impl<Impl>(); }
342  };
343  
344  }; // end namespace CssmClient
345  
346  } // end namespace Security
347  
348  #endif //_H_CDSA_CLIENT_SECURESTORAGE