]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/pcsc++.h
Security-58286.1.32.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / pcsc++.h
1 /*
2 * Copyright (c) 2004,2011-2012,2014 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 // pcsc++ - PCSC client interface layer in C++
27 //
28 // NOTE: TO BE MOVED TO security_utilities LAYER.
29 //
30 #ifndef _H_PCSC_PP
31 #define _H_PCSC_PP
32
33 #include <TargetConditionals.h>
34
35 #if TARGET_OS_OSX
36
37 #include <security_utilities/utilities.h>
38 #include <security_utilities/errors.h>
39 #include <security_utilities/transactions.h>
40 #include <security_utilities/debugging.h>
41 #include <PCSC/winscard.h>
42 #include <vector>
43 #include <string>
44
45 #include <cstdio>
46
47
48 namespace Security {
49 namespace PCSC {
50
51
52 //
53 // PCSC-domain error exceptions
54 //
55 class Error : public CommonError {
56 public:
57 Error(unsigned long err);
58
59 const unsigned long error;
60 OSStatus osStatus() const;
61 int unixError() const;
62 const char *what () const throw ();
63
64 static void check(unsigned long err) { if (err != SCARD_S_SUCCESS) throwMe(err); }
65 static void throwMe(unsigned long err);
66 };
67
68
69 //
70 // A PODWrapper for the PCSC READERSTATE structure
71 //
72 class ReaderState : public PodWrapper<ReaderState, SCARD_READERSTATE> {
73 public:
74 void set(const char *name, unsigned long known = SCARD_STATE_UNAWARE);
75
76 const char *name() const { return szReader; }
77 void name(const char *s) { szReader = s; }
78
79 unsigned long lastKnown() const { return dwCurrentState; }
80 void lastKnown(unsigned long s);
81
82 unsigned long state() const { return dwEventState; }
83 bool state(unsigned long it) const { return state() & it; }
84 bool changed() const { return state(SCARD_STATE_CHANGED); }
85
86 template <class T>
87 T * &userData() { return reinterpret_cast<T * &>(pvUserData); }
88
89 // DataOid access to the ATR data
90 const void *data() const { return rgbAtr; }
91 size_t length() const { return cbAtr; }
92 void setATR(const void *atr, size_t size);
93
94 IFDUMP(void dump());
95 };
96
97
98 //
99 // A Session represents the entire process state for the PCSC protocol
100 //
101 class Session {
102 friend class Card;
103 public:
104 Session();
105 virtual ~Session();
106
107 void open();
108 void close();
109 bool isOpen() const { return mIsOpen; }
110
111 void listReaders(vector<string> &readers, const char *groups = NULL);
112
113 void statusChange(ReaderState *readers, unsigned int nReaders, long timeout = 0);
114 void statusChange(ReaderState &reader, long timeout = 0)
115 { return statusChange(&reader, 1, timeout); }
116 void statusChange(vector<ReaderState> &readers, long timeout = 0)
117 { return statusChange(&readers[0], (unsigned int)readers.size(), timeout); }
118
119
120 private:
121 bool check(long rc);
122
123 private:
124 bool mIsOpen;
125 SCARDCONTEXT mContext;
126 std::vector<char> mReaderBuffer;
127 };
128
129
130 //
131 // A Card represents a PCSC-managed card slot
132 //
133 class Card {
134 public:
135 static const unsigned long defaultProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
136
137 Card();
138 virtual ~Card();
139
140 void connect(Session &session, const char *reader,
141 unsigned long share = SCARD_SHARE_SHARED,
142 unsigned long protocols = defaultProtocols);
143 void reconnect(unsigned long share = SCARD_SHARE_SHARED,
144 unsigned long protocols = defaultProtocols,
145 unsigned long initialization = SCARD_LEAVE_CARD);
146 void disconnect(unsigned long disposition = SCARD_LEAVE_CARD);
147 virtual void didDisconnect();
148 virtual void didEnd();
149
150 void checkReset(unsigned int rv);
151 bool isConnected() const { return mConnectedState == kConnected; }
152 bool isInTransaction() const { return mTransactionNestLevel > 0; }
153
154 void transmit(const unsigned char *pbSendBuffer, size_t cbSendLength,
155 unsigned char *pbRecvBuffer, size_t &pcbRecvLength);
156
157 // primitive transaction interface
158 void begin();
159 void end(unsigned long disposition = SCARD_LEAVE_CARD);
160 void cancel();
161
162 protected:
163 void setIOType(unsigned long activeProtocol);
164
165 IFDUMP(void dump(const char *direction, const unsigned char *buffer, size_t length);)
166
167 private:
168 enum
169 {
170 kInitial,
171 kConnected,
172 kDisconnected
173 } mConnectedState;
174
175 int32_t mHandle;
176 int mTransactionNestLevel;
177 SCARD_IO_REQUEST *mIOType;
178 };
179
180
181 //
182 // A PCSC-layer transaction (exclusive sequence of calls)
183 //
184 class Transaction : public ManagedTransaction<Card> {
185 public:
186 Transaction(Card &card, Outcome outcome = conditional)
187 : ManagedTransaction<Card>(card, outcome), mDisposition(SCARD_LEAVE_CARD) { }
188
189 void disposition(unsigned long disp); // change disposition on successful outcome
190
191 protected:
192 void commitAction();
193
194 private:
195 unsigned long mDisposition; // disposition on success
196 };
197
198
199 } // namespce PCSC
200 } // namespace Security
201
202 #endif //TARGET_OS_OSX
203
204 #endif //_H_PCSC_PP