1/* 2 * Copyright (c) 2000-2007 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> 43#include <security_agent_client/agentclient.h> 44#include <security_utilities/timeflow.h> 45#include <string> 46#include <map> 47 48 49class Key; 50class Connection; 51class Process; 52class Session; 53using MachPlusPlus::MachServer; 54 55 56// 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. 62// 63class DbCommon : public PerSession { 64public: 65 DbCommon(Session &ssn); 66 67 Session &session() const; 68 69 virtual void sleepProcessing(); // generic action on system sleep 70 virtual void lockProcessing(); // generic action on "lock" requests 71 72 virtual bool belongsToSystem() const; // belongs to system (root) security domain 73 74protected: 75 void notify(NotificationEvent event, const DLDbIdentifier &ident); 76}; 77 78 79// 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 82// access. 83// 84class Database : public PerProcess, public AclSource { 85 static const NotificationEvent lockedEvent = kNotificationEventLocked; 86 static const NotificationEvent unlockedEvent = kNotificationEventUnlocked; 87 static const NotificationEvent passphraseChangedEvent = kNotificationEventPassphraseChanged; 88 89protected: 90 Database(Process &proc); 91 92public: 93 Process& process() const; 94 95 virtual bool transient() const = 0; // is transient store (reboot clears) 96 97public: 98 // 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. 102 // 103 class Subsidiary : public PerProcess { 104 public: 105 Subsidiary(Database &db) { referent(db); } 106 Database &database() const { return referent<Database>(); } 107 Process &process() const { return database().process(); } 108 }; 109 110 // 111 // Cryptographic service calls. 112 // These must be supported by any type of database. 113 // 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; 118 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; 127 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; 130 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; 138 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; 149 150 virtual void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred); 151 virtual SecurityServerAcl &acl(); 152 153 virtual bool isLocked(); 154 155public: 156 class Search : public Subsidiary { 157 public: 158 Search(Database &db) : Subsidiary(db) { } 159 }; 160 161 class Record : public Subsidiary { 162 public: 163 Record(Database &db) : Subsidiary(db) { } 164 }; 165 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); 179 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); 187 188 virtual void releaseSearch(Search &search); 189 virtual void releaseRecord(Record &record); 190 191public: 192 // SecurityServerAcl personality 193 AclKind aclKind() const; 194 Database *relatedDatabase(); 195 196 bool belongsToSystem() const { return common().belongsToSystem(); } 197 198public: 199 // support ACL remote secret validation (default is no support) 200 virtual bool validateSecret(const AclSubject *subject, const AccessCredentials *cred); 201 202public: 203 static const int maxUnlockTryCount = 3; 204 205public: 206 DbCommon& common() const { return parent<DbCommon>(); } 207 virtual const char *dbName() const = 0; 208 virtual void dbName(const char *name); 209}; 210 211 212// 213// This class implements a "system keychain unlock record" store 214// 215class SystemKeychainKey { 216public: 217 SystemKeychainKey(const char *path); 218 ~SystemKeychainKey(); 219 220 bool matches(const DbBlob::Signature &signature); 221 CssmKey &key() { return mKey; } 222 223private: 224 std::string mPath; // path to file 225 CssmKey mKey; // proper CssmKey with data in mBlob 226 227 bool mValid; // mBlob was validly read from mPath 228 UnlockBlob mBlob; // contents of mPath as last read 229 230 Time::Absolute mCachedDate; // modify date of file when last read 231 Time::Absolute mUpdateThreshold; // cutoff threshold for checking again 232 233 static const int checkDelay = 1; // seconds minimum delay between update checks 234 235 bool update(); 236}; 237 238#endif //_H_DATABASE 239