]> git.saurik.com Git - apple/securityd.git/blob - src/kcdatabase.h
securityd-26232.tar.gz
[apple/securityd.git] / src / kcdatabase.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, 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 // kcdatabase - software database container implementation.
27 //
28 // A KeychainDatabase is a software storage container,
29 // implemented in cooperation by the AppleCSLDP CDSA plugin and this daemon.
30 //
31 #ifndef _H_KCDATABASE
32 #define _H_KCDATABASE
33
34 #include "localdatabase.h"
35
36 class KeychainDatabase;
37 class KeychainDbCommon;
38 class KeychainKey;
39
40
41 //
42 // We identify KeychainDatabases uniquely by a combination of
43 // a DLDbIdentifier and a database (blob) identifier. Equivalence
44 // by DbIdentifier is the criterion for parent-side merging.
45 //
46 class DbIdentifier {
47 public:
48 DbIdentifier(const DLDbIdentifier &id, DbBlob::Signature sig)
49 : mIdent(id), mSig(sig) { }
50
51 const DLDbIdentifier &dlDbIdentifier() const { return mIdent; }
52 const DbBlob::Signature &signature() const { return mSig; }
53 operator const DLDbIdentifier &() const { return dlDbIdentifier(); }
54 operator const DbBlob::Signature &() const { return signature(); }
55 const char *dbName() const { return mIdent.dbName(); }
56
57 bool operator < (const DbIdentifier &id) const // simple lexicographic
58 {
59 if (mIdent < id.mIdent) return true;
60 if (id.mIdent < mIdent) return false;
61 return mSig < id.mSig;
62 }
63
64 bool operator == (const DbIdentifier &id) const
65 { return mIdent == id.mIdent && mSig == id.mSig; }
66
67 private:
68 DLDbIdentifier mIdent;
69 DbBlob::Signature mSig;
70 };
71
72
73 //
74 // A vestigal system-global database instance
75 // We don't (yet) use it for anything. Perhaps it should carry our ACL...
76 //
77 class KeychainDbGlobal : public PerGlobal {
78 public:
79 KeychainDbGlobal(const DbIdentifier &id);
80 ~KeychainDbGlobal();
81
82 const DbIdentifier &identifier() const { return mIdentifier; }
83
84 private:
85 DbIdentifier mIdentifier; // database external identifier [const]
86 };
87
88
89 //
90 // KeychainDatabase DbCommons
91 //
92 class KeychainDbCommon : public LocalDbCommon,
93 public DatabaseCryptoCore, public MachServer::Timer {
94 public:
95 KeychainDbCommon(Session &ssn, const DbIdentifier &id);
96 ~KeychainDbCommon();
97
98 KeychainDbGlobal &global() const;
99
100 bool unlockDb(DbBlob *blob, void **privateAclBlob = NULL);
101 void lockDb(); // make locked (if currently unlocked)
102 bool isLocked() const { return mIsLocked; } // lock status
103 void setUnlocked();
104 void invalidateBlob() { version++; }
105
106 void activity(); // reset lock timeout
107
108 void makeNewSecrets();
109
110 const DbIdentifier &identifier() const {return mIdentifier; }
111 const DLDbIdentifier &dlDbIdent() const { return identifier(); }
112 const char *dbName() const { return dlDbIdent().dbName(); }
113
114 DbBlob *encode(KeychainDatabase &db);
115
116 void notify(NotificationEvent event);
117
118 void sleepProcessing();
119 void lockProcessing();
120
121 public:
122 // debugging
123 IFDUMP(void dumpNode());
124
125 protected:
126 void action(); // timer queue action to lock keychain
127
128 public:
129 // all following data locked with object lock
130 uint32 sequence; // change sequence number
131 DBParameters mParams; // database parameters (arbitrated copy)
132
133 uint32 version; // version stamp for change tracking
134
135 private:
136 DbIdentifier mIdentifier; // database external identifier [const]
137 // all following data protected by object lock
138 bool mIsLocked; // logically locked
139 bool mValidParams; // mParams has been set
140 };
141
142
143 //
144 // A Database object represents an Apple CSP/DL open database (DL/DB) object.
145 // It maintains its protected semantic state (including keys) and provides controlled
146 // access.
147 //
148 class KeychainDatabase : public LocalDatabase, private virtual SecurityServerAcl {
149 friend class KeychainDbCommon;
150 public:
151 KeychainDatabase(const DLDbIdentifier &id, const DBParameters &params, Process &proc,
152 const AccessCredentials *cred, const AclEntryPrototype *owner);
153 KeychainDatabase(const DLDbIdentifier &id, const DbBlob *blob, Process &proc,
154 const AccessCredentials *cred);
155 // keychain synchronization
156 KeychainDatabase(KeychainDatabase &src, Process &proc, const DbBlob *secretsBlob, const CssmData &agentData);
157 virtual ~KeychainDatabase();
158
159 KeychainDbCommon &common() const;
160 const char *dbName() const;
161 bool transient() const;
162
163 KeychainDbGlobal &global() const { return common().global(); }
164
165 public:
166 static const int maxUnlockTryCount = 3;
167
168 public:
169 const DbIdentifier &identifier() const { return common().identifier(); }
170
171 public:
172 // encoding/decoding databases
173 DbBlob *blob();
174
175 void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
176 void changePassphrase(const AccessCredentials *cred);
177 RefPointer<Key> extractMasterKey(Database &db, const AccessCredentials *cred,
178 const AclEntryPrototype *owner, uint32 usage, uint32 attrs);
179 void commitSecretsForSync(KeychainDatabase &cloneDb);
180
181 // lock/unlock processing
182 void lockDb(); // unconditional lock
183 void unlockDb(); // full-feature unlock
184 void unlockDb(const CssmData &passphrase); // unlock with passphrase
185
186 bool decode(); // unlock given established master key
187 bool decode(const CssmData &passphrase); // set master key from PP, try unlock
188
189 bool validatePassphrase(const CssmData &passphrase) const; // nonthrowing validation
190 bool isLocked() const { return common().isLocked(); } // lock status
191 void notify(NotificationEvent event) { return common().notify(event); }
192 void activity() const { common().activity(); } // reset timeout clock
193
194 // encoding/decoding keys
195 void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
196 KeyBlob *encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl);
197 KeyBlob *recodeKey(KeychainKey &oldKey);
198 bool validBlob() const { return mBlob && version == common().version; }
199
200 // manage database parameters
201 void setParameters(const DBParameters &params);
202 void getParameters(DBParameters &params);
203
204 // where's my (database) ACL?
205 SecurityServerAcl &acl();
206
207 AclKind aclKind() const;
208 Database *relatedDatabase();
209
210 // ACL state management hooks
211 void instantiateAcl();
212 void changedAcl();
213
214 // miscellaneous utilities
215 static void validateBlob(const DbBlob *blob);
216
217 // debugging
218 IFDUMP(void dumpNode());
219
220 protected:
221 RefPointer<Key> makeKey(const CssmKey &newKey, uint32 moreAttributes, const AclEntryPrototype *owner);
222 RefPointer<Key> makeKey(Database &db, const CssmKey &newKey, uint32 moreAttributes, const AclEntryPrototype *owner);
223
224 void makeUnlocked(); // interior version of unlock()
225 void makeUnlocked(const AccessCredentials *cred); // like () with explicit cred
226 void makeUnlocked(const CssmData &passphrase); // interior version of unlock(CssmData)
227
228 void establishOldSecrets(const AccessCredentials *creds);
229 void establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason);
230
231 static CssmClient::Key keyFromCreds(const TypedList &sample, unsigned int requiredLength);
232
233 void encode(); // (re)generate mBlob if needed
234
235 private:
236 // all following data is locked by the common lock
237 bool mValidData; // valid ACL and params (blob decoded)
238
239 uint32 version; // version stamp for blob validity
240 DbBlob *mBlob; // database blob (encoded)
241
242 AccessCredentials *mCred; // local access credentials (always valid)
243
244 RefPointer<KeychainDatabase> mRecodingSource; // keychain synchronization ONLY; should not require accessors
245 };
246
247 #endif //_H_KCDATABASE