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_utilities/timeflow.h> 
  52 using MachPlusPlus::MachServer
; 
  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. 
  62 class DbCommon 
: public PerSession 
{ 
  64         DbCommon(Session 
&ssn
); 
  66         Session 
&session() const; 
  68         virtual void sleepProcessing();         // generic action on system sleep 
  69         virtual void lockProcessing();          // generic action on "lock" requests 
  71         virtual bool belongsToSystem() const; // belongs to system (root) security domain 
  73     virtual uint32 
dbVersion() = 0;     // For databases that have a concept of version, return the version 
  76         void notify(NotificationEvent event
, const DLDbIdentifier 
&ident
); 
  81 // A Database object represents an Apple CSP/DL open database (DL/DB) object. 
  82 // It maintains its protected semantic state (including keys) and provides controlled 
  85 class Database 
: public PerProcess
, public AclSource 
{ 
  86     static const NotificationEvent lockedEvent 
= kNotificationEventLocked
; 
  87     static const NotificationEvent unlockedEvent 
= kNotificationEventUnlocked
; 
  88     static const NotificationEvent passphraseChangedEvent 
= kNotificationEventPassphraseChanged
; 
  91         Database(Process 
&proc
); 
  94         Process
& process() const; 
  96         virtual bool transient() const = 0;                     // is transient store (reboot clears) 
 100         // A common class for objects that "belong" to a Database and 
 101         // don't have parents up the global stack. These will die along with 
 102         // the Database when it goes. 
 104         class Subsidiary 
: public PerProcess 
{ 
 106                 Subsidiary(Database 
&db
) { referent(db
); } 
 107                 Database 
&database() const { return referent
<Database
>(); } 
 108                 Process 
&process() const { return database().process(); } 
 112         // Cryptographic service calls. 
 113         // These must be supported by any type of database. 
 115         virtual void releaseKey(Key 
&key
); 
 116     virtual void queryKeySizeInBits(Key 
&key
, CssmKeySize 
&result
) = 0; 
 117     virtual void getOutputSize(const Context 
&context
, Key 
&key
, 
 118                 uint32 inputSize
, bool encrypt
, uint32 
&result
) = 0; 
 120         virtual void generateSignature(const Context 
&context
, Key 
&key
, 
 121                 CSSM_ALGORITHMS signOnlyAlgorithm
, const CssmData 
&data
, CssmData 
&signature
) = 0; 
 122         virtual void verifySignature(const Context 
&context
, Key 
&key
, 
 123                 CSSM_ALGORITHMS verifyOnlyAlgorithm
, const CssmData 
&data
, const CssmData 
&signature
) = 0; 
 124         virtual void generateMac(const Context 
&context
, Key 
&key
, 
 125                 const CssmData 
&data
, CssmData 
&mac
) = 0; 
 126         virtual void verifyMac(const Context 
&context
, Key 
&key
, 
 127                 const CssmData 
&data
, const CssmData 
&mac
) = 0; 
 129         virtual void encrypt(const Context 
&context
, Key 
&key
, const CssmData 
&clear
, CssmData 
&cipher
) = 0; 
 130         virtual void decrypt(const Context 
&context
, Key 
&key
, const CssmData 
&cipher
, CssmData 
&clear
) = 0; 
 132         virtual void generateKey(const Context 
&context
, 
 133                 const AccessCredentials 
*cred
, const AclEntryPrototype 
*owner
, 
 134                 uint32 usage
, uint32 attrs
, RefPointer
<Key
> &newKey
) = 0; 
 135         virtual void generateKey(const Context 
&context
, 
 136                 const AccessCredentials 
*cred
, const AclEntryPrototype 
*owner
, 
 137                 uint32 pubUsage
, uint32 pubAttrs
, uint32 privUsage
, uint32 privAttrs
, 
 138                 RefPointer
<Key
> &publicKey
, RefPointer
<Key
> &privateKey
) = 0; 
 140     virtual void wrapKey(const Context 
&context
, const AccessCredentials 
*cred
, 
 141                 Key 
*wrappingKey
, Key 
&keyToBeWrapped
, 
 142         const CssmData 
&descriptiveData
, CssmKey 
&wrappedKey
) = 0; 
 143         virtual void unwrapKey(const Context 
&context
, 
 144                 const AccessCredentials 
*cred
, const AclEntryPrototype 
*owner
, 
 145                 Key 
*wrappingKey
, Key 
*publicKey
, CSSM_KEYUSE usage
, CSSM_KEYATTR_FLAGS attrs
, 
 146                 const CssmKey wrappedKey
, RefPointer
<Key
> &unwrappedKey
, CssmData 
&descriptiveData
) = 0; 
 147         virtual void deriveKey(const Context 
&context
, Key 
*key
, 
 148                 const AccessCredentials 
*cred
, const AclEntryPrototype 
*owner
, 
 149                 CssmData 
*param
, uint32 usage
, uint32 attrs
, RefPointer
<Key
> &derivedKey
) = 0; 
 151         virtual void authenticate(CSSM_DB_ACCESS_TYPE mode
, const AccessCredentials 
*cred
); 
 153     // returns true if these credentials contain a valid password or master key for this database 
 154     virtual bool checkCredentials(const AccessCredentials 
*cred
); 
 155         virtual SecurityServerAcl 
&acl(); 
 157         virtual bool isLocked(); 
 160         class Search 
: public Subsidiary 
{ 
 162                 Search(Database 
&db
) : Subsidiary(db
) { } 
 165         class Record 
: public Subsidiary 
{ 
 167                 Record(Database 
&db
) : Subsidiary(db
) { } 
 170         virtual void findFirst(const CssmQuery 
&query
, 
 171                 CssmDbRecordAttributeData 
*inAttributes
, mach_msg_type_number_t inAttributesLength
, 
 172                 CssmData 
*data
, RefPointer
<Key
> &key
, RefPointer
<Search
> &search
, 
 173                 RefPointer
<Record
> &record
, 
 174                 CssmDbRecordAttributeData 
* &outAttributes
, mach_msg_type_number_t 
&outAttributesLength
); 
 175         virtual void findNext(Search 
*search
, 
 176                 CssmDbRecordAttributeData 
*inAttributes
, mach_msg_type_number_t inAttributesLength
, 
 177                 CssmData 
*data
, RefPointer
<Key
> &key
, RefPointer
<Record
> &record
, 
 178                 CssmDbRecordAttributeData 
* &outAttributes
, mach_msg_type_number_t 
&outAttributesLength
); 
 179         virtual void findRecordHandle(Record 
*record
, 
 180                 CssmDbRecordAttributeData 
*inAttributes
, mach_msg_type_number_t inAttributesLength
, 
 181                 CssmData 
*data
, RefPointer
<Key
> &key
, 
 182                 CssmDbRecordAttributeData 
* &outAttributes
, mach_msg_type_number_t 
&outAttributesLength
); 
 184         virtual void insertRecord(CSSM_DB_RECORDTYPE recordtype
, 
 185                 const CssmDbRecordAttributeData 
*attributes
, mach_msg_type_number_t inAttributesLength
, 
 186                 const CssmData 
&data
, RecordHandle 
&record
); 
 187         virtual void modifyRecord(CSSM_DB_RECORDTYPE recordtype
, Record 
*record
, 
 188                 const CssmDbRecordAttributeData 
*attributes
, mach_msg_type_number_t inAttributesLength
, 
 189                 const CssmData 
*data
, CSSM_DB_MODIFY_MODE modifyMode
); 
 190         virtual void deleteRecord(Database::Record 
*record
); 
 192         virtual void releaseSearch(Search 
&search
); 
 193         virtual void releaseRecord(Record 
&record
); 
 196         // SecurityServerAcl personality 
 197         AclKind 
aclKind() const; 
 198         Database 
*relatedDatabase(); 
 200         bool belongsToSystem() const { return common().belongsToSystem(); } 
 203         // support ACL remote secret validation (default is no support) 
 204         virtual bool validateSecret(const AclSubject 
*subject
, const AccessCredentials 
*cred
); 
 207         static const int maxUnlockTryCount 
= 3; 
 210         DbCommon
& common() const                        { return parent
<DbCommon
>(); } 
 211         virtual const char *dbName() const = 0; 
 212         virtual void dbName(const char *name
); 
 214     virtual uint32 
dbVersion() { return common().dbVersion(); } 
 216     // Check if this database is in the middle of a recode/migration 
 217     virtual bool isRecoding() { return false; }