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