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