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
29namespace Security
30{
31
32namespace 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//
42class CSPDLImpl : public CSPImpl, public DLImpl
43{
44public:
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
80private:
81};
82
83
84class CSPDL : public CSP, public DL
85{
86public:
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//
115class SSCSPDLImpl : public CSPDLImpl
116{
117public:
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);
124private:
125};
126
127class SSCSPDL : public CSPDL
128{
129public:
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//
144class SSGroup;
145class SSDbUniqueRecord;
146
147class SSDbImpl : public DbImpl
148{
149public:
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	SSDbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
158							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
159							const CSSM_DATA *data,
160							const CSSM_RESOURCE_CONTROL_CONTEXT *rc = NULL);
161
162	SSDbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
163							const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
164							const CSSM_DATA *data, const SSGroup &group,
165							const CSSM_ACCESS_CREDENTIALS *cred);
166
167	// DbCursorMaker
168	DbCursorImpl *newDbCursor(const CSSM_QUERY &query,
169							  Allocator &allocator);
170	DbCursorImpl *newDbCursor(uint32 capacity, Allocator &allocator);
171
172	// SSDbUniqueRecordMaker
173	DbUniqueRecordImpl *newDbUniqueRecord();
174
175	CSP csp() { return parent<CSP>(); }
176};
177
178class SSDb : public Db
179{
180public:
181	typedef SSDbImpl Impl;
182
183	explicit SSDb(Impl *impl) : Db(impl) {}
184	SSDb(const SSCSPDL &cspdl, const char *inDbName,
185		 const CSSM_NET_ADDRESS *inDbLocation = NULL)
186		: Db(cspdl->newDb(inDbName, inDbLocation)) {}
187
188	Impl *operator ->() const { return &impl<Impl>(); }
189	Impl &operator *() const { return impl<Impl>(); }
190};
191
192
193//
194// SSGroup -- Group key with acl, used to protect a group of items.
195//
196class SSGroupImpl : public KeyImpl
197{
198public:
199	SSGroupImpl(const SSDb &ssDb, const CSSM_DATA &dataBlob);
200	SSGroupImpl(const SSDb &ssDb,
201				const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry);
202
203	static bool isGroup(const CSSM_DATA &dataBlob);
204
205	const CssmData label() const;
206	void decodeDataBlob(const CSSM_DATA &dataBlob,
207						const CSSM_ACCESS_CREDENTIALS *cred,
208						Allocator &allocator, CSSM_DATA &data);
209	void encodeDataBlob(const CSSM_DATA *data,
210						const CSSM_ACCESS_CREDENTIALS *cred,
211						CssmDataContainer &dataBlob);
212
213private:
214	// Constants
215	enum
216	{
217		// Label prefix for a secure storage group
218		kGroupMagic = FOUR_CHAR_CODE('ssgp'),
219
220		// Size of label (including prefix)
221		kLabelSize = 20,
222
223		// Size of IV
224		kIVSize = 8
225	};
226
227	CSSM_DB_ATTR_DECL(kLabel);
228
229	CssmDataContainer mLabel;
230};
231
232class SSGroup : public Key
233{
234public:
235	typedef SSGroupImpl Impl;
236	explicit SSGroup(Impl *impl) : Key(impl) {}
237
238	SSGroup() : Key(NULL) {}
239
240	// Create a new group.
241	SSGroup(const SSDb &ssDb,
242			const CSSM_RESOURCE_CONTROL_CONTEXT *credAndAclEntry)
243	: Key(new Impl(ssDb, credAndAclEntry)) {}
244
245	// Lookup an existing group based on a dataBlob.
246	SSGroup(const SSDb &ssDb, const CSSM_DATA &dataBlob)
247	: Key(new Impl(ssDb, dataBlob)) {}
248
249	Impl *operator ->() const { return &impl<Impl>(); }
250	Impl &operator *() const { return impl<Impl>(); }
251};
252
253
254//
255// SSDbCursor -- Cursor for iterating over Securely Stored records (or keys)
256//
257class SSDbCursorImpl : public DbDbCursorImpl
258{
259public:
260	SSDbCursorImpl(const Db &db, const CSSM_QUERY &query,
261				   Allocator &allocator);
262	SSDbCursorImpl(const Db &db, uint32 capacity,
263				   Allocator &allocator);
264
265	bool next(DbAttributes *attributes, ::CssmDataContainer *data,
266			  DbUniqueRecord &uniqueId);
267	bool next(DbAttributes *attributes, ::CssmDataContainer *data,
268			  DbUniqueRecord &uniqueId, const CSSM_ACCESS_CREDENTIALS *cred);
269	bool nextKey(DbAttributes *attributes, Key &key, DbUniqueRecord &uniqueId);
270	//bool nextGroup(DbAttributes *attributes, SSGroup &group, DbUniqueRecord &uniqueId);
271
272	SSDb database() { return parent<SSDb>(); }
273protected:
274	void activate();
275	void deactivate();
276};
277
278class SSDbCursor : public DbCursor
279{
280public:
281	typedef SSDbCursorImpl Impl;
282
283	explicit SSDbCursor(Impl *impl) : DbCursor(impl) {}
284	SSDbCursor(const SSDb &ssDb, const CSSM_QUERY &query,
285			   Allocator &allocator = Allocator::standard())
286		: DbCursor(ssDb->newDbCursor(query, allocator)) {}
287	SSDbCursor(const SSDb &ssDb, const uint32 capacity = 0,
288			   Allocator &allocator = Allocator::standard())
289		: DbCursor(ssDb->newDbCursor(capacity, allocator)) {}
290
291	Impl *operator ->() const { return &impl<Impl>(); }
292	Impl &operator *() const { return impl<Impl>(); }
293};
294
295
296//
297// SSDbUniqueRecord
298//
299class SSDbUniqueRecordImpl : public DbUniqueRecordImpl
300{
301public:
302	SSDbUniqueRecordImpl(const Db &db);
303	virtual ~SSDbUniqueRecordImpl();
304
305	void deleteRecord();
306	void deleteRecord(const CSSM_ACCESS_CREDENTIALS *cred);
307	void modify(CSSM_DB_RECORDTYPE recordType,
308				const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
309				const CSSM_DATA *data,
310				CSSM_DB_MODIFY_MODE modifyMode);
311	void modify(CSSM_DB_RECORDTYPE recordType,
312				const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
313				const CSSM_DATA *data,
314				CSSM_DB_MODIFY_MODE modifyMode,
315				const CSSM_ACCESS_CREDENTIALS *cred);
316	void get(DbAttributes *attributes, ::CssmDataContainer *data);
317	void get(DbAttributes *attributes, ::CssmDataContainer *data,
318			 const CSSM_ACCESS_CREDENTIALS *cred);
319
320	SSDb database() { return parent<SSDb>(); }
321
322	// Return the group that this record is in.
323	SSGroup group();
324};
325
326class SSDbUniqueRecord : public DbUniqueRecord
327{
328public:
329	typedef SSDbUniqueRecordImpl Impl;
330
331	explicit SSDbUniqueRecord(Impl *impl) : DbUniqueRecord(impl) {}
332	SSDbUniqueRecord(const SSDb &ssDb)
333		: DbUniqueRecord(ssDb->newDbUniqueRecord()) {}
334
335	Impl *operator ->() const { return &impl<Impl>(); }
336	Impl &operator *() const { return impl<Impl>(); }
337};
338
339}; // end namespace CssmClient
340
341} // end namespace Security
342
343#endif //_H_CDSA_CLIENT_SECURESTORAGE
344