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