1/* 2 * Copyright (c) 2000-2008,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// tokendatabase - software database container implementation. 27// 28// A TokenDatabase represents access to an external (secure) storage container 29// of some kind (usually a smartcard token). 30// 31#ifndef _H_TOKENDATABASE 32#define _H_TOKENDATABASE 33 34#include "database.h" 35#include "tokenacl.h" 36#include "session.h" 37#include "token.h" 38#include <security_utilities/adornments.h> 39 40class TokenDatabase; 41class TokenDbCommon; 42class TokenKey; 43class TokenDaemon; 44 45 46// 47// The global per-system object for a TokenDatabase (the TokenDbGlobal so to 48// speak) is the Token object itself (from token.h). 49// 50 51 52// 53// TokenDatabase DbCommons 54// 55class TokenDbCommon : public DbCommon, public Adornable { 56public: 57 TokenDbCommon(Session &ssn, Token &tk, const char *name); 58 ~TokenDbCommon(); 59 60 Token &token() const; 61 62 uint32 subservice() const { return token().subservice(); } 63 std::string dbName() const; 64 65 Adornable &store(); 66 void resetAcls(); 67 68 void notify(NotificationEvent event); 69 70 void lockProcessing(); 71 72 typedef Token::ResetGeneration ResetGeneration; 73 74private: 75 std::string mDbName; // name given during open 76 bool mHasAclState; // Adornment is carrying active ACL state 77 78 ResetGeneration mResetLevel; // validity tag 79}; 80 81 82// 83// A Database object represents a SC/CSPDL per-process access to a token. 84// 85class TokenDatabase : public Database { 86 friend class TokenDbCommon; 87public: 88 TokenDatabase(uint32 ssid, Process &proc, const char *name, const AccessCredentials *cred); 89 ~TokenDatabase(); 90 91 TokenDbCommon &common() const; 92 Token &token() const { return common().token(); } 93 TokenDaemon &tokend(); 94 uint32 subservice() const { return common().subservice(); } 95 const char *dbName() const; 96 void dbName(const char *name); 97 bool transient() const; 98 99 SecurityServerAcl &acl(); // it's our Token 100 void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls); // post-processing 101 102 bool isLocked(); 103 bool pinState(uint32 pin, int *count = NULL); 104 105 void notify(NotificationEvent event) { return common().notify(event); } 106 107 bool validateSecret(const AclSubject *subject, const AccessCredentials *cred); 108 109 const AccessCredentials *openCreds() const { return mOpenCreds; } 110 111protected: 112 // any Process-referent concept handle we hand out to the client 113 class Handler { 114 public: 115 Handler() : mHandle(0) { } 116 GenericHandle &tokenHandle() { return mHandle; } 117 GenericHandle tokenHandle() const { return mHandle; } 118 119 protected: 120 GenericHandle mHandle; 121 }; 122 123 // CSSM-style search handles (returned by findFirst) 124 struct Search : public Database::Search, public Handler { 125 Search(TokenDatabase &db) : Database::Search(db) { } 126 TokenDatabase &database() const { return referent<TokenDatabase>(); } 127 ~Search(); 128 129 Search *commit() { database().addReference(*this); return this; } 130 }; 131 132 // CSSM-style record handles (returned by findFirst/findNext et al) 133 struct Record : public Database::Record, public Handler, public TokenAcl { 134 Record(TokenDatabase &db) : Database::Record(db) { } 135 TokenDatabase &database() const { return referent<TokenDatabase>(); } 136 ~Record(); 137 138 Record *commit() { database().addReference(*this); return this; } 139 140 void validate(AclAuthorization auth, const AccessCredentials *cred) 141 { TokenAcl::validate(auth, cred, &database()); } 142 143 // TokenAcl personality 144 AclKind aclKind() const; 145 Token &token(); 146 using Handler::tokenHandle; 147 GenericHandle tokenHandle() const; 148 }; 149 150public: 151 // 152 // Cryptographic service calls 153 // 154 void queryKeySizeInBits(Key &key, CssmKeySize &result); 155 void getOutputSize(const Context &context, Key &key, uint32 inputSize, bool encrypt, uint32 &result); 156 157 // service calls 158 void generateSignature(const Context &context, Key &key, CSSM_ALGORITHMS signOnlyAlgorithm, 159 const CssmData &data, CssmData &signature); 160 void verifySignature(const Context &context, Key &key, CSSM_ALGORITHMS verifyOnlyAlgorithm, 161 const CssmData &data, const CssmData &signature); 162 void generateMac(const Context &context, Key &key, 163 const CssmData &data, CssmData &mac); 164 void verifyMac(const Context &context, Key &key, 165 const CssmData &data, const CssmData &mac); 166 167 void encrypt(const Context &context, Key &key, const CssmData &clear, CssmData &cipher); 168 void decrypt(const Context &context, Key &key, const CssmData &cipher, CssmData &clear); 169 170 void generateKey(const Context &context, 171 const AccessCredentials *cred, const AclEntryPrototype *owner, 172 uint32 usage, uint32 attrs, RefPointer<Key> &newKey); 173 void generateKey(const Context &context, 174 const AccessCredentials *cred, const AclEntryPrototype *owner, 175 uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs, 176 RefPointer<Key> &publicKey, RefPointer<Key> &privateKey); 177 void deriveKey(const Context &context, Key *key, 178 const AccessCredentials *cred, const AclEntryPrototype *owner, 179 CssmData *param, uint32 usage, uint32 attrs, RefPointer<Key> &derivedKey); 180 181 void wrapKey(const Context &context, const AccessCredentials *cred, 182 Key *hWrappingKey, Key &keyToBeWrapped, 183 const CssmData &descriptiveData, CssmKey &wrappedKey); 184 void unwrapKey(const Context &context, 185 const AccessCredentials *cred, const AclEntryPrototype *owner, 186 Key *wrappingKey, Key *publicKey, CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, 187 const CssmKey wrappedKey, RefPointer<Key> &unwrappedKey, CssmData &descriptiveData); 188 189public: 190 // 191 // Data-access calls 192 // 193 void findFirst(const CssmQuery &query, 194 CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength, 195 CssmData *data, RefPointer<Key> &key, 196 RefPointer<Database::Search> &search, RefPointer<Database::Record> &record, 197 CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength); 198 void findNext(Database::Search *search, 199 CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength, 200 CssmData *data, RefPointer<Key> &key, RefPointer<Database::Record> &record, 201 CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength); 202 void findRecordHandle(Database::Record *record, 203 CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength, 204 CssmData *data, RefPointer<Key> &key, 205 CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength); 206 void insertRecord(CSSM_DB_RECORDTYPE recordtype, 207 const CssmDbRecordAttributeData *attributes, mach_msg_type_number_t inAttributesLength, 208 const CssmData &data, RefPointer<Database::Record> &record); 209 void modifyRecord(CSSM_DB_RECORDTYPE recordtype, Record *record, 210 const CssmDbRecordAttributeData *attributes, mach_msg_type_number_t inAttributesLength, 211 const CssmData *data, CSSM_DB_MODIFY_MODE modifyMode); 212 void deleteRecord(Database::Record *record); 213 214 // authenticate to database 215 void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred); 216 217private: 218 // internal utilities 219 RefPointer<Key> makeKey(KeyHandle hKey, const CssmKey *key, 220 uint32 moreAttributes, const AclEntryPrototype *owner); 221 222 class InputKey { 223 public: 224 InputKey(Key *key) { setup(key); } 225 InputKey(Key &key) { setup(&key); } 226 ~InputKey(); 227 228 operator KeyHandle () const { return mKeyHandle; } 229 operator const CssmKey * () const { return mKeyPtr; } 230 231 private: 232 KeyHandle mKeyHandle; 233 CssmKey mKey; 234 CssmKey *mKeyPtr; 235 236 void setup(Key *key); 237 }; 238 239private: 240 AccessCredentials *mOpenCreds; // credentials passed during open 241 mutable std::string mDbName; // stored name for method dbName() which need to call c_str on object outside function scope 242}; 243 244 245#endif //_H_TOKENDATABASE 246