1/*
2 * Copyright (c) 2000-2007 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// database - abstract database management
27//
28// This file defines database objects that represent different
29// way to implement "database with cryptographic operations on its contents".
30// The objects here are abstract and need to be implemented to be useful.
31//
32#ifndef _H_DATABASE
33#define _H_DATABASE
34
35#include "structure.h"
36#include "acls.h"
37#include "dbcrypto.h"
38#include "notifications.h"
39#include <security_utilities/utilities.h>
40#include <security_cdsa_utilities/u32handleobject.h>
41#include <security_cdsa_utilities/cssmdb.h>
42#include <security_utilities/machserver.h>
43#include <security_agent_client/agentclient.h>
44#include <security_utilities/timeflow.h>
45#include <string>
46#include <map>
47
48
49class Key;
50class Connection;
51class Process;
52class Session;
53using MachPlusPlus::MachServer;
54
55
56//
57// A Database::DbCommon is the "common core" of all Database objects that
58// represent the same client database (on disk, presumably).
59// NOTE: DbCommon obeys exterior locking protocol: the caller (always Database)
60// must lock it before operating on its non-const members. In practice,
61// most Database methods lock down their DbCommon first thing.
62//
63class DbCommon : public PerSession {
64public:
65	DbCommon(Session &ssn);
66
67	Session &session() const;
68
69	virtual void sleepProcessing();		// generic action on system sleep
70	virtual void lockProcessing();		// generic action on "lock" requests
71
72	virtual bool belongsToSystem() const; // belongs to system (root) security domain
73
74protected:
75	void notify(NotificationEvent event, const DLDbIdentifier &ident);
76};
77
78
79//
80// A Database object represents an Apple CSP/DL open database (DL/DB) object.
81// It maintains its protected semantic state (including keys) and provides controlled
82// access.
83//
84class Database : public PerProcess, public AclSource {
85    static const NotificationEvent lockedEvent = kNotificationEventLocked;
86    static const NotificationEvent unlockedEvent = kNotificationEventUnlocked;
87    static const NotificationEvent passphraseChangedEvent = kNotificationEventPassphraseChanged;
88
89protected:
90	Database(Process &proc);
91
92public:
93	Process& process() const;
94
95	virtual bool transient() const = 0;			// is transient store (reboot clears)
96
97public:
98	//
99	// A common class for objects that "belong" to a Database and
100	// don't have parents up the global stack. These will die along with
101	// the Database when it goes.
102	//
103	class Subsidiary : public PerProcess {
104	public:
105		Subsidiary(Database &db) { referent(db); }
106		Database &database() const { return referent<Database>(); }
107		Process &process() const { return database().process(); }
108	};
109
110	//
111	// Cryptographic service calls.
112	// These must be supported by any type of database.
113	//
114	virtual void releaseKey(Key &key);
115    virtual void queryKeySizeInBits(Key &key, CssmKeySize &result) = 0;
116    virtual void getOutputSize(const Context &context, Key &key,
117		uint32 inputSize, bool encrypt, uint32 &result) = 0;
118
119	virtual void generateSignature(const Context &context, Key &key,
120		CSSM_ALGORITHMS signOnlyAlgorithm, const CssmData &data, CssmData &signature) = 0;
121	virtual void verifySignature(const Context &context, Key &key,
122		CSSM_ALGORITHMS verifyOnlyAlgorithm, const CssmData &data, const CssmData &signature) = 0;
123	virtual void generateMac(const Context &context, Key &key,
124		const CssmData &data, CssmData &mac) = 0;
125	virtual void verifyMac(const Context &context, Key &key,
126		const CssmData &data, const CssmData &mac) = 0;
127
128	virtual void encrypt(const Context &context, Key &key, const CssmData &clear, CssmData &cipher) = 0;
129	virtual void decrypt(const Context &context, Key &key, const CssmData &cipher, CssmData &clear) = 0;
130
131	virtual void generateKey(const Context &context,
132		const AccessCredentials *cred, const AclEntryPrototype *owner,
133		uint32 usage, uint32 attrs, RefPointer<Key> &newKey) = 0;
134	virtual void generateKey(const Context &context,
135		const AccessCredentials *cred, const AclEntryPrototype *owner,
136		uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
137		RefPointer<Key> &publicKey, RefPointer<Key> &privateKey) = 0;
138
139    virtual void wrapKey(const Context &context, const AccessCredentials *cred,
140		Key *wrappingKey, Key &keyToBeWrapped,
141        const CssmData &descriptiveData, CssmKey &wrappedKey) = 0;
142	virtual void unwrapKey(const Context &context,
143		const AccessCredentials *cred, const AclEntryPrototype *owner,
144		Key *wrappingKey, Key *publicKey, CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs,
145		const CssmKey wrappedKey, RefPointer<Key> &unwrappedKey, CssmData &descriptiveData) = 0;
146	virtual void deriveKey(const Context &context, Key *key,
147		const AccessCredentials *cred, const AclEntryPrototype *owner,
148		CssmData *param, uint32 usage, uint32 attrs, RefPointer<Key> &derivedKey) = 0;
149
150	virtual void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
151	virtual SecurityServerAcl &acl();
152
153	virtual bool isLocked();
154
155public:
156	class Search : public Subsidiary {
157	public:
158		Search(Database &db) : Subsidiary(db) { }
159	};
160
161	class Record : public Subsidiary {
162	public:
163		Record(Database &db) : Subsidiary(db) { }
164	};
165
166	virtual void findFirst(const CssmQuery &query,
167		CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength,
168		CssmData *data, RefPointer<Key> &key, RefPointer<Search> &search,
169		RefPointer<Record> &record,
170		CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength);
171	virtual void findNext(Search *search,
172		CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength,
173		CssmData *data, RefPointer<Key> &key, RefPointer<Record> &record,
174		CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength);
175	virtual void findRecordHandle(Record *record,
176		CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength,
177		CssmData *data, RefPointer<Key> &key,
178		CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength);
179
180	virtual void insertRecord(CSSM_DB_RECORDTYPE recordtype,
181		const CssmDbRecordAttributeData *attributes, mach_msg_type_number_t inAttributesLength,
182		const CssmData &data, RecordHandle &record);
183	virtual void modifyRecord(CSSM_DB_RECORDTYPE recordtype, Record *record,
184		const CssmDbRecordAttributeData *attributes, mach_msg_type_number_t inAttributesLength,
185		const CssmData *data, CSSM_DB_MODIFY_MODE modifyMode);
186	virtual void deleteRecord(Database::Record *record);
187
188	virtual void releaseSearch(Search &search);
189	virtual void releaseRecord(Record &record);
190
191public:
192	// SecurityServerAcl personality
193	AclKind aclKind() const;
194	Database *relatedDatabase();
195
196	bool belongsToSystem() const { return common().belongsToSystem(); }
197
198public:
199	// support ACL remote secret validation (default is no support)
200	virtual bool validateSecret(const AclSubject *subject, const AccessCredentials *cred);
201
202public:
203	static const int maxUnlockTryCount = 3;
204
205public:
206	DbCommon& common() const			{ return parent<DbCommon>(); }
207	virtual const char *dbName() const = 0;
208	virtual void dbName(const char *name);
209};
210
211
212//
213// This class implements a "system keychain unlock record" store
214//
215class SystemKeychainKey {
216public:
217	SystemKeychainKey(const char *path);
218	~SystemKeychainKey();
219
220	bool matches(const DbBlob::Signature &signature);
221	CssmKey &key()		{ return mKey; }
222
223private:
224	std::string mPath;					// path to file
225	CssmKey mKey;						// proper CssmKey with data in mBlob
226
227	bool mValid;						// mBlob was validly read from mPath
228	UnlockBlob mBlob;					// contents of mPath as last read
229
230	Time::Absolute mCachedDate;			// modify date of file when last read
231	Time::Absolute mUpdateThreshold;	// cutoff threshold for checking again
232
233	static const int checkDelay = 1;	// seconds minimum delay between update checks
234
235	bool update();
236};
237
238#endif //_H_DATABASE
239