1/*
2 * Copyright (c) 2004 Apple Computer, 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//
27// C++ gate to "Muscle" smartcard interface layer
28//
29// Note: This is written to go together with <pcsc++.h>, rather than stand on
30// its own. It doesn't represent a "all Muscle" view of the card world.
31//
32#ifndef _H_MUSCLE_PP
33#define _H_MUSCLE_PP
34
35#include <security_utilities/refcount.h>
36#include <security_utilities/pcsc++.h>
37#include <PCSC/musclecard.h>
38#include <set>
39
40
41namespace Security {
42namespace Muscle {
43
44
45//
46// Muscle-domain error exceptions
47//
48class Error : public CommonError {
49public:
50	Error(MSC_RV err);
51
52    const MSC_RV error;
53	OSStatus osStatus() const;
54	int unixError() const;
55	const char *what () const throw ();
56
57	static void check(MSC_RV err) { if (err != MSC_SUCCESS) throwMe(err); }
58	static void throwMe(MSC_RV err);
59};
60
61
62//
63// Unified ACLs of the Muscle kind
64//
65class ACL {
66public:
67	typedef MSCUShort16 Value;
68
69	ACL(Value write = MSC_AUT_ALL, Value read = MSC_AUT_ALL, Value erase = MSC_AUT_ALL);
70
71	ACL() { mRead = mWrite = mErase = MSC_AUT_ALL; }
72
73	operator MSCKeyACL () const;
74	operator MSCObjectACL () const;
75
76	Value read() const	{ return mRead; }
77	bool read(Value mask) const { return mRead & mask; }
78	Value &read()		{ return mRead; }
79	Value write() const	{ return mWrite; }
80	bool write(Value mask) const { return mWrite & mask; }
81	Value &write()		{ return mWrite; }
82	Value erase() const { return mErase; }
83	bool erase(Value mask) const { return mErase & mask; }
84	Value &erase()		{ return mErase; }
85	// erase is "use" on keys; they're synonymous
86	Value use() const { return mErase; }
87	bool use(Value mask) const { return mErase & mask; }
88	Value &use()		{ return mErase; }
89
90	string form(char ue) const;
91
92private:
93	MSCUShort16 mRead;
94	MSCUShort16 mWrite;
95	MSCUShort16 mErase;
96};
97
98
99//
100// Muscle item representations (keys and objects unified, the cheap way)
101//
102class CardItem : public RefCount {
103protected:
104	CardItem() { }
105
106public:
107	virtual ~CardItem();
108
109	virtual unsigned size() const = 0;
110	virtual const char *name() const = 0;
111
112	virtual const ACL &acl() const = 0;
113	virtual ACL &acl() = 0;
114
115	virtual void debugDump() = 0;
116
117	bool operator < (const CardItem &other) const { return this < &other; }
118};
119
120class Key : public CardItem, public MSCKeyInfo {
121public:
122	Key(const MSCKeyInfo &info);
123
124	unsigned id() const				{ return this->keyNum; }
125	const char *name() const;
126	unsigned type() const			{ return this->keyType; }
127	unsigned size() const;
128	unsigned mode() const			{ return this->keyPolicy.cipherMode; }
129	unsigned operations() const		{ return this->keyPolicy.cipherDirection; }
130
131	const ACL &acl() const;
132	ACL &acl();
133
134	void debugDump();
135
136private:
137	char mKeyName[8];				// made-up name "Kn"
138};
139
140class Object : public CardItem, public MSCObjectInfo {
141public:
142	Object(const MSCObjectInfo &info) : MSCObjectInfo(info) { }
143
144	const char *name() const;
145	unsigned size() const;
146
147	const ACL &acl() const;
148	ACL &acl();
149
150	void debugDump();
151};
152
153
154//
155// A Muscle connection to a card.
156// This is NOT a PodWrapper (for MSCTokenConnection or anything else).
157//
158class Transaction;
159
160class Connection : public MSCTokenConnection, public MSCStatusInfo {
161public:
162	Connection();
163	~Connection();
164
165	void open(const PCSC::ReaderState &reader, unsigned share = MSC_SHARE_EXCLUSIVE);
166	void close();
167
168	operator bool () const { return mIsOpen; }
169
170	void begin(Transaction *trans = NULL);
171	void end(Transaction *trans = NULL);
172	Transaction *currentTransaction() const;
173
174	typedef set<RefPointer<CardItem> > ItemSet;
175	void getItems(ItemSet &items, bool getKeys = true, bool getOthers = true);
176
177	void updateStatus();
178
179private:
180	bool mIsOpen;
181	Transaction *mCurrentTransaction;
182};
183
184
185class Transaction {
186public:
187	Transaction(Connection &con);
188	~Transaction();
189
190	Connection &connection;
191};
192
193
194}	// namespace Muscle
195}	// namespace Security
196
197
198#endif //_H_MUSCLE_PP
199