2 * Copyright (c) 2000-2008 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // database - abstract database management
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.
35 #include "structure.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>
53 using MachPlusPlus::MachServer
;
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.
63 class DbCommon
: public PerSession
{
65 DbCommon(Session
&ssn
);
67 Session
&session() const;
69 virtual void sleepProcessing(); // generic action on system sleep
70 virtual void lockProcessing(); // generic action on "lock" requests
72 virtual bool belongsToSystem() const; // belongs to system (root) security domain
75 void notify(NotificationEvent event
, const DLDbIdentifier
&ident
);
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
84 class Database
: public PerProcess
, public AclSource
{
85 static const NotificationEvent lockedEvent
= kNotificationEventLocked
;
86 static const NotificationEvent unlockedEvent
= kNotificationEventUnlocked
;
87 static const NotificationEvent passphraseChangedEvent
= kNotificationEventPassphraseChanged
;
90 Database(Process
&proc
);
93 Process
& process() const;
95 virtual bool transient() const = 0; // is transient store (reboot clears)
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.
103 class Subsidiary
: public PerProcess
{
105 Subsidiary(Database
&db
) { referent(db
); }
106 Database
&database() const { return referent
<Database
>(); }
107 Process
&process() const { return database().process(); }
111 // Cryptographic service calls.
112 // These must be supported by any type of database.
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;
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;
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;
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;
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;
150 virtual void authenticate(CSSM_DB_ACCESS_TYPE mode
, const AccessCredentials
*cred
);
151 virtual SecurityServerAcl
&acl();
153 virtual bool isLocked();
156 class Search
: public Subsidiary
{
158 Search(Database
&db
) : Subsidiary(db
) { }
161 class Record
: public Subsidiary
{
163 Record(Database
&db
) : Subsidiary(db
) { }
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
);
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
);
188 virtual void releaseSearch(Search
&search
);
189 virtual void releaseRecord(Record
&record
);
192 // SecurityServerAcl personality
193 AclKind
aclKind() const;
194 Database
*relatedDatabase();
196 bool belongsToSystem() const { return common().belongsToSystem(); }
199 // support ACL remote secret validation (default is no support)
200 virtual bool validateSecret(const AclSubject
*subject
, const AccessCredentials
*cred
);
203 static const int maxUnlockTryCount
= 3;
206 DbCommon
& common() const { return parent
<DbCommon
>(); }
207 virtual const char *dbName() const = 0;
208 virtual void dbName(const char *name
);
213 // This class implements a "system keychain unlock record" store
215 class SystemKeychainKey
{
217 SystemKeychainKey(const char *path
);
218 ~SystemKeychainKey();
220 bool matches(const DbBlob::Signature
&signature
);
221 CssmKey
&key() { return mKey
; }
224 std::string mPath
; // path to file
225 CssmKey mKey
; // proper CssmKey with data in mBlob
227 bool mValid
; // mBlob was validly read from mPath
228 UnlockBlob mBlob
; // contents of mPath as last read
230 Time::Absolute mCachedDate
; // modify date of file when last read
231 Time::Absolute mUpdateThreshold
; // cutoff threshold for checking again
233 static const int checkDelay
= 1; // seconds minimum delay between update checks