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// 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 44namespace Security { 45namespace PCSC { 46 47 48// 49// PCSC-domain error exceptions 50// 51class Error : public CommonError { 52public: 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// 68class ReaderState : public PodWrapper<ReaderState, SCARD_READERSTATE> { 69public: 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// 97class Session { 98 friend class Card; 99public: 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 116private: 117 bool check(long rc); 118 119private: 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// 129class Card { 130public: 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 158protected: 159 void setIOType(unsigned long activeProtocol); 160 161 IFDUMP(void dump(const char *direction, const unsigned char *buffer, size_t length);) 162 163private: 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// 180class Transaction : public ManagedTransaction<Card> { 181public: 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 187protected: 188 void commitAction(); 189 190private: 191 unsigned long mDisposition; // disposition on success 192}; 193 194 195} // namespce PCSC 196} // namespace Security 197 198 199#endif //_H_PCSC_PP 200