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