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