././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/0000755000175000017500000000000000000000000013457 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/ACKS0000644000175000017500000000062100000000000014122 0ustar00rousseaurousseauAcknowledgements ---------------- This list is sorted in alphabetical order, and is probably incomplete. I'd like to thank everybody who contributed in any way, with code, bug reports, and comments. -jda Jarle Bauck Hamar Antonio Aranda Frank Aune Michel Beziat Mattias Brändström Luc Duche Nodir Gulyamov Yong David Huang Adam Laurie Henryk Plotz Michael Roehner Ludovic Rousseau David Wagner ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/ChangeLog0000644000175000017500000002472700000000000015245 0ustar00rousseaurousseau2.0.2 (September 2021) ====================== * Fix an issue in ReaderMonitor() that failed to enumerate readers on macOS * getReaderNames(): handle SCARD_E_SERVICE_STOPPED on Windows generated on last reader removal * Restrict MAX_BUFFER_SIZE_EXTENDED to 65535 and fix an issue on Lenovo laptops with NXP NFC readers * SmartcardException: display a positive PCSC error code 2.0.1 (June 2021) ================= * Add .reconnect() method to high-level API * Handle removal of the last reader on Windows * Fix support of macOS Big Sur * Use Python3 by default * Handle bogus ACS ACR122U PICC reader 2.0.0 (September 2020) ====================== * SCardStatus(): Fix a crash in case of PC/SC error * toASCIIString(): replace non-ASCII char by '.' * remove i386 (32-bits) support on macOS 1.9.9 (August 2019) =================== * Makefile: use twine to upload to pypi.python.org * test: fix Exception test on 32-bits CPU * test: correctly handle macOS versions older than 10.10 1.9.8 (March 2019) ================== * SmartcardException: store the PC/SC return code in hresult * CardMonitoring: stop the looping only if PCSC exited * setup: support build on OpenBSD, and other BSD * Fix Windows 10 SCARD_E_SERVICE_STOPPED from SCardListReaders() * Minor documentation improvements 1.9.7 (June 2018) ================= * Modify CardMonitoring's deleteObserver method to cleanly remove threads * Python 3: fix smartcard/Synchronization.py * Python 3: Fix SCardGetErrorMessage() on Windows * PCSCPart10: add parseFeatureRequest(), parseTlvProperties() * Fix PEP8 warnings * Minor documentation improvements 1.9.6 (August 2017) =================== * include test/__init__.py in the archive tarball. "make test" now works. That fixes build using Python 3.6 1.9.5 (Feb 2017) ================ * SCardGetStatusChange(): fix a memory leak with Python 3 * SCardTransmit(): use SCARD_PCI_RAW for undefined protocol * Improve epydoc documentation 1.9.4 (May 2016) ================ * Fix installation using pip and easy_install * Avoid El Capitan SCardGetAttrib bug * CardConnection: Add context management * PCSCCardConnection: raise NoCardException if SCARD_E_NO_SMARTCARD * Stop CardMonitor monitor thread after traceback print. * minor improvements 1.9.3 (March 2016) ================== * Fix SCardControl() on Windows 7 * Fix installation using pip and easy_install 1.9.2 (February 2016) ===================== * Fix toBytes regression * Fix installation using pip * improve pydoc documentation * user-guide.rst: use real sample codes * minor improvements 1.9.1 (September 2015) ====================== * Create a new version so that the upload to Pypi does _not_ contain the swig generated files. 1.9.0 (August 2015) =================== * add Python3 support (Python2 is still supported) * fix a lot of pylint warnings * smartcard/test/* replace deprecated assert calls * add tox support and coverage reports, run test suite on Travis * add Travis CI support to automatically build on Unix * add AppVeyor support to automatically build on Windows * minor bugs fixed * Big thank you to Alex Willmer for his work on pyscard 1.7.0 (June 2015) =========== * PCSCCardConnection: Fix a problem with mode=SCARD_SHARE_DIRECT * add support of cygwin as a build platform * Fix a problem with Windows Remote Desktop * Switch from distutils to setuptools * dropped support for Python 2.5 and earlier (Alex Willmer) * dropped support for OS X 10.5 (Leopard) and earlier (Alex Willmer) * minor bugs fixed 1.6.16 (December 2014) =================== * added support for windows 64bit amd64 (Jean-Daniel Aussel) * support python "new" classes (derive classes from object) (Ludovic Rousseau from chrysn feature request ID 3110077) * fixed Reader.__eq__() (Ludovic Rousseau from Bernard Paulus bug ID 3418113) * fixed extended APDU transmit buffer too short by 2 (Jean-Daniel Aussel from bugs ID 2914636 and 3106761) * make Card and Reader objects hashable (Jean-Daniel Aussel from Hans-Peter Jansen feature request and patch) * convert the user guide to python-Sphinx 1.6.12 (August 2010) =================== * comply with PEP 8 (Ludovic Rousseau) * comply with PEP 352 (Jean-Daniel Aussel) * support of pcsclite 1.6 and deprecated LPSCARD_READERSTATE_A (Ludovic Rousseau) * support of py2exe scripts for wxWindows examples (Jean-Daniel Aussel) * partial support of remote pcsc readers with pyro (Jean-Daniel Aussel) 1.6.10 (May 2010) =================== * connect() has a new disposition parameter that is passed to SCardDisconnect (Ludovic Rousseau) * fixed winscard_init() bad initialization causing problems in multithreaded environment (Ludovic Rousseau) * Use MAX_BUFFER_SIZE_EXTENDED (64k) instead of 1024 for SCardControl and SCardTransmit (Ludovic Rousseau, reported by Lukasz Drygiel) * call winscard_init() to load the library only in the %init section instead of in each wrapped function (Ludovic Rousseau) * for Snow Leopard, do not pass -framework PCSC to the compiler (Martin Paljak) * reformatting to meet pep8 (Style Guide for Python Code) guidelines (Ludovic Rousseau) * rename FEATURE_MCT_READERDIRECT in FEATURE_MCT_READER_DIRECT to be conform with PCSC v2 part 10 ch. 2.3 (Ludovic Rousseau) * added missing CARD_E_NO_READERS_AVAILABLE (Kjell Tore Fossbakk) * added support of x86_64 on Mac OS X Snow Leopard (Jakob Schlyter) * ATR can be passed in input in the reader state list (Benoit Allard) * clear state changed bit in waitforcard/waitforcardevent upon time-out or reader removal (Jean-Daniel Aussel) * removed clearing of states and ATR content upon SCardGetStatusChange() error (Benoit Allard); handling is now moved up in python framework (Jean-Daniel Aussel) 1.6.8 (July 2009) ================= * fixed SCARD_ERROR types to match correct types on linux and Mac OS X (Ludovic Rousseau) * store g_rgSCard* references as void* (Ludovic Rousseau) * modified Mac OS X build to locate PCSC headers using -framework option (Ludovic Rousseau) * added contrib root directory and parseATR as first contribution (Ludovic Rousseau) * updated a few samples to support SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 instead of just SCARD_PROTOCOL_T0 (Ludovic Rousseau) * added SCARD_E_NO_READERS_AVAILABLE definition (Ludovic Rousseau) * added simpleAPDU.py, a simple script to send a couple of APDUs (Ludovic Rousseau) * added support for Snow Leopard 10.6 (Ludovic Rousseau) * redefined error codes to be non-Windows or -linux specifics (Ludovic Rousseau) * added definitions of SCARD_ATTR_xxx values for Mac OS X (Jean-Daniel Aussel) * delay SCardEstablishContext call until needed instead of login, to allow use of utility classes such as toHexString, even when the PCSC resource manager or pcscd daemon is not started (Ludovic Rousseau) * added javascript code for Piwik web analytics to documentation pages (Jean-Daniel Aussel) * update sourceforge logo pages to latest sourceforge standard (Jean-Daniel Aussel) * fixed ATR parsing logics (Ludovic Rousseau) * added control() method to CardConnection() (Ludovic Rousseau) * added mode argument to connect() method of CardConnection (Ludovic Rousseau) * added PCSC v2 feature management (Ludovic Rousseau) 1.6.7 ===== * better thread support and clean-up in ReaderMonitoringThread (Frank Aune) * fixed issue on Mac OS X Leopard with dlsym loading of bad SCardControl function (Mattias Brändström) * supported build of documentation files on linux and removed unresolved doc links (Ludovic Rousseau) 1.6.6 ===== * added support for Mac OS X Leopard 1.6.5 ===== * added sample_MonitorCardsAndTransmit.py sample to illustrate how to transmit apdu to a card notified by the card monitor * added support for SCardControl (Ludovic Rousseau) * added support for Max OS X Tiger (Ludovic Rousseau/Jean-Daniel Aussel) (Leopard not supported) * added debian package directory (Ludovice Rousseau) * support for python 2.3, 2.4 and 2.5 distutils * automated insertion of sourceforge logo in html pages generated by epydoc * fixed documentation generation to include examples 1.6.4 ===== * handled several issues reported by Michael Roehner concerning waitforcard() not detecting card in reader/card USB stick; changed the waitforcard() and waitforcardevent() to poll every 100ms for new readers and cards in these readers * following issue reported by Jarle Bauck Hamar, added samples on how to perform exclusive card connection or protect transmit() from being interupted by another thread or process * fixed ATR parsing error for optional interface bytes reported by Jarle Bauck Hamar 1.6.3 ===== * better handling of protocol selection with associated test cases and added getATR_T1 example (issue reported by Adam Laurie for T=1 cards, and request from Yong David Huang for Omnikey CM5321 RFID that failed with T0|T1 mask). * added handling of linux 64-bit platform and graceful exit for unsupported platform, thanks to Henryk Plötz * added support for float value timeout in CardRequest, thanks to Henryk Plötz; updated test cases and a couple of samples with float timeouts. 1.6.2 ===== * started support for Mac OS X Darwin; not yet operational * fixed issue with "'NoneType' object is not callable" exception on some clean-up routines executed from __del__ methods (CardMonitoring, ReaderMonitoring, CardConnection) * added default protocol, protocol argument to CardConnection.connect(), and get/setProtocol methods to CardConnection, PCSCCardConnection and CardConnectionDecorator 1.6.1 ===== * maintenance release: - define LPCTSTR and LPTSTR for recent releases of pcsc-lite - print formatting of userdata in SCardHelper_PrintReaderStateList - updated home page and download links to point to sourceforge.net 1.6.0 ===== * released open-source with LGPL license ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762728.0 pyscard-2.0.2/LICENSE0000644000175000017500000006037300000000000014475 0ustar00rousseaurousseau GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/MANIFEST.in0000644000175000017500000000170400000000000015217 0ustar00rousseaurousseauinclude ACKS include ChangeLog include LICENSE include MANIFEST.in include Makefile include README include README.md include TODO include smartcard/scard/PcscDefs.i include smartcard/scard/PcscTypemaps.i include smartcard/scard/gemalto.ver include smartcard/scard/helpers.c include smartcard/scard/helpers.h include smartcard/scard/memlog.h include smartcard/scard/pcsctypes.h include smartcard/scard/pyscard-reader.h include smartcard/scard/scard.def include smartcard/scard/scard.i include smartcard/scard/scard.rc include smartcard/scard/winscarddll.c include smartcard/scard/winscarddll.h include smartcard/test/configcheck.py recursive-include smartcard/Examples *.py *.ico recursive-include smartcard/doc *.html *.jpg *.css *.js *.png *.txt recursive-include smartcard/test/framework *.txt *.py recursive-include smartcard/test/frameworkpcsc *.txt *.py recursive-include smartcard/test/scard *.txt *.py recursive-include smartcard/wx *.ico include test/*.py ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1618255307.0 pyscard-2.0.2/Makefile0000644000175000017500000000071400000000000015121 0ustar00rousseaurousseauPYTHON ?= python3 build: $(PYTHON) setup.py build clean: $(PYTHON) setup.py clean rm -rf build pypi: clean # files generated by swig rm -f smartcard/scard/scard.py rm -f smartcard/scard/scard_wrap.c # files generated by sphinx rm -rf smartcard/doc/_build rm -rf dist $(PYTHON) setup.py sdist python3 -m twine upload dist/* test: build $(PYTHON) setup.py test ChangeLog.git: git log --stat --decorate=short > $@ .PHONY: clean build pypi test ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/PKG-INFO0000644000175000017500000000230100000000000014550 0ustar00rousseaurousseauMetadata-Version: 2.1 Name: pyscard Version: 2.0.2 Summary: Smartcard module for Python. Home-page: https://github.com/LudovicRousseau/pyscard Author: Ludovic Rousseau Author-email: ludovic.rousseau@free.fr License: UNKNOWN Download-URL: http://sourceforge.net/projects/pyscard/files/pyscard/pyscard%202.0.2/pyscard-2.0.2.tar.gz/download Description: Smartcard package for Python Platform: linux Platform: win32 Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+) Classifier: Intended Audience :: Developers Classifier: Operating System :: Unix Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: MacOS :: MacOS X Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Security Provides-Extra: Gui Provides-Extra: Pyro ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398267.0 pyscard-2.0.2/README.md0000644000175000017500000000223300000000000014736 0ustar00rousseaurousseaupyscard: smartcard library for python ===================================== [pyscard](https://pyscard.sourceforge.io/) - python smart card library - is a python module adding smart cards support to [python](https://www.python.org/). ![alt text](https://pyscard.sourceforge.io/_images/pyscard.jpg "pyscard architecture") Documentation ------------- https://pyscard.sourceforge.io/user-guide.html#pyscard-user-guide Samples ------- High level API samples: See https://pyscard.sourceforge.io/pyscard-framework.html#framework-samples Low level API samples: See https://pyscard.sourceforge.io/pyscard-wrapper.html#wrapper-samples Continuous Integration status ----------------------------- Travis CI: [![Build Status](https://travis-ci.com/LudovicRousseau/pyscard.svg?branch=master)](https://travis-ci.com/LudovicRousseau/pyscard) AppVeyor: [![Build status](https://ci.appveyor.com/api/projects/status/c97dsaodpcwkm0ra?svg=true)](https://ci.appveyor.com/project/LudovicRousseau/pyscard) Coveralls: [![Coverage Status](https://coveralls.io/repos/LudovicRousseau/pyscard/badge.svg?branch=master&service=github)](https://coveralls.io/github/LudovicRousseau/pyscard?branch=master) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762663.0 pyscard-2.0.2/TODO0000644000175000017500000000063700000000000014155 0ustar00rousseaurousseau- complete support of remote readers with Pyro and add in documentation - document construction of standalone windows application using py2exe - documentation and implementation of card services - documentation of CardConnectionDecorator; add a meaningful example (OP secure channel?) - documentation of wxPython classes; fix wxPython code on Mac OS X - more error checking chains - more unit tests May 2010 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1190004 pyscard-2.0.2/pyscard.egg-info/0000755000175000017500000000000000000000000016616 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343237.0 pyscard-2.0.2/pyscard.egg-info/PKG-INFO0000644000175000017500000000230100000000000017707 0ustar00rousseaurousseauMetadata-Version: 2.1 Name: pyscard Version: 2.0.2 Summary: Smartcard module for Python. Home-page: https://github.com/LudovicRousseau/pyscard Author: Ludovic Rousseau Author-email: ludovic.rousseau@free.fr License: UNKNOWN Download-URL: http://sourceforge.net/projects/pyscard/files/pyscard/pyscard%202.0.2/pyscard-2.0.2.tar.gz/download Description: Smartcard package for Python Platform: linux Platform: win32 Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+) Classifier: Intended Audience :: Developers Classifier: Operating System :: Unix Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: MacOS :: MacOS X Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Security Provides-Extra: Gui Provides-Extra: Pyro ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343237.0 pyscard-2.0.2/pyscard.egg-info/SOURCES.txt0000644000175000017500000001445100000000000020507 0ustar00rousseaurousseauACKS ChangeLog LICENSE MANIFEST.in Makefile README.md TODO setup.py ./smartcard/ATR.py ./smartcard/AbstractCardRequest.py ./smartcard/Card.py ./smartcard/CardConnection.py ./smartcard/CardConnectionDecorator.py ./smartcard/CardConnectionEvent.py ./smartcard/CardConnectionObserver.py ./smartcard/CardMonitoring.py ./smartcard/CardNames.py ./smartcard/CardRequest.py ./smartcard/CardService.py ./smartcard/CardType.py ./smartcard/ClassLoader.py ./smartcard/Exceptions.py ./smartcard/ExclusiveConnectCardConnection.py ./smartcard/ExclusiveTransmitCardConnection.py ./smartcard/Observer.py ./smartcard/PassThruCardService.py ./smartcard/ReaderMonitoring.py ./smartcard/Session.py ./smartcard/Synchronization.py ./smartcard/System.py ./smartcard/__init__.py ./smartcard/guid.py ./smartcard/ulist.py ./smartcard/pcsc/PCSCCardConnection.py ./smartcard/pcsc/PCSCCardRequest.py ./smartcard/pcsc/PCSCContext.py ./smartcard/pcsc/PCSCExceptions.py ./smartcard/pcsc/PCSCPart10.py ./smartcard/pcsc/PCSCReader.py ./smartcard/pcsc/PCSCReaderGroups.py ./smartcard/pcsc/__init__.py ./smartcard/pyro/PyroReader.py ./smartcard/pyro/__init__.py ./smartcard/reader/Reader.py ./smartcard/reader/ReaderFactory.py ./smartcard/reader/ReaderGroups.py ./smartcard/reader/__init__.py ./smartcard/scard/__init__.py ./smartcard/sw/ErrorChecker.py ./smartcard/sw/ErrorCheckingChain.py ./smartcard/sw/ISO7816_4ErrorChecker.py ./smartcard/sw/ISO7816_4_SW1ErrorChecker.py ./smartcard/sw/ISO7816_8ErrorChecker.py ./smartcard/sw/ISO7816_9ErrorChecker.py ./smartcard/sw/SWExceptions.py ./smartcard/sw/__init__.py ./smartcard/sw/op21_ErrorChecker.py ./smartcard/util/__init__.py ./smartcard/wx/APDUHexValidator.py ./smartcard/wx/APDUTracerPanel.py ./smartcard/wx/CardAndReaderTreePanel.py ./smartcard/wx/ReaderToolbar.py ./smartcard/wx/SimpleSCardApp.py ./smartcard/wx/SimpleSCardAppEventObserver.py ./smartcard/wx/SimpleSCardAppFrame.py ./smartcard/wx/__init__.py ./smartcard/wx/resources/reader.ico ./smartcard/wx/resources/smartcard.ico pyscard.egg-info/PKG-INFO pyscard.egg-info/SOURCES.txt pyscard.egg-info/dependency_links.txt pyscard.egg-info/pbr.json pyscard.egg-info/requires.txt pyscard.egg-info/top_level.txt smartcard/Examples/framework/sample_ATR.py smartcard/Examples/framework/sample_CardConnectionDecorator.py smartcard/Examples/framework/sample_ConsoleConnectionTracer.py smartcard/Examples/framework/sample_CustomCardType.py smartcard/Examples/framework/sample_CustomErrorChecker.py smartcard/Examples/framework/sample_ErrorChecking.py smartcard/Examples/framework/sample_ExclusiveCardConnection.py smartcard/Examples/framework/sample_MonitorCards.py smartcard/Examples/framework/sample_MonitorCardsAndTransmit.py smartcard/Examples/framework/sample_MonitorReaders.py smartcard/Examples/framework/sample_TransmitCardObserver.py smartcard/Examples/framework/sample_apduTracerInterpreter.py smartcard/Examples/framework/sample_toHexString.py smartcard/Examples/scard-api/sample_control.py smartcard/Examples/scard-api/sample_getATR.py smartcard/Examples/scard-api/sample_getAttrib.py smartcard/Examples/scard-api/sample_getStatusChange.py smartcard/Examples/scard-api/sample_listCards.py smartcard/Examples/scard-api/sample_listInterfaces.py smartcard/Examples/scard-api/sample_locateCards.py smartcard/Examples/scard-api/sample_pinpad.py smartcard/Examples/scard-api/sample_readerGroups.py smartcard/Examples/scard-api/sample_readers.py smartcard/Examples/scard-api/sample_selectDFTelecom.py smartcard/Examples/scard-api/sample_transaction.py smartcard/Examples/simple/getATR.py smartcard/Examples/simple/getATR_context.py smartcard/Examples/simple/selectDF_TELECOM.py smartcard/Examples/simple/simpleAPDU.py smartcard/Examples/wx/apdumanager/SampleAPDUManagerPanel.py smartcard/Examples/wx/apdumanager/apdumanager.py smartcard/Examples/wx/apdumanager/setup.py smartcard/Examples/wx/apdumanager/images/mysmartcard.ico smartcard/Examples/wx/cardmonitor/cardmonitor.py smartcard/Examples/wx/cardmonitor/setup.py smartcard/Examples/wx/cardmonitor/images/mysmartcard.ico smartcard/Examples/wx/pcscdiag/pcscdiag.py smartcard/Examples/wx/readerviewer/readerviewer.py smartcard/Examples/wx/readerviewer/setup.py smartcard/Examples/wx/readerviewer/images/readerviewer.ico smartcard/doc/images/pyscard.jpg smartcard/doc/images/sflogo.php.png smartcard/scard/PcscDefs.i smartcard/scard/PcscTypemaps.i smartcard/scard/gemalto.ver smartcard/scard/helpers.c smartcard/scard/helpers.h smartcard/scard/memlog.h smartcard/scard/pcsctypes.h smartcard/scard/pyscard-reader.h smartcard/scard/scard.def smartcard/scard/scard.i smartcard/scard/scard.rc smartcard/scard/winscarddll.c smartcard/scard/winscarddll.h smartcard/test/configcheck.py smartcard/test/framework/local_config.py smartcard/test/framework/readme.txt smartcard/test/framework/testcase_ATR.py smartcard/test/framework/testcase_CAtr.py smartcard/test/framework/testcase_Card.py smartcard/test/framework/testcase_CardConnection.py smartcard/test/framework/testcase_CardMonitor.py smartcard/test/framework/testcase_CardRequest.py smartcard/test/framework/testcase_CardService.py smartcard/test/framework/testcase_CardType.py smartcard/test/framework/testcase_ErrorChecking.py smartcard/test/framework/testcase_ExclusiveCardConnection.py smartcard/test/framework/testcase_readergroups.py smartcard/test/framework/testcase_readermonitor.py smartcard/test/framework/testcase_readermonitorstress.py smartcard/test/framework/testcase_readers.py smartcard/test/framework/testcase_ulist.py smartcard/test/framework/testcase_utils.py smartcard/test/framework/testsuite_framework.py smartcard/test/frameworkpcsc/local_config.py smartcard/test/frameworkpcsc/readme.txt smartcard/test/frameworkpcsc/testcase_pcscreadergroups.py smartcard/test/frameworkpcsc/testsuite_frameworkpcsc.py smartcard/test/scard/local_config.py smartcard/test/scard/readme.txt smartcard/test/scard/testcase_getatr.py smartcard/test/scard/testcase_getattrib.py smartcard/test/scard/testcase_geterrormessage.py smartcard/test/scard/testcase_listcards.py smartcard/test/scard/testcase_locatecards.py smartcard/test/scard/testcase_readergroups.py smartcard/test/scard/testcase_returncodes.py smartcard/test/scard/testcase_transaction.py smartcard/test/scard/testsuite_scard.py smartcard/wx/resources/reader.ico smartcard/wx/resources/smartcard.ico test/__init__.py test/test_ATR.py test/test_Exceptions.py test/test_SCardGetErrorMessage.py test/test_util.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343237.0 pyscard-2.0.2/pyscard.egg-info/dependency_links.txt0000644000175000017500000000000100000000000022664 0ustar00rousseaurousseau ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762667.0 pyscard-2.0.2/pyscard.egg-info/pbr.json0000644000175000017500000000005700000000000020276 0ustar00rousseaurousseau{"is_release": false, "git_version": "7065afc"}././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343237.0 pyscard-2.0.2/pyscard.egg-info/requires.txt0000644000175000017500000000003500000000000021214 0ustar00rousseaurousseau [Gui] wxPython [Pyro] Pyro ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343237.0 pyscard-2.0.2/pyscard.egg-info/top_level.txt0000644000175000017500000000001200000000000021341 0ustar00rousseaurousseausmartcard ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/setup.cfg0000644000175000017500000000004600000000000015300 0ustar00rousseaurousseau[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/setup.py0000755000175000017500000001342700000000000015203 0ustar00rousseaurousseau#! /usr/bin/env python3 """Setup file for distutils __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2007-2018 Ludovic Rousseau ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from distutils.util import get_platform import sys from setuptools import setup, Extension from setuptools.command.build_py import build_py if sys.version_info[0:2] < (2, 6): raise RuntimeError("pyscard requires Python 2.6+ to build.") platform_include_dirs = [] platform_sources = [] platform_libraries = [] platform_extra_compile_args = [] # ['-ggdb', '-O0'] platform_extra_link_args = [] # ['-ggdb'] if get_platform() in ('win32', 'win-amd64'): platform__cc_defines = [('WIN32', '100')] platform_swig_opts = ['-DWIN32'] platform_sources = ['smartcard/scard/scard.rc'] platform_libraries = ['winscard'] elif 'cygwin-' in get_platform(): platform__cc_defines = [('WIN32', '100')] platform_swig_opts = ['-DWIN32'] platform_libraries = ['winscard'] elif 'macosx-' in get_platform(): if 'macosx-10.6' in get_platform(): macosx_define = '__LEOPARD__' # Snow Leopard, Python 2.6 else: macosx_define = '__LION__' # Lion (and above), Python 2.7 platform__cc_defines = [('PCSCLITE', '1'), ('__APPLE__', '1'), (macosx_define, '1')] platform_swig_opts = ['-DPCSCLITE', '-D__APPLE__', '-D' + macosx_define] # Other (GNU/Linux, etc.) # else: platform__cc_defines = [('PCSCLITE', '1')] platform_swig_opts = ['-DPCSCLITE'] platform_include_dirs = ['/usr/include/PCSC', '/usr/local/include/PCSC'] VERSION_INFO = (2, 0, 2, 0) VERSION_STR = '%i.%i.%i' % VERSION_INFO[:3] VERSION_ALT = '%i,%01i,%01i,%04i' % VERSION_INFO class BuildPyBuildExtFirst(build_py): """Workaround substitude `build_py` command for SWIG""" def run(self): # Run build_ext first so that SWIG generated files are included self.run_command('build_ext') return build_py.run(self) kw = {'name': "pyscard", 'version': VERSION_STR, 'description': "Smartcard module for Python.", 'author': "Ludovic Rousseau", 'author_email': "ludovic.rousseau@free.fr", 'url': "https://github.com/LudovicRousseau/pyscard", 'long_description': 'Smartcard package for Python', 'platforms': ['linux', 'win32'], 'packages': ["smartcard", "smartcard.pcsc", "smartcard.pyro", "smartcard.reader", "smartcard.scard", "smartcard.sw", "smartcard.util", "smartcard.wx", ], 'package_dir': {"": "."}, 'package_data': { "smartcard.wx": ["resources/*.ico"], }, 'cmdclass': {'build_py': BuildPyBuildExtFirst}, # the _scard.pyd extension to build 'ext_modules': [Extension("smartcard.scard._scard", define_macros=[ ('VER_PRODUCTVERSION', VERSION_ALT), ('VER_PRODUCTVERSION_STR', VERSION_STR)] \ + platform__cc_defines, include_dirs=['smartcard/scard/'] \ + platform_include_dirs, sources=["smartcard/scard/helpers.c", "smartcard/scard/winscarddll.c", "smartcard/scard/scard.i"] \ + platform_sources, libraries=platform_libraries, extra_compile_args=platform_extra_compile_args, extra_link_args=platform_extra_link_args, swig_opts=['-outdir', 'smartcard/scard'] \ + platform_swig_opts)], 'extras_require': { 'Gui': ['wxPython'], 'Pyro': ['Pyro'], }, 'test_suite': 'test', 'classifiers': [ 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: GNU Lesser General Public License v2 ' 'or later (LGPLv2+)', 'Intended Audience :: Developers', 'Operating System :: Unix', 'Operating System :: Microsoft :: Windows', 'Operating System :: MacOS :: MacOS X', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Topic :: Security', ] } # FIXME Sourceforge downloads are unauthenticated, migrate to PyPI kw['download_url'] = ('http://sourceforge.net/projects/%(name)s/files' '/%(name)s/%(name)s%%20%(version)s' '/%(name)s-%(version)s.tar.gz/download' % kw) setup(**kw) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1109965 pyscard-2.0.2/smartcard/0000755000175000017500000000000000000000000015437 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399350.0 pyscard-2.0.2/smartcard/ATR.py0000644000175000017500000002424500000000000016446 0ustar00rousseaurousseau"""ATR class managing some of the Answer To Reset content. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.Exceptions import SmartcardException from smartcard.util import toHexString class ATR(object): """ATR class.""" clockrateconversion = [372, 372, 558, 744, 1116, 1488, 1860, 'RFU', 'RFU', 512, 768, 1024, 1536, 2048, 'RFU', 'RFU', 'RFU'] bitratefactor = ['RFU', 1, 2, 4, 8, 16, 32, 'RFU', 12, 20, 'RFU', 'RFU', 'RFU', 'RFU', 'RFU', 'RFU'] currenttable = [25, 50, 100, 'RFU'] def __init__(self, bytes): """Construct a new atr from bytes.""" self.bytes = bytes self.__initInstance__() def __checksyncbyte__(self): """Check validity of TS.""" if not 0x3b == self.bytes[0] and not 0x03f == self.bytes[0]: raise SmartcardException("invalid TS 0x%-0.2x" % self.bytes[0]) def __initInstance__(self): """ Parse ATR and initialize members: - TS: initial character - T0: format character - TA[n], TB[n], TC[n], TD[n], for n=0,1,...: protocol parameters @note: protocol parameters indices start at 0, e.g. TA[0], TA[1] correspond to the ISO standard TA1, TA2 parameters - historicalBytes: the ATR T1, T2, ..., TK historical bytes - TCK: checksum byte (only for protocols different from T=0) - FI: clock rate conversion factor - DI: voltage adjustment factor - PI1: programming voltage factor - II: maximum programming current factor - N: extra guard time """ self.__checksyncbyte__() # initial character self.TS = self.bytes[0] # format character self.T0 = self.bytes[1] # count of historical bytes self.K = self.T0 & 0x0f # initialize optional characters lists self.TA = [] self.TB = [] self.TC = [] self.TD = [] self.Y = [] self.hasTA = [] self.hasTB = [] self.hasTC = [] self.hasTD = [] TD = self.T0 hasTD = 1 n = 0 offset = 1 self.interfaceBytesCount = 0 while hasTD: self.Y += [TD >> 4 & 0x0f] self.hasTD += [(self.Y[n] & 0x08) != 0] self.hasTC += [(self.Y[n] & 0x04) != 0] self.hasTB += [(self.Y[n] & 0x02) != 0] self.hasTA += [(self.Y[n] & 0x01) != 0] self.TA += [None] self.TB += [None] self.TC += [None] self.TD += [None] if self.hasTA[n]: self.TA[n] = self.bytes[offset + self.hasTA[n]] if self.hasTB[n]: self.TB[n] = self.bytes[offset + self.hasTA[n] + self.hasTB[n]] if self.hasTC[n]: self.TC[n] = self.bytes[offset + self.hasTA[n] + self.hasTB[n] + self.hasTC[n]] if self.hasTD[n]: self.TD[n] = self.bytes[offset + self.hasTA[n] + self.hasTB[n] + self.hasTC[n] + self.hasTD[n]] self.interfaceBytesCount += self.hasTA[n] +\ self.hasTB[n] +\ self.hasTC[n] +\ self.hasTD[n] TD = self.TD[n] hasTD = self.hasTD[n] offset = offset + self.hasTA[n] + self.hasTB[n] +\ self.hasTC[n] + self.hasTD[n] n = n + 1 # historical bytes self.historicalBytes = self.bytes[offset + 1:offset + 1 + self.K] # checksum self.hasChecksum = (len(self.bytes) == offset + 1 + self.K + 1) if self.hasChecksum: self.TCK = self.bytes[-1] checksum = 0 for b in self.bytes[1:]: checksum = checksum ^ b self.checksumOK = (checksum == 0) else: self.TCK = None # clock-rate conversion factor if self.hasTA[0]: self.FI = self.TA[0] >> 4 & 0x0f else: self.FI = None # bit-rate adjustment factor if self.hasTA[0]: self.DI = self.TA[0] & 0x0f else: self.DI = None # maximum programming current factor if self.hasTB[0]: self.II = self.TB[0] >> 5 & 0x03 else: self.II = None # programming voltage factor if self.hasTB[0]: self.PI1 = self.TB[0] & 0x1f else: self.PI1 = None # extra guard time self.N = self.TC[0] def getChecksum(self): """Return the checksum of the ATR. Checksum is mandatory only for T=1.""" return self.TCK def getHistoricalBytes(self): """Return historical bytes.""" return self.historicalBytes def getHistoricalBytesCount(self): """Return count of historical bytes.""" return len(self.historicalBytes) def getInterfaceBytesCount(self): """Return count of interface bytes.""" return self.interfaceBytesCount def getTA1(self): """Return TA1 byte.""" return self.TA[0] def getTB1(self): """Return TB1 byte.""" return self.TB[0] def getTC1(self): """Return TC1 byte.""" return self.TC[0] def getTD1(self): """Return TD1 byte.""" return self.TD[0] def getBitRateFactor(self): """Return bit rate factor.""" if self.DI is not None: return ATR.bitratefactor[self.DI] else: return 1 def getClockRateConversion(self): """Return clock rate conversion.""" if self.FI is not None: return ATR.clockrateconversion[self.FI] else: return 372 def getProgrammingCurrent(self): """Return maximum programming current.""" if self.II is not None: return ATR.currenttable[self.II] else: return 50 def getProgrammingVoltage(self): """Return programming voltage.""" if self.PI1 is not None: return 5 * (1 + self.PI1) else: return 5 def getGuardTime(self): """Return extra guard time.""" return self.N def getSupportedProtocols(self): """Returns a dictionnary of supported protocols.""" protocols = {} for td in self.TD: if td is not None: strprotocol = "T=%d" % (td & 0x0F) protocols[strprotocol] = True if not self.hasTD[0]: protocols['T=0'] = True return protocols def isT0Supported(self): """Return True if T=0 is supported.""" protocols = self.getSupportedProtocols() return 'T=0' in protocols def isT1Supported(self): """Return True if T=1 is supported.""" protocols = self.getSupportedProtocols() return 'T=1' in protocols def isT15Supported(self): """Return True if T=15 is supported.""" protocols = self.getSupportedProtocols() return 'T=15' in protocols def dump(self): """Dump the details of an ATR.""" for i in range(0, len(self.TA)): if self.TA[i] is not None: print("TA%d: %x" % (i + 1, self.TA[i])) if self.TB[i] is not None: print("TB%d: %x" % (i + 1, self.TB[i])) if self.TC[i] is not None: print("TC%d: %x" % (i + 1, self.TC[i])) if self.TD[i] is not None: print("TD%d: %x" % (i + 1, self.TD[i])) print('supported protocols ' + ','.join(self.getSupportedProtocols())) print('T=0 supported: ' + str(self.isT0Supported())) print('T=1 supported: ' + str(self.isT1Supported())) if self.getChecksum(): print('checksum: %d' % self.getChecksum()) print('\tclock rate conversion factor: ' + str(self.getClockRateConversion())) print('\tbit rate adjustment factor: ' + str(self.getBitRateFactor())) print('\tmaximum programming current: ' + str(self.getProgrammingCurrent())) print('\tprogramming voltage: ' + str(self.getProgrammingVoltage())) print('\tguard time: ' + str(self.getGuardTime())) print('nb of interface bytes: %d' % self.getInterfaceBytesCount()) print('nb of historical bytes: %d' % self.getHistoricalBytesCount()) def __str__(self): """Returns a string representation of the ATR as a strem of bytes.""" return toHexString(self.bytes) if __name__ == '__main__': """Small sample illustrating the use of ATR.""" atrs = [[0x3F, 0x65, 0x25, 0x00, 0x2C, 0x09, 0x69, 0x90, 0x00], [0x3F, 0x65, 0x25, 0x08, 0x93, 0x04, 0x6C, 0x90, 0x00], [0x3B, 0x16, 0x94, 0x7C, 0x03, 0x01, 0x00, 0x00, 0x0D], [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03], [0x3B, 0xE3, 0x00, 0xFF, 0x81, 0x31, 0x52, 0x45, 0xA1, 0xA2, 0xA3, 0x1B], [0x3B, 0xE5, 0x00, 0x00, 0x81, 0x21, 0x45, 0x9C, 0x10, 0x01, 0x00, 0x80, 0x0D]] for atr in atrs: a = ATR(atr) print(80 * '-') print(a) a.dump() print(toHexString(a.getHistoricalBytes())) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/AbstractCardRequest.py0000644000175000017500000000656400000000000021732 0ustar00rousseaurousseau"""AbstractCardRequest class. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.PassThruCardService import PassThruCardService import smartcard.System class AbstractCardRequest(object): """The base class for xxxCardRequest classes. A CardRequest is used for waitForCard() invocations and specifies what kind of smart card an application is waited for. Known subclasses: smartcard.pcsc.PCSCCardRequest""" def __init__(self, newcardonly=False, readers=None, cardType=None, cardServiceClass=None, timeout=1): """Construct new CardRequest. @param newcardonly: if True, request a new card; default is False, i.e. accepts cards already inserted @param readers: the list of readers to consider for requesting a card; default is to consider all readers @param cardType: the L{smartcard.CardType.CardType} to wait for; default is L{smartcard.CardType.AnyCardType}, i.e. the request will succeed with any card @param cardServiceClass: the specific card service class to create and bind to the card;default is to create and bind a L{smartcard.PassThruCardService} @param timeout: the time in seconds we are ready to wait for connecting to the requested card. default is to wait one second; to wait forever, set timeout to None """ self.newcardonly = newcardonly self.readersAsked = readers self.cardType = cardType self.cardServiceClass = cardServiceClass self.timeout = timeout # if no CardType requeted, use AnyCardType if self.cardType is None: self.cardType = AnyCardType() # if no card service requested, use pass-thru card service if self.cardServiceClass is None: self.cardServiceClass = PassThruCardService def getReaders(self): """Returns the list or readers on which to wait for cards.""" # if readers not given, use all readers if self.readersAsked is None: return smartcard.System.readers() else: return self.readersAsked def waitforcard(self): """Wait for card insertion and returns a card service.""" pass def waitforcardevent(self): """Wait for card insertion or removal.""" pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/Card.py0000644000175000017500000000506200000000000016665 0ustar00rousseaurousseau"""Card class. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.reader.Reader import Reader from smartcard.System import readers from smartcard.util import toHexString class Card(object): """Card class.""" def __init__(self, reader, atr): """Card constructor. reader: reader in which the card is inserted atr: ATR of the card""" self.reader = reader self.atr = atr def __repr__(self): """Return a string representing the Card (atr and reader concatenation).""" return toHexString(self.atr) + ' / ' + str(self.reader) def __eq__(self, other): """Return True if self==other (same reader and same atr). Return False otherwise.""" if isinstance(other, Card): return (self.atr == other.atr and repr(self.reader) == repr(other.reader)) else: return False def __ne__(self, other): """Return True if self!=other (same reader and same atr).Returns False otherwise.""" return not self.__eq__(other) def __hash__(self): """Returns a hash value for this object (str(self) is unique).""" return hash(str(self)) def createConnection(self): """Return a CardConnection to the Card object.""" readerobj = None if isinstance(self.reader, Reader): readerobj = self.reader elif type(self.reader) == str: for reader in readers(): if self.reader == str(reader): readerobj = reader if readerobj: return readerobj.createConnection() else: # raise CardConnectionException( # 'not a valid reader: ' + str(self.reader)) return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1618255307.0 pyscard-2.0.2/smartcard/CardConnection.py0000644000175000017500000002115700000000000020710 0ustar00rousseaurousseau"""The CardConnection abstract class manages connections with a card and apdu transmission. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardConnectionEvent import CardConnectionEvent from smartcard.Observer import Observable class CardConnection(Observable): """Card connection abstract class. Known subclasses: smartcard.pcsc.PCSCCardConnection """ T0_protocol = 0x00000001 T1_protocol = 0x00000002 RAW_protocol = 0x00010000 T15_protocol = 0x00000008 def __init__(self, reader): """Construct a new card connection. @param reader: name of the reader in which the smartcard to connect to is located. """ Observable.__init__(self) self.reader = reader self.errorcheckingchain = None self.defaultprotocol = CardConnection.T0_protocol |\ CardConnection.T1_protocol def __del__(self): """Connect to card.""" pass def addSWExceptionToFilter(self, exClass): """Add a status word exception class to be filtered. @param exClass: the class to filter, e.g. L{smartcard.sw.SWException.WarningProcessingException} Filtered exceptions will not be raised when encountered in the error checking chain.""" if self.errorcheckingchain is not None: self.errorcheckingchain[0].addFilterException(exClass) def addObserver(self, observer): """Add a CardConnection observer.""" Observable.addObserver(self, observer) def deleteObserver(self, observer): """Remove a CardConnection observer.""" Observable.deleteObserver(self, observer) def connect(self, protocol=None, mode=None, disposition=None): """Connect to card. @param protocol: a bit mask of the protocols to use, from L{CardConnection.T0_protocol}, L{CardConnection.T1_protocol}, L{CardConnection.RAW_protocol}, L{CardConnection.T15_protocol} @param mode: SCARD_SHARE_SHARED (default), SCARD_SHARE_EXCLUSIVE or SCARD_SHARE_DIRECT @param disposition: SCARD_LEAVE_CARD (default), SCARD_RESET_CARD, SCARD_UNPOWER_CARD or SCARD_EJECT_CARD """ Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent('connect')) def reconnect(self, protocol=None, mode=None, disposition=None): """Reconnect to card. @param protocol: a bit mask of the protocols to use, from L{CardConnection.T0_protocol}, L{CardConnection.T1_protocol}, L{CardConnection.RAW_protocol}, L{CardConnection.T15_protocol} @param mode: SCARD_SHARE_SHARED (default), SCARD_SHARE_EXCLUSIVE or SCARD_SHARE_DIRECT @param disposition: SCARD_LEAVE_CARD, SCARD_RESET_CARD (default), SCARD_UNPOWER_CARD or SCARD_EJECT_CARD """ Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent('reconnect')) def disconnect(self): """Disconnect from card.""" Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent('disconnect')) def getATR(self): """Return card ATR""" pass def getProtocol(self): """Return bit mask for the protocol of connection, or None if no protocol set. The return value is a bit mask of CardConnection.T0_protocol, CardConnection.T1_protocol, CardConnection.RAW_protocol, CardConnection.T15_protocol """ return self.defaultprotocol def getReader(self): """Return card connection reader""" return self.reader def setErrorCheckingChain(self, errorcheckingchain): """Add an error checking chain. @param errorcheckingchain: a smartcard.sw.ErrorCheckingChain object The error checking strategies in errorchecking chain will be tested with each received response APDU, and a smartcard.sw.SWException.SWException will be raised upon error.""" self.errorcheckingchain = errorcheckingchain def setProtocol(self, protocol): """Set protocol for card connection. @param protocol: a bit mask of CardConnection.T0_protocol, CardConnection.T1_protocol, CardConnection.RAW_protocol, CardConnection.T15_protocol e.g. setProtocol(CardConnection.T1_protocol | CardConnection.T0_protocol) """ self.defaultprotocol = protocol def transmit(self, bytes, protocol=None): """Transmit an apdu. Internally calls doTransmit() class method and notify observers upon command/response APDU events. Subclasses must override the doTransmit() class method. @param bytes: list of bytes to transmit @param protocol: the transmission protocol, from CardConnection.T0_protocol, CardConnection.T1_protocol, or CardConnection.RAW_protocol """ Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent( 'command', [bytes, protocol])) data, sw1, sw2 = self.doTransmit(bytes, protocol) Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent( 'response', [data, sw1, sw2])) if self.errorcheckingchain is not None: self.errorcheckingchain[0](data, sw1, sw2) return data, sw1, sw2 def doTransmit(self, bytes, protocol): """Performs the command APDU transmission. Subclasses must override this method for implementing apdu transmission.""" pass def control(self, controlCode, bytes=[]): """Send a control command and buffer. Internally calls doControl() class method and notify observers upon command/response events. Subclasses must override the doControl() class method. @param controlCode: command code @param bytes: list of bytes to transmit """ Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent( 'command', [controlCode, bytes])) data = self.doControl(controlCode, bytes) Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent( 'response', data)) if self.errorcheckingchain is not None: self.errorcheckingchain[0](data) return data def doControl(self, controlCode, bytes): """Performs the command control. Subclasses must override this method for implementing control.""" pass def getAttrib(self, attribId): """return the requested attribute @param attribId: attribute id like SCARD_ATTR_VENDOR_NAME """ Observable.setChanged(self) Observable.notifyObservers(self, CardConnectionEvent( 'attrib', [attribId])) data = self.doGetAttrib(attribId) if self.errorcheckingchain is not None: self.errorcheckingchain[0](data) return data def doGetAttrib(self, attribId): """Performs the command get attrib. Subclasses must override this method for implementing get attrib.""" pass def __enter__(self): """Enter the runtime context. """ return self def __exit__(self, type, value, traceback): """Exit the runtime context trying to disconnect. """ self.disconnect() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1618255307.0 pyscard-2.0.2/smartcard/CardConnectionDecorator.py0000644000175000017500000000647600000000000022562 0ustar00rousseaurousseau"""The CardConnectionDecorator is a Decorator around the CardConnection abstract class, and allows dynamic addition of features to the CardConnection, e.g. implementing a secure channel.. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardConnection import CardConnection class CardConnectionDecorator(CardConnection): """Card connection decorator class.""" def __init__(self, cardConnectionComponent): """Construct a new card connection decorator. CardConnectionComponent: CardConnection component to decorate """ self.component = cardConnectionComponent def addSWExceptionToFilter(self, exClass): """call inner component addSWExceptionToFilter""" self.component.addSWExceptionToFilter(exClass) def addObserver(self, observer): """call inner component addObserver""" self.component.addObserver(observer) def deleteObserver(self, observer): """call inner component deleteObserver""" self.component.deleteObserver(observer) def connect(self, protocol=None, mode=None, disposition=None): """call inner component connect""" self.component.connect(protocol, mode, disposition) def reconnect(self, protocol=None, mode=None, disposition=None): """call inner component reconnect""" self.component.reconnect(protocol, mode, disposition) def disconnect(self): """call inner component disconnect""" self.component.disconnect() def getATR(self): """call inner component getATR""" return self.component.getATR() def getProtocol(self): """call inner component getProtocol""" return self.component.getProtocol() def getReader(self): """call inner component getReader""" return self.component.getReader() def setErrorCheckingChain(self, errorcheckingchain): """call inner component setErrorCheckingChain""" self.component.setErrorCheckingChain(errorcheckingchain) def setProtocol(self, protocol): """call inner component setProtocol""" return self.component.setProtocol(protocol) def transmit(self, bytes, protocol=None): """call inner component transmit""" return self.component.transmit(bytes, protocol) def control(self, controlCode, bytes=[]): """call inner component control""" return self.component.control(controlCode, bytes) def getAttrib(self, attribId): """call inner component getAttrib""" return self.component.getAttrib(attribId) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1618255307.0 pyscard-2.0.2/smartcard/CardConnectionEvent.py0000644000175000017500000000271100000000000021705 0ustar00rousseaurousseau"""The CardConnectionEvent is sent to CardConnectionObserver objects when a CardConnection event occurs. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ class CardConnectionEvent(object): """Base class for card connection events. This event is notified by CardConnection objects.""" def __init__(self, type, args=None): """ @param type: 'connect', 'reconnect', 'disconnect', 'command', 'response' @param args: None for 'connect', 'reconnect' or 'disconnect' command APDU byte list for 'command' [response data, sw1, sw2] for 'response' """ self.type = type self.args = args ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399359.0 pyscard-2.0.2/smartcard/CardConnectionObserver.py0000644000175000017500000000454100000000000022416 0ustar00rousseaurousseau"""CardConnectionObserver interface. CardConnectionObserver is a base class for objects that are to be notified upon CardConnection events. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.util import toHexString from smartcard.Observer import Observer # ReaderObserver interface class CardConnectionObserver(Observer): """ CardConnectionObserver is a base class for objects that are to be notified upon CardConnection events. """ def update(self, cardconnection, cardconnectionevent): """Called upon CardConnection event. cardconnection: the observed card connection object cardconnectionevent: the CardConnectionEvent sent by the connection """ pass class ConsoleCardConnectionObserver(CardConnectionObserver): def update(self, cardconnection, ccevent): if 'connect' == ccevent.type: print('connecting to ' + cardconnection.getReader()) elif 'reconnect' == ccevent.type: print('reconnecting to ' + cardconnection.getReader()) elif 'disconnect' == ccevent.type: print('disconnecting from ' + cardconnection.getReader()) elif 'command' == ccevent.type: print('> ' + toHexString(ccevent.args[0])) elif 'response' == ccevent.type: if [] == ccevent.args[0]: print('< [] %02X %02X' % tuple(ccevent.args[-2:])) else: print('< ' + toHexString(ccevent.args[0]) + " " + "%02X %02X" % tuple(ccevent.args[-2:])) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399365.0 pyscard-2.0.2/smartcard/CardMonitoring.py0000644000175000017500000002152300000000000020733 0ustar00rousseaurousseau"""Smart card insertion/removal monitoring classes. CardObserver is a base class for objects that are to be notified upon smart card insertion/removal. CardMonitor is a singleton object notifying registered CardObservers upon reader insertion/removal. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from threading import Thread, Event from time import sleep import traceback from smartcard.Observer import Observer from smartcard.Observer import Observable from smartcard.CardRequest import CardRequest from smartcard.Exceptions import SmartcardException from smartcard.scard import SCARD_E_NO_SERVICE _START_ON_DEMAND_ = False # CardObserver interface class CardObserver(Observer): """ CardObserver is a base abstract class for objects that are to be notified upon smart card insertion / removal. """ def __init__(self): pass def update(self, observable, handlers): """Called upon smart card insertion / removal. @param observable: @param handlers: - addedcards: list of inserted smart cards causing notification - removedcards: list of removed smart cards causing notification """ pass class CardMonitor(object): """Class that monitors smart card insertion / removals. and notify observers note: a card monitoring thread will be running as long as the card monitor has observers, or CardMonitor.stop() is called. Do not forget to delete all your observers by calling deleteObserver, or your program will run forever... Uses the singleton pattern from Thinking in Python Bruce Eckel, http://mindview.net/Books/TIPython to make sure there is only one CardMonitor. """ class __CardMonitorSingleton(Observable): """The real smart card monitor class. A single instance of this class is created by the public CardMonitor class. """ def __init__(self): Observable.__init__(self) if _START_ON_DEMAND_: self.rmthread = None else: self.rmthread = CardMonitoringThread(self) def addObserver(self, observer): """Add an observer. We only start the card monitoring thread when there are observers. """ Observable.addObserver(self, observer) if _START_ON_DEMAND_: if self.countObservers() > 0 and self.rmthread is None: self.rmthread = CardMonitoringThread(self) else: observer.update(self, (self.rmthread.cards, [])) def deleteObserver(self, observer): """Remove an observer. We delete the CardMonitoringThread reference when there are no more observers. """ Observable.deleteObserver(self, observer) if _START_ON_DEMAND_: if self.countObservers() == 0: if self.rmthread is not None: self.rmthread.stop() self.rmthread.join() self.rmthread = None def __str__(self): return 'CardMonitor' # the singleton instance = None def __init__(self): if not CardMonitor.instance: CardMonitor.instance = CardMonitor.__CardMonitorSingleton() def __getattr__(self, name): return getattr(self.instance, name) class CardMonitoringThread(object): """Card insertion thread. This thread waits for card insertion. """ class __CardMonitoringThreadSingleton(Thread): """The real card monitoring thread class. A single instance of this class is created by the public CardMonitoringThread class. """ def __init__(self, observable): Thread.__init__(self) self.observable = observable self.stopEvent = Event() self.stopEvent.clear() self.cards = [] self.setDaemon(True) # the actual monitoring thread def run(self): """Runs until stopEvent is notified, and notify observers of all card insertion/removal. """ self.cardrequest = CardRequest(timeout=0.1) while self.stopEvent.isSet() != 1: try: currentcards = self.cardrequest.waitforcardevent() addedcards = [] for card in currentcards: if not self.cards.__contains__(card): addedcards.append(card) removedcards = [] for card in self.cards: if not currentcards.__contains__(card): removedcards.append(card) if addedcards != [] or removedcards != []: self.cards = currentcards self.observable.setChanged() self.observable.notifyObservers( (addedcards, removedcards)) # when CardMonitoringThread.__del__() is invoked in # response to shutdown, e.g., when execution of the # program is done, other globals referenced by the # __del__() method may already have been deleted. # this causes ReaderMonitoringThread.run() to except # with a TypeError or AttributeError except TypeError: pass except AttributeError: pass except SmartcardException as exc: # FIXME Tighten the exceptions caught by this block traceback.print_exc() # Most likely raised during interpreter shutdown due # to unclean exit which failed to remove all observers. # To solve this, we set the stop event and pass the # exception to let the thread finish gracefully. if exc.hresult == SCARD_E_NO_SERVICE: self.stopEvent.set() # stop the thread by signaling stopEvent def stop(self): self.stopEvent.set() # the singleton instance = None def __init__(self, observable): if not CardMonitoringThread.instance: CardMonitoringThread.instance = \ CardMonitoringThread.__CardMonitoringThreadSingleton(observable) CardMonitoringThread.instance.start() def join(self, *args, **kwargs): if self.instance: self.instance.join(*args, **kwargs) CardMonitoringThread.instance = None def __getattr__(self, name): if self.instance: return getattr(self.instance, name) # commented to avoid bad clean-up sequence of python where __del__ # is called when some objects it uses are already gargabe collected # def __del__(self): # if CardMonitoringThread.instance!=None: # CardMonitoringThread.instance.stop() # CardMonitoringThread.instance = None if __name__ == "__main__": print('insert or remove cards in the next 10 seconds') # a simple card observer that prints added/removed cards class printobserver(CardObserver): def __init__(self, obsindex): self.obsindex = obsindex def update(self, observable, handlers): addedcards, removedcards = handlers print("%d - added: %s" % (self.obsindex, str(addedcards))) print("%d - removed: %s" % (self.obsindex, str(removedcards))) class testthread(Thread): def __init__(self, obsindex): Thread.__init__(self) self.readermonitor = CardMonitor() self.obsindex = obsindex self.observer = None def run(self): # create and register observer self.observer = printobserver(self.obsindex) self.readermonitor.addObserver(self.observer) sleep(10) self.readermonitor.deleteObserver(self.observer) t1 = testthread(1) t2 = testthread(2) t1.start() t2.start() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399368.0 pyscard-2.0.2/smartcard/CardNames.py0000644000175000017500000000636300000000000017656 0ustar00rousseaurousseau"""Card Names class __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from _bsddb import DBNotFoundError from bsddb import hashopen from os import environ from os.path import join from pickle import dumps, loads, HIGHEST_PROTOCOL from smartcard.Synchronization import Synchronization, synchronize from smartcard.util import toBytes class __CardNames__(Synchronization): """__CardNames__ inner class. Stores card names and card types into a bsddb hash database. The smartcard.CardNames.CardNames singleton manages the creation of the unique instance of this class. """ def __init__(self): Synchronization.__init__(self) carddb_dir = environ['ALLUSERSPROFILE'] carddb_file = 'cardnames.bdb' carddb_file = join(carddb_dir, carddb_file) self.db = hashopen(carddb_file, 'w') def __del__(self): self.db.sync() self.db.close() def add(self, cardname, cardtype): self.db[cardname] = dumps(cardtype, HIGHEST_PROTOCOL) self.db.sync() def delete(self, cardname): try: del self.db[cardname] except DBNotFoundError: pass def dump(self): for k, v in list(self.db.items()): print(k, repr(loads(v))) def find(self, atr, reader=None): for k, v in list(self.db.items()): if loads(v).matches(atr, reader): return k synchronize(__CardNames__, "add delete dump find") class CardNames(object): """The CardNames organizes cards by a unique name and an associated smartcard.CardType.CardType.""" """The single instance of __CardNames__""" instance = None def __init__(self): """Constructor: create a single instance of __readergroups on first call""" if CardNames.instance is None: CardNames.instance = __CardNames__() def __getattr__(self, name): """All operators redirected to inner class.""" return getattr(self.instance, name) if __name__ == '__main__': from smartcard.CardType import ATRCardType # define a card by its ATR ct = ATRCardType([0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00, 0x0D]) # create CardName cn = CardNames() cn.add("Palmera Protect V2", ct) cn.dump() print(cn.find([0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00, 0x0D])) print(cn.find([0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00])) cn.delete("Palmera Protect V2") print('---------') cn.dump() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399375.0 pyscard-2.0.2/smartcard/CardRequest.py0000644000175000017500000000644500000000000020244 0ustar00rousseaurousseau"""Smartcard CardRequest. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.pcsc.PCSCCardRequest import PCSCCardRequest class CardRequest(object): """A CardRequest is used for waitForCard() invocations and specifies what kind of smart card an application is waited for. """ def __init__(self, newcardonly=False, readers=None, cardType=None, cardServiceClass=None, timeout=1): """Construct new CardRequest. @param newcardonly: if True, request a new card default is False, i.e. accepts cards already inserted @param readers: the list of readers to consider for requesting a card default is to consider all readers @param cardType: the L{smartcard.CardType.CardType} to wait for; default is L{smartcard.CardType.AnyCardType}, i.e. the request will succeed with any card @param cardServiceClass: the specific card service class to create and bind to the card default is to create and bind a L{smartcard.PassThruCardService} @param timeout: the time in seconds we are ready to wait for connecting to the requested card. default is to wait one second to wait forever, set timeout to None """ self.pcsccardrequest = PCSCCardRequest(newcardonly, readers, cardType, cardServiceClass, timeout) def getReaders(self): """Returns the list or readers on which to wait for cards.""" return self.pcsccardrequest.getReaders() def waitforcard(self): """Wait for card insertion and returns a card service.""" return self.pcsccardrequest.waitforcard() def waitforcardevent(self): """Wait for card insertion or removal.""" return self.pcsccardrequest.waitforcardevent() if __name__ == '__main__': """Small sample illustrating the use of CardRequest.py.""" from smartcard.util import toHexString print('Insert a new card within 10 seconds') cr = CardRequest(timeout=10, newcardonly=True) cs = cr.waitforcard() cs.connection.connect() print(cs.connection.getReader() + ' ' + toHexString(cs.connection.getATR())) cs.connection.disconnect() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399378.0 pyscard-2.0.2/smartcard/CardService.py0000644000175000017500000000451000000000000020203 0ustar00rousseaurousseau"""Card service abstract class. A card service is a class providings specific smart card functionality, e.g. a GSM file system or an Open Platform loader. CardService is an abstract class from which concrete card services are derived. A concrete card service is almost always smart card operating system specific. The card service performs its specific smart card functionnality by accessing the smartcard with a CardConnection. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * class CardService(object): """Card service abstract class. Known subclasses: smartcard.PassThruCardService """ def __init__(self, connection, cardname=None): """Construct a new card service and bind to a smart card in a reader. connection: the CardConnection used to access the smart card """ self.connection = connection self.cardname = cardname def __del__(self): """Destructor. Disconnect card and destroy card service resources.""" self.connection.disconnect() def supports(cardname): pass supports = staticmethod(supports) if __name__ == '__main__': """Small sample illustrating the use of CardService.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] from smartcard.System import readers cc = readers()[0].createConnection() cs = CardService(cc) cs.connection.connect() data, sw1, sw2 = cs.connection.transmit(SELECT + DF_TELECOM) print("%X %X" % (sw1, sw2)) cs.connection.disconnect() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399381.0 pyscard-2.0.2/smartcard/CardType.py0000644000175000017500000000704000000000000017525 0ustar00rousseaurousseau"""Abstract CarType. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.Exceptions import InvalidATRMaskLengthException from smartcard.System import readers from smartcard.util import toHexString class CardType(object): """Abstract base class for CardTypes. Known sub-classes: L{smartcard.CardType.AnyCardType} L{smartcard.CardType.ATRCardType}.""" def __init__(self): """CardType constructor.""" pass def matches(self, atr, reader=None): """Returns true if atr and card connected match the CardType. @param atr: the atr to chek for matching @param reader: the reader (optional); default is None The reader can be use in some sub-classes to do advanced matching that require connecting to the card.""" pass class AnyCardType(CardType): """The AnyCardType matches any card.""" def matches(self, atr, reader=None): """Always returns true, i.e. AnyCardType matches any card. @param atr: the atr to chek for matching @param reader: the reader (optional); default is None""" return True class ATRCardType(CardType): """The ATRCardType defines a card from an ATR and a mask.""" def __init__(self, atr, mask=None): """ATRCardType constructor. @param atr: the ATR of the CardType @param mask: an optional mask to be applied to the ATR for L{CardType} matching default is None """ self.atr = list(atr) self.mask = mask if mask is None: self.maskedatr = self.atr else: if len(self.atr) != len(self.mask): raise InvalidATRMaskLengthException(toHexString(mask)) self.maskedatr = list(map(lambda x, y: x & y, self.atr, self.mask)) def matches(self, atr, reader=None): """Returns true if the atr matches the masked CardType atr. @param atr: the atr to chek for matching @param reader: the reader (optional); default is None When atr is compared to the CardType ATR, matches returns true if and only if CardType.atr & CardType.mask = atr & CardType.mask, where & is the bitwise logical AND.""" if len(atr) != len(self.atr): return not True if self.mask is not None: maskedatr = list(map(lambda x, y: x & y, list(atr), self.mask)) else: maskedatr = atr return self.maskedatr == maskedatr if __name__ == '__main__': """Small sample illustrating the use of CardType.py.""" r = readers() print(r) connection = r[0].createConnection() connection.connect() atrct = ATRCardType([0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00, 0x0D]) print(atrct.matches(connection.getATR())) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/ClassLoader.py0000644000175000017500000000324100000000000020205 0ustar00rousseaurousseau"""ClassLoader allows you to load modules from packages without hard-coding their class names in code; instead, they might be specified in a configuration file, as command-line parameters, or within an interface. Source: Robert Brewer at the Python Cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223972 License: PSF license (http://docs.python.org/license.html). """ def get_mod(modulePath): """Import a module.""" return __import__(modulePath, globals(), locals(), ['']) def get_func(fullFuncName): """Retrieve a function object from a full dotted-package name.""" # Parse out the path, module, and function lastDot = fullFuncName.rfind(u".") funcName = fullFuncName[lastDot + 1:] modPath = fullFuncName[:lastDot] aMod = get_mod(modPath) aFunc = getattr(aMod, funcName) # Assert that the function is a *callable* attribute. assert callable(aFunc), u"%s is not callable." % fullFuncName # Return a reference to the function itself, # not the results of the function. return aFunc def get_class(fullClassName, parentClass=None): """Load a module and retrieve a class (NOT an instance). If the parentClass is supplied, className must be of parentClass or a subclass of parentClass (or None is returned). """ aClass = get_func(fullClassName) # Assert that the class is a subclass of parentClass. if parentClass is not None: if not issubclass(aClass, parentClass): raise TypeError(u"%s is not a subclass of %s" % (fullClassName, parentClass)) # Return a reference to the class itself, not an instantiated object. return aClass ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1069946 pyscard-2.0.2/smartcard/Examples/0000755000175000017500000000000000000000000017215 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1190004 pyscard-2.0.2/smartcard/Examples/framework/0000755000175000017500000000000000000000000021212 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399454.0 pyscard-2.0.2/smartcard/Examples/framework/sample_ATR.py0000755000175000017500000000267500000000000023570 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script for the smartcard.ATR utility class. __author__ = "http://www.gemalto.com" Copyright 2001-2009 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.ATR import ATR from smartcard.util import toHexString atr = ATR([0x3B, 0x9E, 0x95, 0x80, 0x1F, 0xC3, 0x80, 0x31, 0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x29, 0x02, 0x01, 0x01, 0x81, 0xCD, 0xB9]) print(atr) print('historical bytes: ', toHexString(atr.getHistoricalBytes())) print('checksum: ', "0x%X" % atr.getChecksum()) print('checksum OK: ', atr.checksumOK) print('T0 supported: ', atr.isT0Supported()) print('T1 supported: ', atr.isT1Supported()) print('T15 supported: ', atr.isT15Supported()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399461.0 pyscard-2.0.2/smartcard/Examples/framework/sample_CardConnectionDecorator.py0000755000175000017500000000732100000000000027667 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that illustrates card connection decorators. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.CardConnectionDecorator import CardConnectionDecorator from smartcard.util import toHexString # define two custom CardConnectionDecorator # the decorators are very simple, just to illustrate # shortly how several decorators can be added to the # card connection class SecureChannelConnection(CardConnectionDecorator): '''This decorator is a mockup of secure channel connection. It merely pretends to cypher/uncypher upon apdu transmission.''' def __init__(self, cardconnection): CardConnectionDecorator.__init__(self, cardconnection) def cypher(self, bytes): '''Cypher mock-up; you would include the secure channel logics here.''' print('cyphering', toHexString(bytes)) return bytes def uncypher(self, data): '''Uncypher mock-up; you would include the secure channel logics here.''' print('uncyphering', toHexString(data)) return data def transmit(self, bytes, protocol=None): """Cypher/uncypher APDUs before transmission""" cypheredbytes = self.cypher(bytes) data, sw1, sw2 = CardConnectionDecorator.transmit( self, cypheredbytes, protocol) if [] != data: data = self.uncypher(data) return data, sw1, sw2 class FakeATRConnection(CardConnectionDecorator): '''This decorator changes the fist byte of the ATR. This is just an example to show that decorators can be nested.''' def __init__(self, cardconnection): CardConnectionDecorator.__init__(self, cardconnection) def getATR(self): """Replace first BYTE of ATR by 3F""" atr = CardConnectionDecorator.getATR(self) return [0x3f] + atr[1:] # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] # request any card type cardtype = AnyCardType() cardrequest = CardRequest(timeout=1.5, cardType=cardtype) cardservice = cardrequest.waitforcard() # attach the console tracer observer = ConsoleCardConnectionObserver() cardservice.connection.addObserver(observer) # attach our decorator cardservice.connection = FakeATRConnection( SecureChannelConnection(cardservice.connection)) # connect to the card and perform a few transmits cardservice.connection.connect() print('ATR', toHexString(cardservice.connection.getATR())) apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399468.0 pyscard-2.0.2/smartcard/Examples/framework/sample_ConsoleConnectionTracer.py0000755000175000017500000000354400000000000027721 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that monitors card connection events. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] # request any card type cardtype = AnyCardType() cardrequest = CardRequest(timeout=1.5, cardType=cardtype) cardservice = cardrequest.waitforcard() # attach the console tracer observer = ConsoleCardConnectionObserver() cardservice.connection.addObserver(observer) # connect to the card and perform a few transmits cardservice.connection.connect() apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399478.0 pyscard-2.0.2/smartcard/Examples/framework/sample_CustomCardType.py0000755000175000017500000000326600000000000026045 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that demonstrates how to create a custom CardType. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import CardType from smartcard.CardRequest import CardRequest from smartcard.util import toHexString class DCCardType(CardType): # define our custom CardType # this card type defines direct convention card # (first atr byte equal to 0x3b) def matches(self, atr, reader=None): return atr[0] == 0x3B # request a direct convention card cardtype = DCCardType() cardrequest = CardRequest(timeout=1, cardType=cardtype) cardservice = cardrequest.waitforcard() # connect and print atr and reader cardservice.connection.connect() print(toHexString(cardservice.connection.getATR())) print(cardservice.connection.getReader()) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399481.0 pyscard-2.0.2/smartcard/Examples/framework/sample_CustomErrorChecker.py0000755000175000017500000000563100000000000026706 0ustar00rousseaurousseau#! /usr/bin/env python3 """Sample script for APDU error checking with a custom error checker. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.sw.ErrorCheckingChain import ErrorCheckingChain from smartcard.sw.ErrorChecker import ErrorChecker from smartcard.sw.SWExceptions import SWException class MyErrorChecker(ErrorChecker): """Our custom error checker that will except if 0x61 sw1: raise SWException(data, sw1, sw2) # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] if __name__ == '__main__': print('Insert a card within 10 seconds') print('Cards without a DF_TELECOM will except') # request any card cardtype = AnyCardType() cardrequest = CardRequest(timeout=10, cardType=cardtype) cardservice = cardrequest.waitforcard() # our error checking chain errorchain = [] errorchain = [ErrorCheckingChain([], MyErrorChecker())] cardservice.connection.setErrorCheckingChain(errorchain) # attach the console tracer observer = ConsoleCardConnectionObserver() cardservice.connection.addObserver(observer) # send a few apdus; exceptions will occur upon errors cardservice.connection.connect() try: SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) if sw1 == 0x9F: GET_RESPONSE = [0XA0, 0XC0, 00, 00] apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) except SWException as e: print(e, "%x %x" % (e.sw1, e.sw2)) cardservice.connection.disconnect() import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399484.0 pyscard-2.0.2/smartcard/Examples/framework/sample_ErrorChecking.py0000755000175000017500000000605000000000000025656 0ustar00rousseaurousseau#! /usr/bin/env python3 """Sample script for APDU error checking. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.sw.ErrorCheckingChain import ErrorCheckingChain from smartcard.sw.ISO7816_4ErrorChecker import ISO7816_4ErrorChecker from smartcard.sw.ISO7816_8ErrorChecker import ISO7816_8ErrorChecker from smartcard.sw.ISO7816_9ErrorChecker import ISO7816_9ErrorChecker from smartcard.sw.SWExceptions import SWException, WarningProcessingException # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] if __name__ == '__main__': print('Insert a card within 10 seconds') print('Cards without a DF_TELECOM will except') # request any card type cardtype = AnyCardType() cardrequest = CardRequest(timeout=10, cardType=cardtype) cardservice = cardrequest.waitforcard() # use ISO7816-4 and ISO7816-8 error checking strategy # first check iso7816_8 errors, then iso7816_4 errors errorchain = [] errorchain = [ErrorCheckingChain(errorchain, ISO7816_9ErrorChecker())] errorchain = [ErrorCheckingChain(errorchain, ISO7816_8ErrorChecker())] errorchain = [ErrorCheckingChain(errorchain, ISO7816_4ErrorChecker())] cardservice.connection.setErrorCheckingChain(errorchain) # filter Warning Processing Exceptions (sw1 = 0x62 or 0x63) cardservice.connection.addSWExceptionToFilter(WarningProcessingException) # attach the console tracer observer = ConsoleCardConnectionObserver() cardservice.connection.addObserver(observer) # connect to the card and perform a few transmits cardservice.connection.connect() try: apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) except SWException as e: print(str(e)) cardservice.connection.disconnect() import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399487.0 pyscard-2.0.2/smartcard/Examples/framework/sample_ExclusiveCardConnection.py0000755000175000017500000000473500000000000027722 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that illustrates exclusive card connection decorators. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.util import toHexString from smartcard.ExclusiveConnectCardConnection import \ ExclusiveConnectCardConnection from smartcard.ExclusiveTransmitCardConnection import \ ExclusiveTransmitCardConnection # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] # request any card type cardtype = AnyCardType() cardrequest = CardRequest(timeout=5, cardType=cardtype) cardservice = cardrequest.waitforcard() # attach the console tracer observer = ConsoleCardConnectionObserver() cardservice.connection.addObserver(observer) # attach our decorator cardservice.connection = ExclusiveTransmitCardConnection( ExclusiveConnectCardConnection(cardservice.connection)) # connect to the card and perform a few transmits cardservice.connection.connect() print('ATR', toHexString(cardservice.connection.getATR())) try: # lock for initiating transaction cardservice.connection.lock() apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) finally: # unlock connection at the end of the transaction cardservice.connection.unlock() import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399494.0 pyscard-2.0.2/smartcard/Examples/framework/sample_MonitorCards.py0000755000175000017500000000404500000000000025537 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that monitors smartcard insertion/removal. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from time import sleep from smartcard.CardMonitoring import CardMonitor, CardObserver from smartcard.util import toHexString # a simple card observer that prints inserted/removed cards class PrintObserver(CardObserver): """A simple card observer that is notified when cards are inserted/removed from the system and prints the list of cards """ def update(self, observable, actions): (addedcards, removedcards) = actions for card in addedcards: print("+Inserted: ", toHexString(card.atr)) for card in removedcards: print("-Removed: ", toHexString(card.atr)) if __name__ == '__main__': print("Insert or remove a smartcard in the system.") print("This program will exit in 10 seconds") print("") cardmonitor = CardMonitor() cardobserver = PrintObserver() cardmonitor.addObserver(cardobserver) sleep(10) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(cardobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399491.0 pyscard-2.0.2/smartcard/Examples/framework/sample_MonitorCardsAndTransmit.py0000755000175000017500000000544700000000000027713 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that monitors smartcard insertion/removal and select DF_TELECOM on inserted cards __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from time import sleep from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.CardMonitoring import CardMonitor, CardObserver from smartcard.util import toHexString # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] # a simple card observer that tries to select DF_TELECOM on an inserted card class selectDFTELECOMObserver(CardObserver): """A simple card observer that is notified when cards are inserted/removed from the system and prints the list of cards """ def __init__(self): self.observer = ConsoleCardConnectionObserver() def update(self, observable, actions): (addedcards, removedcards) = actions for card in addedcards: print("+Inserted: ", toHexString(card.atr)) card.connection = card.createConnection() card.connection.connect() card.connection.addObserver(self.observer) apdu = SELECT + DF_TELECOM response, sw1, sw2 = card.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = card.connection.transmit(apdu) for card in removedcards: print("-Removed: ", toHexString(card.atr)) if __name__ == '__main__': print("Insert or remove a SIM card in the system.") print("This program will exit in 60 seconds") print("") cardmonitor = CardMonitor() selectobserver = selectDFTELECOMObserver() cardmonitor.addObserver(selectobserver) sleep(60) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(selectobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399496.0 pyscard-2.0.2/smartcard/Examples/framework/sample_MonitorReaders.py0000755000175000017500000000360600000000000026072 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that monitors smartcard readers. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from time import sleep from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver class printobserver(ReaderObserver): """A simple reader observer that is notified when readers are added/removed from the system and prints the list of readers """ def update(self, observable, actions): (addedreaders, removedreaders) = actions print("Added readers", addedreaders) print("Removed readers", removedreaders) if __name__ == '__main__': print("Add or remove a smartcard reader to the system.") print("This program will exit in 10 seconds") print("") readermonitor = ReaderMonitor() readerobserver = printobserver() readermonitor.addObserver(readerobserver) sleep(10) # don't forget to remove observer, or the # monitor will poll forever... readermonitor.deleteObserver(readerobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399500.0 pyscard-2.0.2/smartcard/Examples/framework/sample_TransmitCardObserver.py0000755000175000017500000000446400000000000027243 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that monitors card insertions, connects to cards and transmit an apdu __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from time import sleep from smartcard.CardMonitoring import CardMonitor, CardObserver from smartcard.util import * # replace by your favourite apdu SELECT_DF_TELECOM = [0xA0, 0xA4, 0x00, 0x00, 0x02, 0x7F, 0x10] class transmitobserver(CardObserver): """A card observer that is notified when cards are inserted/removed from the system, connects to cards and SELECT DF_TELECOM """ def __init__(self): self.cards = [] def update(self, observable, actions): (addedcards, removedcards) = actions for card in addedcards: if card not in self.cards: self.cards += [card] print("+Inserted: ", toHexString(card.atr)) card.connection = card.createConnection() card.connection.connect() response, sw1, sw2 = card.connection.transmit( SELECT_DF_TELECOM) print("%.2x %.2x" % (sw1, sw2)) for card in removedcards: print("-Removed: ", toHexString(card.atr)) if card in self.cards: self.cards.remove(card) if __name__ == '__main__': print("Insert or remove a smartcard in the system.") print("This program will exit in 100 seconds") print("") cardmonitor = CardMonitor() cardobserver = transmitobserver() cardmonitor.addObserver(cardobserver) sleep(100) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399452.0 pyscard-2.0.2/smartcard/Examples/framework/sample_apduTracerInterpreter.py0000755000175000017500000000574000000000000027454 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that defines a custom card connection observer. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import CardConnectionObserver from smartcard.util import toHexString class TracerAndSELECTInterpreter(CardConnectionObserver): """This observer will interprer SELECT and GET RESPONSE bytes and replace them with a human readable string.""" def update(self, cardconnection, ccevent): if 'connect' == ccevent.type: print('connecting to ' + cardconnection.getReader()) elif 'disconnect' == ccevent.type: print('disconnecting from ' + cardconnection.getReader()) elif 'command' == ccevent.type: str = toHexString(ccevent.args[0]) str = str.replace("A0 A4 00 00 02", "SELECT") str = str.replace("A0 C0 00 00", "GET RESPONSE") print('>', str) elif 'response' == ccevent.type: if [] == ccevent.args[0]: print('< []', "%-2X %-2X" % tuple(ccevent.args[-2:])) else: print('<', toHexString(ccevent.args[0]), "%-2X %-2X" % tuple(ccevent.args[-2:])) # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] # we request any type and wait for 10s for card insertion cardtype = AnyCardType() cardrequest = CardRequest(timeout=10, cardType=cardtype) cardservice = cardrequest.waitforcard() # create an instance of our observer and attach to the connection observer = TracerAndSELECTInterpreter() cardservice.connection.addObserver(observer) # connect and send APDUs # the observer will trace on the console cardservice.connection.connect() apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) else: print('no DF_TELECOM') import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399498.0 pyscard-2.0.2/smartcard/Examples/framework/sample_toHexString.py0000755000175000017500000000446000000000000025412 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script to illustrate toHexString() utility method __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.util import * print(40 * '-') bytes = [59, 101, 0, 0, 156, 17, 1, 1, 3] print('bytes = [59, 101, 0, 0, 156, 17, 1, 1, 3]') print('toHexString(bytes) =', toHexString(bytes)) print('toHexString(bytes, COMMA) =', toHexString(bytes, COMMA)) print('toHexString(bytes, PACK) =', toHexString(bytes, PACK)) print('toHexString(bytes, HEX) =', toHexString(bytes, HEX)) print('toHexString(bytes, HEX | COMMA) =', toHexString(bytes, HEX | COMMA)) print('toHexString(bytes, HEX | UPPERCASE) =', toHexString(bytes, HEX | UPPERCASE)) print('toHexString(bytes, HEX | UPPERCASE | COMMA) =', toHexString(bytes, HEX | UPPERCASE | COMMA)) print(40 * '-') bytes = [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03] print('bytes = [ 0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03 ]') print('toHexString(bytes, COMMA) =', toHexString(bytes, COMMA)) print('toHexString(bytes) =', toHexString(bytes)) print('toHexString(bytes, PACK) =', toHexString(bytes, PACK)) print('toHexString(bytes, HEX) =', toHexString(bytes, HEX)) print('toHexString(bytes, HEX | COMMA) =', toHexString(bytes, HEX | COMMA)) print('toHexString(bytes, HEX | UPPERCASE) =', toHexString(bytes, HEX | UPPERCASE)) print('toHexString(bytes, HEX | UPPERCASE | COMMA) =', toHexString(bytes, HEX | UPPERCASE | COMMA)) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1190004 pyscard-2.0.2/smartcard/Examples/scard-api/0000755000175000017500000000000000000000000021060 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399504.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_control.py0000755000175000017500000001037100000000000024460 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: send a Control Code to a card or reader __author__ = "Ludovic Rousseau" Copyright 2007-2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * from smartcard.util import toBytes try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) if len(readers) < 1: raise error('No smart card readers') for zreader in readers: print('Trying to Control reader:', zreader) try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to connect: ' + SCardGetErrorMessage(hresult)) print('Connected with active protocol', dwActiveProtocol) try: if 'winscard' == resourceManager: # IOCTL_SMARTCARD_GET_ATTRIBUTE = SCARD_CTL_CODE(2) hresult, response = SCardControl( hcard, SCARD_CTL_CODE(2), toBytes("%.8lx" % SCARD_ATTR_VENDOR_NAME)) if hresult != SCARD_S_SUCCESS: raise error( 'SCardControl failed: ' + SCardGetErrorMessage(hresult)) r = "" for i in range(len(response)): r += "%c" % response[i] print('SCARD_ATTR_VENDOR_NAME:', r) elif 'pcsclite' == resourceManager: # get firmware on Gemplus readers hresult, response = SCardControl( hcard, SCARD_CTL_CODE(1), [0x02]) if hresult != SCARD_S_SUCCESS: raise error( 'SCardControl failed: ' + SCardGetErrorMessage(hresult)) r = "" for i in range(len(response)): r += "%c" % response[i] print('Control:', r) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to disconnect: ' + SCardGetErrorMessage(hresult)) print('Disconnected') except error as message: print(error, message) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') except error as e: print(e) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399506.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_getATR.py0000755000175000017500000000656700000000000024142 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: get card ATR in first pcsc reader __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * import smartcard.util import sys if __name__ == '__main__': hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) if len(readers) < 1: raise Exception('No smart card readers') print('PCSC Readers:', readers) for reader in readers: print('Trying to retreive ATR of card in', reader) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if hresult != SCARD_S_SUCCESS: print('Unable to connect: ' + SCardGetErrorMessage(hresult)) else: print('Connected with active protocol', dwActiveProtocol) try: hresult, reader, state, protocol, atr = SCardStatus(hcard) if hresult != SCARD_S_SUCCESS: print('failed to get status: ' + SCardGetErrorMessage(hresult)) print('Reader:', reader) print('State:', hex(state)) print('Protocol:', protocol) print('ATR:', smartcard.util.toHexString( atr, smartcard.util.HEX)) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: print('Failed to disconnect: ' + SCardGetErrorMessage(hresult)) print('Disconnected') finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error('Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399510.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_getAttrib.py0000755000175000017500000001460700000000000024733 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: List card attributes __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import struct from smartcard.scard import * import smartcard.util import sys attributes = { SCARD_ATTR_ATR_STRING: 'SCARD_ATTR_ATR_STRING', SCARD_ATTR_CHANNEL_ID: 'SCARD_ATTR_CHANNEL_ID', SCARD_ATTR_CHARACTERISTICS: 'SCARD_ATTR_CHARACTERISTICS', SCARD_ATTR_CURRENT_BWT: 'SCARD_ATTR_CURRENT_BWT', SCARD_ATTR_CURRENT_CLK: 'SCARD_ATTR_CURRENT_CLK', SCARD_ATTR_CURRENT_CWT: 'SCARD_ATTR_CURRENT_CWT', SCARD_ATTR_CURRENT_D: 'SCARD_ATTR_CURRENT_D', SCARD_ATTR_CURRENT_EBC_ENCODING: 'SCARD_ATTR_CURRENT_EBC_ENCODING', SCARD_ATTR_CURRENT_F: 'SCARD_ATTR_CURRENT_F', SCARD_ATTR_CURRENT_IFSC: 'SCARD_ATTR_CURRENT_IFSC', SCARD_ATTR_CURRENT_IFSD: 'SCARD_ATTR_CURRENT_IFSD', SCARD_ATTR_CURRENT_IO_STATE: 'SCARD_ATTR_CURRENT_IO_STATE', SCARD_ATTR_CURRENT_N: 'SCARD_ATTR_CURRENT_N', SCARD_ATTR_CURRENT_PROTOCOL_TYPE: 'SCARD_ATTR_CURRENT_PROTOCOL_TYPE', SCARD_ATTR_CURRENT_W: 'SCARD_ATTR_CURRENT_W', SCARD_ATTR_DEFAULT_CLK: 'SCARD_ATTR_DEFAULT_CLK', SCARD_ATTR_DEFAULT_DATA_RATE: 'SCARD_ATTR_DEFAULT_DATA_RATE', SCARD_ATTR_DEVICE_FRIENDLY_NAME_A: 'SCARD_ATTR_DEVICE_FRIENDLY_NAME_A', SCARD_ATTR_DEVICE_FRIENDLY_NAME_W: 'SCARD_ATTR_DEVICE_FRIENDLY_NAME_W', SCARD_ATTR_DEVICE_IN_USE: 'SCARD_ATTR_DEVICE_IN_USE', SCARD_ATTR_DEVICE_SYSTEM_NAME_A: 'SCARD_ATTR_DEVICE_SYSTEM_NAME_A', SCARD_ATTR_DEVICE_SYSTEM_NAME_W: 'SCARD_ATTR_DEVICE_SYSTEM_NAME_W', SCARD_ATTR_DEVICE_UNIT: 'SCARD_ATTR_DEVICE_UNIT', SCARD_ATTR_ESC_AUTHREQUEST: 'SCARD_ATTR_ESC_AUTHREQUEST', SCARD_ATTR_ESC_CANCEL: 'SCARD_ATTR_ESC_CANCEL', SCARD_ATTR_ESC_RESET: 'SCARD_ATTR_ESC_RESET', SCARD_ATTR_EXTENDED_BWT: 'SCARD_ATTR_EXTENDED_BWT', SCARD_ATTR_ICC_INTERFACE_STATUS: 'SCARD_ATTR_ICC_INTERFACE_STATUS', SCARD_ATTR_ICC_PRESENCE: 'SCARD_ATTR_ICC_PRESENCE', SCARD_ATTR_ICC_TYPE_PER_ATR: 'SCARD_ATTR_ICC_TYPE_PER_ATR', SCARD_ATTR_MAXINPUT: 'SCARD_ATTR_MAXINPUT', SCARD_ATTR_MAX_CLK: 'SCARD_ATTR_MAX_CLK', SCARD_ATTR_MAX_DATA_RATE: 'SCARD_ATTR_MAX_DATA_RATE', SCARD_ATTR_MAX_IFSD: 'SCARD_ATTR_MAX_IFSD', SCARD_ATTR_POWER_MGMT_SUPPORT: 'SCARD_ATTR_POWER_MGMT_SUPPORT', SCARD_ATTR_SUPRESS_T1_IFS_REQUEST: 'SCARD_ATTR_SUPRESS_T1_IFS_REQUEST', SCARD_ATTR_USER_AUTH_INPUT_DEVICE: 'SCARD_ATTR_USER_AUTH_INPUT_DEVICE', SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE: 'SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE', SCARD_ATTR_VENDOR_IFD_SERIAL_NO: 'SCARD_ATTR_VENDOR_IFD_SERIAL_NO', SCARD_ATTR_VENDOR_IFD_TYPE: 'SCARD_ATTR_VENDOR_IFD_TYPE', SCARD_ATTR_VENDOR_IFD_VERSION: 'SCARD_ATTR_VENDOR_IFD_VERSION', SCARD_ATTR_VENDOR_NAME: 'SCARD_ATTR_VENDOR_NAME', } if 'pcsclite' == resourceManager: extra_attributes = { SCARD_ATTR_ASYNC_PROTOCOL_TYPES: 'SCARD_ATTR_ASYNC_PROTOCOL_TYPES', SCARD_ATTR_SYNC_PROTOCOL_TYPES: 'SCARD_ATTR_SYNC_PROTOCOL_TYPES', } attributes.update(extra_attributes) def printAttribute(attrib, value): print('-----------------', attributes[attrib], '-----------------') print(value) print(smartcard.util.toHexString(value, smartcard.util.HEX)) print(struct.pack(*['<' + 'B' * len(value)] + value)) if __name__ == '__main__': hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) if len(readers) < 1: raise error('No smart card readers') for reader in readers: print('Trying to retreive attributes of', reader) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if hresult != SCARD_S_SUCCESS: print(error, 'Unable to connect: ' + SCardGetErrorMessage(hresult)) else: print('Connected with active protocol', dwActiveProtocol) try: for i in list(attributes.keys()): hresult, attrib = SCardGetAttrib(hcard, i) if hresult == SCARD_S_SUCCESS: printAttribute(i, attrib) else: print('-----------------', attributes[i], '-----------------') print('error:', SCardGetErrorMessage(hresult)) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to disconnect: ' + SCardGetErrorMessage(hresult)) print('Disconnected') finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399512.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_getStatusChange.py0000755000175000017500000000754100000000000026076 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: Detect card insertion/removal __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * import smartcard.util srTreeATR = \ [0x3B, 0x77, 0x94, 0x00, 0x00, 0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22] srTreeMask = \ [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] def printstate(state): reader, eventstate, atr = state print(reader + " " + smartcard.util.toHexString(atr, smartcard.util.HEX)) if eventstate & SCARD_STATE_ATRMATCH: print('\tCard found') if eventstate & SCARD_STATE_UNAWARE: print('\tState unware') if eventstate & SCARD_STATE_IGNORE: print('\tIgnore reader') if eventstate & SCARD_STATE_UNAVAILABLE: print('\tReader unavailable') if eventstate & SCARD_STATE_EMPTY: print('\tReader empty') if eventstate & SCARD_STATE_PRESENT: print('\tCard present in reader') if eventstate & SCARD_STATE_EXCLUSIVE: print('\tCard allocated for exclusive use by another application') if eventstate & SCARD_STATE_INUSE: print('\tCard in used by another application but can be shared') if eventstate & SCARD_STATE_MUTE: print('\tCard is mute') if eventstate & SCARD_STATE_CHANGED: print('\tState changed') if eventstate & SCARD_STATE_UNKNOWN: print('\tState unknowned') try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) readerstates = [] for i in range(len(readers)): readerstates += [(readers[i], SCARD_STATE_UNAWARE)] print('----- Current reader and card states are: -------') hresult, newstates = SCardGetStatusChange(hcontext, 0, readerstates) for i in newstates: printstate(i) print('----- Please insert or remove a card ------------') hresult, newstates = SCardGetStatusChange( hcontext, INFINITE, newstates) print('----- New reader and card states are: -----------') for i in newstates: printstate(i) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) except error as e: print(e) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399514.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_listCards.py0000755000175000017500000000614300000000000024732 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: List cards introduced in the system __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * import sys if 'winscard' == resourceManager: # Cryptoflex 8k v2 is introduced in standard Windows 2000 slbCryptoFlex8kv2ATR = \ [0x3B, 0x95, 0x15, 0x40, 0x00, 0x68, 0x01, 0x02, 0x00, 0x00] try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, card = SCardListCards(hcontext, slbCryptoFlex8kv2ATR, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failure to locate Schlumberger Cryptoflex 8k v2 card: ' + SCardGetErrorMessage(hresult)) print('Located by ATR:', card) hresult, cards = SCardListCards(hcontext, [], []) if hresult != SCARD_S_SUCCESS: raise error( 'Failure to list cards: ' + SCardGetErrorMessage(hresult)) print('Cards:', cards) for i in cards: hresult, providerguid = SCardGetCardTypeProviderName( hcontext, i, SCARD_PROVIDER_PRIMARY) if hresult == SCARD_S_SUCCESS: print(i, 'Primary provider:', providername) hresult, providername = SCardGetCardTypeProviderName( hcontext, i, SCARD_PROVIDER_CSP) if hresult == SCARD_S_SUCCESS: print(i, 'CSP Provider:', providername) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') except error as e: print(e) elif 'pcsclite' == resourceManager: print('SCardListCards not supported by pcsc lite') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399516.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_listInterfaces.py0000755000175000017500000001062600000000000025762 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: List card interfaces __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import platform from smartcard.scard import * import smartcard.guid import sys if 'winscard' == resourceManager: znewcardName = 'dummy-card' znewcardATR = [0x3B, 0x77, 0x94, 0x00, 0x00, 0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22] znewcardMask = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] znewcardPrimGuid = \ smartcard.guid.strToGUID('{128F3806-4F70-4ccf-977A-60C390664840}') znewcardSecGuid = \ smartcard.guid.strToGUID('{EB7F69EA-BA20-47d0-8C50-11CFDEB63BBE}') def main(): hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise scard.error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: # list interfaces for a known card if -1 != platform.platform().find('Windows-7'): expectedCard = 'Identity Device (Microsoft Generic Profile)' elif -1 != platform.platform().find('Windows-Vista-6.0'): expectedCard = 'Axalto Cryptoflex .NET' else: expectedCard = 'Schlumberger Cryptoflex 8k v2' hresult, interfaces = SCardListInterfaces( hcontext, expectedCard) if hresult != SCARD_S_SUCCESS: raise scard.error( 'Failed to list interfaces: ' + SCardGetErrorMessage(hresult)) print('Interfaces for ', expectedCard, ':', interfaces) # introduce a card (forget first in case it is already present) hresult = SCardForgetCardType(hcontext, znewcardName) print('Introducing card ' + znewcardName) hresult = SCardIntroduceCardType( hcontext, znewcardName, znewcardPrimGuid, znewcardPrimGuid + znewcardSecGuid, znewcardATR, znewcardMask) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to introduce card type: ' + SCardGetErrorMessage(hresult)) # list card interfaces hresult, interfaces = SCardListInterfaces(hcontext, znewcardName) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list interfaces: ' + SCardGetErrorMessage(hresult)) for i in interfaces: print('Interface for ' + znewcardName + ' :', smartcard.guid.GUIDToStr(i)) print('Forgeting card ' + znewcardName) hresult = SCardForgetCardType(hcontext, znewcardName) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to remove card type: ' + SCardGetErrorMessage(hresult)) finally: hresult2 = SCardReleaseContext(hcontext) if hresult2 != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') main() elif 'pcsclite' == resourceManager: print('SCardListInterfaces not supported by pcsc lite') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399518.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_locateCards.py0000755000175000017500000001161400000000000025225 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: Locate cards in the system __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * import sys if 'winscard' == resourceManager: znewcardName = 'dummy-card' znewcardATR = [0x3B, 0x77, 0x94, 0x00, 0x00, 0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22] znewcardMask = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise scard.error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise scard.error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) # introduce a card (forget first in case it is already present) hresult = SCardForgetCardType(hcontext, znewcardName) print('Introducing card ' + znewcardName) hresult = SCardIntroduceCardType(hcontext, znewcardName, [], [], znewcardATR, znewcardMask) if hresult != SCARD_S_SUCCESS: if hresult == ERROR_ALREADY_EXISTS: print('Card already exists') else: raise error( 'Failed to introduce card type: ' + SCardGetErrorMessage(hresult)) hresult, cards = SCardListCards(hcontext, [], []) if hresult != SCARD_S_SUCCESS: raise error('Failure to list cards') print('Cards:', cards) readerstates = [] for i in range(len(readers)): readerstates += [(readers[i], SCARD_STATE_UNAWARE)] print(readerstates) hresult, newstates = SCardLocateCards( hcontext, cards, readerstates) for i in newstates: reader, eventstate, atr = i print(reader, end=' ') for b in atr: print("0x%.2X" % b, end=' ') print("") if eventstate & SCARD_STATE_ATRMATCH: print('Card found') if eventstate & SCARD_STATE_UNAWARE: print('State unware') if eventstate & SCARD_STATE_IGNORE: print('Ignore reader') if eventstate & SCARD_STATE_UNAVAILABLE: print('Reader unavailable') if eventstate & SCARD_STATE_EMPTY: print('Reader empty') if eventstate & SCARD_STATE_PRESENT: print('Card present in reader') if eventstate & SCARD_STATE_EXCLUSIVE: print('Card allocated for exclusive use') if eventstate & SCARD_STATE_INUSE: print('Card in use but can be shared') if eventstate & SCARD_STATE_MUTE: print('Card is mute') if eventstate & SCARD_STATE_CHANGED: print('State changed') if eventstate & SCARD_STATE_UNKNOWN: print('State unknowned') finally: hresult = SCardForgetCardType(hcontext, znewcardName) hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') except error as e: print(e) elif 'pcsclite' == resourceManager: print('SCardLocateCards not supported by pcsc lite') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399520.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_pinpad.py0000755000175000017500000001231500000000000024253 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: send a Control Code to a card or reader __author__ = "Ludovic Rousseau" Copyright 2009-2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * from smartcard.util import toASCIIBytes from smartcard.pcsc.PCSCExceptions import * import sys def can_do_verify_pin(hCard): FEATURE_VERIFY_PIN_DIRECT = 6 return parse_get_feature_request(hCard, FEATURE_VERIFY_PIN_DIRECT) def can_do_modify_pin(hCard): FEATURE_MODIFY_PIN_DIRECT = 7 return parse_get_feature_request(hCard, FEATURE_MODIFY_PIN_DIRECT) def parse_get_feature_request(hCard, feature): # check the reader can do a verify pin CM_IOCTL_GET_FEATURE_REQUEST = SCARD_CTL_CODE(3400) hresult, response = SCardControl(hcard, CM_IOCTL_GET_FEATURE_REQUEST, []) if hresult != SCARD_S_SUCCESS: raise BaseSCardException(hresult) print(response) while len(response) > 0: tag = response[0] if feature == tag: return (((((response[2] << 8) + response[3]) << 8) + response[4]) << 8) + response[5] response = response[6:] def verifypin(hCard, control=None): if control is None: control = can_do_verify_pin(hCard) if control is None: raise Exception("Not a pinpad") command = [0x00, # bTimerOut 0x00, # bTimerOut2 0x82, # bmFormatString 0x04, # bmPINBlockString 0x00, # bmPINLengthFormat 0x08, 0x04, # wPINMaxExtraDigit 0x02, # bEntryValidationCondition 0x01, # bNumberMessage 0x04, 0x09, # wLangId 0x00, # bMsgIndex 0x00, 0x00, 0x00, # bTeoPrologue 13, 0, 0, 0, # ulDataLength 0x00, 0x20, 0x00, 0x00, 0x08, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30] # abData hresult, response = SCardControl(hcard, control, command) if hresult != SCARD_S_SUCCESS: raise BaseSCardException(hresult) return hresult, response try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise EstablishContextException(hresult) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise ListReadersException(hresult) print('PCSC Readers:', readers) if len(readers) < 1: raise Exception("No smart card readers") for zreader in readers: print('Trying to Control reader:', zreader) try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if hresult != SCARD_S_SUCCESS: raise BaseSCardException(hresult) print('Connected with active protocol', dwActiveProtocol) try: SELECT = [0x00, 0xA4, 0x04, 0x00, 0x06, 0xA0, 0x00, 0x00, 0x00, 0x18, 0xFF] hresult, response = SCardTransmit( hcard, dwActiveProtocol, SELECT) if hresult != SCARD_S_SUCCESS: raise BaseSCardException(hresult) cmd_verify = can_do_verify_pin(hcard) if (cmd_verify): print("can do verify pin: 0x%08X" % cmd_verify) cmd_modify = can_do_modify_pin(hcard) if (cmd_modify): print("can do modify pin: 0x%08X" % cmd_modify) hresult, response = verifypin(hcard, cmd_verify) print('Control:', response) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: raise BaseSCardException(hresult) print('Disconnected') except error as message: print(error, message) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise ReleaseContextException(hresult) print('Released context.') except error as e: print(e) if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399522.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_readerGroups.py0000755000175000017500000001354400000000000025447 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: illustrate reader groups functions __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * newgroup = 'MyReaderGroup' try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers in all groups:', readers) hresult, readerGroups = SCardListReaderGroups(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to list reader groups: ' + SCardGetErrorMessage(hresult)) print('PCSC Reader groups:', readerGroups) if 'winscard' == resourceManager: hresult = SCardIntroduceReaderGroup(hcontext, newgroup) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to introduce reader group: ' + SCardGetErrorMessage(hresult)) dummyreader = readers[0] + ' dummy' hresult = SCardIntroduceReader(hcontext, dummyreader, readers[0]) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to introduce reader: ' + dummyreader + ' : ' + SCardGetErrorMessage(hresult)) hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers in all groups:', readers) hresult = SCardAddReaderToGroup(hcontext, dummyreader, newgroup) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to add reader to group: ' + SCardGetErrorMessage(hresult)) hresult, readerGroups = SCardListReaderGroups(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to list reader groups: ' + SCardGetErrorMessage(hresult)) print('PCSC Reader groups:', readerGroups) hresult, readers = SCardListReaders(hcontext, [newgroup]) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers in group ' + newgroup + ' : ' + SCardGetErrorMessage(hresult)) print('PCSC Readers in reader group', newgroup, ':', readers) hresult = SCardRemoveReaderFromGroup( hcontext, dummyreader, newgroup) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to remove reader from group: ' + SCardGetErrorMessage(hresult)) hresult, readerGroups = SCardListReaderGroups(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to list reader groups: ' + SCardGetErrorMessage(hresult)) print('PCSC Reader groups:', readerGroups) hresult = SCardForgetReaderGroup(hcontext, newgroup) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to forget reader group: ' + SCardGetErrorMessage(hresult)) hresult = SCardForgetReader(hcontext, dummyreader) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to forget readers ' + SCardGetErrorMessage(hresult)) hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers in all groups:', readers) elif 'pcsclite' == resourceManager: hresult, readers = SCardListReaders(hcontext, readerGroups) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers in groups ' + repr(readerGroups) + ' : ' + SCardGetErrorMessage(hresult)) print('PCSC Readers in reader group', readerGroups, ':', readers) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) except error as e: print(e) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399524.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_readers.py0000755000175000017500000000432000000000000024422 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: List PCSC readers __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) hresult, readerGroups = SCardListReaderGroups(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to list reader groups: ' + SCardGetErrorMessage(hresult)) print('PCSC Reader groups:', readerGroups) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) except error as e: print(e) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399526.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_selectDFTelecom.py0000755000175000017500000001025400000000000026002 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: Select DF_TELECOM on a SIM card __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * import smartcard.util import sys SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] GET_RESPONSE = [0xA0, 0xC0, 0x00, 0x00] try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context : ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) if len(readers) < 1: raise error('No smart card readers') for zreader in readers: print('Trying to select DF_TELECOM of card in', zreader) try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to connect: ' + SCardGetErrorMessage(hresult)) print('Connected with active protocol', dwActiveProtocol) try: hresult, response = SCardTransmit( hcard, dwActiveProtocol, SELECT + DF_TELECOM) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to transmit: ' + SCardGetErrorMessage(hresult)) print('Selected DF_TELECOM: ' + smartcard.util.toHexString( response, smartcard.util.HEX)) hresult, response = SCardTransmit( hcard, dwActiveProtocol, GET_RESPONSE + [response[1]]) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to transmit: ' + SCardGetErrorMessage(hresult)) print('GET_RESPONSE after SELECT DF_TELECOM: ' + smartcard.util.toHexString( response, smartcard.util.HEX)) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to disconnect: ' + SCardGetErrorMessage(hresult)) print('Disconnected') except error as message: print(error, message) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') except error as e: print(e) if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399530.0 pyscard-2.0.2/smartcard/Examples/scard-api/sample_transaction.py0000755000175000017500000001015200000000000025322 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample for python PCSC wrapper module: perform a simple transaction __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * try: hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to establish context: ' + SCardGetErrorMessage(hresult)) print('Context established!') try: hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error( 'Failed to list readers: ' + SCardGetErrorMessage(hresult)) print('PCSC Readers:', readers) if len(readers) < 1: raise error('No smart card readers') for zreader in readers: print('Trying to perform transaction on card in', zreader) try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if hresult != SCARD_S_SUCCESS: raise error( 'unable to connect: ' + SCardGetErrorMessage(hresult)) print('Connected with active protocol', dwActiveProtocol) try: hresult = SCardBeginTransaction(hcard) if hresult != SCARD_S_SUCCESS: raise error( 'failed to begin transaction: ' + SCardGetErrorMessage(hresult)) print('Beginning transaction') hresult, reader, state, protocol, atr = SCardStatus(hcard) if hresult != SCARD_S_SUCCESS: raise error( 'failed to get status: ' + SCardGetErrorMessage(hresult)) print('ATR:', end=' ') for i in range(len(atr)): print("0x%.2X" % atr[i], end=' ') print("") finally: hresult = SCardEndTransaction(hcard, SCARD_LEAVE_CARD) if hresult != SCARD_S_SUCCESS: raise error( 'failed to end transaction: ' + SCardGetErrorMessage(hresult)) print('Transaction ended') hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: raise error( 'failed to disconnect: ' + SCardGetErrorMessage(hresult)) print('Disconnected') except error as message: print(error, message) finally: hresult = SCardReleaseContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error( 'failed to release context: ' + SCardGetErrorMessage(hresult)) print('Released context.') except error as e: print(e) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/simple/0000755000175000017500000000000000000000000020506 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399536.0 pyscard-2.0.2/smartcard/Examples/simple/getATR.py0000755000175000017500000000272100000000000022213 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that displays the ATR of inserted cards. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.Exceptions import NoCardException from smartcard.System import readers from smartcard.util import toHexString import sys for reader in readers(): try: connection = reader.createConnection() connection.connect() print(reader, toHexString(connection.getATR())) except NoCardException: print(reader, 'no card inserted') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399533.0 pyscard-2.0.2/smartcard/Examples/simple/getATR_context.py0000755000175000017500000000313400000000000023756 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that displays the ATR of inserted cards. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.Exceptions import NoCardException from smartcard.System import readers from smartcard.util import toHexString import sys # Use a connection context # the connection object is automatically destroyed at the end of with block for reader in readers(): with reader.createConnection() as connection: try: connection.connect() print(reader, toHexString(connection.getATR())) except NoCardException: print(reader, 'no card inserted') # sleep(5) if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399538.0 pyscard-2.0.2/smartcard/Examples/simple/selectDF_TELECOM.py0000755000175000017500000000447600000000000023737 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script that tries to select the DF_TELECOM on all inserted cards. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Copyright 2010 Ludovic Rousseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.Exceptions import CardRequestTimeoutException import sys # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] # request any card type cardtype = AnyCardType() try: # request card insertion print('insert a card (SIM card if possible) within 10s') cardrequest = CardRequest(timeout=10, cardType=cardtype) cardservice = cardrequest.waitforcard() # attach the console tracer observer = ConsoleCardConnectionObserver() cardservice.connection.addObserver(observer) # connect to the card and perform a few transmits cardservice.connection.connect() apdu = SELECT + DF_TELECOM response, sw1, sw2 = cardservice.connection.transmit(apdu) # there is a DF_TELECOM if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = cardservice.connection.transmit(apdu) else: print('no DF_TELECOM') except CardRequestTimeoutException: print('time-out: no card inserted during last 10s') if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399540.0 pyscard-2.0.2/smartcard/Examples/simple/simpleAPDU.py0000755000175000017500000000314600000000000023032 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Sample script to send 2 APDU __author__ = "Ludovic Rousseau" Copyright 2009 Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import sys from smartcard.System import readers # define the APDUs used in this script SELECT_APPLET = [0x00, 0xA4, 0x04, 0x00, 0x06, 0xA0, 0x00, 0x00, 0x00, 0x18, 0xFF] GET_TIME = [0x80, 0x38, 0x00, 0xA0] if __name__ == '__main__': # get all the available readers r = readers() print("Available readers: ", r) # by default we use the first reader i = 0 if len(sys.argv) > 1: i = int(sys.argv[1]) print("Using: %s" % r[i]) connection = r[i].createConnection() connection.connect() data, sw1, sw2 = connection.transmit(SELECT_APPLET) print("Select Applet: %02X %02X" % (sw1, sw2)) data, sw1, sw2 = connection.transmit(GET_TIME) print("Get Time: %02X %02X" % (sw1, sw2)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1069946 pyscard-2.0.2/smartcard/Examples/wx/0000755000175000017500000000000000000000000017653 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/apdumanager/0000755000175000017500000000000000000000000022137 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623944157.0 pyscard-2.0.2/smartcard/Examples/wx/apdumanager/SampleAPDUManagerPanel.py0000755000175000017500000002142100000000000026662 0ustar00rousseaurousseau#! /usr/bin/env python3 # -*- coding: iso-8859-15 -*- """ Simple panel that defines a dialog to send APDUs to a card. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import wx from smartcard.wx.APDUHexValidator import APDUHexValidator from smartcard.wx.SimpleSCardAppEventObserver import \ SimpleSCardAppEventObserver from smartcard.util import toBytes, toHexString [ID_TEXT_COMMAND, ID_TEXTCTRL_COMMAND, ID_TEXT_RESPONSE, ID_TEXTCTRL_RESPONSE, ID_TEXT_SW, ID_TEXT_SW1, ID_TEXTCTRL_SW1, ID_TEXT_SW2, ID_TEXTCTRL_SW2, ID_CARDSTATE, ID_TRANSMIT] = [wx.NewId() for x in range(11)] class SampleAPDUManagerPanel(wx.Panel, SimpleSCardAppEventObserver): '''A simple panel that displays activated cards and readers and can send APDU to a connected card.''' def __init__(self, parent): wx.Panel.__init__(self, parent, -1) SimpleSCardAppEventObserver.__init__(self) self.layoutControls() self.Bind(wx.EVT_BUTTON, self.OnTransmit, self.transmitbutton) # callbacks from SimpleSCardAppEventObserver interface def OnActivateCard(self, card): """Called when a card is activated by double-clicking on the card or reader tree control or toolbar. In this sample, we just connect to the card on the first activation.""" SimpleSCardAppEventObserver.OnActivateCard(self, card) self.feedbacktext.SetLabel('Activated card: ' + repr(card)) self.transmitbutton.Enable() def OnActivateReader(self, reader): """Called when a reader is activated by double-clicking on the reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnActivateReader(self, reader) self.feedbacktext.SetLabel('Activated reader: ' + repr(reader)) self.transmitbutton.Disable() def OnDeactivateCard(self, card): """Called when a card is deactivated in the reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnActivateCard(self, card) self.feedbacktext.SetLabel('Deactivated card: ' + repr(card)) self.transmitbutton.Disable() def OnDeselectCard(self, card): """Called when a card is selected by clicking on the card or reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnSelectCard(self, card) self.feedbacktext.SetLabel('Deselected card: ' + repr(card)) self.transmitbutton.Disable() def OnSelectCard(self, card): """Called when a card is selected by clicking on the card or reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnSelectCard(self, card) self.feedbacktext.SetLabel('Selected card: ' + repr(card)) if hasattr(self.selectedcard, 'connection'): self.transmitbutton.Enable() def OnSelectReader(self, reader): """Called when a reader is selected by clicking on the reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnSelectReader(self, reader) self.feedbacktext.SetLabel('Selected reader: ' + repr(reader)) self.transmitbutton.Disable() # callbacks def OnTransmit(self, event): if hasattr(self.selectedcard, 'connection'): apdu = self.commandtextctrl.GetValue() if type(u'') == type(apdu): apdu = apdu.encode('utf8') data, sw1, sw2 = \ self.selectedcard.connection.transmit(toBytes(apdu)) self.SW1textctrl.SetValue("%x" % sw1) self.SW2textctrl.SetValue("%x" % sw2) self.responsetextctrl.SetValue(toHexString(data + [sw1, sw2])) event.Skip() def layoutControls(self): # create controls statictextCommand = wx.StaticText( self, ID_TEXT_COMMAND, "Command", wx.DefaultPosition, wx.DefaultSize, 0) self.commandtextctrl = wx.TextCtrl( self, ID_TEXTCTRL_COMMAND, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE, validator=APDUHexValidator()) statictextResponse = wx.StaticText( self, ID_TEXT_RESPONSE, "Response", wx.DefaultPosition, wx.DefaultSize, 0) self.responsetextctrl = wx.TextCtrl( self, ID_TEXTCTRL_RESPONSE, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY) statictextStatusWords = wx.StaticText( self, ID_TEXT_SW, "Status Words", wx.DefaultPosition, wx.DefaultSize, 0) statictextSW1 = wx.StaticText( self, ID_TEXT_SW1, "SW1", wx.DefaultPosition, wx.DefaultSize, 0) self.SW1textctrl = wx.TextCtrl( self, ID_TEXTCTRL_SW1, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_READONLY) statictextSW2 = wx.StaticText( self, ID_TEXT_SW2, "SW2", wx.DefaultPosition, wx.DefaultSize, 0) self.SW2textctrl = wx.TextCtrl( self, ID_TEXTCTRL_SW2, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_READONLY) self.feedbacktext = wx.StaticText( self, ID_CARDSTATE, "", wx.DefaultPosition, wx.DefaultSize, 0) # layout controls boxsizerCommand = wx.BoxSizer(wx.HORIZONTAL) boxsizerCommand.Add(statictextCommand, 1, wx.ALIGN_CENTER | wx.ALL, 5) boxsizerCommand.Add(self.commandtextctrl, 5, wx.EXPAND | wx.ALL, 5) boxsizerResponse = wx.BoxSizer(wx.HORIZONTAL) boxsizerResponse.Add( statictextResponse, 1, wx.ALIGN_CENTER | wx.ALL, 5) boxsizerResponse.Add(self.responsetextctrl, 5, wx.EXPAND | wx.ALL, 5) boxsizerSW = wx.BoxSizer(wx.HORIZONTAL) boxsizerSW.Add(statictextSW1, 0, wx.ALIGN_CENTER | wx.ALL, 5) boxsizerSW.Add(self.SW1textctrl, 0, wx.EXPAND | wx.ALL, 5) boxsizerSW.Add(statictextSW2, 0, wx.ALIGN_CENTER | wx.ALL, 5) boxsizerSW.Add(self.SW2textctrl, 0, wx.EXPAND | wx.ALL, 5) item11 = wx.BoxSizer(wx.HORIZONTAL) item11.Add(statictextStatusWords, 0, wx.ALIGN_CENTER | wx.ALL, 5) item11.Add(boxsizerSW, 0, wx.EXPAND | wx.ALL, 5) boxsizerResponseAndSW = wx.BoxSizer(wx.VERTICAL) boxsizerResponseAndSW.Add(boxsizerResponse, 0, wx.EXPAND | wx.ALL, 5) boxsizerResponseAndSW.Add(item11, 0, wx.EXPAND | wx.ALL, 5) staticboxAPDU = wx.StaticBox(self, -1, "APDU") boxsizerAPDU = wx.StaticBoxSizer(staticboxAPDU, wx.VERTICAL) boxsizerAPDU.Add(boxsizerCommand, 1, wx.EXPAND | wx.ALL, 5) boxsizerAPDU.Add(boxsizerResponseAndSW, 4, wx.EXPAND | wx.ALL, 5) staticboxEvents = wx.StaticBox(self, -1, "Card/Reader Events") boxsizerEvents = wx.StaticBoxSizer(staticboxEvents, wx.HORIZONTAL) boxsizerEvents.Add(self.feedbacktext, 0, wx.ALIGN_CENTER | wx.ALL, 5) sizerboxTransmitButton = wx.BoxSizer(wx.HORIZONTAL) sizerboxTransmitButton.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) self.transmitbutton = wx.Button( self, ID_TRANSMIT, "Transmit", wx.DefaultPosition, wx.DefaultSize, 0) self.transmitbutton.Disable() sizerboxTransmitButton.Add( self.transmitbutton, 0, wx.ALIGN_CENTER | wx.ALL, 5) sizerboxTransmitButton.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizerPanel = wx.BoxSizer(wx.VERTICAL) sizerPanel.Add(boxsizerAPDU, 3, wx.EXPAND | wx.ALL, 5) sizerPanel.Add(boxsizerEvents, 1, wx.EXPAND | wx.ALL, 5) sizerPanel.Add(sizerboxTransmitButton, 1, wx.EXPAND | wx.ALL, 5) self.SetSizer(sizerPanel) self.SetAutoLayout(True) sizerPanel.Fit(self) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398750.0 pyscard-2.0.2/smartcard/Examples/wx/apdumanager/apdumanager.py0000755000175000017500000000372100000000000025003 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Simple application to send APDUs to a card. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import os import sys import os.path from smartcard.wx.SimpleSCardApp import * from SampleAPDUManagerPanel import SampleAPDUManagerPanel def we_are_frozen(): """Returns whether we are frozen via py2exe. This will affect how we find out where we are located. From WhereAmI page on py2exe wiki.""" return hasattr(sys, "frozen") def module_path(): """ This will get us the program's directory, even if we are frozen using py2exe. From WhereAmI page on py2exe wiki.""" if we_are_frozen(): return os.path.dirname( unicode(sys.executable, sys.getfilesystemencoding())) return os.path.dirname(unicode(__file__, sys.getfilesystemencoding())) def main(argv): app = SimpleSCardApp( appname='A tool to send apdu to a card', apppanel=SampleAPDUManagerPanel, appstyle=TR_SMARTCARD | TR_READER | PANEL_APDUTRACER, appicon=os.path.join(module_path(), 'images', 'mysmartcard.ico'), size=(800, 600)) app.MainLoop() if __name__ == "__main__": import sys main(sys.argv) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/apdumanager/images/0000755000175000017500000000000000000000000023404 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/Examples/wx/apdumanager/images/mysmartcard.ico0000644000175000017500000000047600000000000026435 0ustar00rousseaurousseau(( 333s333{wwwwwws{s{swwwwsw{ww{w{swwwws{s{sww{wwws{{././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398754.0 pyscard-2.0.2/smartcard/Examples/wx/apdumanager/setup.py0000644000175000017500000000254700000000000023661 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Setup script to build a standalone apdumanager.exe executable on windows using py2exe. Run: python.exe setup.py py2exe, to build executable file. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from distutils.core import setup import py2exe from smartcard.wx import ICO_SMARTCARD, ICO_READER Mydata_files = [('images', ['images/mysmartcard.ico', ICO_SMARTCARD, ICO_READER])] setup(windows=['apdumanager.py'], data_files=Mydata_files, options={"py2exe": {"dll_excludes": ["MSVCP90.dll"]}} ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/cardmonitor/0000755000175000017500000000000000000000000022174 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398756.0 pyscard-2.0.2/smartcard/Examples/wx/cardmonitor/cardmonitor.py0000755000175000017500000001116300000000000025074 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Simple smart card monitoring application. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import os.path import sys from smartcard.wx.SimpleSCardApp import * from smartcard.wx.SimpleSCardAppEventObserver import \ SimpleSCardAppEventObserver ID_TEXT = 10000 def we_are_frozen(): """Returns whether we are frozen via py2exe. This will affect how we find out where we are located. From WhereAmI page on py2exe wiki.""" return hasattr(sys, "frozen") def module_path(): """ This will get us the program's directory, even if we are frozen using py2exe. From WhereAmI page on py2exe wiki.""" if we_are_frozen(): return os.path.dirname( unicode(sys.executable, sys.getfilesystemencoding())) return os.path.dirname(unicode(__file__, sys.getfilesystemencoding())) class SamplePanel(wx.Panel, SimpleSCardAppEventObserver): '''A simple panel that displays activated cards and readers. The panel implements the SimpleSCardAppEventObserver, and has a chance to react on reader and card activation/deactivation.''' def __init__(self, parent): wx.Panel.__init__(self, parent, -1) sizer = wx.FlexGridSizer(0, 3, 0, 0) sizer.AddGrowableCol(1) sizer.AddGrowableRow(1) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) self.feedbacktext = wx.StaticText( self, ID_TEXT, "", wx.DefaultPosition, wx.DefaultSize, 0) sizer.Add(self.feedbacktext, 0, wx.ALIGN_LEFT | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) sizer.Add([20, 20], 0, wx.ALIGN_CENTER | wx.ALL, 5) self.SetSizer(sizer) self.SetAutoLayout(True) # callbacks from SimpleSCardAppEventObserver interface def OnActivateCard(self, card): """Called when a card is activated by double-clicking on the card or reader tree control or toolbar. In this sample, we just connect to the card on the first activation.""" SimpleSCardAppEventObserver.OnActivateCard(self, card) self.feedbacktext.SetLabel('Activated card: ' + repr(card)) def OnActivateReader(self, reader): """Called when a reader is activated by double-clicking on the reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnActivateReader(self, reader) self.feedbacktext.SetLabel('Activated reader: ' + repr(reader)) def OnDeactivateCard(self, card): """Called when a card is deactivated in the reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnActivateCard(self, card) self.feedbacktext.SetLabel('Deactivated card: ' + repr(card)) def OnSelectCard(self, card): """Called when a card is selected by clicking on the card or reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnSelectCard(self, card) self.feedbacktext.SetLabel('Selected card: ' + repr(card)) def OnSelectReader(self, reader): """Called when a reader is selected by clicking on the reader tree control or toolbar.""" SimpleSCardAppEventObserver.OnSelectReader(self, reader) self.feedbacktext.SetLabel('Selected reader: ' + repr(reader)) def main(argv): app = SimpleSCardApp( appname='A simple card monitoring tool', apppanel=SamplePanel, appstyle=TR_SMARTCARD | TR_READER, appicon=os.path.join( module_path(), 'images', 'mysmartcard.ico'), size=(800, 600)) app.MainLoop() if __name__ == "__main__": import sys main(sys.argv) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/cardmonitor/images/0000755000175000017500000000000000000000000023441 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/Examples/wx/cardmonitor/images/mysmartcard.ico0000644000175000017500000000047600000000000026472 0ustar00rousseaurousseau(( 333s333{wwwwwws{s{swwwwsw{ww{w{swwwws{s{sww{wwws{{././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398758.0 pyscard-2.0.2/smartcard/Examples/wx/cardmonitor/setup.py0000644000175000017500000000253400000000000023712 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Setup script to build a standalone cardmonitor.exe executable on windows using py2exe. Run: python.exe setup.py py2exe, to build executable file. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from distutils.core import setup import py2exe from smartcard.wx import ICO_SMARTCARD, ICO_READER Mydata_files = [('images', ['images/mysmartcard.ico', ICO_SMARTCARD, ICO_READER])] setup(windows=['cardmonitor.py'], data_files=Mydata_files, options={"py2exe": {"dll_excludes": ["MSVCP90.dll"]}} ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/pcscdiag/0000755000175000017500000000000000000000000021430 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399569.0 pyscard-2.0.2/smartcard/Examples/wx/pcscdiag/pcscdiag.py0000755000175000017500000000742000000000000023565 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Example wxPython application that displays readers and inserted cards ATRs. This example displays a snapshot of the readers and cards, there is no automatic refresh of the readers and cards. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import smartcard.Exceptions import smartcard.System import smartcard.util # wxPython GUI modules (http://www.wxpython.org) try: import wx except ImportError: print('You need wxpython (http://www.wxpython.org) ' + \ 'to run this sample from the source code!') print('press a key to continue') import msvcrt msvcrt.getch() import sys sys.exit() def getATR(reader): """Return the ATR of the card inserted into the reader.""" connection = reader.createConnection() atr = "" try: connection.connect() atr = smartcard.util.toHexString(connection.getATR()) connection.disconnect() except smartcard.Exceptions.NoCardException: atr = "no card inserted" return atr class pcscdiag(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size=(600, 400)) w, h = self.GetClientSizeTuple() self.tree = wx.TreeCtrl( self, wx.NewId(), wx.DefaultPosition, (w, h), wx.TR_HAS_BUTTONS | wx.TR_EDIT_LABELS) self.InitTree() self.OnExpandAll() def InitTree(self): self.tree.AddRoot("Readers and ReaderGroups") readerNode = self.tree.AppendItem(self.tree.GetRootItem(), "Readers") for reader in smartcard.System.readers(): childReader = self.tree.AppendItem(readerNode, repr(reader)) childCard = self.tree.AppendItem(childReader, getATR(reader)) readerGroupNode = self.tree.AppendItem( self.tree.GetRootItem(), "Readers Groups") for readergroup in smartcard.System.readergroups(): childReaderGroup = self.tree.AppendItem( readerGroupNode, readergroup) readers = smartcard.System.readers(readergroup) for reader in readers: child = self.tree.AppendItem(childReaderGroup, repr(reader)) def OnExpandAll(self): """ expand all nodes """ root = self.tree.GetRootItem() fn = self.tree.Expand self.traverse(root, fn) self.tree.Expand(root) def traverse(self, traverseroot, function, cookie=0): """ recursivly walk tree control """ if self.tree.ItemHasChildren(traverseroot): firstchild, cookie = self.tree.GetFirstChild(traverseroot) function(firstchild) self.traverse(firstchild, function, cookie) child = self.tree.GetNextSibling(traverseroot) if child: function(child) self.traverse(child, function, cookie) if __name__ == '__main__': app = wx.PySimpleApp() frame = pcscdiag(None, "Smartcard readers and reader groups") frame.Show() app.MainLoop() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/readerviewer/0000755000175000017500000000000000000000000022337 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/Examples/wx/readerviewer/images/0000755000175000017500000000000000000000000023604 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/Examples/wx/readerviewer/images/readerviewer.ico0000644000175000017500000000047600000000000026773 0ustar00rousseaurousseau(( `ff`p38`x p`xppxxppxpxxxxpxpxp @?././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398762.0 pyscard-2.0.2/smartcard/Examples/wx/readerviewer/readerviewer.py0000755000175000017500000000353700000000000025410 0ustar00rousseaurousseau#! /usr/bin/env python3 """Simple smart card reader monitoring application. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import os.path import sys from smartcard.wx.SimpleSCardApp import * def we_are_frozen(): """Returns whether we are frozen via py2exe. This will affect how we find out where we are located. From WhereAmI page on py2exe wiki.""" return hasattr(sys, "frozen") def module_path(): """ This will get us the program's directory, even if we are frozen using py2exe. From WhereAmI page on py2exe wiki.""" if we_are_frozen(): return os.path.dirname( unicode(sys.executable, sys.getfilesystemencoding())) return os.path.dirname(unicode(__file__, sys.getfilesystemencoding())) def main(argv): app = SimpleSCardApp( appname='A simple reader monitoring tool', apppanel=None, appstyle=TR_READER, appicon=os.path.join(module_path(), 'images', 'readerviewer.ico'), size=(800, 600)) app.MainLoop() if __name__ == "__main__": import sys main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398763.0 pyscard-2.0.2/smartcard/Examples/wx/readerviewer/setup.py0000644000175000017500000000253600000000000024057 0ustar00rousseaurousseau#! /usr/bin/env python3 """ Setup script to build a standalone readerviewer.exe executable on windows using py2exe. Run: python.exe setup.py py2exe, to build executable file. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from distutils.core import setup import py2exe from smartcard.wx import ICO_SMARTCARD, ICO_READER Mydata_files = [('images', ['images/readerviewer.ico', ICO_SMARTCARD, ICO_READER])] setup(windows=['readerviewer.py'], data_files=Mydata_files, options={"py2exe": {"dll_excludes": ["MSVCP90.dll"]}} ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/smartcard/Exceptions.py0000644000175000017500000000703500000000000020137 0ustar00rousseaurousseau"""Smartcard module exceptions. This module defines the exceptions raised by the smartcard module. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import SCardGetErrorMessage class SmartcardException(Exception): """Base class for smartcard exceptions. smartcard exceptions are generated by the smartcard module and shield scard (i.e. PCSC) exceptions raised by the scard module. """ def __init__(self, message="", hresult=-1, *args): super(SmartcardException, self).__init__(message, *args) self.hresult = int(hresult) def __str__(self): text = super(SmartcardException, self).__str__() if self.hresult != -1: hresult = self.hresult if hresult < 0: # convert 0x-7FEFFFE3 into 0x8010001D hresult += 0x100000000 text += ": %s (0x%08X)" % (SCardGetErrorMessage(self.hresult), hresult) return text class CardConnectionException(SmartcardException): """Raised when a CardConnection class method fails.""" pass class CardRequestException(SmartcardException): """Raised when a CardRequest wait fails.""" pass class CardRequestTimeoutException(SmartcardException): """Raised when a CardRequest times out.""" def __init__(self, *args): SmartcardException.__init__(self, "Time-out during card request", *args) class CardServiceException(SmartcardException): """Raised when a CardService class method fails.""" pass class CardServiceStoppedException(SmartcardException): """Raised when the CardService was stopped""" pass class InvalidATRMaskLengthException(SmartcardException): """Raised when an ATR mask does not match an ATR length.""" def __init__(self, mask): SmartcardException.__init__(self, 'Invalid ATR mask length: %s' %mask) class InvalidReaderException(SmartcardException): """Raised when trying to acces an invalid smartcard reader.""" def __init__(self, readername): SmartcardException.__init__(self, 'Invalid reader: %s' % readername) class ListReadersException(SmartcardException): """Raised when smartcard readers cannot be listed.""" def __init__(self, hresult): SmartcardException.__init__(self, 'Failed to list readers', hresult=hresult) class NoCardException(SmartcardException): """Raised when no card in is present in reader.""" def __init__(self, message, hresult): SmartcardException.__init__(self, message, hresult=hresult) class NoReadersException(SmartcardException): """Raised when the system has no smartcard reader.""" def __init__(self, *args): SmartcardException.__init__(self, 'No reader found', *args) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399392.0 pyscard-2.0.2/smartcard/ExclusiveConnectCardConnection.py0000644000175000017500000000616700000000000024116 0ustar00rousseaurousseau"""CardConnectionDecorator that provides exclusive use of a card. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardConnectionDecorator import CardConnectionDecorator from smartcard.Exceptions import CardConnectionException from smartcard.scard import SCardConnect, SCardDisconnect from smartcard.scard import SCARD_LEAVE_CARD, SCARD_SHARE_EXCLUSIVE from smartcard.scard import SCardGetErrorMessage from smartcard.pcsc import PCSCCardConnection import smartcard.pcsc class ExclusiveConnectCardConnection(CardConnectionDecorator): '''This decorator uses exclusive access to the card during connection to prevent other processes to connect to this card.''' def __init__(self, cardconnection): CardConnectionDecorator.__init__(self, cardconnection) def connect(self, protocol=None, mode=None, disposition=None): '''Disconnect and reconnect in exclusive mode PCSCCardconnections.''' CardConnectionDecorator.connect(self, protocol, mode, disposition) component = self.component while True: if isinstance(component, smartcard.pcsc.PCSCCardConnection.PCSCCardConnection): pcscprotocol = PCSCCardConnection.translateprotocolmask( protocol) if 0 == pcscprotocol: pcscprotocol = component.getProtocol() if component.hcard is not None: hresult = SCardDisconnect(component.hcard, SCARD_LEAVE_CARD) if hresult != 0: raise CardConnectionException( 'Failed to disconnect: ' + SCardGetErrorMessage(hresult)) hresult, component.hcard, dwActiveProtocol = SCardConnect( component.hcontext, str(component.reader), SCARD_SHARE_EXCLUSIVE, pcscprotocol) if hresult != 0: raise CardConnectionException( 'Failed to connect with SCARD_SHARE_EXCLUSIVE' + SCardGetErrorMessage(hresult)) # print('reconnected exclusive') break if hasattr(component, 'component'): component = component.component else: break ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399395.0 pyscard-2.0.2/smartcard/ExclusiveTransmitCardConnection.py0000644000175000017500000000664600000000000024330 0ustar00rousseaurousseau"""Sample CardConnectionDecorator that provides exclusive transmit() __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardConnectionDecorator import CardConnectionDecorator from smartcard.Exceptions import CardConnectionException from smartcard.scard import SCardBeginTransaction, SCardEndTransaction from smartcard.scard import SCARD_LEAVE_CARD from smartcard.scard import SCardGetErrorMessage import smartcard.pcsc class ExclusiveTransmitCardConnection(CardConnectionDecorator): '''This decorator uses SCardBeginTransaction/SCardEndTransaction to preserve other processes of threads to access the card during transmit().''' def __init__(self, cardconnection): CardConnectionDecorator.__init__(self, cardconnection) def lock(self): '''Lock card with SCardBeginTransaction.''' component = self.component while True: if isinstance( component, smartcard.pcsc.PCSCCardConnection.PCSCCardConnection): hresult = SCardBeginTransaction(component.hcard) if 0 != hresult: raise CardConnectionException( 'Failed to lock with SCardBeginTransaction: ' + SCardGetErrorMessage(hresult)) else: # print('locked') pass break if hasattr(component, 'component'): component = component.component else: break def unlock(self): '''Unlock card with SCardEndTransaction.''' component = self.component while True: if isinstance( component, smartcard.pcsc.PCSCCardConnection.PCSCCardConnection): hresult = SCardEndTransaction(component.hcard, SCARD_LEAVE_CARD) if 0 != hresult: raise CardConnectionException( 'Failed to unlock with SCardEndTransaction: ' + SCardGetErrorMessage(hresult)) else: # print('unlocked') pass break if hasattr(component, 'component'): component = component.component else: break def transmit(self, bytes, protocol=None): '''Gain exclusive access to card during APDU transmission for if this decorator decorates a PCSCCardConnection.''' data, sw1, sw2 = CardConnectionDecorator.transmit( self, bytes, protocol) return data, sw1, sw2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/Observer.py0000644000175000017500000000417000000000000017602 0ustar00rousseaurousseau""" from Thinking in Python, Bruce Eckel http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Observer.html (c) Copyright 2008, Creative Commons Attribution-Share Alike 3.0. Class support for "observer" pattern. The observer class is the base class for all smartcard package observers. Known subclasses: L{smartcard.ReaderObserver} """ from smartcard.Synchronization import * class Observer(object): def update(observable, arg): '''Called when the observed object is modified. You call an Observable object's notifyObservers method to notify all the object's observers of the change.''' pass class Observable(Synchronization): def __init__(self): self.obs = [] self.changed = 0 Synchronization.__init__(self) def addObserver(self, observer): if observer not in self.obs: self.obs.append(observer) def deleteObserver(self, observer): self.obs.remove(observer) def notifyObservers(self, arg=None): '''If 'changed' indicates that this object has changed, notify all its observers, then call clearChanged(). Each observer has its update() called with two arguments: this observable object and the generic 'arg'.''' self.mutex.acquire() try: if not self.changed: return # Make a local copy in case of synchronous # additions of observers: localArray = self.obs[:] self.clearChanged() finally: self.mutex.release() # Update observers for observer in localArray: observer.update(self, arg) def deleteObservers(self): self.obs = [] def setChanged(self): self.changed = 1 def clearChanged(self): self.changed = 0 def hasChanged(self): return self.changed def countObservers(self): return len(self.obs) synchronize(Observable, "addObserver deleteObserver deleteObservers " + "setChanged clearChanged hasChanged " + "countObservers") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399405.0 pyscard-2.0.2/smartcard/PassThruCardService.py0000644000175000017500000000430100000000000021673 0ustar00rousseaurousseau"""Card service abstract class. A card service is a class providings specific smart card functionality, e.g. a GSM file system or an Open Platform loader. CardService is an abstract class from which concrete card services are derived. A concrete card service is almost always smart card operating system specific __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard import CardService class PassThruCardService(CardService.CardService): """Pass-thru card service class.""" def __init__(self, connection, cardname=None): """Construct a pass-thru card service. connection: the CardConnection used to access the smart card """ CardService.CardService.__init__(self, connection, cardname) def supports(cardname): """Returns True if the cardname is supported by the card service. The PassThruCardService supports all cardnames and always returns True.""" return True supports = staticmethod(supports) if __name__ == '__main__': """Small sample illustrating the use of CardService.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] from smartcard.System import readers cc = readers()[0].createConnection() cs = PassThruCardService(cc) cs.connection.connect() data, sw1, sw2 = cs.connection.transmit(SELECT + DF_TELECOM) print("%X %X" % (sw1, sw2)) cs.connection.disconnect() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399409.0 pyscard-2.0.2/smartcard/ReaderMonitoring.py0000644000175000017500000002041600000000000021264 0ustar00rousseaurousseau"""Smart card reader monitoring classes. ReaderObserver is a base class for objects that are to be notified upon smartcard reader insertion/removal. ReaderMonitor is a singleton object notifying registered ReaderObservers upon reader insertion/removal. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from threading import Thread, Event from time import sleep import traceback import smartcard.System from smartcard.Observer import Observer from smartcard.Observer import Observable from smartcard.Synchronization import * # ReaderObserver interface class ReaderObserver(Observer): """ ReaderObserver is a base abstract class for objects that are to be notified upon smartcard reader insertion/removal. """ def __init__(self): pass def update(self, observable, handlers): """Called upon reader insertion/removal. @param observable: @param handlers: - addedreaders: list of added readers causing notification - removedreaders: list of removed readers causing notification """ pass class ReaderMonitor(Observable): """Class that monitors reader insertion/removal. and notify observers note: a reader monitoring thread will be running as long as the reader monitor has observers, or ReaderMonitor.stop() is called. It implements the shared state design pattern, where objects of the same type all share the same state, in our case essentially the ReaderMonitoring Thread. Thanks to Frank Aune for implementing the shared state pattern logics. """ __shared_state = {} def __init__(self, startOnDemand=True, readerProc=smartcard.System.readers, period=1): self.__dict__ = self.__shared_state Observable.__init__(self) self.startOnDemand = startOnDemand self.readerProc = readerProc self.period = period if self.startOnDemand: self.rmthread = None else: self.rmthread = ReaderMonitoringThread(self, self.readerProc, self.period) self.rmthread.start() def addObserver(self, observer): """Add an observer.""" Observable.addObserver(self, observer) # If self.startOnDemand is True, the reader monitoring # thread only runs when there are observers. if self.startOnDemand: if 0 < self.countObservers(): if not self.rmthread: self.rmthread = ReaderMonitoringThread( self, self.readerProc, self.period) # start reader monitoring thread in another thread to # avoid a deadlock; addObserver and notifyObservers called # in the ReaderMonitoringThread run() method are # synchronized try: # Python 3.x import _thread _thread.start_new_thread(self.rmthread.start, ()) except: # Python 2.x import thread thread.start_new_thread(self.rmthread.start, ()) else: observer.update(self, (self.rmthread.readers, [])) def deleteObserver(self, observer): """Remove an observer.""" Observable.deleteObserver(self, observer) # If self.startOnDemand is True, the reader monitoring # thread is stopped when there are no more observers. if self.startOnDemand: if 0 == self.countObservers(): self.rmthread.stop() del self.rmthread self.rmthread = None def __str__(self): return self.__class__.__name__ synchronize(ReaderMonitor, "addObserver deleteObserver deleteObservers " + "setChanged clearChanged hasChanged " + "countObservers") class ReaderMonitoringThread(Thread): """Reader insertion thread. This thread polls for pcsc reader insertion, since no reader insertion event is available in pcsc. """ __shared_state = {} def __init__(self, observable, readerProc, period): self.__dict__ = self.__shared_state Thread.__init__(self) self.observable = observable self.stopEvent = Event() self.stopEvent.clear() self.readers = [] self.setDaemon(True) self.setName('smartcard.ReaderMonitoringThread') self.readerProc = readerProc self.period = period def run(self): """Runs until stopEvent is notified, and notify observers of all reader insertion/removal. """ while not self.stopEvent.isSet(): try: # no need to monitor if no observers if 0 < self.observable.countObservers(): currentReaders = self.readerProc() addedReaders = [] removedReaders = [] if currentReaders != self.readers: for reader in currentReaders: if reader not in self.readers: addedReaders.append(reader) for reader in self.readers: if reader not in currentReaders: removedReaders.append(reader) if addedReaders or removedReaders: # Notify observers self.readers = [] for r in currentReaders: self.readers.append(r) self.observable.setChanged() self.observable.notifyObservers((addedReaders, removedReaders)) # wait every second on stopEvent self.stopEvent.wait(self.period) except Exception: # FIXME Tighten the exceptions caught by this block traceback.print_exc() # Most likely raised during interpreter shutdown due # to unclean exit which failed to remove all observers. # To solve this, we set the stop event and pass the # exception to let the thread finish gracefully. self.stopEvent.set() def stop(self): self.stopEvent.set() self.join() if __name__ == "__main__": print('insert or remove readers in the next 20 seconds') # a simple reader observer that prints added/removed readers class printobserver(ReaderObserver): def __init__(self, obsindex): self.obsindex = obsindex def update(self, observable, handlers): addedreaders, removedreaders = handlers print("%d - added: " % self.obsindex, addedreaders) print("%d - removed: " % self.obsindex, removedreaders) class testthread(Thread): def __init__(self, obsindex): Thread.__init__(self) self.readermonitor = ReaderMonitor() self.obsindex = obsindex self.observer = None def run(self): # create and register observer self.observer = printobserver(self.obsindex) self.readermonitor.addObserver(self.observer) sleep(20) self.readermonitor.deleteObserver(self.observer) t1 = testthread(1) t2 = testthread(2) t1.start() t2.start() t1.join() t2.join() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399412.0 pyscard-2.0.2/smartcard/Session.py0000644000175000017500000000734600000000000017446 0ustar00rousseaurousseau""" Smartcard Session. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.Exceptions import InvalidReaderException, NoReadersException from smartcard.PassThruCardService import PassThruCardService from smartcard.System import readers class Session(object): """The Session object enables programmers to transmit APDU to smartcards. This is an example of use of the Session object: import smartcard reader=smartcard.listReaders() s = smartcard.Session(reader[0]) SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] data, sw1, sw2 = s.sendCommandAPDU(SELECT+DF_TELECOM) print(data, sw1, sw2) s.close() print(`s`) """ def __init__(self, readerName=None, cardServiceClass=None): """Session constructor. Initializes a smart card session and connect to the card. @param readerName: reader to connect to; default is first PCSC reader @param cardServiceClass: card service to bind the session to; default is None """ # if reader name not given, select first reader if readerName is None: if len(readers()) > 0: self.reader = readers()[0] self.readerName = repr(self.reader) else: raise NoReadersException() # otherwise select reader from name else: self.readerName = readerName for reader in readers(): if readerName == str(reader): self.reader = reader self.readerName = repr(self.reader) try: self.reader except AttributeError: raise InvalidReaderException(self.readerName) # open card connection and bind PassThruCardService cc = self.reader.createConnection() self.cs = PassThruCardService(cc) self.cs.connection.connect() def close(self): """Close the smartcard session. Closing a session will disconnect from the card.""" self.cs.connection.disconnect() def sendCommandAPDU(self, command): """Send an APDU command to the connected smartcard. @param command: list of APDU bytes, e.g. [0xA0, 0xA4, 0x00, 0x00, 0x02] @return: a tuple (response, sw1, sw2) where response is the APDU response sw1, sw2 are the two status words """ response, sw1, sw2 = self.cs.connection.transmit(command) if len(response) > 2: response.append(sw1) response.append(sw2) return response, sw1, sw2 def getATR(self): """Returns the ATR of the connected card.""" return self.cs.connection.getATR() def __repr__(self): """Returns a string representation of the session.""" return "" % self.readerName if __name__ == '__main__': """Small sample illustrating the use of Session.py.""" pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/Synchronization.py0000644000175000017500000000254000000000000021213 0ustar00rousseaurousseau""" from Thinking in Python, Bruce Eckel http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Observer.html (c) Copyright 2008, Creative Commons Attribution-Share Alike 3.0. Simple emulation of Java's 'synchronized' keyword, from Peter Norvig. """ from threading import RLock def synchronized(method): def f(*args): self = args[0] self.mutex.acquire() # print(method.__name__, 'acquired') try: return method(*args) finally: self.mutex.release() # print(method.__name__, 'released') return f def synchronize(klass, names=None): """Synchronize methods in the given class. Only synchronize the methods whose names are given, or all methods if names=None.""" # basestring does not exist on Python 3 try: basestring except NameError: basestring = (str, bytes) if isinstance(names, basestring): names = names.split() for (name, val) in list(klass.__dict__.items()): if callable(val) and name != '__init__' and \ (names is None or name in names): # print("synchronizing", name) setattr(klass, name, synchronized(val)) class Synchronization(object): # You can create your own self.mutex, or inherit from this class: def __init__(self): self.mutex = RLock() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399418.0 pyscard-2.0.2/smartcard/System.py0000644000175000017500000000356200000000000017303 0ustar00rousseaurousseau"""Smartcard system utility functions and classes. Manages smartcard readers and reader groups. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import smartcard.reader.ReaderFactory import smartcard.pcsc.PCSCReaderGroups def readers(groups=[]): """Returns the list of smartcard readers in groups. If group is not specified, returns the list of all smartcard readers. import smartcard r=smartcard.readers() r=smartcard.readers(['SCard$DefaultReaders', 'MyReaderGroup']) """ return smartcard.reader.ReaderFactory.ReaderFactory.readers(groups) def readergroups(): """Returns the list of reader groups.""" return smartcard.pcsc.PCSCReaderGroups.PCSCReaderGroups().instance # for legacy only def listReaders(): """Returns the list of smartcard readers. Deprecated - Use smartcard.System.readers() instead. """ zreaders = [] for reader in readers(): zreaders.append(str(reader)) return zreaders if __name__ == '__main__': print(readers()) print(readers(['SCard$DefaultReaders'])) print(readergroups()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/__init__.py0000644000175000017500000000214300000000000017550 0ustar00rousseaurousseau"""Smartcard utility module. The smartcard utility module provides classes and functions to access smartcards and readers. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ # for legacy only from smartcard.System import listReaders from smartcard.Session import Session __all__ = ['listReaders', 'Session'] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1069946 pyscard-2.0.2/smartcard/doc/0000755000175000017500000000000000000000000016204 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/doc/images/0000755000175000017500000000000000000000000017451 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/doc/images/pyscard.jpg0000644000175000017500000006177500000000000021640 0ustar00rousseaurousseauJFIF``C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( (#o!iUw-Hil`I2YjI'Ԛ__$?kUXB5@K/(/_Bh/B5@K/(/_BhaYߡG!~%E   ? ,Э(_k_Q_ e~nE/_BB5@K/+v,!~%Yߡ[Q`0 ,У  ݢ_ e~k_VX /B5@K/(/_BhaYߡG!~%E   ? ,Э(_k_Q_ e~nE/_BB5@K/+v,/ x~iΎ$Ik bI$ĤxEk'm]!Q"b(QEQEQEQEQEQEQEQE/W/t[赮:ZDTQEY!EPEPEPEPEPEPEPEPEPEPEPEPEPOQֿX:'Ek'm]!Q"X*J ( ( ( ( ( ( ( (#=p*"N`Or'AuZ#j($(((kP_k6|;I LXCl.൷ Fw9' ߑE]EqR|M"z_1: P˞޵@zֹinh1i#ӏz.MEr!Z&o3@n1 H (ɤ|o cu-Swٴo@PsEh65կJ}bINpÎU|Tx{tMP )];vcⵍe.mxDRHt*=kkVWQizI_/dK86K v,zmor/'K q ((QEQEuEtIs)GZ [WAa oTH(((((((((y?ʹȓ:EuǼ\Io֪$ڢ* ( ( 6w.mɧ(HffSr0sx#ҽ"3RZԏdŭ\Fee d#iSدAUTPTt`RҰ\QмVڼefWQE0 (Q@Q@>)GZ [WAa oW?uEtIDb((((((((((:ZQ?{U?D-jL(((((((((((((('?(_?j,?m\ S"^趮A?Q,QE%Q@Q@Q@Q@Q@Q@Q@Q@r'AuZ'y?ʹȓ:ETIEUQEQEQEQEQEQEQEQEQEQEQEQEQEdEk'm]!\QֿX:'*%((((((((( 2+*h.  h*h.  h*h.  h*h.  ku֍m+`y6 }9+yy&4vr4zj1K832:9[E0ƱƊU$&F/ xWC+{m.WKc5خJяx SCt?M]tY2R2k㭽V96~z0A(2_A<B?  k*h.OЩ& (*h.OЩ& (*h.OЩ& (*h.OЩ& (*h.OЩ& (*h.|BHLvۦ[T" BQAn~V'95ce*O%62v_z(Ǔݎgƈ#Xco6$1^͸ 7cvy/ r<#qlwއwpG"*N25j9/_.APyN=x?M4 4?C֎ǩ#Au qn承=AW 9A<B*PԴPEPEPEPEPEPEPEPEPEPEPEPEP\Y..PG8;3%z>A| NO4?EЀQ C khQ`(>xJ- P? m#+. 8 )'AӉ9&>"N5b#Ȍ E2n +u :4KۼIa3I$$W4[Î [Gc)Xyx-sx?M5(TQUz XQE ( ( ( jiv̭,-d5zuOmv#ic Td@,~.*%~)L=X{~ 37K#VU;ht6)4% r%$(5j] h袹L|weZ_Bd@ *}c$G{e*B0u;VF`csOP g 4?C3@ѴV"Hmm"t3mܤhEQEQEQEQEQEQEQEQEQEQEQEQEQEg/j/k;D^"u?@5NXUd[=p*"x{)jiO|"'m&QPPQEQEQEQEQEW/u%k^? G[kVL_P?">>!Y\cĭΦ( ( ( ( ( ( (<߂O.o$e3IbJyl?_z'k0k0oEo_ëao;9Pː:t!_E|_MxO}5E4[R{mV>kg6ƩxM &6塹`ʬFs.I5;B<'B? / k# i67qh]N$;cyoJw|gf& "6hjw{#$9GW_G!_E|_Mr#N[EvRNs3*DHl2W>fjMӴoؘ dGxFh#+/ Я/&|4f 1,I<遃GW_G!_E|_MoQ@?xO}4?_GW_G!_E|_MoW/ikC"ݶ9[U cD? hm#+-@4Oi+&YyaskGZS3{nzm )# @qw.|!?4fy&gcI+'vR.znW/'DtY~ogb>qtɠ xO}4?_Ko } Hid0EH^C I$:бE. c#+/ Я/& B<'B? / kz#+/ Я/& B<'B? / kz#+/ Я/& B<'Baiz?46db Dh_G5(zmgJӵjvt+" ]M`.FGW_G!_E|_MoQ@?xO}4?_GW_G!_E|_MoQ@?xO}4?_GW_G!_E|_MoQ@?xO}5bxsHh'x%daA A]buj 2?I^m=ctP?N2.F8´oQX쮵[4{0D#<ׁW?\Eyu|],lPY; +w sv)kzg/|GS&}a`s(/1E_:@;zZIu# dhAؓYW^E;#Tƭ^!cՕE1¯r1 zg%÷}t6:հ,.VHi$F2ܫ&(\4_j:- !|<@җR-Ʊ^iuu e$ry\^ֻj(\֊冎!jEQE ( iqo/ϓ>3ת$8B0@"GMԅ=ۓ7~G/U KM7f;y~|U! BI } `N#OQSO>FV}[zԓ5E4i%m[ޕI<ɨ9o]f%\;ݍzi=zӴWuPpv5z(Ǔ (AEPEPEPEPEPX2O}.l& _?uǏ}.?kzn~?}m(z(AEPEPEPEPX1_mj۬Oȏ6Eß K[Ճ|9`o_>zEP ((#fvk5OjUWP$y.VPGך'y??ʲ|"N` g2_5G2_5[P2_5G2_5[P2_5G2_5[P2_5ToUw$7[h^Aez/S#:(\s^mOw/@3 ry={gh/( gh/gh/( gh/gh/( gh/gh/(U/a2H@$[W?l۳Ήdۜ ~_[^&@wzEP ({w%?V`.F3zo8OC_̵?`ׅo@QE ( ( ( ( n?[VbxD}-~?U$VAWm%QG>]Zެȃ襭 (Q@Q@d?D-kZ'$?k@ͪ(Wxz.-V3g5儲xHJ>63 R'/|aewdIwH2ߌϮ}|}⹴m}RM6kXmK27yjyw{qRWqk0k[]m2êpA1ҽB(C[^&@wz5j?/h?׬_e(Q@`.F`q+.?hX7<{`m6foQE((((+?# m[u趠g' kTZ]Tޯǒ=G sv)kz|"?mX(QEQEG?{Ut[赭iOȓ:E6jonZG~nPy+Vl=^2Mi:'9< N1uf#,x}k[Y.MV[a(ͼh<> ~γX<0o3?@+*.b:ͤS%-*Oayö"Ȥ&`}oƚP<$qD}-4nY=σ `UI*9V 2>|@_z׈n#DB22 5?]LKf%C#AcFbh5[R/Vp 1ӷu4QL(E o@z4Oi(׬ D^"袊QEw#`i[Ճw#`mhXZz8kvu43NcEPޢ(QEQEQEQEV'Gqڶ?# m@OkvQz' k_A-%nz?AR`#D.E-oWϞQE(('$?kZǼY>'AuZmQE(ajyijeKܠFW#reKx3꺀wfMg+(ù)x¾.}zBVMxKy@ ySN[:NEk0ldv=z8潎V ?u?:_@Y6@!ݳ OZԲzׇӬl쥆C4x+(sţg:_źx5F!-';h:Vw%ͥOl U@$ }:(\(b ((k_ѢNXF GeM'4A EP (t_zoyCf`_8h?%oV#\PQ@((((`ۏշX1_mjx_I?կU_G ly+s|"?m sv)kz|(AEPEPsǼY>'AuZؑwɜnW1JѬtѥ[Kxn(\8gSEay,-%Ty,-%TEay,-%Ty,-%TEay,-%Ty,-%TEay,-%Ty,-%TEay,-%Ty,-%TEay,-%Ty,-%TEay,-%Ty,-%TEay,-%Ty,-%T{[^&@wzʽOXZMD4{)F3޷,-kj#,:3P(Q@`}lJެ-CG]n41qoV#g@EP ((((Oȏ6Em'Gqځ<*ROkvQz[Jȃ襭G>]Zޯ=`(QEQEQEQEQEQEQEQEQEQEQEQEQES$8T4"q`)V:71dW1A84 O żkyR;Xs Ah5s*٦W=GU<YV1L@zdPu˘-|On&p7HGtU ͝ⅺuS%@ƀ+m?Qm{o3ʬqk;P4IId0n~ʣz 84] &MBuBH9SՏ<ڢ(QEQEQEV'Gqڶ?# m@OkvQz' k_A-%nz?AR`#D.E-oWϞQE(((kJ;y4zRh)e 4 EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?EP)e 4m?~E¡& `ۏշX1_mjx_I?կU_G ly+s|"?m sv)kz|(AEPEPsǼ\焴}.OhNm;i噠RIדtsǼY>'AuZ[ebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EPebi? t EP:H'J~bi? t EPebi? t EPebi? t EPemKšæf3ں:O:xOڀ/Džr_*z<-!S (Oȏ6Em'Gqځ<*ROkvQz[Jȃ襭G>]Zޯ=`(QEQE'VOIoֵy??ʲ|"N` ڢ(QEQEQEQT]VDԵ 6.$ =uk y*\pFEKEPExPf"Ig'e#5QESdqO#g {VouO6ŊL!,py Ԣ(QEd6~%կgJ ,F u#5/uk sJecqyK(WP͸#FQ@Q@dEk'mZՓuE/Džr_*z<-!S (Oȏ6Em'Gqځ<*ROkvQz[Jȃ襭G>]Zޯ=`(QEQE'VOIoֵy??ʲ|"N` ڢ(Tm,DD,#TPx6x4h9}?V{ӯX.r@5|}|Mt$t<=zzWçXIu W}R%Wo&lm)"6m!aԎ+-|gX-ih!m/~NݲMexC^>ғL/4hld߄3`yp1^<+AH( +{TPi1ocmGzs7 |C*O>&yQ>0'rk^u>.<$t$u-;#'x=+ٖ-AېT1Ӝ5RVC0O^X.x}:DywM%[O޵1\BǮ dZÛOJ|` ḳ(1+*ЀG+CwZ,<_?xAеBm<14Ip2r;NFO[]iGu)..-iLY{f`Wh{`wzݖǩ^[d(;09`ۏշX1_mjx_I?կU_G ly+s|"?m sv)kz|(AEPEPsǼY>'AuZ֟=p*:Z3j(AEPEPEPEPEPEPEPEPEPEPEPEPEPEPY>)GZ [VdEk'm@?m\ oT(+?# m[u趠g' kTZ]Tޯǒ=G sv)kz|"?mX(QEQEG?{UxKXfYnZu-x`ۏ VAWm_V#D.E-oV?AR|Q@(((((((((((((((((((((`ۏշX1_mjx_I?կU_G ly+s|"?mw(<C6G,zm=V x5|U^G5kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~kYsWG4W_ _??dG%~k'Gqڤßҿ2?x@Qkl>pw,Ll<$VAWm_V缛Brm`'Vd췉sg++o_cvg7nݷv4 R+E #<""/ȯFY?c'hY?c'k"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;"/ȣȋy'+ѿVOAX?VOAX>C{ 9"I|<"ddt;ڷk]*+?RxԏXAx-|_,=NǢY~ (Ɠ l^V?%JƏK<7ClQXxo +c?, W4EcY4 h0i_ g`ҿ6? l@V?%JƏK<7ClQXxo +c?, W4EcY4 h0i_ g`ҿ6? l@V?%JƏK<7ClQXxo +c?, W4EcY4 h0i_ g`ҿ6? l@V?%JƏK<7ClQXxo +c?, W4EcY4 h0i_ g`ҿ6? l@V?%JƏK<7ClQXxo +c?, W4EcY4 h0i_ g`ҿ6? l@V?%JƏK<7ClQXxo +c?, W4EcY4 hÄxJƀ6(|gj5%lI(2tOG>]ZޭH ~aX?ةDaX?أ6=m?( ~OEAO>i>߱S@}}`bϬTPaX?أ6=m?( ~OEAO>i>߱S@}}`bϬTPaX?أ6=m?( ~OEAO>i>߱S@}}`bϬTPaX?أ6=m?( ~OEAO>i>߱S@}}`bϬTPaX?أ6=m?( ~OEAO>i>߱S@}}`bϬTPaX?أ6=m?+vuFpA8WAX18FqځDT1|Nb@/1|IR~h9m*݌LG>]Zެȃ襭(QEQEQEQEQEQEQEQEk4^F};V%ŕҺ]B^۪ [+d088=ğn#H:88WG[GSj:uy˨[yBqß K[Ճ|9`o_>zEjҾCIY,,S0~BLIrHkExڵ{ ;{[iRRɈ2O\ÿjso\uz1S=w&ypW^5O𷃠4gmdqMxY(Iraܜpz>'ekjRGi)jM99 .=a0|XV` &X 2v09sӃhJOu ; 1\ D^D6\,zEcw˥+jؽrcU.eoM=?[-V|s損$9N,zx;ķ^##ә eƑA018VW hʮ ESѴ16џkx2\,y^j4T]#EKOgTGu<}uG[7e٣9ȸAr+SysXt0D[8OՋ;[v́~3KmIo ty"!xz3]"[qDOl" XAϗa>UI<7O7N7 *nSF3KK]igtO*naw Ep^$6 4]6n<<{s]7|Co/ YCqnJHak^A_ ? 5=kTTSi$7 fP8>u:mGiG>Dapx\,vW|RDi]yd.:9پ x+oLvT?k|]/ǥQ^z/n|9kq>d('%G!Ӑ0yJ~(K|otb妠al>vNN,z5NPAk[j6g 9\ ~,>#jj{+m3^+;I۾9ch.ķgd$WdboT]ib)L5_kj>$Ҵ{O4{7y 6gۏ|Qp4W\x\ x8i5 #uv2ž^vp;ڭhn}- Ӗ6k-5a ?RM+IS vXX p]؅Ul9X>2mu]',2$r[YsF qNvW_0SEJ1+#/^}베`ۏշX1_mjVAWm_V#D.E-oV?AR|qڥwZT-m}g&;*gcFI 3Ɗ㬾ZY|H[_+7*ϻ<zះv5N! e,TQE=M2 F56q|ϽC}Q>&uQ,g;H]X.p1k:0HBa>Ra^kXN`ȮJU^@r یzX.qwlkvYڅw4~YpsÌc5MgB׮#7?ik>at$]3E5ݼחZZ-(v0,9RG9,K]hַ,ڎ{[8U@@߽oI'5]w;>O?y`}k8t0xkh.txd=Ő]n[a=Oei1 ;V}IK[_vÆ^EAsԼ+uu?zٌe6- A:[;i Џ_o{=:> hr̞@d'#Q:k^!ڝ< n-=c'LWuǤ@mm_( . '`c oJe-?RV }@e+?(l}*ΣXִ9muEV)VUGC$~SRoQFoGe7m: _0 fNNkaee \'2sSX_A%6VάSw7]J 3CLn|dhz߇hZ.iVN$U7mZ:͈1_갛wg?78,<ڮiecOImw"HG=1 )+{^y5{_R0g_U3$c=뿢m;C\]X>cKx9!A*I<a;_@O }8ʊv {'xuI{tmʹ S=l,_0y_1=~n]MX.pמ|;o5a&<=wݻW 1$yUЁX5&|AfHlZ+r;3]X OxxWZ H6n2q׵mE趭n?[P' kTZ]Tޯǒ=G sv)kz|"?mX(QEQEQEQEQEQEQE_ o7JZ4/]Һ ۤp\g63a̚pm]$2 g޽Vk:Mim*yM8&+i~1\$6IJWYMDHXUDPUFL(AEPEPEPEPEPEPEPX1_mj۬Oȏ6Eß K[xCVms-"ӭ)/cVF*AlM'CF7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7M'CF?7 / "z4h0 Ѣ/*7?# mL4h0>zDKa:Gw3;lOjVAWm} k_A-%n}^sWa?dF:>M(G^&G<(tŠ((((((((((((((((((((((?UJ* u-././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/doc/images/sflogo.php.png0000644000175000017500000000552100000000000022241 0ustar00rousseaurousseauPNG  IHDR}%?qgAMA  cHRMnt$m_l<XGO IDATxb`?Y glƏWL88%H2ӧO'2=rsƨ_~=E9矌1ƱK+3o߾W@; ކ$CxC0L i5L`<^xC0z 4Wb@VbЧ I@#^bfiN" wHS$ārÌdˀ9( *\`u?0S1, a``7LgM?d{eyFJ ep@w Gq @(b"i97 5(DK%L]y?B-,nޖ_vE03Ӈ ]Sa)g 1 n`Q /x?֟"DVd@?;0D6&XpT1.`ADA kx:@ >2H[RHOLF HH4| &H5!RTOZ__L@/$S4ҝc!>pKAt<98${AZW@e'XpW,RRR@ݻ% deC\h&P 0q+ k-5ul$ɯstۑ$@\ :rc + ,L6E0e@7u*v@ZxFv%ј]!H3h 0q"iL4<<Ϟsr?ؾ ^g@D1 O {!9X0I^;h&;U88T[ѵ֗u|ή[4$ fS1`p-Bq#w9oWU7ma$uiQєR*crM0HaFQ4!q5;au417[hZ*CM$*}A1ueYH 0?í7N *G-0y&/L|( 1"_,tKa `.s7M@qH2JMGnx (i$@o#E (1h&P.b&@v翫G010H2p10f`/*)h#rba$,B"J"+N<#@Cr\X÷ , , " lT¥ ;@GALAH_,#<@ p,/LYlD@l:a1wh15>^_wu% /17ï ?_3 l8Ci lUU@ p߷^pJ)< Хw& <|M; a C´Xq @ y(PD/ !jD]2afaI4) "=q{0}] ځ c8p<w@*RvyX.j2`"L `YU j&dxz&pSdT^XF 8`dd =7 'q-%IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399398.0 pyscard-2.0.2/smartcard/guid.py0000644000175000017500000000421100000000000016737 0ustar00rousseaurousseau"""smartcard.guid Utility functions to handle GUIDs as strings or list of bytes __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import uuid # guid is ulong+ushort+ushort+uchar[8] def strToGUID(s): """Converts a GUID string into a list of bytes. >>> strToGUID('{AD4F1667-EA75-4124-84D4-641B3B197C65}') [103, 22, 79, 173, 117, 234, 36, 65, 132, 212, 100, 27, 59, 25, 124, 101] """ dat = uuid.UUID(hex=s) if isinstance(dat.bytes_le, str): # Python 2 dat = [ord(e) for e in dat.bytes_le] else: # Python 3 dat = list(dat.bytes_le) return dat def GUIDToStr(g): """Converts a GUID sequence of bytes into a string. >>> GUIDToStr([103,22,79,173, 117,234, 36,65, ... 132, 212, 100, 27, 59, 25, 124, 101]) '{AD4F1667-EA75-4124-84D4-641B3B197C65}' """ try: dat = uuid.UUID(bytes_le=bytes(g)) except: dat = uuid.UUID(bytes_le=''.join(map(chr, g))) return '{' + str(dat).upper() + '}' if __name__ == "__main__": """Small sample illustrating the use of guid.py.""" guid_in = '{AD4F1667-EA75-4124-84D4-641B3B197C65}' print(guid_in) dummycardguid1 = strToGUID(guid_in) print(dummycardguid1) guid_out = GUIDToStr(dummycardguid1) print(guid_out) if guid_in != guid_out: print("Failure") else: print("Success") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/pcsc/0000755000175000017500000000000000000000000016367 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399588.0 pyscard-2.0.2/smartcard/pcsc/PCSCCardConnection.py0000644000175000017500000002702400000000000022310 0ustar00rousseaurousseau"""PCSCCardConnection class manages connections thru a PCSC reader. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardConnection import CardConnection from smartcard.Exceptions import (CardConnectionException, NoCardException, SmartcardException) from smartcard.scard import * def translateprotocolmask(protocol): """Translate CardConnection protocol mask into PCSC protocol mask.""" pcscprotocol = 0 if None != protocol: if CardConnection.T0_protocol & protocol: pcscprotocol |= SCARD_PROTOCOL_T0 if CardConnection.T1_protocol & protocol: pcscprotocol |= SCARD_PROTOCOL_T1 if CardConnection.RAW_protocol & protocol: pcscprotocol |= SCARD_PROTOCOL_RAW if CardConnection.T15_protocol & protocol: pcscprotocol |= SCARD_PROTOCOL_T15 return pcscprotocol def translateprotocolheader(protocol): """Translate protocol into PCSC protocol header.""" pcscprotocol = 0 if None != protocol: if CardConnection.T0_protocol == protocol: pcscprotocol = SCARD_PCI_T0 if CardConnection.T1_protocol == protocol: pcscprotocol = SCARD_PCI_T1 if CardConnection.RAW_protocol == protocol: pcscprotocol = SCARD_PCI_RAW return pcscprotocol dictProtocolHeader = {SCARD_PCI_T0: 'T0', SCARD_PCI_T1: 'T1', SCARD_PCI_RAW: 'RAW'} dictProtocol = {SCARD_PROTOCOL_T0: 'T0', SCARD_PROTOCOL_T1: 'T1', SCARD_PROTOCOL_RAW: 'RAW', SCARD_PROTOCOL_T15: 'T15', SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1: 'T0 or T1'} class PCSCCardConnection(CardConnection): """PCSCCard connection class. Handles connection with a card thru a PCSC reader.""" def __init__(self, reader): """Construct a new PCSC card connection. reader: the reader in which the smartcard to connect to is located. """ CardConnection.__init__(self, reader) self.hcard = None hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != 0: raise CardConnectionException( 'Failed to establish context : ' + \ SCardGetErrorMessage(hresult)) def __del__(self): """Destructor. Clean PCSC connection resources.""" # race condition: module CardConnection # can disappear before __del__ is called self.disconnect() hresult = SCardReleaseContext(self.hcontext) if hresult != 0: raise CardConnectionException( 'Failed to release context: ' + \ SCardGetErrorMessage(hresult)) CardConnection.__del__(self) def connect(self, protocol=None, mode=None, disposition=None): """Connect to the card. If protocol is not specified, connect with the default connection protocol. If mode is not specified, connect with SCARD_SHARE_SHARED.""" CardConnection.connect(self, protocol) pcscprotocol = translateprotocolmask(protocol) if 0 == pcscprotocol: pcscprotocol = self.getProtocol() if mode == None: mode = SCARD_SHARE_SHARED # store the way to dispose the card if disposition == None: disposition = SCARD_UNPOWER_CARD self.disposition = disposition hresult, self.hcard, dwActiveProtocol = SCardConnect( self.hcontext, str(self.reader), mode, pcscprotocol) if hresult != 0: self.hcard = None if hresult in (SCARD_W_REMOVED_CARD, SCARD_E_NO_SMARTCARD): raise NoCardException('Unable to connect', hresult=hresult) else: raise CardConnectionException( 'Unable to connect with protocol: ' + \ dictProtocol[pcscprotocol] + '. ' + \ SCardGetErrorMessage(hresult)) protocol = 0 if dwActiveProtocol == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1: # special case for T0 | T1 # this happen when mode=SCARD_SHARE_DIRECT and no protocol is # then negociated with the card protocol = CardConnection.T0_protocol | CardConnection.T1_protocol else: for p in dictProtocol: if p == dwActiveProtocol: protocol = eval("CardConnection.%s_protocol" % dictProtocol[p]) PCSCCardConnection.setProtocol(self, protocol) def reconnect(self, protocol=None, mode=None, disposition=None): """Reconnect to the card. If protocol is not specified, connect with the default connection protocol. If mode is not specified, connect with SCARD_SHARE_SHARED. If disposition is not specified, do a warm reset (SCARD_RESET_CARD)""" CardConnection.reconnect(self, protocol) if self.hcard == None: raise CardConnectionException('Card not connected') pcscprotocol = translateprotocolmask(protocol) if 0 == pcscprotocol: pcscprotocol = self.getProtocol() if mode == None: mode = SCARD_SHARE_SHARED # store the way to dispose the card if disposition == None: disposition = SCARD_RESET_CARD self.disposition = disposition hresult, dwActiveProtocol = SCardReconnect(self.hcard, mode, pcscprotocol, self.disposition) if hresult != 0: self.hcard = None if hresult in (SCARD_W_REMOVED_CARD, SCARD_E_NO_SMARTCARD): raise NoCardException('Unable to reconnect', hresult=hresult) else: raise CardConnectionException( 'Unable to reconnect with protocol: ' + \ dictProtocol[pcscprotocol] + '. ' + \ SCardGetErrorMessage(hresult)) protocol = 0 if dwActiveProtocol == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1: # special case for T0 | T1 # this happen when mode=SCARD_SHARE_DIRECT and no protocol is # then negociated with the card protocol = CardConnection.T0_protocol | CardConnection.T1_protocol else: for p in dictProtocol: if p == dwActiveProtocol: protocol = eval("CardConnection.%s_protocol" % dictProtocol[p]) PCSCCardConnection.setProtocol(self, protocol) def disconnect(self): """Disconnect from the card.""" # when __del__() is invoked in response to a module being deleted, # e.g., when execution of the program is done, other globals referenced # by the __del__() method may already have been deleted. # this causes CardConnection.disconnect to except with a TypeError try: CardConnection.disconnect(self) except TypeError: pass if None != self.hcard: hresult = SCardDisconnect(self.hcard, self.disposition) if hresult != 0: raise CardConnectionException( 'Failed to disconnect: ' + \ SCardGetErrorMessage(hresult)) self.hcard = None def getATR(self): """Return card ATR""" CardConnection.getATR(self) if None == self.hcard: raise CardConnectionException('Card not connected') hresult, reader, state, protocol, atr = SCardStatus(self.hcard) if hresult != 0: raise CardConnectionException( 'Failed to get status: ' + \ SCardGetErrorMessage(hresult)) return atr def doTransmit(self, bytes, protocol=None): """Transmit an apdu to the card and return response apdu. @param bytes: command apdu to transmit (list of bytes) @param protocol: the transmission protocol, from CardConnection.T0_protocol, CardConnection.T1_protocol, or CardConnection.RAW_protocol @return: a tuple (response, sw1, sw2) where sw1 is status word 1, e.g. 0x90 sw2 is status word 2, e.g. 0x1A response are the response bytes excluding status words """ if None == protocol: protocol = self.getProtocol() CardConnection.doTransmit(self, bytes, protocol) pcscprotocolheader = translateprotocolheader(protocol) if 0 == pcscprotocolheader: raise CardConnectionException( 'Invalid protocol in transmit: must be ' + \ 'CardConnection.T0_protocol, ' + \ 'CardConnection.T1_protocol, or ' + \ 'CardConnection.RAW_protocol') if None == self.hcard: raise CardConnectionException('Card not connected') hresult, response = SCardTransmit( self.hcard, pcscprotocolheader, bytes) if hresult != 0: raise CardConnectionException( 'Failed to transmit with protocol ' + \ dictProtocolHeader[pcscprotocolheader] + '. ' + \ SCardGetErrorMessage(hresult)) if len(response) < 2: raise CardConnectionException( 'Card returned no valid response') sw1 = (response[-2] + 256) % 256 sw2 = (response[-1] + 256) % 256 data = [(x + 256) % 256 for x in response[:-2]] return list(data), sw1, sw2 def doControl(self, controlCode, bytes=[]): """Transmit a control command to the reader and return response. controlCode: control command bytes: command data to transmit (list of bytes) return: response are the response bytes (if any) """ CardConnection.doControl(self, controlCode, bytes) hresult, response = SCardControl(self.hcard, controlCode, bytes) if hresult != 0: raise SmartcardException( 'Failed to control ' + SCardGetErrorMessage(hresult)) data = [(x + 256) % 256 for x in response] return list(data) def doGetAttrib(self, attribId): """get an attribute attribId: Identifier for the attribute to get return: response are the attribute byte array """ CardConnection.doGetAttrib(self, attribId) hresult, response = SCardGetAttrib(self.hcard, attribId) if hresult != 0: raise SmartcardException( 'Failed to getAttrib ' + SCardGetErrorMessage(hresult)) return response if __name__ == '__main__': """Small sample illustrating the use of CardConnection.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] from smartcard.pcsc.PCSCReader import PCSCReader from smartcard.pcsc.PCSCPart10 import CM_IOCTL_GET_FEATURE_REQUEST cc = PCSCReader.readers()[0].createConnection() cc.connect() print("%r %x %x" % cc.transmit(SELECT + DF_TELECOM)) print(cc.control(CM_IOCTL_GET_FEATURE_REQUEST, [])) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/smartcard/pcsc/PCSCCardRequest.py0000644000175000017500000003302300000000000021635 0ustar00rousseaurousseau"""PCSC Smartcard request. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import threading import time from smartcard.AbstractCardRequest import AbstractCardRequest from smartcard.Exceptions import CardRequestTimeoutException from smartcard.Exceptions import CardRequestException, ListReadersException from smartcard.pcsc.PCSCReader import PCSCReader from smartcard.pcsc.PCSCContext import PCSCContext from smartcard import Card from smartcard.scard import * def signalEvent(evt, isInfinite): if not isInfinite: evt.set() class PCSCCardRequest(AbstractCardRequest): """PCSC CardRequest class.""" def __init__(self, newcardonly=False, readers=None, cardType=None, cardServiceClass=None, timeout=1): """Construct new PCSCCardRequest. @param newcardonly: if True, request a new card default is False, i.e. accepts cards already inserted @param readers: the list of readers to consider for requesting a card default is to consider all readers @param cardType: the CardType class to wait for; default is AnyCardType, i.e. the request will returns with new or already inserted cards @param cardServiceClass: the specific card service class to create and bind to the card default is to create and bind a PassThruCardService @param timeout: the time in seconds we are ready to wait for connecting to the requested card. default is to wait one second to wait forever, set timeout to None """ AbstractCardRequest.__init__( self, newcardonly, readers, cardType, cardServiceClass, timeout) # polling interval in s for SCardGetStatusChange self.pollinginterval = 0.1 # if timeout is None, translate to scard.INFINITE if None == self.timeout: self.timeout = INFINITE # otherwise, from seconds to milliseconds else: self.timeout = int(self.timeout) self.hcontext = PCSCContext().getContext() def getReaderNames(self): """Returns the list or PCSC readers on which to wait for cards.""" # renew the context in case PC/SC was stopped # this happens on Windows when the last reader is disconnected self.hcontext = PCSCContext().getContext() # get inserted readers hresult, pcscreaders = SCardListReaders(self.hcontext, []) if hresult in [SCARD_E_NO_READERS_AVAILABLE, SCARD_E_SERVICE_STOPPED]: return [] if SCARD_S_SUCCESS != hresult: raise ListReadersException(hresult) readers = [] # if no readers asked, use all inserted readers if None == self.readersAsked: readers = pcscreaders # otherwise use only the asked readers that are inserted else: for reader in self.readersAsked: if not isinstance(reader, type("")): reader = str(reader) if reader in pcscreaders: readers = readers + [reader] return readers def waitforcard(self): """Wait for card insertion and returns a card service.""" AbstractCardRequest.waitforcard(self) cardfound = False # for non infinite timeout, a timer will signal # the end of the time-out by setting the evt event evt = threading.Event() if INFINITE == self.timeout: timertimeout = 1 else: timertimeout = self.timeout timer = threading.Timer( timertimeout, signalEvent, [evt, INFINITE == self.timeout]) # create a dictionary entry for new readers readerstates = {} readernames = self.getReaderNames() for reader in readernames: if not reader in readerstates: readerstates[reader] = (reader, SCARD_STATE_UNAWARE) # remove dictionary entry for readers that disappeared for oldreader in list(readerstates.keys()): if oldreader not in readernames: del readerstates[oldreader] # call SCardGetStatusChange only if we have some readers if {} != readerstates: hresult, newstates = SCardGetStatusChange( self.hcontext, 0, list(readerstates.values())) else: hresult = 0 newstates = [] # we can expect normally time-outs or reader # disappearing just before the call # otherwise, raise execption on error if 0 != hresult and \ SCARD_E_TIMEOUT != hresult and \ SCARD_E_UNKNOWN_READER != hresult: raise CardRequestException( 'Failed to SCardGetStatusChange ' + \ SCardGetErrorMessage(hresult)) # in case of timeout or reader disappearing, # the content of the states is useless # in which case we clear the changed bit if SCARD_E_TIMEOUT == hresult or SCARD_E_UNKNOWN_READER == hresult: for state in newstates: state[1] = state[1] & (0xFFFFFFFF ^ SCARD_STATE_CHANGED) # update readerstate for state in newstates: readername, eventstate, atr = state readerstates[readername] = (readername, eventstate) # if a new card is not requested, just return the first available if not self.newcardonly: for state in newstates: readername, eventstate, atr = state if eventstate & SCARD_STATE_PRESENT: reader = PCSCReader(readername) if self.cardType.matches(atr, reader): if self.cardServiceClass.supports('dummy'): cardfound = True return self.cardServiceClass( reader.createConnection()) timerstarted = False while not evt.isSet() and not cardfound: if not timerstarted: timerstarted = True timer.start() time.sleep(self.pollinginterval) # create a dictionary entry for new readers readernames = self.getReaderNames() for reader in readernames: if not reader in readerstates: readerstates[reader] = (reader, SCARD_STATE_UNAWARE) # remove dictionary entry for readers that disappeared for oldreader in list(readerstates.keys()): if oldreader not in readernames: del readerstates[oldreader] # wait for card insertion if {} != readerstates: hresult, newstates = SCardGetStatusChange( self.hcontext, 0, list(readerstates.values())) else: hresult = SCARD_E_TIMEOUT newstates = [] # time-out if SCARD_E_TIMEOUT == hresult: if evt.isSet(): raise CardRequestTimeoutException() # reader vanished before or during the call elif SCARD_E_UNKNOWN_READER == hresult: pass # some error happened elif 0 != hresult: timer.cancel() raise CardRequestException( 'Failed to get status change ' + \ SCardGetErrorMessage(hresult)) # something changed! else: # check if we have to return a match, i.e. # if no new card in inserted and there is a card found # or if a new card is requested, and there is a change+present for state in newstates: readername, eventstate, atr = state r, oldstate = readerstates[readername] # the status can change on a card already inserted, e.g. # unpowered, in use, ... # if a new card is requested, clear the state changed bit # if the card was already inserted and is still inserted if self.newcardonly: if oldstate & SCARD_STATE_PRESENT and \ eventstate & \ (SCARD_STATE_CHANGED | SCARD_STATE_PRESENT): eventstate = eventstate & \ (0xFFFFFFFF ^ SCARD_STATE_CHANGED) if (self.newcardonly and \ eventstate & SCARD_STATE_PRESENT and \ eventstate & SCARD_STATE_CHANGED) or \ (not self.newcardonly and \ eventstate & SCARD_STATE_PRESENT): reader = PCSCReader(readername) if self.cardType.matches(atr, reader): if self.cardServiceClass.supports('dummy'): cardfound = True timer.cancel() return self.cardServiceClass( reader.createConnection()) # update state dictionary readerstates[readername] = (readername, eventstate) if evt.isSet(): raise CardRequestTimeoutException() def waitforcardevent(self): """Wait for card insertion or removal.""" AbstractCardRequest.waitforcardevent(self) presentcards = [] evt = threading.Event() # for non infinite timeout, a timer will signal the end of the time-out if INFINITE == self.timeout: timertimeout = 1 else: timertimeout = self.timeout timer = threading.Timer( timertimeout, signalEvent, [evt, INFINITE == self.timeout]) # get status change until time-out, e.g. evt is set readerstates = {} timerstarted = False while not evt.isSet(): if not timerstarted: timerstarted = True timer.start() time.sleep(self.pollinginterval) # reinitialize at each iteration just in case a new reader appeared readernames = self.getReaderNames() for reader in readernames: # create a dictionary entry for new readers if not reader in readerstates: readerstates[reader] = (reader, SCARD_STATE_UNAWARE) # remove dictionary entry for readers that disappeared for oldreader in list(readerstates.keys()): if oldreader not in readernames: del readerstates[oldreader] # get status change if {} != readerstates: hresult, newstates = SCardGetStatusChange( self.hcontext, 0, list(readerstates.values())) else: hresult = 0 newstates = [] # time-out if SCARD_E_TIMEOUT == hresult: if evt.isSet(): raise CardRequestTimeoutException() # the reader was unplugged during the loop elif SCARD_E_UNKNOWN_READER == hresult: pass # some error happened elif 0 != hresult: timer.cancel() raise CardRequestException( 'Failed to get status change ' + \ SCardGetErrorMessage(hresult)) # something changed! else: timer.cancel() for state in newstates: readername, eventstate, atr = state r, oldstate = readerstates[readername] # the status can change on a card already inserted, e.g. # unpowered, in use, ... Clear the state changed bit if # the card was already inserted and is still inserted if oldstate & SCARD_STATE_PRESENT and \ eventstate & \ (SCARD_STATE_CHANGED | SCARD_STATE_PRESENT): eventstate = eventstate & \ (0xFFFFFFFF ^ SCARD_STATE_CHANGED) if eventstate & SCARD_STATE_PRESENT and \ eventstate & SCARD_STATE_CHANGED: presentcards.append(Card.Card(readername, atr)) return presentcards if evt.isSet(): raise CardRequestTimeoutException() if __name__ == '__main__': """Small sample illustrating the use of PCSCCardRequest.py.""" from smartcard.util import toHexString print('Insert a new card within 10 seconds') cr = PCSCCardRequest(timeout=10, newcardonly=True) cs = cr.waitforcard() cs.connection.connect() print(cs.connection.getReader() + ' ' + toHexString(cs.connection.getATR())) cs.connection.disconnect() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/smartcard/pcsc/PCSCContext.py0000644000175000017500000000440500000000000021041 0ustar00rousseaurousseau"""PCSC context singleton. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from threading import RLock from smartcard.scard import * from smartcard.pcsc.PCSCExceptions import EstablishContextException class PCSCContext(object): """Manage a singleton pcsc context handle.""" class __PCSCContextSingleton: """The actual pcsc context class as a singleton.""" def __init__(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != 0: raise EstablishContextException(hresult) def getContext(self): return self.hcontext def releaseContext(self): return SCardReleaseContext(self.hcontext) # the singleton mutex = RLock() instance = None def __init__(self): PCSCContext.mutex.acquire() try: if not PCSCContext.instance: self.renewContext() finally: PCSCContext.mutex.release() def __getattr__(self, name): if self.instance: return getattr(self.instance, name) def renewContext(): PCSCContext.mutex.acquire() try: if PCSCContext.instance is not None: PCSCContext.instance.releaseContext() PCSCContext.instance = PCSCContext.__PCSCContextSingleton() finally: PCSCContext.mutex.release() return PCSCContext.instance.getContext() renewContext = staticmethod(renewContext) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/pcsc/PCSCExceptions.py0000644000175000017500000000766300000000000021547 0ustar00rousseaurousseau"""Smartcard module exceptions. This module defines the exceptions raised by the smartcard.pcsc modules. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ # gemalto scard library import smartcard.scard class BaseSCardException(Exception): """Base class for scard (aka PCSC) exceptions. scard exceptions are raised by the scard module, i.e. low-level PCSC access to readers and cards. """ def __init__(self, hresult): """Constructor that stores the pcsc error status.""" self.hresult = hresult def __str__(self): """Returns a string representation of the exception.""" return repr("scard exception: " + smartcard.scard.SCardGetErrorMessage(self.hresult)) class AddReaderToGroupException(BaseSCardException): """Raised when scard fails to add a new reader to a PCSC reader group.""" def __init__(self, hresult, readername="", groupname=""): BaseSCardException.__init__(self, hresult) self.readername = readername self.groupname = groupname def __str__(self): return repr('Failure to add reader: ' + self.readername + ' to group: ' + self.groupname + ' ' + smartcard.scard.SCardGetErrorMessage(self.hresult)) class EstablishContextException(BaseSCardException): """Raised when scard failed to establish context with PCSC.""" def __str__(self): """Returns a string representation of the exception.""" return repr('Failure to establish context: ' + smartcard.scard.SCardGetErrorMessage(self.hresult)) class ListReadersException(BaseSCardException): """Raised when scard failed to list readers.""" def __str__(self): return repr('Failure to list readers: ' + smartcard.scard.SCardGetErrorMessage(self.hresult)) class IntroduceReaderException(BaseSCardException): """Raised when scard fails to introduce a new reader to PCSC.""" def __init__(self, hresult, readername=""): BaseSCardException.__init__(self, hresult) self.readername = readername def __str__(self): return repr('Failure to introduce a new reader: ' + self.readername + ' ' + smartcard.scard.SCardGetErrorMessage(self.hresult)) class ReleaseContextException(BaseSCardException): """Raised when scard failed to release PCSC context.""" def __str__(self): return repr('Failure to release context: ' + smartcard.scard.SCardGetErrorMessage(self.hresult)) class RemoveReaderFromGroupException(BaseSCardException): """Raised when scard fails to remove a reader from a PCSC reader group.""" def __init__(self, hresult, readername="", groupname=""): BaseSCardException.__init__(self, hresult) self.readername = readername self.groupname = groupname def __str__(self): return repr('Failure to remove reader: ' + self.readername + ' from group: ' + self.groupname + ' ' + smartcard.scard.SCardGetErrorMessage(self.hresult)) if __name__ == "__main__": try: raise EstablishContextException(smartcard.scard.SCARD_E_NO_MEMORY) except BaseSCardException as exc: print(exc) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399599.0 pyscard-2.0.2/smartcard/pcsc/PCSCPart10.py0000644000175000017500000002200600000000000020461 0ustar00rousseaurousseau"""PCSCPart10: PC/SC Part 10 (pinpad) __author__ = "Ludovic Rousseau" Copyright 2009-2010 Ludovic Rosseau Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * # constants defined in PC/SC v2 Part 10 CM_IOCTL_GET_FEATURE_REQUEST = SCARD_CTL_CODE(3400) FEATURE_VERIFY_PIN_START = 0x01 FEATURE_VERIFY_PIN_FINISH = 0x02 FEATURE_MODIFY_PIN_START = 0x03 FEATURE_MODIFY_PIN_FINISH = 0x04 FEATURE_GET_KEY_PRESSED = 0x05 FEATURE_VERIFY_PIN_DIRECT = 0x06 FEATURE_MODIFY_PIN_DIRECT = 0x07 FEATURE_MCT_READER_DIRECT = 0x08 FEATURE_MCT_UNIVERSAL = 0x09 FEATURE_IFD_PIN_PROPERTIES = 0x0A FEATURE_ABORT = 0x0B FEATURE_SET_SPE_MESSAGE = 0x0C FEATURE_VERIFY_PIN_DIRECT_APP_ID = 0x0D FEATURE_MODIFY_PIN_DIRECT_APP_ID = 0x0E FEATURE_WRITE_DISPLAY = 0x0F FEATURE_GET_KEY = 0x10 FEATURE_IFD_DISPLAY_PROPERTIES = 0x11 FEATURE_GET_TLV_PROPERTIES = 0x12 FEATURE_CCID_ESC_COMMAND = 0x13 Features = { "FEATURE_VERIFY_PIN_START": FEATURE_VERIFY_PIN_START, "FEATURE_VERIFY_PIN_FINISH": FEATURE_VERIFY_PIN_FINISH, "FEATURE_MODIFY_PIN_START": FEATURE_MODIFY_PIN_START, "FEATURE_MODIFY_PIN_FINISH": FEATURE_MODIFY_PIN_FINISH, "FEATURE_GET_KEY_PRESSED": FEATURE_GET_KEY_PRESSED, "FEATURE_VERIFY_PIN_DIRECT": FEATURE_VERIFY_PIN_DIRECT, "FEATURE_MODIFY_PIN_DIRECT": FEATURE_MODIFY_PIN_DIRECT, "FEATURE_MCT_READER_DIRECT": FEATURE_MCT_READER_DIRECT, "FEATURE_MCT_UNIVERSAL": FEATURE_MCT_UNIVERSAL, "FEATURE_IFD_PIN_PROPERTIES": FEATURE_IFD_PIN_PROPERTIES, "FEATURE_ABORT": FEATURE_ABORT, "FEATURE_SET_SPE_MESSAGE": FEATURE_SET_SPE_MESSAGE, "FEATURE_VERIFY_PIN_DIRECT_APP_ID": FEATURE_VERIFY_PIN_DIRECT_APP_ID, "FEATURE_MODIFY_PIN_DIRECT_APP_ID": FEATURE_MODIFY_PIN_DIRECT_APP_ID, "FEATURE_WRITE_DISPLAY": FEATURE_WRITE_DISPLAY, "FEATURE_GET_KEY": FEATURE_GET_KEY, "FEATURE_IFD_DISPLAY_PROPERTIES": FEATURE_IFD_DISPLAY_PROPERTIES, "FEATURE_GET_TLV_PROPERTIES": FEATURE_GET_TLV_PROPERTIES, "FEATURE_CCID_ESC_COMMAND": FEATURE_CCID_ESC_COMMAND} # properties returned by FEATURE_GET_TLV_PROPERTIES PCSCv2_PART10_PROPERTY_wLcdLayout = 1 PCSCv2_PART10_PROPERTY_bEntryValidationCondition = 2 PCSCv2_PART10_PROPERTY_bTimeOut2 = 3 PCSCv2_PART10_PROPERTY_wLcdMaxCharacters = 4 PCSCv2_PART10_PROPERTY_wLcdMaxLines = 5 PCSCv2_PART10_PROPERTY_bMinPINSize = 6 PCSCv2_PART10_PROPERTY_bMaxPINSize = 7 PCSCv2_PART10_PROPERTY_sFirmwareID = 8 PCSCv2_PART10_PROPERTY_bPPDUSupport = 9 PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize = 10 PCSCv2_PART10_PROPERTY_wIdVendor = 11 PCSCv2_PART10_PROPERTY_wIdProduct = 12 Properties = { "PCSCv2_PART10_PROPERTY_wLcdLayout": PCSCv2_PART10_PROPERTY_wLcdLayout, "PCSCv2_PART10_PROPERTY_bEntryValidationCondition": \ PCSCv2_PART10_PROPERTY_bEntryValidationCondition, "PCSCv2_PART10_PROPERTY_bTimeOut2": PCSCv2_PART10_PROPERTY_bTimeOut2, "PCSCv2_PART10_PROPERTY_wLcdMaxCharacters": \ PCSCv2_PART10_PROPERTY_wLcdMaxCharacters, "PCSCv2_PART10_PROPERTY_wLcdMaxLines": PCSCv2_PART10_PROPERTY_wLcdMaxLines, "PCSCv2_PART10_PROPERTY_bMinPINSize": PCSCv2_PART10_PROPERTY_bMinPINSize, "PCSCv2_PART10_PROPERTY_bMaxPINSize": PCSCv2_PART10_PROPERTY_bMaxPINSize, "PCSCv2_PART10_PROPERTY_sFirmwareID": PCSCv2_PART10_PROPERTY_sFirmwareID, "PCSCv2_PART10_PROPERTY_bPPDUSupport": PCSCv2_PART10_PROPERTY_bPPDUSupport, "PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize": PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize, "PCSCv2_PART10_PROPERTY_wIdVendor": PCSCv2_PART10_PROPERTY_wIdVendor, "PCSCv2_PART10_PROPERTY_wIdProduct": PCSCv2_PART10_PROPERTY_wIdProduct} # we already have: Features['FEATURE_x'] = FEATURE_x # we will now also have: Features[FEATURE_x] = 'FEATURE_x' for k in list(Features.keys()): Features[Features[k]] = k for k in list(Properties.keys()): Properties[Properties[k]] = k def parseFeatureRequest(response): """ Get the list of Part10 features supported by the reader. @param response: result of CM_IOCTL_GET_FEATURE_REQUEST commmand @rtype: list @return: a list of list [[tag1, value1], [tag2, value2]] """ features = [] while (len(response) > 0): tag = response[0] control = ((((((response[2] << 8) + response[3]) << 8) + response[4]) << 8) + response[5]) try: features.append([Features[tag], control]) except KeyError: pass del response[:6] return features def getFeatureRequest(cardConnection): """ Get the list of Part10 features supported by the reader. @param cardConnection: L{CardConnection} object @rtype: list @return: a list of list [[tag1, value1], [tag2, value2]] """ response = cardConnection.control(CM_IOCTL_GET_FEATURE_REQUEST, []) return parseFeatureRequest(response) def hasFeature(featureList, feature): """ return the controlCode for a feature or None @param feature: feature to look for @param featureList: feature list as returned by L{getFeatureRequest()} @return: feature value or None """ for f in featureList: if f[0] == feature or Features[f[0]] == feature: return f[1] def getPinProperties(cardConnection, featureList=None, controlCode=None): """ return the PIN_PROPERTIES structure @param cardConnection: L{CardConnection} object @param featureList: feature list as returned by L{getFeatureRequest()} @param controlCode: control code for L{FEATURE_IFD_PIN_PROPERTIES} @rtype: dict @return: a dict """ if controlCode is None: if featureList is None: featureList = getFeatureRequest(cardConnection) controlCode = hasFeature(featureList, FEATURE_IFD_PIN_PROPERTIES) if controlCode is None: return {'raw': []} response = cardConnection.control(controlCode, []) d = { 'raw': response, 'LcdLayoutX': response[0], 'LcdLayoutY': response[1], 'EntryValidationCondition': response[2], 'TimeOut2': response[3]} return d def getTlvProperties(cardConnection, featureList=None, controlCode=None): """ return the GET_TLV_PROPERTIES structure @param cardConnection: L{CardConnection} object @param featureList: feature list as returned by L{getFeatureRequest()} @param controlCode: control code for L{FEATURE_GET_TLV_PROPERTIES} @rtype: dict @return: a dict """ if controlCode is None: if featureList is None: featureList = getFeatureRequest(cardConnection) controlCode = hasFeature(featureList, FEATURE_GET_TLV_PROPERTIES) if controlCode is None: return {'raw': []} response = cardConnection.control(controlCode, []) return parseTlvProperties(response) def parseTlvProperties(response): """ return the GET_TLV_PROPERTIES structure @param response: result of L{FEATURE_GET_TLV_PROPERTIES} @rtype: dict @return: a dict """ d = { 'raw': response, } # create a new list to consume it tmp = list(response) while tmp: tag = tmp[0] len = tmp[1] data = tmp[2:2 + len] if PCSCv2_PART10_PROPERTY_sFirmwareID == tag: # convert to a string data = "".join([chr(c) for c in data]) # we now suppose the value is an integer elif 1 == len: # byte data = data[0] elif 2 == len: # 16 bits value data = data[1] * 256 + data[0] elif 4 == len: # 32 bits value data = ((data[3] * 256 + data[2]) * 256 + data[1]) * 256 + data[0] # store the value in the dictionnary try: d[Properties[tag]] = data except KeyError: d["UNKNOWN"] = data del tmp[0:2 + len] return d if __name__ == '__main__': """Small sample illustrating the use of PCSCPart10.""" from smartcard.pcsc.PCSCReader import PCSCReader cc = PCSCReader.readers()[0].createConnection() cc.connect(mode=SCARD_SHARE_DIRECT) # print(cc.control(CM_IOCTL_GET_FEATURE_REQUEST)) features = getFeatureRequest(cc) print(features) print(hasFeature(features, FEATURE_VERIFY_PIN_START)) print(hasFeature(features, FEATURE_VERIFY_PIN_DIRECT)) properties = getPinProperties(cc) print("\nPinProperties:") for k, v in list(properties.items()): print(" %s: %s" % (k, v)) print("\nTlvProperties:") properties = getTlvProperties(cc) for k, v in list(properties.items()): print(" %s: %s" % (k, v)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399604.0 pyscard-2.0.2/smartcard/pcsc/PCSCReader.py0000644000175000017500000001140000000000000020610 0ustar00rousseaurousseau"""PCSCReader: concrete reader class for PCSC Readers __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.CardConnectionDecorator import CardConnectionDecorator from smartcard.reader.Reader import Reader from smartcard.pcsc.PCSCContext import PCSCContext from smartcard.pcsc.PCSCCardConnection import PCSCCardConnection from smartcard.Exceptions import * from smartcard.pcsc.PCSCExceptions import * from smartcard.scard import * def __PCSCreaders__(hcontext, groups=[]): """Returns the list of PCSC smartcard readers in PCSC group. If group is not specified, returns the list of all PCSC smartcard readers. """ # in case we have a string instead of a list if isinstance(groups, type("")): groups = [groups] hresult, readers = SCardListReaders(hcontext, groups) if hresult != 0: if hresult == SCARD_E_NO_READERS_AVAILABLE: readers = [] elif hresult == SCARD_E_SERVICE_STOPPED: raise CardServiceStoppedException() else: raise ListReadersException(hresult) return readers class PCSCReader(Reader): """PCSC reader class.""" def __init__(self, readername): """Constructs a new PCSC reader.""" Reader.__init__(self, readername) def addtoreadergroup(self, groupname): """Add reader to a reader group.""" hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if 0 != hresult: raise EstablishContextException(hresult) try: hresult = SCardIntroduceReader(hcontext, self.name, self.name) if 0 != hresult and SCARD_E_DUPLICATE_READER != hresult: raise IntroduceReaderException(hresult, self.name) hresult = SCardAddReaderToGroup(hcontext, self.name, groupname) if 0 != hresult: raise AddReaderToGroupException(hresult, self.name, groupname) finally: hresult = SCardReleaseContext(hcontext) if 0 != hresult: raise ReleaseContextException(hresult) def removefromreadergroup(self, groupname): """Remove a reader from a reader group""" hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if 0 != hresult: raise EstablishContextException(hresult) try: hresult = SCardRemoveReaderFromGroup(hcontext, self.name, groupname) if 0 != hresult: raise RemoveReaderFromGroupException(hresult, self.name, groupname) finally: hresult = SCardReleaseContext(hcontext) if 0 != hresult: raise ReleaseContextException(hresult) def createConnection(self): """Return a card connection thru PCSC reader.""" return CardConnectionDecorator(PCSCCardConnection(self.name)) class Factory: def create(readername): return PCSCReader(readername) create = staticmethod(create) def readers(groups=[]): creaders = [] hcontext = PCSCContext().getContext() try: pcsc_readers = __PCSCreaders__(hcontext, groups) except CardServiceStoppedException: hcontext = PCSCContext.renewContext() pcsc_readers = __PCSCreaders__(hcontext, groups) for reader in pcsc_readers: creaders.append(PCSCReader.Factory.create(reader)) return creaders readers = staticmethod(readers) if __name__ == '__main__': from smartcard.util import * SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] creaders = PCSCReader.readers() for reader in creaders: try: print(reader.name) connection = reader.createConnection() connection.connect() print(toHexString(connection.getATR())) data, sw1, sw2 = connection.transmit(SELECT + DF_TELECOM) print("%02X %02X" % (sw1, sw2)) except NoCardException: print('no card in reader') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399602.0 pyscard-2.0.2/smartcard/pcsc/PCSCReaderGroups.py0000644000175000017500000000777400000000000022033 0ustar00rousseaurousseau"""PCSCReaderGroups organizes smartcard readers as groups. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.scard import * from smartcard.reader.ReaderGroups import readergroups, innerreadergroups from smartcard.pcsc.PCSCExceptions import * class pcscinnerreadergroups(innerreadergroups): """Smartcard PCSC readers groups inner class. The PCSCReaderGroups singleton manages the creation of the unique instance of this class. """ def __init__(self, initlist=None): """Constructor.""" innerreadergroups.__init__(self, initlist) self.unremovablegroups = ['SCard$DefaultReaders'] def getreadergroups(self): """ Returns the list of smartcard reader groups.""" innerreadergroups.getreadergroups(self) hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != 0: raise EstablishContextException(hresult) hresult, readers = SCardListReaderGroups(hcontext) if hresult != 0: raise ListReadersException(hresult) hresult = SCardReleaseContext(hcontext) if hresult != 0: raise ReleaseContextException(hresult) return readers def addreadergroup(self, newgroup): """Add a reader group""" hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if 0 != hresult: raise error( 'Failed to establish context: ' + \ SCardGetErrorMessage(hresult)) try: hresult = SCardIntroduceReaderGroup(hcontext, newgroup) if 0 != hresult: raise error( 'Unable to introduce reader group: ' + \ SCardGetErrorMessage(hresult)) else: innerreadergroups.addreadergroup(self, newgroup) finally: hresult = SCardReleaseContext(hcontext) if 0 != hresult: raise error( 'Failed to release context: ' + \ SCardGetErrorMessage(hresult)) def removereadergroup(self, group): """Remove a reader group""" hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if 0 != hresult: raise error( 'Failed to establish context: ' + \ SCardGetErrorMessage(hresult)) try: hresult = SCardForgetReaderGroup(hcontext, group) if hresult != 0: raise error( 'Unable to forget reader group: ' + \ SCardGetErrorMessage(hresult)) else: innerreadergroups.removereadergroup(self, group) finally: hresult = SCardReleaseContext(hcontext) if 0 != hresult: raise error( 'Failed to release context: ' + \ SCardGetErrorMessage(hresult)) class PCSCReaderGroups(readergroups): """PCSC readers groups.""" def __init__(self, initlist=None): """Create a single instance of pcscinnerreadergroups on first call""" self.innerclazz = pcscinnerreadergroups readergroups.__init__(self, initlist) if __name__ == '__main__': print(PCSCReaderGroups().getreadergroups()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/pcsc/__init__.py0000644000175000017500000000000000000000000020466 0ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/pyro/0000755000175000017500000000000000000000000016430 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399630.0 pyscard-2.0.2/smartcard/pyro/PyroReader.py0000644000175000017500000000613700000000000021065 0ustar00rousseaurousseau"""PyroReaderClient: concrete reader class for Remote Readers __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import Pyro.core import Pyro.naming from smartcard.Exceptions import NoCardException from smartcard.reader.Reader import Reader class PyroReader(Reader): """Remote reader class.""" def __init__(self, readername): """Constructs a new Remote Reader client implementation from a Pyro URI.""" ns = Pyro.naming.NameServerLocator().getNS() self.uri = ns.resolve(':pyscard.smartcard.readers.' + readername) self.reader = Pyro.core.getAttrProxyForURI(self.uri) self.name = self.reader.name def addtoreadergroup(self, groupname): """Add reader to a reader group.""" self.reader.addtoreadergroup(groupname) def removefromreadergroup(self, groupname): """Remove a reader from a reader group""" self.reader.removefromreadergroup(groupname) def createConnection(self): """Return a card connection thru a remote reader.""" uri = self.reader.createConnection() return Pyro.core.getAttrProxyForURI(uri) class Factory: def create(readername): return PyroReader(readername) create = staticmethod(create) def readers(groups=[]): readernames = [] try: ns = Pyro.naming.NameServerLocator().getNS() readernames = ns.list(':pyscard.smartcard.readers') except Pyro.errors.NamingError: print('Warning: pyro name server not found') remotereaders = [] for readername in readernames: remotereaders.append(PyroReader.Factory.create(readername[0])) return remotereaders readers = staticmethod(readers) if __name__ == '__main__': SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] from smartcard.util import * remotereaders = PyroReader.readers() for reader in remotereaders: try: print(reader.name, ', uri: ', reader.uri) connection = reader.createConnection() connection.connect() print(toHexString(connection.getATR())) data, sw1, sw2 = connection.transmit(SELECT + DF_TELECOM) print("%X %X" % (sw1, sw2)) except NoCardException as x: print('no card in reader') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/pyro/__init__.py0000644000175000017500000000157200000000000020546 0ustar00rousseaurousseau"""pyro (remote python) utility module. __author__ = "http://www.gemalto.com" Copyright 2011 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/reader/0000755000175000017500000000000000000000000016701 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/reader/Reader.py0000644000175000017500000000405400000000000020460 0ustar00rousseaurousseau"""Smart card Reader abstract class. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ class Reader(object): """Reader abstract class. The reader class is responsible for creating connections with a card. Known subclasses: PCSCReader """ def __init__(self, readername): """Constructs a new reader and store readername.""" self.name = readername def addtoreadergroup(self, groupname): """Add reader to a reader group.""" pass def removefromreadergroup(self, groupname): """Remove reader from a reader group.""" pass def createConnection(self): """Returns a card connection thru reader.""" pass def __eq__(self, other): """Returns True if self==other (same name).""" if type(other) == type(self): return self.name == other.name else: return False def __hash__(self): """Returns a hash value for this object (self.name is unique).""" return hash(self.name) def __repr__(self): """Returns card reader name string for `object` calls.""" return "'%s'" % self.name def __str__(self): """Returns card reader name string for str(object) calls.""" return self.name ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/reader/ReaderFactory.py0000644000175000017500000000401000000000000022000 0ustar00rousseaurousseau"""ReaderFactory: creates smartcard readers. __author__ = "gemalto http://www.gemalto.com" Factory pattern implementation borrowed from Thinking in Python, Bruce Eckel, http://mindview.net/Books/TIPython The code to instanciate the reader Factory() has been updated to dynamically load the module with Robert Brewer ClassLoader.py. Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.ClassLoader import get_class from smartcard.pcsc.PCSCReader import PCSCReader class ReaderFactory(object): """Class to create readers from reader type id.""" factories = {} factorymethods = [PCSCReader.readers] # A Template Method: def createReader(clazz, readername): """Static method to create a reader from a reader clazz. @param clazz: the reader class name @param readername: the reader name """ if not clazz in ReaderFactory.factories: ReaderFactory.factories[clazz] = get_class(clazz).Factory() return ReaderFactory.factories[clazz].create(readername) createReader = staticmethod(createReader) def readers(groups=[]): zreaders = [] for fm in ReaderFactory.factorymethods: zreaders += fm(groups) return zreaders readers = staticmethod(readers) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399678.0 pyscard-2.0.2/smartcard/reader/ReaderGroups.py0000644000175000017500000000715000000000000021660 0ustar00rousseaurousseau"""ReaderGroups manages smart card reader in groups. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.Exceptions import SmartcardException from smartcard.ulist import ulist class BadReaderGroupException(SmartcardException): """Raised when trying to add an invalid reader group.""" def __init__(self): SmartcardException.__init__(self, 'Invalid reader group') class DeleteSCardDefaultReaderGroupException(SmartcardException): """Raised when trying to delete SCard$DefaultReaders reader group.""" def __init__(self): SmartcardException.__init__( self, 'SCard$DefaultReaders cannot be deleted') class innerreadergroups(ulist): """Smartcard readers groups private class. The readergroups singleton manages the creation of the unique instance of this class. """ def __init__(self, initlist=None): """Retrieve and store list of reader groups""" if None == initlist: initlist = self.getreadergroups() if None != initlist: ulist.__init__(self, initlist) self.unremovablegroups = [] def __onadditem__(self, item): """Called when a reader group is added.""" self.addreadergroup(item) def __onremoveitem__(self, item): """Called when a reader group is added.""" self.removereadergroup(item) def __iter__(self): return ulist.__iter__(self) def next(self): return ulist.__next__(self) # # abstract methods implemented in subclasses # def getreadergroups(self): """Returns the list of smartcard reader groups.""" return [] def addreadergroup(self, newgroup): """Add a reader group""" if not isinstance(newgroup, type("")): raise BadReaderGroupException self += newgroup def removereadergroup(self, group): """Remove a reader group""" if not isinstance(group, type("")): raise BadReaderGroupException self.remove(group) def addreadertogroup(self, readername, groupname): """Add a reader to a reader group""" pass def removereaderfromgroup(self, readername, groupname): """Remove a reader from a reader group""" pass class readergroups(object): """ReadersGroups organizes smart card reader as groups.""" """The single instance of __readergroups""" instance = None innerclazz = innerreadergroups def __init__(self, initlist=None): """Create a single instance of innerreadergroups on first call""" if None == readergroups.instance: readergroups.instance = self.innerclazz(initlist) """All operators redirected to inner class.""" def __getattr__(self, name): return getattr(self.instance, name) if __name__ == '__main__': print(readergroups()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/reader/__init__.py0000644000175000017500000000000000000000000021000 0ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/scard/0000755000175000017500000000000000000000000016533 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/PcscDefs.i0000644000175000017500000003251200000000000020402 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ typedef enum { SCARD_SCOPE_USER, SCARD_SCOPE_TERMINAL, SCARD_SCOPE_SYSTEM } ScopeType ; typedef enum { SCARD_SHARE_SHARED, SCARD_SHARE_EXCLUSIVE, SCARD_SHARE_DIRECT } ShareType ; typedef enum { SCARD_LEAVE_CARD, SCARD_RESET_CARD, SCARD_UNPOWER_CARD, SCARD_EJECT_CARD } DispositionType ; typedef enum { SCARD_STATE_UNAWARE, SCARD_STATE_IGNORE, SCARD_STATE_CHANGED, SCARD_STATE_UNKNOWN, SCARD_STATE_UNAVAILABLE, SCARD_STATE_EMPTY, SCARD_STATE_PRESENT, SCARD_STATE_ATRMATCH, SCARD_STATE_EXCLUSIVE, SCARD_STATE_INUSE, SCARD_STATE_MUTE } StateType ; // SCARD_STATE_UNPOWERED is not defined on Windows and old Mac OS X %constant unsigned long SCARD_STATE_UNPOWERED = 0x0400 ; // protocols #ifdef WIN32 typedef enum { SCARD_PROTOCOL_UNDEFINED, SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1, SCARD_PROTOCOL_RAW, SCARD_PROTOCOL_Tx, SCARD_PROTOCOL_DEFAULT, SCARD_PROTOCOL_OPTIMAL } ProtocolType ; // define pcsc lite constants for winscard %constant unsigned long SCARD_PROTOCOL_UNSET = SCARD_PROTOCOL_UNDEFINED ; %constant unsigned long SCARD_PROTOCOL_ANY = SCARD_PROTOCOL_Tx ; %constant unsigned long SCARD_PROTOCOL_T15 = 0x00000008 ; #endif #ifdef PCSCLITE #ifdef __APPLE__ typedef enum { SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1, SCARD_PROTOCOL_RAW, SCARD_PROTOCOL_ANY } ProtocolType ; %constant unsigned long SCARD_PROTOCOL_UNSET = SCARD_PROTOCOL_ANY ; %constant unsigned long SCARD_PROTOCOL_T15 = 0x00000008 ; %constant unsigned long SCARD_PROTOCOL_UNDEFINED = 0 ; %constant unsigned long SCARD_PROTOCOL_OPTIMAL = SCARD_PROTOCOL_ANY ; #else //__APPLE__ typedef enum { SCARD_PROTOCOL_UNSET, SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1, SCARD_PROTOCOL_RAW, SCARD_PROTOCOL_T15, SCARD_PROTOCOL_ANY } ProtocolType ; %constant unsigned long SCARD_PROTOCOL_UNDEFINED = SCARD_PROTOCOL_UNSET ; %constant unsigned long SCARD_PROTOCOL_OPTIMAL = SCARD_PROTOCOL_UNSET ; #endif //!__APPLE__ // define winscard constants for pcsc lite %constant unsigned long SCARD_PROTOCOL_Tx = SCARD_PROTOCOL_ANY ; %constant unsigned long SCARD_PROTOCOL_DEFAULT = SCARD_PROTOCOL_ANY ; #endif //PCSCLITE %constant unsigned long SCARD_PCI_T0 = 0x01 ; %constant unsigned long SCARD_PCI_T1 = 0x02 ; %constant unsigned long SCARD_PCI_RAW = 0x04 ; #ifdef WIN32 typedef enum { SCARD_PROVIDER_PRIMARY, SCARD_PROVIDER_CSP } ProviderType ; typedef enum { SCARD_ATTR_VENDOR_NAME, SCARD_ATTR_VENDOR_IFD_TYPE, SCARD_ATTR_VENDOR_IFD_VERSION, SCARD_ATTR_VENDOR_IFD_SERIAL_NO, SCARD_ATTR_CHANNEL_ID, SCARD_ATTR_DEFAULT_CLK, SCARD_ATTR_MAX_CLK, SCARD_ATTR_DEFAULT_DATA_RATE, SCARD_ATTR_MAX_DATA_RATE, SCARD_ATTR_MAX_IFSD, SCARD_ATTR_POWER_MGMT_SUPPORT, SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE, SCARD_ATTR_USER_AUTH_INPUT_DEVICE, SCARD_ATTR_CHARACTERISTICS, SCARD_ATTR_CURRENT_PROTOCOL_TYPE, SCARD_ATTR_CURRENT_CLK, SCARD_ATTR_CURRENT_F, SCARD_ATTR_CURRENT_D, SCARD_ATTR_CURRENT_N, SCARD_ATTR_CURRENT_W, SCARD_ATTR_CURRENT_IFSC, SCARD_ATTR_CURRENT_IFSD, SCARD_ATTR_CURRENT_BWT, SCARD_ATTR_CURRENT_CWT, SCARD_ATTR_CURRENT_EBC_ENCODING, SCARD_ATTR_EXTENDED_BWT, SCARD_ATTR_ICC_PRESENCE, SCARD_ATTR_ICC_INTERFACE_STATUS, SCARD_ATTR_CURRENT_IO_STATE, SCARD_ATTR_ATR_STRING, SCARD_ATTR_ICC_TYPE_PER_ATR, SCARD_ATTR_ESC_RESET, SCARD_ATTR_ESC_CANCEL, SCARD_ATTR_ESC_AUTHREQUEST, SCARD_ATTR_MAXINPUT, SCARD_ATTR_DEVICE_UNIT, SCARD_ATTR_DEVICE_IN_USE, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, SCARD_ATTR_DEVICE_SYSTEM_NAME_A, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, SCARD_ATTR_DEVICE_SYSTEM_NAME_W, SCARD_ATTR_SUPRESS_T1_IFS_REQUEST } AttributeType ; typedef enum { // from winerror.h ERROR_ALREADY_EXISTS } ErrorTypeWin32Only; #endif // WIN32 #ifdef PCSCLITE typedef enum { SCARD_ATTR_VENDOR_NAME , SCARD_ATTR_VENDOR_IFD_TYPE , SCARD_ATTR_VENDOR_IFD_VERSION , SCARD_ATTR_VENDOR_IFD_SERIAL_NO , SCARD_ATTR_CHANNEL_ID , SCARD_ATTR_ASYNC_PROTOCOL_TYPES , SCARD_ATTR_DEFAULT_CLK , SCARD_ATTR_MAX_CLK , SCARD_ATTR_DEFAULT_DATA_RATE , SCARD_ATTR_MAX_DATA_RATE , SCARD_ATTR_MAX_IFSD , SCARD_ATTR_SYNC_PROTOCOL_TYPES , SCARD_ATTR_POWER_MGMT_SUPPORT , SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE , SCARD_ATTR_USER_AUTH_INPUT_DEVICE , SCARD_ATTR_CHARACTERISTICS , SCARD_ATTR_CURRENT_PROTOCOL_TYPE , SCARD_ATTR_CURRENT_CLK , SCARD_ATTR_CURRENT_F , SCARD_ATTR_CURRENT_D , SCARD_ATTR_CURRENT_N , SCARD_ATTR_CURRENT_W , SCARD_ATTR_CURRENT_IFSC , SCARD_ATTR_CURRENT_IFSD , SCARD_ATTR_CURRENT_BWT , SCARD_ATTR_CURRENT_CWT , SCARD_ATTR_CURRENT_EBC_ENCODING , SCARD_ATTR_EXTENDED_BWT , SCARD_ATTR_ICC_PRESENCE , SCARD_ATTR_ICC_INTERFACE_STATUS , SCARD_ATTR_CURRENT_IO_STATE , SCARD_ATTR_ATR_STRING , SCARD_ATTR_ICC_TYPE_PER_ATR , SCARD_ATTR_ESC_RESET , SCARD_ATTR_ESC_CANCEL , SCARD_ATTR_ESC_AUTHREQUEST , SCARD_ATTR_MAXINPUT , SCARD_ATTR_DEVICE_UNIT , SCARD_ATTR_DEVICE_IN_USE , SCARD_ATTR_DEVICE_FRIENDLY_NAME_A , SCARD_ATTR_DEVICE_SYSTEM_NAME_A , SCARD_ATTR_DEVICE_FRIENDLY_NAME_W , SCARD_ATTR_DEVICE_SYSTEM_NAME_W , SCARD_ATTR_SUPRESS_T1_IFS_REQUEST } AttributeType ; %constant unsigned long SCARD_ATTR_DEVICE_FRIENDLY_NAME = SCARD_ATTR_DEVICE_FRIENDLY_NAME_A ; %constant unsigned long SCARD_ATTR_DEVICE_SYSTEM_NAME = SCARD_ATTR_DEVICE_SYSTEM_NAME_A ; #endif //PCSCLITE /* int and unsigned long are different on 64-bits systems */ #ifdef __APPLE__ #define TYPE int #else #define TYPE long #endif %constant TYPE SCARD_S_SUCCESS = SCARD_S_SUCCESS ; %constant TYPE SCARD_F_INTERNAL_ERROR = SCARD_F_INTERNAL_ERROR ; %constant TYPE SCARD_E_CANCELLED = SCARD_E_CANCELLED ; %constant TYPE SCARD_E_INVALID_HANDLE = SCARD_E_INVALID_HANDLE ; %constant TYPE SCARD_E_INVALID_PARAMETER = SCARD_E_INVALID_PARAMETER ; %constant TYPE SCARD_E_INVALID_TARGET = SCARD_E_INVALID_TARGET ; %constant TYPE SCARD_E_NO_MEMORY = SCARD_E_NO_MEMORY ; %constant TYPE SCARD_F_WAITED_TOO_LONG = SCARD_F_WAITED_TOO_LONG ; %constant TYPE SCARD_E_INSUFFICIENT_BUFFER = SCARD_E_INSUFFICIENT_BUFFER ; %constant TYPE SCARD_E_UNKNOWN_READER = SCARD_E_UNKNOWN_READER ; %constant TYPE SCARD_E_TIMEOUT = SCARD_E_TIMEOUT ; %constant TYPE SCARD_E_SHARING_VIOLATION = SCARD_E_SHARING_VIOLATION ; %constant TYPE SCARD_E_NO_SMARTCARD = SCARD_E_NO_SMARTCARD ; %constant TYPE SCARD_E_UNKNOWN_CARD = SCARD_E_UNKNOWN_CARD ; %constant TYPE SCARD_E_CANT_DISPOSE = SCARD_E_CANT_DISPOSE ; %constant TYPE SCARD_E_PROTO_MISMATCH = SCARD_E_PROTO_MISMATCH ; %constant TYPE SCARD_E_NOT_READY = SCARD_E_NOT_READY ; %constant TYPE SCARD_E_INVALID_VALUE = SCARD_E_INVALID_VALUE ; %constant TYPE SCARD_E_SYSTEM_CANCELLED = SCARD_E_SYSTEM_CANCELLED ; %constant TYPE SCARD_F_COMM_ERROR = SCARD_F_COMM_ERROR ; %constant TYPE SCARD_F_UNKNOWN_ERROR = SCARD_F_UNKNOWN_ERROR ; %constant TYPE SCARD_E_INVALID_ATR = SCARD_E_INVALID_ATR ; %constant TYPE SCARD_E_NOT_TRANSACTED = SCARD_E_NOT_TRANSACTED ; %constant TYPE SCARD_E_READER_UNAVAILABLE = SCARD_E_READER_UNAVAILABLE ; %constant TYPE SCARD_E_PCI_TOO_SMALL = SCARD_E_PCI_TOO_SMALL ; %constant TYPE SCARD_E_READER_UNSUPPORTED = SCARD_E_READER_UNSUPPORTED ; %constant TYPE SCARD_E_DUPLICATE_READER = SCARD_E_DUPLICATE_READER ; %constant TYPE SCARD_E_CARD_UNSUPPORTED = SCARD_E_CARD_UNSUPPORTED ; %constant TYPE SCARD_E_NO_SERVICE = SCARD_E_NO_SERVICE ; %constant TYPE SCARD_E_SERVICE_STOPPED = SCARD_E_SERVICE_STOPPED ; #ifdef SCARD_E_NO_READERS_AVAILABLE %constant TYPE SCARD_E_NO_READERS_AVAILABLE = SCARD_E_NO_READERS_AVAILABLE ; #else %constant TYPE SCARD_E_NO_READERS_AVAILABLE = 0x8010002E ; #endif %constant TYPE SCARD_E_UNSUPPORTED_FEATURE = SCARD_E_UNSUPPORTED_FEATURE ; %constant TYPE SCARD_W_UNSUPPORTED_CARD = SCARD_W_UNSUPPORTED_CARD ; %constant TYPE SCARD_W_UNRESPONSIVE_CARD = SCARD_W_UNRESPONSIVE_CARD ; %constant TYPE SCARD_W_UNPOWERED_CARD = SCARD_W_UNPOWERED_CARD ; %constant TYPE SCARD_W_RESET_CARD = SCARD_W_RESET_CARD ; %constant TYPE SCARD_W_REMOVED_CARD = SCARD_W_REMOVED_CARD ; #ifdef SCARD_W_SECURITY_VIOLATION /* introduced in pcsc-lite > 1.5.2 */ %constant TYPE SCARD_W_SECURITY_VIOLATION = SCARD_W_SECURITY_VIOLATION ; %constant TYPE SCARD_W_WRONG_CHV = SCARD_W_WRONG_CHV ; %constant TYPE SCARD_W_CHV_BLOCKED = SCARD_W_CHV_BLOCKED ; %constant TYPE SCARD_W_EOF = SCARD_W_EOF ; %constant TYPE SCARD_W_CANCELLED_BY_USER = SCARD_W_CANCELLED_BY_USER ; %constant TYPE SCARD_W_CARD_NOT_AUTHENTICATED = SCARD_W_CARD_NOT_AUTHENTICATED ; %constant TYPE SCARD_E_UNEXPECTED = SCARD_E_UNEXPECTED ; %constant TYPE SCARD_E_ICC_INSTALLATION = SCARD_E_ICC_INSTALLATION ; %constant TYPE SCARD_E_ICC_CREATEORDER = SCARD_E_ICC_CREATEORDER ; %constant TYPE SCARD_E_DIR_NOT_FOUND = SCARD_E_DIR_NOT_FOUND ; %constant TYPE SCARD_E_FILE_NOT_FOUND = SCARD_E_FILE_NOT_FOUND ; %constant TYPE SCARD_E_NO_DIR = SCARD_E_NO_DIR ; %constant TYPE SCARD_E_NO_FILE = SCARD_E_NO_FILE ; %constant TYPE SCARD_E_NO_ACCESS = SCARD_E_NO_ACCESS ; %constant TYPE SCARD_E_WRITE_TOO_MANY = SCARD_E_WRITE_TOO_MANY ; %constant TYPE SCARD_E_BAD_SEEK = SCARD_E_BAD_SEEK ; %constant TYPE SCARD_E_INVALID_CHV = SCARD_E_INVALID_CHV ; %constant TYPE SCARD_E_UNKNOWN_RES_MNG = SCARD_E_UNKNOWN_RES_MNG ; %constant TYPE SCARD_E_NO_SUCH_CERTIFICATE = SCARD_E_NO_SUCH_CERTIFICATE ; %constant TYPE SCARD_E_CERTIFICATE_UNAVAILABLE = SCARD_E_CERTIFICATE_UNAVAILABLE ; %constant TYPE SCARD_E_COMM_DATA_LOST = SCARD_E_COMM_DATA_LOST ; %constant TYPE SCARD_E_NO_KEY_CONTAINER = SCARD_E_NO_KEY_CONTAINER ; %constant TYPE SCARD_E_SERVER_TOO_BUSY = SCARD_E_SERVER_TOO_BUSY ; #else %constant TYPE SCARD_W_SECURITY_VIOLATION = 0x8010006A ; %constant TYPE SCARD_W_WRONG_CHV = 0x8010006B ; %constant TYPE SCARD_W_CHV_BLOCKED = 0x8010006C ; %constant TYPE SCARD_W_EOF = 0x8010006D ; %constant TYPE SCARD_W_CANCELLED_BY_USER = 0x8010006E ; %constant TYPE SCARD_W_CARD_NOT_AUTHENTICATED = 0x8010006F ; %constant TYPE SCARD_E_UNEXPECTED = 0x8010001F ; %constant TYPE SCARD_E_ICC_INSTALLATION = 0x80100020 ; %constant TYPE SCARD_E_ICC_CREATEORDER = 0x80100021 ; %constant TYPE SCARD_E_DIR_NOT_FOUND = 0x80100023 ; %constant TYPE SCARD_E_FILE_NOT_FOUND = 0x80100024 ; %constant TYPE SCARD_E_NO_DIR = 0x80100025 ; %constant TYPE SCARD_E_NO_FILE = 0x80100026 ; %constant TYPE SCARD_E_NO_ACCESS = 0x80100027 ; %constant TYPE SCARD_E_WRITE_TOO_MANY = 0x80100028 ; %constant TYPE SCARD_E_BAD_SEEK = 0x80100029 ; %constant TYPE SCARD_E_INVALID_CHV = 0x8010002A ; %constant TYPE SCARD_E_UNKNOWN_RES_MNG = 0x8010002B ; %constant TYPE SCARD_E_NO_SUCH_CERTIFICATE = 0x8010002C ; %constant TYPE SCARD_E_CERTIFICATE_UNAVAILABLE = 0x8010002D ; %constant TYPE SCARD_E_COMM_DATA_LOST = 0x8010002F ; %constant TYPE SCARD_E_NO_KEY_CONTAINER = 0x80100030 ; %constant TYPE SCARD_E_SERVER_TOO_BUSY = 0x80100031 ; #endif #ifdef WIN32 typedef enum { ERROR_INVALID_HANDLE } Win32ErrorType ; #endif //WIN32 #ifdef PCSCLITE %constant unsigned long INVALID_HANDLE = SCARD_E_INVALID_HANDLE ; #endif //PCSCLITE // this error code is defined outside the enum, since it is available // on winscard only (e.g. not in pcsc lite) %constant unsigned long SCARD_P_SHUTDOWN = 0x80100018 ; // Infinite timeout %constant unsigned long INFINITE = 0x7FFFFFFF ; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/PcscTypemaps.i0000644000175000017500000003461500000000000021331 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ // Tell SWIG to wrap all the wrappers with Python's thread macros %exception { Py_BEGIN_ALLOW_THREADS; $function Py_END_ALLOW_THREADS; } /*============================================================================== // // support for list of BYTEs, aka BYTELIST // ==============================================================================*/ #ifdef SWIG(python) #endif %typemap(in,numinputs=0) BYTELIST *OUTPUT(BYTELIST temp) { $1 = &temp; $1->ab = NULL; $1->bAllocated=FALSE; } // builds a byte list from a Python list %typemap(in) BYTELIST* INPUT(BYTELIST*) { $1 = SCardHelper_PyByteListToBYTELIST( $input ); if (NULL == $1) goto fail; } // release bytelist arg %typemap(freearg) BYTELIST* { if(NULL!=$1) { if(NULL!=$1->ab) { mem_Free( $1->ab ); } if($1->bAllocated==TRUE) { mem_Free( $1 ); } } } // builds a Python list from a byte list %typemap(argout) BYTELIST *OUTPUT { SCardHelper_AppendByteListToPyObject( $1, &$result ); } // other names for BYTELIST as INPUT parameter %apply BYTELIST* INPUT { BYTELIST* ATR }; %apply BYTELIST* INPUT { BYTELIST* ATTRIBUTESIN }; %apply BYTELIST* INPUT { BYTELIST* MASK }; %apply BYTELIST* INPUT { BYTELIST* APDUCOMMAND }; %apply BYTELIST* INPUT { BYTELIST* INBUFFER }; // other names for BYTELIST as OUTPUT parameter %apply BYTELIST* OUTPUT { BYTELIST* ATROUT }; %apply BYTELIST* OUTPUT { BYTELIST* ATTRIBUTES }; %apply BYTELIST* OUTPUT { BYTELIST* APDURESPONSE }; %apply BYTELIST* OUTPUT { BYTELIST* OUTBUFFER }; /*============================================================================== // // support for ERRORSTRING // ==============================================================================*/ // on win32, the ERRORSTRING is allocated and // must be free'd with Local Free // release ERRORSTRING OUTPUT argument. // on pcsc-lite, the error string is not allocated, // i.e. nothing to do. %typemap(ret) ERRORSTRING* { #ifdef WIN32 if(NULL!=$1) { HLOCAL hlocal = LocalFree( $1 ); if(NULL!=hlocal) { fprintf( stderr, "Failed to free error message string!\n" ); } } #endif // WIN32 } // builds a Python string from a STRING %typemap(out) ERRORSTRING* { SCardHelper_OutErrorStringAsPyObject( $1, &$result ); } /*============================================================================== // // support for GUIDLIST // ==============================================================================*/ %typemap(in,numinputs=0) GUIDLIST *OUTPUT(GUIDLIST temp) { $1 = &temp; $1->bAllocated=FALSE; } // release GUIDLIST INPUT argument // for input arg, GUIDLIST was allocated from the heap // i.e. $1 has to be freed %typemap(freearg) GUIDLIST* INPUT { if(NULL!=$1) { if(NULL!=$1->aguid) { if($1->hcontext) { unsigned long lRes=(mySCardFreeMemory)( $1->hcontext, $1->aguid ); if (lRes!=SCARD_S_SUCCESS) { fprintf( stderr, "kaboom!\n" ); } } else { mem_Free( $1->aguid ); } } mem_Free( $1 ); } } // release GUIDLIST OUTPUT argument // for output arg, GUIDLIST was not allocated // from the heap, but from the stack // i.e. $1 must not be freed %typemap(freearg) GUIDLIST* OUTPUT { if(NULL!=$1) { if(NULL!=$1->aguid) { if($1->hcontext) { unsigned long lRes=(mySCardFreeMemory)( $1->hcontext, $1->aguid ); if (lRes!=SCARD_S_SUCCESS) { fprintf( stderr, "kaboom!\n" ); } } else { mem_Free( $1->aguid ); } } } } // builds a win32 string list from a Python list %typemap(in) GUIDLIST* INPUT(GUIDLIST*) { $1 = SCardHelper_PyGuidListToGUIDLIST( $input ); if (NULL == $1) goto fail; } // builds a Python list from a GUID list %typemap(argout) GUIDLIST *OUTPUT { SCardHelper_AppendGuidListToPyObject( $1, &$result ); } // other names for GUIDLIST as INPUT parameter %apply GUIDLIST* INPUT { GUIDLIST* PRIMARYPROVIDER }; %apply GUIDLIST* INPUT { GUIDLIST* PROVIDERLIST }; // other names for GUIDLIST as OUTPUT parameter %apply GUIDLIST* OUTPUT { GUIDLIST* GUIDINTERFACES }; /*============================================================================== // // support for READERSTATELIST* // ==============================================================================*/ %typemap(in,numinputs=0) READERSTATELIST *OUTPUT(READERSTATELIST temp) { $1 = &temp; } // release READERSTATELIST INPUT/OUTPUT argument // for input arg, READERSTATELIST was allocated from the heap // i.e. $1 has to be freed %typemap(freearg) READERSTATELIST* BOTH { if(NULL!=$1) { int i; for(i=0; i<$1->cRStates; i++ ) { if($1->aszReaderNames[i]) { mem_Free( $1->aszReaderNames[i] ); } } if(NULL!=$1->ars) { mem_Free( $1->ars ); } if(NULL!=$1->aszReaderNames) { mem_Free( $1->aszReaderNames ); } mem_Free( $1 ); } } // release READERSTATELIST OUTPUT argument // for output arg, READERSTATELIST was not allocated // from the heap, but from the stack // i.e. $1 must not be freed %typemap(freearg) READERSTATELIST* OUTPUT { if(NULL!=$1) { int i; for(i=0; i<$1->cRStates; i++ ) { if($1->aszReaderNames[i]) { mem_Free( $1->aszReaderNames[i] ); } } if(NULL!=$1->ars) { mem_Free( $1->ars ); } if(NULL!=$1->aszReaderNames) { mem_Free( $1->aszReaderNames ); } } } // builds a READERSTATE list string list from a Python list %typemap(in) READERSTATELIST *prsl(READERSTATELIST*) { $1 = SCardHelper_PyReaderStateListToREADERSTATELIST( $input ); if (NULL == $1) goto fail; } // builds a Python list from a win32 string list %typemap(argout) READERSTATELIST *prsl { SCardHelper_AppendReaderStateListToPyObject( $1, &$result ); } // reader state list as input and output //%typemap(in) READERSTATELIST *BOTH = READERSTATELIST *prsl; //%typemap(argout) READERSTATELIST *BOTH = READERSTATELIST *prsl; // other names for READERSTATELIST as inpu/output parameter %apply READERSTATELIST *BOTH {READERSTATELIST* prsl}; /*============================================================================== // // support for SCARDCONTEXT // ==============================================================================*/ %typemap(in,numinputs=0) SCARDCONTEXT *OUTPUT(SCARDCONTEXT temp) { $1 = &temp; } %typemap(in) SCARDCONTEXT hcontext(SCARDCONTEXT) { $1 = SCardHelper_PyScardContextToSCARDCONTEXT( $input ); if (0 == $1) goto fail; } %typemap(argout) SCARDCONTEXT *OUTPUT { SCardHelper_AppendSCardContextToPyObject( *$1, &$result ); } // different names for SCARDCONTEXT OUTPUT parameters %apply SCARDCONTEXT* OUTPUT { SCARDCONTEXT* phcontext }; /*============================================================================== // // support for SCARDDWORDARG // ==============================================================================*/ %typemap(in,numinputs=0) SCARDDWORDARG *OUTPUT(SCARDDWORDARG temp) { $1 = &temp; } %typemap(in) SCARDDWORDARG INPUT(SCARDDWORDARG) { $1 = SCardHelper_PySCardDwordArgToSCARDDWORDARG( $input ); if (-1 == $1) goto fail; } %typemap(argout) SCARDDWORDARG* OUTPUT { SCardHelper_AppendSCardDwordArgToPyObject( *$1, &$result ); } // different names for SCARDWORDARG INPUT parameters %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwProviderId }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwShareMode }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwPreferredProtocols }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwDisposition }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwScope }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwAttrId }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwTimeout }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwInitialization }; %apply SCARDDWORDARG INPUT { SCARDDWORDARG dwControlCode }; // different names for SCARDWORDARG OUTPUT parameters %apply SCARDDWORDARG* OUTPUT { SCARDDWORDARG* pdwActiveProtocol }; %apply SCARDDWORDARG* OUTPUT { SCARDDWORDARG* pdwProtocol }; %apply SCARDDWORDARG* OUTPUT { SCARDDWORDARG* pdwState }; /*============================================================================== // // support for SCARDHANDLE // ==============================================================================*/ %typemap(in,numinputs=0) SCARDHANDLE *OUTPUT(SCARDHANDLE temp) { $1 = &temp; } %typemap(in) SCARDHANDLE hcard(SCARDHANDLE) { $1 = SCardHelper_PyScardHandleToSCARDHANDLE( $input ); if (0 == $1) goto fail; } %typemap(argout) SCARDHANDLE* OUTPUT { SCardHelper_AppendSCardHandleToPyObject( *$1, &$result ); } // different names for SCARDHANDLE OUTPUT parameters %apply SCARDHANDLE* OUTPUT { SCARDHANDLE* phcard }; /*============================================================================== // // support for SCARDRETCODE // ==============================================================================*/ %typemap(out) SCARDRETCODE { $result = PyLong_FromLong((long)$1); } /*============================================================================== // // support for STRING // ==============================================================================*/ // release STRING INPUT argument. // string is allocated in SCardHelper_PyStringToString // string->sz is always allocated %typemap(freearg) STRING* INPUT { if(NULL!=$1) { if(NULL!=$1->sz) { if($1->hcontext) { unsigned long lRes=(mySCardFreeMemory)( $1->hcontext, $1->sz ); if (lRes!=SCARD_S_SUCCESS) { fprintf( stderr, "kaboom!\n" ); } } else { mem_Free( $1->sz ); } $1->sz=NULL; } mem_Free( $1 ); } } // release STRING OUTPUT argument. // string is not allocated // string->sz is always allocated %typemap(freearg) STRING* OUTPUT { if(NULL!=$1) { if(NULL!=$1->sz) { if($1->hcontext) { unsigned long lRes=(mySCardFreeMemory)( $1->hcontext, $1->sz ); if (lRes!=SCARD_S_SUCCESS) { fprintf( stderr, "kaboom!\n" ); } } else { mem_Free( $1->sz ); } $1->sz=NULL; } } } // force the argument to be ignored %typemap(in,numinputs=0) STRING *OUTPUT(STRING temp) { $1 = &temp; $1->bAllocated=FALSE; } // builds a string from a Python string %typemap(in) STRING *INPUT( STRING ) { $1 = SCardHelper_PyStringToString( $input ); if (NULL == $1) goto fail; } // builds a Python string from a STRING %typemap(argout) STRING *OUTPUT { SCardHelper_AppendStringToPyObject( $1, &$result ); } // other names for STRING as output parameter %apply STRING* OUTPUT { PROVIDERNAME_t* pszProviderName }; %apply STRING* OUTPUT { STRING* pszReaderNameOut }; /*============================================================================== // // support for STRINGLIST // SCardxxx API stores multi-strings as a concatenation // of strings terminated by a null, e.g. // item0\0item2\0lastitem\0\0 // ==============================================================================*/ // for OUTPUT STRINGLIST, free the allocated buffer // for winscard, the buffer is automatically allocated and // has to be freed by SCardFreeMemory. // for pcsclite, the buffer is allocated with mem_Malloc and // has to be freed by mem_Free. %typemap(freearg) STRINGLIST* { if(NULL!=$1) { if(NULL!=$1->ac) { if($1->hcontext) { unsigned long lRes=(mySCardFreeMemory)( $1->hcontext, $1->ac ); if (lRes!=SCARD_S_SUCCESS) { fprintf( stderr, "Failed to SCardFreeMemory!\n" ); } } else { if( NULL!=$1->ac ) { mem_Free( $1->ac ); } } } if($1->bAllocated==TRUE) { mem_Free( $1 ); } } } %typemap(in,numinputs=0) STRINGLIST *OUTPUT(STRINGLIST temp) { $1 = &temp; $1->bAllocated=FALSE; } // builds a win32 string list from a Python list %typemap(in) STRINGLIST* INPUT(STRINGLIST*) { $1 = SCardHelper_PyStringListToStringList( $input ); if (NULL == $1) goto fail; } // builds a Python list from a win32 string list %typemap(argout) STRINGLIST *OUTPUT { SCardHelper_AppendStringListToPyObject( $1, &$result ); } // other names for STRINGLIST as input parameter %apply STRINGLIST* INPUT { STRINGLIST* CARDSTOLOCATE }; %apply STRINGLIST* INPUT { STRINGLIST* psl }; %apply STRINGLIST* INPUT { STRINGLIST* READERGROUPSIN }; // other names for STRINGLIST as output parameter %apply STRINGLIST* OUTPUT { STRINGLIST* MATCHINGCARDS }; %apply STRINGLIST* OUTPUT { STRINGLIST* READERSFOUND }; %apply STRINGLIST* OUTPUT { STRINGLIST* READERGROUPSOUT }; %apply STRINGLIST* OUTPUT { STRINGLIST* pszReaderName }; //#endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/__init__.py0000644000175000017500000000004400000000000020642 0ustar00rousseaurousseaufrom smartcard.scard.scard import * ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/gemalto.ver0000644000175000017500000000674500000000000020715 0ustar00rousseaurousseau#ifndef VER_COMPANYNAME_STR #define VER_COMPANYNAME_STR "gemalto\0" #endif #ifndef VER_LEGALCOPYRIGHT_YEARS #define VER_LEGALCOPYRIGHT_YEARS "2001-2012" #endif #ifndef VER_LEGALCOPYRIGHT_STR #define VER_LEGALCOPYRIGHT_STR "Copyright \251 gemalto" VER_LEGALCOPYRIGHT_YEARS #endif #ifndef VER_PRODUCTNAME_STR #define VER_PRODUCTNAME_STR "Smart Cards Sofware Development Tools" #endif /* VER_PRODUCTVERSION and VER_PRODUCTVERSION_STR are provided by setup.py */ #ifndef VER_FILEVERSION #define VER_FILEVERSION VER_PRODUCTVERSION #endif #ifndef VER_FILEFLAGSMASK #define VER_FILEFLAGSMASK (VS_FF_DEBUG | VS_FF_PRERELEASE) #endif #ifndef VER_FILEFLAGS #ifdef DEBUG #define VER_FILEFLAGS (VS_FF_DEBUG) #else #define VER_FILEFLAGS (0) #endif #endif #ifndef VER_FILEOS #ifdef WIN32 #define VER_FILEOS VOS_NT_WINDOWS32 #else #define VER_FILEOS VOS_DOS_WINDOWS16 #endif #endif #ifndef VER_FILEVERSION_STR #define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR #endif #ifndef VER_ORIGINALFILENAME_STR #define VER_ORIGINALFILENAME_STR VER_INTERNALNAME_STR #endif #define EXPORT_TAG #ifdef RC_INVOKED VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_PRODUCTVERSION FILEFLAGSMASK VER_FILEFLAGSMASK FILEFLAGS VER_FILEFLAGS FILEOS VER_FILEOS FILETYPE VER_FILETYPE FILESUBTYPE VER_FILESUBTYPE BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ BEGIN VALUE "CompanyName", VER_COMPANYNAME_STR VALUE "FileDescription", VER_FILEDESCRIPTION_STR EXPORT_TAG VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", VER_INTERNALNAME_STR VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR VALUE "ProductName", VER_PRODUCTNAME_STR VALUE "ProductVersion", VER_PRODUCTVERSION_STR #ifdef VER_OLESELFREGISTER VALUE "OleSelfRegister", "\0" #endif END BLOCK "040c04b0" /* LANG_FRENCH/SUBLANG_FRENCH */ BEGIN VALUE "CompanyName", VER_COMPANYNAME_STR VALUE "FileDescription", VER_FILEDESCRIPTION_STR EXPORT_TAG VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", VER_INTERNALNAME_STR VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR VALUE "ProductName", VER_PRODUCTNAME_STR VALUE "ProductVersion", VER_PRODUCTVERSION_STR #ifdef VER_OLESELFREGISTER VALUE "OleSelfRegister", "\0" #endif END #ifdef VER_ANSICP /* Some apps are hard coded to look for ANSI CP. */ BLOCK "040904E4" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Ansi CP */ BEGIN VALUE "CompanyName", VER_COMPANYNAME_STR VALUE "FileDescription", VER_FILEDESCRIPTION_STR EXPORT_TAG VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", VER_INTERNALNAME_STR VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR VALUE "ProductName", VER_PRODUCTNAME_STR VALUE "ProductVersion", VER_PRODUCTVERSION_STR #ifdef VER_OLESELFREGISTER VALUE "OleSelfRegister", "\0" #endif END #endif END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 0x04B0 END END #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/helpers.c0000644000175000017500000010750300000000000020347 0ustar00rousseaurousseau/*=========================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ===========================================================================*/ #ifdef WIN32 #include #endif #ifdef __APPLE__ #include #else #include #endif #include #include #include "pcsctypes.h" #include "helpers.h" #include "memlog.h" extern PyObject* PyExc_SCardError; #ifdef PCSCLITE #define FALSE (0==1) #define TRUE (1==1) #define lstrlen strlen #endif // PCSCLITE #if PY_MAJOR_VERSION >= 3 #define PyInt_Check(x) PyLong_Check(x) #define PyInt_AsLong(x) PyLong_AsLong(x) #define PyInt_FromLong(x) PyLong_FromLong(x) #define PyString_Check(name) PyUnicode_Check(name) #define PyString_FromString(x) PyUnicode_FromString(x) #define PyString_AsString(str) PyBytes_AsString(str) #endif /**=======================================================================**/ static int _IsAReaderState( PyObject* o) /*=========================================================================== ===========================================================================*/ { PyObject* o2; // expecting at least 2 items: reader name and current state if( (PyTuple_Size(o)!=2) && (PyTuple_Size(o)!=3) ) { PyErr_SetString( PyExc_TypeError, "Expecting two or three items in tuple." ); return 0; } o2 = PyTuple_GetItem(o, 0); if(!PyString_Check(o2)) { PyErr_SetString( PyExc_TypeError, "Expected a string as reader name." ); return 0; } o2 = PyTuple_GetItem(o, 1); if(!PyInt_Check(o2) && !PyLong_Check(o2) ) { PyErr_SetString( PyExc_TypeError, "Expected an Int as second tuple item." ); return 0; } if(PyTuple_Size(o)==3) { o2 = PyTuple_GetItem(o, 2); if(!PyList_Check(o2)) { PyErr_SetString( PyExc_TypeError, "Expected a list as third tuple item." ); return 0; } } return 1; } /**=======================================================================**/ static int _ReaderStateFromTuple( PyObject* o, READERSTATELIST* prl, unsigned int x ) /*=========================================================================== ===========================================================================*/ { char* psz; PyObject* o2; #if PY_MAJOR_VERSION >= 3 PyObject* temp_bytes; #endif // first tuple item is reader name o2=PyTuple_GetItem(o, 0); #if PY_MAJOR_VERSION >= 3 // Convert the readername from string (unicode) to bytes (ascii) temp_bytes = PyUnicode_AsEncodedString(o2, "ASCII", "strict"); // Owned reference if (temp_bytes != NULL) { psz = PyBytes_AsString(temp_bytes); // Borrowed pointer if (NULL == psz) return 0; } else return 0; #else psz = PyString_AsString(o2); #endif prl->aszReaderNames[x] = mem_Malloc(strlen(psz)+1); if (!prl->aszReaderNames[x]) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); return 0; } prl->ars[x].szReader = prl->aszReaderNames[x]; strcpy( prl->aszReaderNames[x], psz ); #if PY_MAJOR_VERSION >= 3 Py_DECREF(temp_bytes); #endif // second tuple item is current state o2=PyTuple_GetItem(o, 1); prl->ars[x].dwCurrentState = (SCARDDWORDARG)PyInt_AsLong(o2); // third tuple item is the ATR (optionally) if(PyTuple_Size(o)==3) { BYTELIST* ATR = mem_Malloc(sizeof(BYTELIST)); if( !ATR ) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); return 0; } o2 = PyTuple_GetItem(o, 2); ATR = SCardHelper_PyByteListToBYTELIST(o2); memcpy(prl->ars[x].rgbAtr, ATR->ab, ATR->cBytes); prl->ars[x].cbAtr = ATR->cBytes; mem_Free(ATR); } return 1; } /**========================================================================== BYTELIST Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendByteListToPyObject( BYTELIST* source, PyObject** ptarget ) /*=========================================================================== builds a Python list from a byte list ===========================================================================*/ { PyObject* oByteList; // create byte list... if( (NULL!=source) && (NULL!=source->ab) ) { unsigned int i; oByteList = PyList_New( source->cBytes ); for(i=0; icBytes; i++) { PyObject* pyby; pyby = Py_BuildValue( "b", source->ab[i] ); PyList_SetItem( oByteList, i, pyby ); } } else { oByteList = PyList_New( 0 ); } // append list to target if( !*ptarget ) { *ptarget = oByteList; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = oByteList; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append(*ptarget,oByteList); Py_XDECREF(oByteList); } } /**=======================================================================**/ BYTELIST* SCardHelper_PyByteListToBYTELIST(PyObject* source) /*=========================================================================== build a Python byte list from a BYTELIST ===========================================================================*/ { Py_ssize_t cBytes, x; BYTELIST* pbl; // sanity check if (!PyList_Check(source)) { PyErr_SetString( PyExc_TypeError, "Expected a list object." ); return NULL; } cBytes = PyList_Size(source); for( x=0; x0) { pbl->ab = mem_Malloc( cBytes*sizeof(unsigned char) ); if( !pbl->ab ) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); mem_Free( pbl ); return NULL; } } else { pbl->ab=NULL; } pbl->bAllocated=TRUE; pbl->cBytes=(SCARDDWORDARG)cBytes; for( x=0; xab[x] = (unsigned char)PyInt_AsLong(o); } return (BYTELIST*)pbl; } /**=======================================================================**/ void SCardHelper_PrintByteList( BYTELIST* apsz ) /*=========================================================================== dump a byte list ===========================================================================*/ { unsigned long i; for(i=0; icBytes; i++) { printf("0x%.2X ", apsz->ab[i] ); } printf("\n"); } /**========================================================================== ERRORSTRING Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_OutErrorStringAsPyObject( ERRORSTRING* source, PyObject** ptarget ) /*=========================================================================== Builds a Python string from an ERRORSTRING ===========================================================================*/ { PyObject* pystr; if( NULL!=source ) { #if (PY_MAJOR_VERSION >= 3) && defined(WIN32) pystr = PyUnicode_Decode( (char*)source, strlen(source), "cp1250" , NULL); #else pystr = PyString_FromString( (char*)source ); #endif *ptarget = pystr; } else { *ptarget = Py_None; Py_INCREF(Py_None); } } /**========================================================================== GUIDLIST Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendGuidListToPyObject( GUIDLIST* source, PyObject** ptarget ) /*=========================================================================== build a Python GUID list from a C GUID list ===========================================================================*/ { PyObject* oByte; PyObject* oGuildItem; PyObject* oGuidList; unsigned char* pc; unsigned int i, j; // create GUID list... for(;;) { if (source!=NULL) { // create GUID list oGuidList = PyList_New( source->cGuids ); if(NULL==oGuidList) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate GUID list" ); break; } for( i=0; icGuids; i++) { oGuildItem=PyList_New( sizeof(GUID) ); if(NULL==oGuildItem) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate GUID item list" ); break; } pc=(unsigned char*)&source->aguid[i]; for (j=0; jbAllocated=TRUE; pgl->cGuids=(unsigned long)cGuids; pgl->hcontext=(unsigned long)NULL; // allocate GUIDs in GUID list if (cGuids>0) { pgl->aguid = mem_Malloc( cGuids*sizeof(GUID) ); if( NULL==pgl->aguid ) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); mem_Free( pgl ); return NULL; } } else { pgl->aguid=NULL; } // fill individual GUIDs /* for( iGuid=0; iGuidxaguid+iGuid*sizeof(GUID); for( x=0; xaguid; for( x=0; xcGuids; i++) { unsigned char* pc=(unsigned char*)&apsz->aguid[i]; for (j=0; jcRStates ); for( i=0; icRStates; i++ ) { PyObject* oReader; PyObject* oEventState; PyObject* oAtr; PyObject* oByte; SCARDDWORDARG j; // reader, event state, atr PyObject* ot = PyTuple_New( 3 ); oReader = PyString_FromString( source->ars[i].szReader ); oEventState = PyInt_FromLong( (SCARDDWORDARG)source->ars[i].dwEventState ); // ATR visibly not initialised if ( source->ars[i].cbAtr > SCARD_ATR_LENGTH) source->ars[i].cbAtr = 0; oAtr = PyList_New( source->ars[i].cbAtr ); for(j=0; jars[i].cbAtr; j++) { oByte = PyInt_FromLong( source->ars[i].rgbAtr[j] ); PyList_SetItem( oAtr, j, oByte ); } PyTuple_SetItem( ot, 0, oReader ); PyTuple_SetItem( ot, 1, oEventState ); PyTuple_SetItem( ot, 2, oAtr ); PyList_SetItem( oRStateList, i, ot ); } } else { oRStateList = PyList_New( 0 ); } if( !*ptarget ) { *ptarget = oRStateList; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = oRStateList; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append(*ptarget,oRStateList); Py_XDECREF(oRStateList); } } /**=======================================================================**/ READERSTATELIST* SCardHelper_PyReaderStateListToREADERSTATELIST(PyObject* source) /*=========================================================================== build a READERSTATELIST from a Python list of reader states ===========================================================================*/ { SCARDDWORDARG cRStates, x; READERSTATELIST* prl; // sanity check if (!PyList_Check(source)) { PyErr_SetString( PyExc_TypeError, "Expected a list object." ); return NULL; } cRStates = (SCARDDWORDARG)PyList_Size(source); for( x=0; xcRStates = cRStates; prl->ars = mem_Malloc( cRStates*sizeof(SCARD_READERSTATE) ); if (!prl->ars) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); mem_Free( prl ); return NULL; } /* zeroise SCARD_READERSTATE to work with remote desktop */ memset(prl->ars, 0, cRStates*sizeof(SCARD_READERSTATE) ); prl->aszReaderNames = mem_Malloc( cRStates*sizeof(char*) ); if (!prl->aszReaderNames) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); mem_Free( prl->ars ); mem_Free( prl ); return NULL; } for( x=0; xaszReaderNames[x] ); } mem_Free( prl->ars ); mem_Free( prl ); return NULL; } } return (READERSTATELIST*)prl; } /**=======================================================================**/ void SCardHelper_PrintReaderStateList( READERSTATELIST* prl ) /*=========================================================================== dump a reader state list ===========================================================================*/ { int i; SCARDDWORDARG j; for( i=0; prl && icRStates; i++ ) { printf("%s userdata: %p current: %lx event: %lx \n", prl->ars[i].szReader, prl->ars[i].pvUserData, (long)prl->ars[i].dwCurrentState, (long)prl->ars[i].dwEventState ); for(j=0; jars[i].cbAtr; j++ ) { printf("0x%.2X ", prl->ars[i].rgbAtr[j] ); } printf("\n"); if(prl->ars[i].dwEventState & SCARD_STATE_UNAWARE) { printf("Card state unaware\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_IGNORE) { printf("Card state ignore\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_CHANGED) { printf("Card state changed\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_UNKNOWN) { printf("Card state unknown\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_UNAVAILABLE) { printf("Card state unavailable\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_EMPTY) { printf("No card in reader\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_PRESENT) { printf("Card in reader\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_ATRMATCH) { printf("Card found\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_EXCLUSIVE) { printf("Card in reader allocated for exclusive use by another application\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_INUSE) { printf("Card in reader is in use but can be shared\n"); } if(prl->ars[i].dwEventState & SCARD_STATE_MUTE) { printf("Card in reader is mute\n"); } } } /**========================================================================== SCARDCONTEXT Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendSCardContextToPyObject( SCARDCONTEXT source, PyObject** ptarget ) /*=========================================================================== builds a Python SCARDCONTEXT from a C SCARDCONTEXT ===========================================================================*/ { PyObject* oScardContext; // create SCARDCONTEXT #ifdef PCSCLITE oScardContext = PyLong_FromLong( (long)source ); #else // !PCSCLITE oScardContext = PyLong_FromVoidPtr( (void*)source ); #endif // PCSCLITE // append list to target if( !*ptarget ) { *ptarget = oScardContext; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = oScardContext; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append(*ptarget,oScardContext); Py_XDECREF(oScardContext); } } /**=======================================================================**/ SCARDCONTEXT SCardHelper_PyScardContextToSCARDCONTEXT(PyObject* source) /*=========================================================================== build a SCARDCONTEXT from a python SCARDCONTEXT ===========================================================================*/ { SCARDCONTEXT scRet=0; // sanity check // do we have a python long? if (!PyLong_Check(source)) { PyErr_SetString( PyExc_TypeError, "Expected a python long as SCARDCONTEXT." ); return 0; } #ifdef PCSCLITE scRet = PyLong_AsLong( source ); #else // !PCSCLITE scRet = PyLong_AsVoidPtr( source ); #endif // PCSCLITE return scRet; } /**========================================================================== SCARDHANDLE Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendSCardHandleToPyObject( SCARDHANDLE source, PyObject** ptarget ) /*=========================================================================== builds a Python SCARDHANDLE from a C SCARDHANDLE ===========================================================================*/ { PyObject* oScardHandle; // create SCARDHANDLE #ifdef PCSCLITE oScardHandle = PyLong_FromLong( (long)source ); #else // !PCSCLITE oScardHandle = PyLong_FromVoidPtr( (void*)source ); #endif // PCSCLITE // append list to target if( !*ptarget ) { *ptarget = oScardHandle; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = oScardHandle; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append(*ptarget,oScardHandle); Py_XDECREF(oScardHandle); } } /**=======================================================================**/ SCARDCONTEXT SCardHelper_PyScardHandleToSCARDHANDLE(PyObject* source) /*=========================================================================== build a SCARDHANDLE from a python SCARDHANDLE ===========================================================================*/ { SCARDHANDLE scRet=0; // sanity check // do we have a python long? if (!PyLong_Check(source)) { PyErr_SetString( PyExc_TypeError, "Expected a python long as SCARDHANDLE." ); return 0; } #ifdef PCSCLITE scRet = PyLong_AsLong( source ); #else // !PCSCLITE scRet = PyLong_AsVoidPtr( source ); #endif // PCSCLITE return scRet; } /**========================================================================== SCARDDWORDARG Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendSCardDwordArgToPyObject( SCARDDWORDARG source, PyObject** ptarget ) /*=========================================================================== builds a Python SCARDDWORDARG from a C SCARDDWORDARG ===========================================================================*/ { PyObject* oScardDword; // create SCARDDWORDARG #ifdef PCSCLITE oScardDword = PyLong_FromLong( (long)source ); #else // !PCSCLITE oScardDword = PyLong_FromUnsignedLong( (unsigned long)source ); #endif // PCSCLITE // append list to target if( !*ptarget ) { *ptarget = oScardDword; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = oScardDword; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append(*ptarget,oScardDword); Py_XDECREF(oScardDword); } } /**=======================================================================**/ SCARDDWORDARG SCardHelper_PySCardDwordArgToSCARDDWORDARG(PyObject* source) /*=========================================================================== build a SCARDDWORDARG from a python SCARDDWORDARG ===========================================================================*/ { SCARDDWORDARG scRet=0; // sanity check // do we have a python long or int? if( !PyLong_Check(source) && !PyInt_Check(source) ) { PyErr_SetString( PyExc_TypeError, "Expected a python integer or long." ); return -1; } #ifdef PCSCLITE scRet = PyLong_AsLong( source ); #else // !PCSCLITE scRet = PyLong_AsUnsignedLong( source ); #endif // PCSCLITE return scRet; } /**========================================================================== STRING Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendStringToPyObject( STRING* source, PyObject** ptarget ) /*=========================================================================== Builds a Python string from a STRING ===========================================================================*/ { PyObject* pystr; if(NULL!=source) { if(NULL!=source->sz) { pystr = PyString_FromString( source->sz ); } else { pystr = Py_None; Py_INCREF(Py_None); } if( !*ptarget ) { *ptarget = pystr; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = pystr; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append( *ptarget, pystr ); Py_XDECREF( pystr ); } } else { if( !*ptarget ) { *ptarget = Py_None; Py_INCREF(Py_None); } } } /**=======================================================================**/ STRING* SCardHelper_PyStringToString( PyObject* source ) /*=========================================================================== Build a STRING from a Python string; the string is allocated and will have to be freed externally to the wrapper ===========================================================================*/ { size_t ulLength; STRING* pstr=NULL; for(;;) { // sanity check if( !PyString_Check( source ) ) { PyErr_SetString( PyExc_TypeError, "Expected a string." ); break; } pstr=(STRING*)mem_Malloc( sizeof(STRING) ); if(NULL==pstr) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate STRING" ); break; } ulLength=strlen( PyString_AsString(source)) + 1 ; pstr->sz=(char*)mem_Malloc( ulLength ); if(NULL==pstr->sz) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate STRING buffer" ); break; } strcpy( pstr->sz, PyString_AsString( source ) ); break; } return pstr; } /**=======================================================================**/ void SCardHelper_PrintString( STRING* str ) /*=========================================================================== dump a string list ===========================================================================*/ { if(NULL!=str) { char* p=str->sz; if( NULL!=p) { printf("%s ", p ); } } } /**========================================================================== STRINGLIST Helpers ===========================================================================*/ /**=======================================================================**/ void SCardHelper_AppendStringListToPyObject( STRINGLIST* source, PyObject** ptarget ) /*=========================================================================== builds a Python list from a STRINGLIST; the multi-string list in the STRINGLIST is stored as series of null-terminated strings terminated by a null, e.g. item0\0item2\0lastitem\0\0) ===========================================================================*/ { unsigned int cStr; char* p=source->ac; PyObject* oStrList; //PyObject* o; // count STRs in STRINGLIST list if( NULL!=p ) { unsigned int i; for( i=0, cStr=0; ; i+=lstrlen( p+i ) + 1 ) { if (lstrlen( p+i ) > 0) { cStr++; } else { break; } } } else { cStr=0; } // create STR list... if( NULL!=p ) { unsigned int i, j; oStrList = PyList_New( cStr ); for( i=0, j=0; ; j++, i+=lstrlen( p+i ) + 1 ) { if (lstrlen( p+i ) > 0) { PyObject* pystr; pystr = PyString_FromString( p+i ); PyList_SetItem( oStrList, j, pystr ); } else { break; } } } else { oStrList = PyList_New( cStr ); } if( !*ptarget ) { *ptarget = oStrList; } else if( *ptarget == Py_None ) { Py_DECREF(Py_None); *ptarget = oStrList; } else { if( !PyList_Check(*ptarget) ) { PyObject* o2 = *ptarget; *ptarget = PyList_New(0); PyList_Append(*ptarget,o2); Py_XDECREF(o2); } PyList_Append(*ptarget,oStrList); Py_XDECREF(oStrList); } } /**=======================================================================**/ STRINGLIST* SCardHelper_PyStringListToStringList(PyObject* source) /*=========================================================================== build a Python string list from a STRINGLIST ===========================================================================*/ { Py_ssize_t cStrings, cChars, x; STRINGLIST* psl; char* p; // sanity check if (!PyList_Check(source)) { PyErr_SetString( PyExc_TypeError, "Expected a list object." ); return NULL; } cStrings = PyList_Size(source); for( x=0, cChars=0; x= 3 cChars += PyUnicode_GET_LENGTH(o) + 1 ; #else cChars += strlen( PyString_AsString(o)) + 1 ; #endif } cChars += 1; psl=mem_Malloc(sizeof(STRINGLIST)); if(!psl) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); return NULL; } psl->bAllocated=TRUE; psl->hcontext = 0; if ( cChars>1 ) { psl->ac = mem_Malloc( cChars*sizeof(char) ); if (!psl->ac) { PyErr_SetString( PyExc_MemoryError, "Unable to allocate temporary array" ); mem_Free( psl ); return NULL; } for( x=0, p=psl->ac; x= 3 // Convert the group name from string (unicode) to bytes (ascii) PyObject * temp_bytes = PyUnicode_AsEncodedString(o, "ASCII", "strict"); // Owned reference if (temp_bytes != NULL) { char * psz = PyBytes_AsString(temp_bytes); // Borrowed pointer if (NULL == psz) return 0; strcpy(p, psz); Py_DECREF(temp_bytes); } #else strcpy( p, PyString_AsString(o) ); #endif p += strlen( p ) + 1; } strcpy( p, "\0" ); } else { psl->ac=NULL; } return (STRINGLIST*)psl; } /**=======================================================================**/ void SCardHelper_PrintStringList( STRINGLIST* sl ) /*=========================================================================== dump a string list ===========================================================================*/ { char* p=(char*)sl->ac; unsigned int i; for( i=0; ; i+=lstrlen( p+i ) + 1 ) { if (lstrlen( p+i ) > 0) { printf("%s ", p+i ); } else { printf("\n" ); break; } } } #ifdef WIN32 /**=======================================================================**/ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) /*=========================================================================== Initialize and clean-up memory logging on process attach and detach ===========================================================================*/ { switch(fdwReason) { case DLL_PROCESS_ATTACH: if (!mem_Init()) { fprintf( stderr, "Failed to initialize memory logging services!\n" ); } break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: if (!mem_CleanUp()) { fprintf( stderr, "Failed to cleanup memory logging services!\n" ); } break; } return TRUE; return 1; } #endif // WIN32 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/helpers.h0000644000175000017500000000731000000000000020347 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ================================================================================ ==============================================================================*/ typedef struct { int bAllocated; unsigned char* ab; SCARDDWORDARG cBytes; } BYTELIST ; typedef char* ERRORSTRING; #ifdef PCSCLITE typedef struct { unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[ 8 ]; } GUID; #endif typedef struct { int bAllocated; GUID* aguid; unsigned long cGuids; SCARDCONTEXT hcontext; } GUIDLIST ; typedef struct { SCARD_READERSTATE* ars; char** aszReaderNames; int cRStates; } READERSTATELIST ; typedef struct { int bAllocated; SCARDCONTEXT hcontext; char* sz; } STRING; typedef struct { int bAllocated; SCARDCONTEXT hcontext; char* ac; } STRINGLIST ; /**============================================================================= F U N C T I O N P R O T O T Y P E S ==============================================================================*/ // BYTELIST helpers void SCardHelper_AppendByteListToPyObject( BYTELIST* source, PyObject** ptarget ); BYTELIST* SCardHelper_PyByteListToBYTELIST(PyObject* source); void SCardHelper_PrintByteList( BYTELIST* apsz ); // ERRORSTRING helpers void SCardHelper_OutErrorStringAsPyObject( ERRORSTRING* source, PyObject** ptarget ); // GUIDLIST helpers void SCardHelper_AppendGuidListToPyObject( GUIDLIST* source, PyObject** ptarget ); GUIDLIST* SCardHelper_PyGuidListToGUIDLIST(PyObject* source); void SCardHelper_PrintGuidList( GUIDLIST* apsz ); // READERSTATELIST helpers void SCardHelper_AppendReaderStateListToPyObject( READERSTATELIST* source, PyObject** ptarget ); READERSTATELIST* SCardHelper_PyReaderStateListToREADERSTATELIST(PyObject* source); void SCardHelper_PrintReaderStateList( READERSTATELIST* apsz ); // SCARDCONTEXT helpers void SCardHelper_AppendSCardContextToPyObject( SCARDCONTEXT source, PyObject** ptarget ); SCARDCONTEXT SCardHelper_PyScardContextToSCARDCONTEXT( PyObject* source ); // SCARDHANDLE helpers void SCardHelper_AppendSCardHandleToPyObject( SCARDHANDLE source, PyObject** ptarget ); SCARDHANDLE SCardHelper_PyScardHandleToSCARDHANDLE( PyObject* source ); // SCARDDWORDARG helpers void SCardHelper_AppendSCardDwordArgToPyObject( SCARDDWORDARG source, PyObject** ptarget ); SCARDDWORDARG SCardHelper_PySCardDwordArgToSCARDDWORDARG( PyObject* source ); // STRING helpers void SCardHelper_AppendStringToPyObject( STRING* source, PyObject** ptarget ); STRING* SCardHelper_PyStringToString( PyObject* source ); void SCardHelper_PrintString( STRING* str ); // STRINGLIST helpers void SCardHelper_AppendStringListToPyObject( STRINGLIST* source, PyObject** ptarget ); STRINGLIST* SCardHelper_PyStringListToStringList(PyObject* source); void SCardHelper_PrintStringList( STRINGLIST* apsz ); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/memlog.h0000644000175000017500000000403200000000000020163 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ #ifndef __MEMLOG_H__ #define __MEMLOG_H__ #ifdef __cplusplus extern "C" { #endif // __cplusplus // // define __ENABLE_MEMLOG__ and write your own version // of mem_XXX functions to enable memory logging; this // is useful to track memory leaks when fiddling with // the swig typemaps. #ifdef __ENABLE_MEMLOG__ int mem_CleanUp( void ); void __cdecl mem_Free( void* pv ); void mem_HeapCheck( void ); int mem_Init( void ); void* __cdecl mem_Malloc( size_t ulSize ); void* __cdecl mem_MallocWithCaller( size_t ulSize, void* pvCaller ); void mem_HeapPrint( void ); // // defaults to free/malloc // #else // !__ENABLE_MEMLOG__ #define mem_CleanUp() (1) #define mem_Free free #define mem_HeapCheck() #define mem_Init() (1) #define mem_Malloc malloc #define mem_MallocWithCaller( x, y ) malloc( x ) #define mem_HeapPrint() #endif // __ENABLE_MEMLOG__ #ifdef __cplusplus } #endif // __cplusplus #endif // __MEMLOG_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/pcsctypes.h0000644000175000017500000000266100000000000020726 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ================================================================================ ==============================================================================*/ #ifndef __PCSCTYPES_H__ #define __PCSCTYPES_H__ #ifdef PCSCLITE #ifdef __APPLE__ typedef uint32_t SCARDDWORDARG; typedef int32_t SCARDRETCODE; #else //!__APPLE__ typedef unsigned long SCARDDWORDARG; typedef long SCARDRETCODE; #endif #else // !PCSCLITE typedef unsigned long SCARDDWORDARG; typedef long SCARDRETCODE; #endif #endif //__PCSCTYPES_H__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/pyscard-reader.h0000644000175000017500000001347000000000000021616 0ustar00rousseaurousseau/*============================================================================== This file contains SCARD_ATTR attributes definitions taken from reader.h, in MUSCLE SmartCard Development ( http://www.linuxnet.com ). It allows to build pyscard on Mac OS X without any dependency on the muscle source code. Indeed, default Mac OS X does not containt reader.h as part of the PCSC.framework. Copyright (C) 1999-2005 David Corcoran Copyright (C) 1999-2009 Ludovic Rousseau The licence of reader.h pcsc-lite is 3-clauses BSD and can be relicenced in LGPL v2+ for pyscard. This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ #define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag))) #define SCARD_CLASS_VENDOR_INFO 1 #define SCARD_CLASS_COMMUNICATIONS 2 #define SCARD_CLASS_PROTOCOL 3 #define SCARD_CLASS_POWER_MGMT 4 #define SCARD_CLASS_SECURITY 5 #define SCARD_CLASS_MECHANICAL 6 #define SCARD_CLASS_VENDOR_DEFINED 7 #define SCARD_CLASS_IFD_PROTOCOL 8 #define SCARD_CLASS_ICC_STATE 9 #define SCARD_CLASS_SYSTEM 0x7fff #define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100) #define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101) #define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102) #define SCARD_ATTR_VENDOR_IFD_SERIAL_NO SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0103) #define SCARD_ATTR_CHANNEL_ID SCARD_ATTR_VALUE(SCARD_CLASS_COMMUNICATIONS, 0x0110) #define SCARD_ATTR_ASYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0120) #define SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0121) #define SCARD_ATTR_MAX_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0122) #define SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0123) #define SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0124) #define SCARD_ATTR_MAX_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0125) #define SCARD_ATTR_SYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0126) #define SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_VALUE(SCARD_CLASS_POWER_MGMT, 0x0131) #define SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0140) #define SCARD_ATTR_USER_AUTH_INPUT_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0142) #define SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_VALUE(SCARD_CLASS_MECHANICAL, 0x0150) #define SCARD_ATTR_CURRENT_PROTOCOL_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0201) #define SCARD_ATTR_CURRENT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0202) #define SCARD_ATTR_CURRENT_F SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0203) #define SCARD_ATTR_CURRENT_D SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0204) #define SCARD_ATTR_CURRENT_N SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0205) #define SCARD_ATTR_CURRENT_W SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0206) #define SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0207) #define SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0208) #define SCARD_ATTR_CURRENT_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0209) #define SCARD_ATTR_CURRENT_CWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020a) #define SCARD_ATTR_CURRENT_EBC_ENCODING SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020b) #define SCARD_ATTR_EXTENDED_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020c) #define SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0300) #define SCARD_ATTR_ICC_INTERFACE_STATUS SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0301) #define SCARD_ATTR_CURRENT_IO_STATE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0302) #define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) #define SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0304) #define SCARD_ATTR_ESC_RESET SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA000) #define SCARD_ATTR_ESC_CANCEL SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA003) #define SCARD_ATTR_ESC_AUTHREQUEST SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA005) #define SCARD_ATTR_MAXINPUT SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA007) #define SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0001) #define SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0002) #define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003) #define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004) #define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005) #define SCARD_ATTR_DEVICE_SYSTEM_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0006) #define SCARD_ATTR_SUPRESS_T1_IFS_REQUEST SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0007) #ifdef UNICODE #define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W #define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W #else #define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A #define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/scard.def0000644000175000017500000000017000000000000020305 0ustar00rousseaurousseauLIBRARY "_scard.pyd" DESCRIPTION 'Python PCSC scard module Dynamic Link Library' EXPORTS init_scard ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/smartcard/scard/scard.i0000644000175000017500000020747100000000000020014 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ %define DOCSTRING "The smartcard.scard module is a simple wrapper on top of the C language PCSC SCardXXX API. The smartcard.scard module is the lower layer of the pyscard framework that provides a higher level interface. You should avoid using the smartcard.scard package directly, and use the pyscard directly because: - smartcard.scard being a C wrapper, the code tends to look like C code written in python syntax - the smartcard package provides higher level abstractions (e.g. CardType, CardConnection), and makes programming easier since it is totally written in Python You can still use the smartcard.scard package if you want to write your own framework, or if you want to perform quick-and-dirty port of C language programs using SCardXXX calls, or if there are features of SCardXXX API that you want to use and that are not available in the pyscard library. Introduction The smartcard.scard module is a Python wrapper around PCSC smart card base services. On Windows, the wrapper is performed around the smart card base components winscard library. On linux and OS X, the wrapper is performed around the PCSC-lite library. The smartcard.scard module provides mapping for the following API functions, depending on the Operating System: =============================== ======= ======= Function Windows Linux OS X =============================== ======= ======= GetOpenCardName SCardAddReaderToGroup Y SCardBeginTransaction Y Y SCardCancel Y Y SCardConnect Y Y SCardControl Y Y SCardDisconnect Y Y SCardEndTransaction Y Y SCardEstablishConteYt Y Y SCardForgetCardType Y SCardForgetReader Y SCardForgetReaderGroup Y SCardFreeMemory SCardGetAttrib Y Y SCardGetCardTypeProviderName Y SCardGetErrorMessage Y SCardGetProviderId SCardGetStatusChange Y Y SCardIntroduceCardType Y SCardIntroduceReader Y SCardIntroduceReaderGroup Y SCardIsValidConteYt Y Y SCardListCards Y SCardListInterfaces Y SCardListReaderGroups Y Y SCardListReaders Y Y SCardLocateCards Y SCardReconnect Y Y SCardReleaseConteYt Y Y SCardRemoveReaderFromGroup Y SCardSetAttrib Y Y SCardSetCartTypeProviderName SCardStatus Y Y SCardTransmit Y Y SCardUIDlgSelectCard =============================== ======= ======= Comments, bug reports, improvements welcome. ------------------------------------------------------------------------------- Copyright 2001-2012 gemalto @Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com @Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA " %enddef %module(docstring=DOCSTRING, package="smartcard.scard") scard %feature("autodoc", "3"); %{ #ifdef WIN32 #include #endif #ifdef __APPLE__ #include #else #include #endif #ifdef PCSCLITE #ifdef __APPLE__ #include "pyscard-reader.h" #ifndef SCARD_CTL_CODE #define SCARD_CTL_CODE(code) (0x42000000 + (code)) #endif #else #include #endif // undefined on older releases #ifndef MAX_BUFFER_SIZE_EXTENDED #define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3 + 2) #endif #else // !PCSCLITE // SCARD_CTL_CODE defined in WinSmCrd.h included by Win32 winscard.h // MAX_BUFFER_SIZE_EXTENDED is pcsc-lite specific // Issues on Lenovo laptop with NXP reader for higher values // See https://github.com/LudovicRousseau/pyscard/issues/100 #define MAX_BUFFER_SIZE_EXTENDED 65535 #endif //PCSCLITE #include "pcsctypes.h" #include "helpers.h" #include "memlog.h" #include "winscarddll.h" typedef STRING PROVIDERNAME_t; %} %include typemaps.i %include PcscTypemaps.i %{ // // these functions are only available on win32 PCSC // #ifdef WIN32 /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _AddReaderToGroup( SCARDCONTEXT hcontext, char* szReaderName, char* szGroupName) { return (mySCardAddReaderToGroupA)( hcontext, szReaderName, szGroupName); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _ForgetCardType(SCARDCONTEXT hcontext, char* pszCardName) { return (mySCardForgetCardTypeA)(hcontext, pszCardName); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _ForgetReader(SCARDCONTEXT hcontext, char* szReaderName) { return (mySCardForgetReaderA)(hcontext, szReaderName); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _ForgetReaderGroup(SCARDCONTEXT hcontext, char* szGroupName) { return (mySCardForgetReaderGroupA)(hcontext, szGroupName); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _GetCardTypeProviderName( SCARDCONTEXT hcontext, char* pszCardName, SCARDDWORDARG dwProviderId, PROVIDERNAME_t* psl) { long lRetCode; unsigned long cchProviderName=SCARD_AUTOALLOCATE; // autoallocate memory; will be freed on output typemap psl->hcontext=hcontext; psl->sz=NULL; lRetCode=(mySCardGetCardTypeProviderNameA)( hcontext, pszCardName, dwProviderId, (LPTSTR)&psl->sz, &cchProviderName); return lRetCode; }; /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _IntroduceCardType( SCARDCONTEXT hcontext, char* pszCardName, GUIDLIST* pguidPrimaryProvider, GUIDLIST* rgguidInterfaces, BYTELIST* pbAtr, BYTELIST* pbAtrMask ) { return (mySCardIntroduceCardTypeA)( hcontext, pszCardName, pguidPrimaryProvider ? pguidPrimaryProvider->aguid : NULL, rgguidInterfaces ? rgguidInterfaces->aguid : NULL, rgguidInterfaces ? rgguidInterfaces->cGuids : 0, pbAtr->ab, pbAtrMask->ab, pbAtr->cBytes); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _IntroduceReader(SCARDCONTEXT hcontext, char* szReaderName, char* szDeviceName) { return (mySCardIntroduceReaderA)(hcontext, szReaderName, szDeviceName); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _IntroduceReaderGroup(SCARDCONTEXT hcontext, char* szGroupName) { return (mySCardIntroduceReaderGroupA)(hcontext, szGroupName); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _ListCards(SCARDCONTEXT hcontext, BYTELIST* pbl, GUIDLIST* guidlist, STRINGLIST* pmszCards) { // autoallocate memory; will be freed on output typemap unsigned long cchCards=SCARD_AUTOALLOCATE; pmszCards->ac=NULL; pmszCards->hcontext=hcontext; //SCardHelper_PrintByteList(pbl); return (mySCardListCardsA)( hcontext, pbl->ab, (NULL==guidlist) ? NULL : guidlist->aguid, (NULL==guidlist) ? 0 : guidlist->cGuids, (LPTSTR)&pmszCards->ac, &cchCards); }; /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _ListInterfaces( SCARDCONTEXT hcontext, char* pszCard, GUIDLIST* pgl ) { long lRetCode; pgl->cGuids = SCARD_AUTOALLOCATE; pgl->hcontext = hcontext; pgl->aguid = NULL; lRetCode = (mySCardListInterfacesA)(hcontext, pszCard, (LPGUID)&pgl->aguid, &pgl->cGuids); if (lRetCode!=SCARD_S_SUCCESS) { pgl->cGuids=0; } return lRetCode; } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _LocateCards( SCARDCONTEXT hcontext, STRINGLIST* mszCards, READERSTATELIST* prl ) { LPCSTR pcstr=(0==strlen((LPCTSTR)mszCards->ac)) ? NULL : (LPCTSTR)mszCards->ac; return (mySCardLocateCardsA)( hcontext, pcstr, prl->ars, prl->cRStates); } /////////////////////////////////////////////////////////////////////////////// SCARDRETCODE _RemoveReaderFromGroup( SCARDCONTEXT hcontext, char* szReaderName, char* szGroupName) { return (mySCardRemoveReaderFromGroupA)( hcontext, szReaderName, szGroupName); } #endif // WIN32 /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _IsValidContext(SCARDCONTEXT hcontext) { return (mySCardIsValidContext)(hcontext); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _GetAttrib(SCARDHANDLE hcard, SCARDDWORDARG dwAttrId, BYTELIST* pbl) { long lRetCode; pbl->cBytes = 65535; pbl->ab = NULL; lRetCode = (mySCardGetAttrib)(hcard, dwAttrId, pbl->ab, &pbl->cBytes); if ((lRetCode!=SCARD_S_SUCCESS) || (pbl->cBytes<1)) { return lRetCode; } pbl->ab = (unsigned char*)mem_Malloc(pbl->cBytes*sizeof(unsigned char)); if (pbl->ab==NULL) { return SCARD_E_NO_MEMORY; } lRetCode = (mySCardGetAttrib)(hcard, dwAttrId, pbl->ab, &pbl->cBytes); return lRetCode; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _SetAttrib(SCARDHANDLE hcard, SCARDDWORDARG dwAttrId, BYTELIST* pbl) { long lRetCode; lRetCode = (mySCardSetAttrib)(hcard, dwAttrId, pbl->ab, pbl->cBytes); return lRetCode; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Control( SCARDHANDLE hcard, SCARDDWORDARG controlCode, BYTELIST* pblSendBuffer, BYTELIST* pblRecvBuffer ) { SCARDRETCODE lRet; pblRecvBuffer->ab = (unsigned char*)mem_Malloc(MAX_BUFFER_SIZE_EXTENDED*sizeof(unsigned char)); pblRecvBuffer->cBytes = MAX_BUFFER_SIZE_EXTENDED; lRet = (mySCardControl)( hcard, controlCode, pblSendBuffer->ab, pblSendBuffer->cBytes, pblRecvBuffer->ab, pblRecvBuffer->cBytes, &pblRecvBuffer->cBytes); return lRet; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _BeginTransaction(SCARDHANDLE hcard) { return (mySCardBeginTransaction)(hcard); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Cancel(SCARDCONTEXT hcontext) { return (mySCardCancel)(hcontext); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Connect( SCARDCONTEXT hcontext, char* szReader, SCARDDWORDARG dwShareMode, SCARDDWORDARG dwPreferredProtocols, LPSCARDHANDLE phCard, SCARDDWORDARG* pdwActiveProtocol ) { SCARDRETCODE lRet; lRet = (mySCardConnectA)( hcontext, (LPCTSTR)szReader, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); return lRet; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Disconnect(SCARDHANDLE hcard, SCARDDWORDARG dwDisposition) { return (mySCardDisconnect)(hcard, dwDisposition); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _EndTransaction(SCARDHANDLE hcard, SCARDDWORDARG dwDisposition) { return (mySCardEndTransaction)(hcard, dwDisposition); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _EstablishContext(SCARDDWORDARG dwScope, SCARDCONTEXT* phContext) { return (mySCardEstablishContext)(dwScope, NULL, NULL, phContext); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _GetStatusChange( SCARDCONTEXT hcontext, SCARDDWORDARG dwTimeout, READERSTATELIST* prsl) { SCARDRETCODE hresult; int i; // bad reader state list if (NULL==prsl) { return SCARD_E_INVALID_PARAMETER; } // remove changed bit for(i=0; icRStates; i++) { // remove changed bit prsl->ars[i].dwCurrentState = prsl->ars[i].dwCurrentState & (0xFFFFFFFF ^ SCARD_STATE_CHANGED); } hresult = (mySCardGetStatusChangeA)(hcontext, dwTimeout, prsl->ars, prsl->cRStates); //printf("\n%.8lx ", hresult); //for(i=0; icRStates; i++) //{ // printf("%.8lx %.8lx ", prsl->ars[i].dwCurrentState, prsl->ars[i].dwEventState); //} return hresult; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _ListReaders( SCARDCONTEXT hcontext, STRINGLIST* pmszGroups, STRINGLIST* pmszReaders) { LPCTSTR mszGroups; SCARDDWORDARG cchReaders; LONG lRetCode; if (pmszGroups) { mszGroups=pmszGroups->ac; } else { mszGroups=NULL; } #ifdef NOAUTOALLOCATE // autoallocate memory; will be freed on output typemap cchReaders=SCARD_AUTOALLOCATE; pmszReaders->ac=NULL; pmszReaders->hcontext=hcontext; return (mySCardListReadersA)(hcontext, mszGroups, (LPTSTR)&pmszReaders->ac, &cchReaders); #endif //AUTOALLOCATE // no autoallocate on pcsc-lite; do a first call to get length // then allocate memory and do a final call #ifndef NOAUTOALLOCATE // set hcontext to 0 so that mem_Free will // be called instead of SCardFreeMemory pmszReaders->hcontext=0; pmszReaders->ac=NULL; cchReaders=0; lRetCode = (mySCardListReadersA)(hcontext, mszGroups, NULL, &cchReaders); if (SCARD_S_SUCCESS!=lRetCode) { return lRetCode; } if (0==cchReaders) { return SCARD_S_SUCCESS; } pmszReaders->ac=mem_Malloc(cchReaders*sizeof(char)); if (NULL==pmszReaders->ac) { return SCARD_E_NO_MEMORY; } return (mySCardListReadersA)(hcontext, mszGroups, (LPTSTR)pmszReaders->ac, &cchReaders); #endif // !NOAUTOALLOCATE } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _ListReaderGroups(SCARDCONTEXT hcontext, STRINGLIST* pmszReaderGroups) { DWORD cchReaderGroups; LONG lRetCode; #ifdef NOAUTOALLOCATE cchReaderGroups = SCARD_AUTOALLOCATE; pmszReaderGroups->ac=NULL; pmszReaderGroups->hcontext=hcontext; return (mySCardListReaderGroupsA)(hcontext, (LPTSTR)&pmszReaderGroups->ac, &cchReaderGroups); #endif // NOAUTOALLOCATE // no autoallocate on pcsc-lite; do a first call to get length // then allocate memory and do a final call #ifndef NOAUTOALLOCATE // set hcontext to 0 so that mem_Free will // be called instead of SCardFreeMemory pmszReaderGroups->hcontext=0; cchReaderGroups = 0; pmszReaderGroups->ac=NULL; lRetCode = (mySCardListReaderGroupsA)(hcontext, (LPTSTR)pmszReaderGroups->ac, &cchReaderGroups); if (SCARD_S_SUCCESS!=lRetCode) { return lRetCode; } if (0==cchReaderGroups) { return SCARD_S_SUCCESS; } pmszReaderGroups->ac=mem_Malloc(cchReaderGroups*sizeof(char)); if (NULL==pmszReaderGroups->ac) { return SCARD_E_NO_MEMORY; } return (mySCardListReaderGroupsA)(hcontext, (LPTSTR)pmszReaderGroups->ac, &cchReaderGroups); #endif // !NOAUTOALLOCATE }; /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Reconnect( SCARDHANDLE hcard, SCARDDWORDARG dwShareMode, SCARDDWORDARG dwPreferredProtocols, SCARDDWORDARG dwInitialization, SCARDDWORDARG* pdwActiveProtocol ) { return (mySCardReconnect)( hcard, dwShareMode, dwPreferredProtocols, dwInitialization, pdwActiveProtocol); } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _ReleaseContext(SCARDCONTEXT hcontext) { SCARDRETCODE lRet; lRet = (mySCardReleaseContext)(hcontext); return lRet; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Status( SCARDHANDLE hcard, STRING* pszReaderName, SCARDDWORDARG* pdwState, SCARDDWORDARG* pdwProtocol, BYTELIST* pbl ) { long lRetCode; SCARDDWORDARG dwReaderLen=256; SCARDDWORDARG dwAtrLen=36; for(;;) { pbl->ab = (unsigned char*)mem_Malloc(dwAtrLen*sizeof(unsigned char)); if (pbl->ab == NULL) { lRetCode=SCARD_E_NO_MEMORY; break; } pbl->cBytes = dwAtrLen; pszReaderName->sz = mem_Malloc(dwReaderLen*sizeof(char)); pszReaderName->hcontext = 0; if (NULL == pszReaderName->sz) { lRetCode=SCARD_E_NO_MEMORY; break; } pszReaderName->sz[0] = '\0'; lRetCode = (mySCardStatusA)( hcard, (LPTSTR)pszReaderName->sz, &dwReaderLen, pdwState, pdwProtocol, pbl->ab, &pbl->cBytes); break; } return lRetCode; } /////////////////////////////////////////////////////////////////////////////// static SCARDRETCODE _Transmit( SCARDHANDLE hcard, unsigned long pioSendPci, BYTELIST* pblSendBuffer, BYTELIST* pblRecvBuffer ) { PSCARD_IO_REQUEST piorequest=NULL; long ret; pblRecvBuffer->ab = (unsigned char*)mem_Malloc(MAX_BUFFER_SIZE_EXTENDED*sizeof(unsigned char)); pblRecvBuffer->cBytes = MAX_BUFFER_SIZE_EXTENDED; // keep in sync with redefinition in PcscDefs.i switch(pioSendPci) { case SCARD_PROTOCOL_T0: piorequest = myg_prgSCardT0Pci; break; case SCARD_PROTOCOL_T1: piorequest = myg_prgSCardT1Pci; break; case SCARD_PROTOCOL_RAW: case SCARD_PROTOCOL_UNDEFINED: piorequest = myg_prgSCardRawPci; break; default: return SCARD_E_INVALID_PARAMETER; } ret = (mySCardTransmit)( hcard, piorequest, pblSendBuffer->ab, pblSendBuffer->cBytes, NULL, pblRecvBuffer->ab, &pblRecvBuffer->cBytes); return ret; } /////////////////////////////////////////////////////////////////////////////// static long _SCARD_CTL_CODE(long code) { return SCARD_CTL_CODE(code); } /////////////////////////////////////////////////////////////////////////////// static ERRORSTRING* _GetErrorMessage(long lErrCode) { #ifdef WIN32 #define _NO_SERVICE_MSG "The Smart card resource manager is not running." DWORD dwRetCode; LPVOID ppszError; dwRetCode=FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, lErrCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&ppszError, 0, NULL); if (0L==dwRetCode) { ppszError=NULL; if (SCARD_E_NO_SERVICE==lErrCode) { ppszError=(LPVOID)LocalAlloc(LPTR, sizeof(_NO_SERVICE_MSG)+1); if (NULL!=ppszError) { strncpy(ppszError, _NO_SERVICE_MSG, sizeof(_NO_SERVICE_MSG)+1); } } } return ppszError; #endif // WIN32 #ifdef PCSCLITE return (ERRORSTRING*)myPcscStringifyError(lErrCode); #endif // PCSCLITE } %} // // a few documentation typemaps // %typemap(doc, name="hcard", type="") (SCARDHANDLE hcard) "hcard: card handle return from SCardConnect()"; %typemap(doc, name="hcard", type="") (SCARDHANDLE* phcard) "hcard: on output, a card handle"; %typemap(doc, name="hcontext", type="") (SCARDCONTEXT hcontext) "hcontext: context handle return from SCardEstablishContext()"; %typemap(doc, name="hcontext", type="") (SCARDCONTEXT* phcontext) "hcontext: on output, a valid context handle if successful"; %typemap(doc, name="readerstatelist", type="tuple[]") (READERSTATELIST *prsl) "readerstatelist: in input/output, a list of reader state tuple (readername, state, atr)"; %typemap(doc, name="groupname", type="") (char* szGroupName) "groupname: card reader group name"; %typemap(doc, name="readername", type="") (char* szReaderName) "readername: card reader name"; %typemap(doc, name="cardname", type="") (char* szCardName) "cardname: friendly name of a card"; %typemap(doc, name="devicename", type="") (char* szDeviceName) "devicename: card reader device name"; %typemap(doc, name="providername", type="") (PROVIDERNAME_t* pszProviderName) "providername: on output, provider name"; %typemap(doc, name="readername", type="") (STRING* pszReaderNameOut) "readername: on output, reader name"; %typemap(doc, name="apducommand", type="byte[]") (BYTELIST* APDUCOMMAND) "apducommand: list of APDU bytes to transmit"; %typemap(doc, name="apduresponse", type="byte[]") (BYTELIST* APDURESPONSE) "apduresponse: on output, the list of APDU response bytes"; %typemap(doc, name="atr", type="byte[]") (BYTELIST* ATR) "atr: card ATR"; %typemap(doc, name="atr", type="byte[]") (BYTELIST* ATROUT) "atr: on output, the card ATR"; %typemap(doc, name="attributes", type="byte[]") (BYTELIST* ATTRIBUTES) "attributes: on output, a list of attributes"; %typemap(doc, name="mask", type="byte[]") (BYTELIST* MASK) "mask: mask to apply to card ATR"; %typemap(doc, name="inbuffer", type="byte[]") (BYTELIST* INBUFFER) "inbuffer: list of bytes to send with the control code"; %typemap(doc, name="outbuffer", type="byte[]") (BYTELIST* OUTBUFFER) "outbuffer: on output, the bytes returned by execution of the control code"; %typemap(doc, name="primaryprovider", type="GUID") (GUIDLIST* PRIMARYPROVIDER) "primaryprovidername: GUID of the smart card primary service provider"; %typemap(doc, name="providerlist", type="GUID[]") (GUIDLIST* PROVIDERLIST) "providerlist: list of GUIDs of interfaces supported by smart card"; %typemap(doc, name="interfaces", type="GUID[]") (GUIDLIST* GUIDINTERFACES) "interfaces: on output, a list of GUIDs of the interfaces supported by the smart card"; %typemap(doc, name="cards", type="") (STRINGLIST* CARDSTOLOCATE) "cards: a list of cards to locate"; %typemap(doc, name="matchingcards", type="[]") (STRINGLIST* MATCHINGCARDS) "matchingcards: on output, a list of matching cards"; %typemap(doc, name="readergroups", type="[]") (STRINGLIST* READERGROUPSIN) "readergroups: a list of reader groups to search for readers"; %typemap(doc, name="readergroups", type="[]") (STRINGLIST* READERGROUPSOUT) "readergroups: on output, the list of reader groups"; %typemap(doc, name="readers", type="[]") (STRINGLIST* READERSFOUND) "matchingcards: on output, a list of readers found"; %typemap(doc, name="readername", type="") (STRINGLIST* pszReaderName) "readername: on output, the name of the reader in which the card is inserted"; %typemap(doc, name="dwActiveProtocol", type="") (SCARDDWORDARG* pdwActiveProtocol) "dwActiveProtocol: on output, active protocol of card connection"; %typemap(doc, name="dwState", type="") (SCARDDWORDARG* pdwState) "dwState: on output, current state of the smart card"; %typemap(doc, name="dwProtocol", type="") (SCARDDWORDARG* pdwProtocol) "dwProtocol: on output, the current protocol"; %typemap(doc, name="dwScope", type="") (SCARDDWORDARG dwScope) "dwScope: context scope"; %typemap(doc, name="dwProviderId", type="") (SCARDDWORDARG dwProviderId) "dwProviderId: provider type, SCARD_PROVIDER_PRIMARY or SCARD_PROVIDER_CSP"; %typemap(doc, name="dwPreferredProtocols", type="") (SCARDDWORDARG dwPreferredProtocols) "dwPreferredProtocols: preferred protocols"; %typemap(doc, name="dwShareMode", type="") (SCARDDWORDARG dwShareMode) "dwShareMode: share mode"; %typemap(doc, name="dwDisposition", type="") (SCARDDWORDARG dwDisposition) "dwDisposition: card disposition on return"; %typemap(doc, name="dwAttrId", type="") (SCARDDWORDARG dwAttrId) "dwAttrId: value of attribute to get"; %typemap(doc, name="dwTimeout", type="") (SCARDDWORDARG dwTimeout) "dwTimeout: timeout value, INFINITE for infinite time-out"; %typemap(doc, name="dwInitialization", type="") (SCARDDWORDARG dwInitialization) "dwInitialization: the type of initialization that should be performed on the card"; %typemap(doc, name="dwControlCode", type="") (SCARDDWORDARG dwControlCode) "dwControlCode: the control code to send"; // // these functions are only available on win32 PCSC // #ifdef WIN32 /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_ADDREADERTOGROUP " adds a reader to a reader group Windows only, not supported by PCSC lite wrapper. example: from smartcard.scard import * ... establish context ... newgroup = 'SCard$MyOwnGroup' reader = 'SchlumbergerSema Reflex USB v.2 0' readeralias = 'SchlumbergerSema Reflex USB v.2 0 alias' hresult = SCardIntroduceReader(hcontext, readeralias, reader]) if hresult != SCARD_S_SUCCESS: raise error, 'Unable to introduce reader: ' + SCardGetErrorMessage(hresult) hresult = SCardAddReaderToGroup(hcontext, readeralias, newgroup) if hresult!=0: raise error, 'Unable to add reader to group: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_ADDREADERTOGROUP; %rename(SCardAddReaderToGroup) _AddReaderToGroup( SCARDCONTEXT hcontext, char* szReaderName, char* szGroupName); SCARDRETCODE _AddReaderToGroup( SCARDCONTEXT hcontext, char* szReaderName, char* szGroupName); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_FORGETCARDTYPE " removes an introduced smart card from the smart card subsystem. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... establish context ... hresult = SCardForgetCardType(hcontext, 'myCardName') if hresult != SCARD_S_SUCCESS: raise error, 'Failed to remove card type: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_FORGETCARDTYPE; %rename(SCardForgetCardType) _ForgetCardType(SCARDCONTEXT hcontext, char* szCardName); SCARDRETCODE _ForgetCardType(SCARDCONTEXT hcontext, char* szCardName); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_FORGETREADER " Removes a previously introduced smart card reader from the smart card subsystem. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... establish context ... ... hresult = SCardForgetReader(hcontext, dummyreader) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to forget readers ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_FORGETREADER; %rename(SCardForgetReader) _ForgetReader(SCARDCONTEXT hcontext, char* szReaderName); SCARDRETCODE _ForgetReader(SCARDCONTEXT hcontext, char* szReaderName); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_FORGETREADERGROUP " Removes a previously introduced smart card reader group from the smart card subsystem. Although this function automatically clears all readers from the group, it does not affect the existence of the individual readers in the database. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... establish context ... ... hresult = SCardForgetReaderGroup(hcontext, newgroup) if hresult != SCARD_S_SUCCESS: raise error, 'Unable to forget reader group: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_FORGETREADERGROUP; %rename(SCardForgetReaderGroup) _ForgetReaderGroup(SCARDCONTEXT hcontext, char* szGroupName); SCARDRETCODE _ForgetReaderGroup(SCARDCONTEXT hcontext, char* szGroupName); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_GETCARDTYPEPROVIDERNAME " Returns the name of the module (dynamic link library) containing the provider for a given card name and provider type. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... establish context ... hresult, cards = SCardListCards(hcontext, [], []) if hresult != SCARD_S_SUCCESS: raise error, 'Failure to list cards: ' + SCardGetErrorMessage(hresult) for i in cards: hresult, providername = SCardGetCardTypeProviderName(hcontext, i, SCARD_PROVIDER_PRIMARY) if hresult == SCARD_S_SUCCESS: print providername hresult, providername = SCardGetCardTypeProviderName(hcontext, i, SCARD_PROVIDER_CSP) if hresult == SCARD_S_SUCCESS: print providername ... " %enddef %feature("docstring") DOCSTRING_GETCARDTYPEPROVIDERNAME; %rename(SCardGetCardTypeProviderName) _GetCardTypeProviderName( SCARDCONTEXT hcontext, char* szCardName, SCARDDWORDARG dwProviderId, PROVIDERNAME_t* pszProviderName ); SCARDRETCODE _GetCardTypeProviderName( SCARDCONTEXT hcontext, char* szCardName, SCARDDWORDARG dwProviderId, PROVIDERNAME_t* pszProviderName ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_INTRODUCECARDTYPE " Introduces a smart card to the smart card subsystem (for the active user) by adding it to the smart card database. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... znewcardName = 'dummy-card' znewcardATR = [0x3B, 0x77, 0x94, 0x00, 0x00, 0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22] znewcardMask = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] znewcardPrimGuid = smartcard.guid.strToGUID('{128F3806-4F70-4ccf-977A-60C390664840}') znewcardSecGuid = smartcard.guid.strToGUID('{EB7F69EA-BA20-47d0-8C50-11CFDEB63BBE}') ... hresult = SCardIntroduceCardType(hcontext, znewcardName, znewcardPrimGuid, znewcardPrimGuid + znewcardSecGuid, znewcardATR, znewcardMask) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to introduce card type: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_INTRODUCECARDTYPE; %rename(SCardIntroduceCardType) _IntroduceCardType( SCARDCONTEXT hcontext, char* szCardName, GUIDLIST* PRIMARYPROVIDER, GUIDLIST* PROVIDERLIST, BYTELIST* ATR, BYTELIST* MASK ); SCARDRETCODE _IntroduceCardType( SCARDCONTEXT hcontext, char* szCardName, GUIDLIST* PRIMARYPROVIDER, GUIDLIST* PROVIDERLIST, BYTELIST* ATR, BYTELIST* MASK ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_INTRODUCEREADER " Introduces a reader to the smart card subsystem. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... dummyreader = readers[0] + ' dummy' hresult = SCardIntroduceReader(hcontext, dummyreader, readers[0]) if hresult != SCARD_S_SUCCESS: raise error, 'Unable to introduce reader: ' + dummyreader + ' : ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_INTRODUCEREADER; %rename(SCardIntroduceReader) _IntroduceReader(SCARDCONTEXT hcontext, char* szReaderName, char* szDeviceName); SCARDRETCODE _IntroduceReader(SCARDCONTEXT hcontext, char* szReaderName, char* szDeviceName); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_INTRODUCEREADERGROUP " Introduces a reader group to the smart card subsystem. However, the reader group is not created until the group is specified when adding a reader to the smart card database. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult = SCardIntroduceReaderGroup(hcontext, 'SCard$MyOwnGroup') if hresult != SCARD_S_SUCCESS: raise error, 'Unable to introduce reader group: ' + SCardGetErrorMessage(hresult) hresult = SCardAddReaderToGroup(hcontext, 'SchlumbergerSema Reflex USB v.2 0', 'SCard$MyOwnGroup') if hresult != SCARD_S_SUCCESS: raise error, 'Unable to add reader to group: ' + SCardGetErrorMessage(hresult) " %enddef %feature("docstring") DOCSTRING_INTRODUCEREADERGROUP; %rename(SCardIntroduceReaderGroup) _IntroduceReaderGroup(SCARDCONTEXT hcontext, char* szGroupName); SCARDRETCODE _IntroduceReaderGroup(SCARDCONTEXT hcontext, char* szGroupName); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_LISTINTERFACES " Provides a list of interfaces supplied by a given card. The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by the card Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, interfaces = SCardListInterfaces(hcontext, 'Schlumberger Cryptoflex 8k v2') if hresult != SCARD_S_SUCCESS: raise error, 'Failed to list interfaces: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_LISTINTERFACES; %rename(SCardListInterfaces) _ListInterfaces(SCARDCONTEXT hcontext, char* szCardName, GUIDLIST* GUIDINTERFACES); SCARDRETCODE _ListInterfaces(SCARDCONTEXT hcontext, char* szCardName, GUIDLIST* GUIDINTERFACES); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_LISTCARDS " Searches the smart card database and provides a list of named cards previously introduced to the system by the user. The caller specifies an ATR string, a set of interface identifiers (GUIDs), or both. If both an ATR string and an identifier array are supplied, the cards returned will match the ATR string supplied and support the interfaces specified. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * ... slbCryptoFlex8kv2ATR = [ 0x3B, 0x95, 0x15, 0x40, 0x00, 0x68, 0x01, 0x02, 0x00, 0x00 ] hresult, card = SCardListCards(hcontext, slbCryptoFlex8kv2ATR, []) if hresult ! =SCARD_S_SUCCESS: raise error, 'Failure to locate Schlumberger Cryptoflex 8k v2 card: ' + SCardGetErrorMessage(hresult) hresult, cards = SCardListCards(hcontext, [], []) if hresult != SCARD_S_SUCCESS: raise error, 'Failure to list cards: ' + SCardGetErrorMessage(hresult) print 'Cards: ', cards ... " %enddef %feature("docstring") DOCSTRING_LISTCARDS; %rename (SCardListCards) _ListCards( SCARDCONTEXT hcontext, BYTELIST* ATR, GUIDLIST* PROVIDERLIST, STRINGLIST* MATCHINGCARDS); SCARDRETCODE _ListCards( SCARDCONTEXT hcontext, BYTELIST* ATR, GUIDLIST* PROVIDERLIST, STRINGLIST* MATCHINGCARDS); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_LOCATECARDS " Searches the readers listed in the readerstate parameter for a card with an ATR string that matches one of the card names specified in mszCards, returning immediately with the result. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, readers = SCardListReaders(hcontext, []) readerstates = [] cards = ['Schlumberger Cryptoflex 4k', 'Schlumberger Cryptoflex 8k', 'Schlumberger Cryptoflex 8k v2'] for i in xrange(len(readers)): readerstates += [(readers[i], SCARD_STATE_UNAWARE)] hresult, newstates = SCardLocateCards(hcontext, cards, readerstates) for i in newstates: reader, eventstate, atr = i print reader, for b in atr: print '0x%.2X' % b, print "" if eventstate & SCARD_STATE_ATRMATCH: print 'Card found' if eventstate & SCARD_STATE_EMPTY: print 'Reader empty' if eventstate & SCARD_STATE_PRESENT: print 'Card present in reader' ... " %enddef %feature("docstring") DOCSTRING_LOCATECARDS; %rename(SCardLocateCards) _LocateCards( SCARDCONTEXT hcontext, STRINGLIST* CARDSTOLOCATE, READERSTATELIST *prsl); SCARDRETCODE _LocateCards( SCARDCONTEXT hcontext, STRINGLIST* CARDSTOLOCATE, READERSTATELIST *prsl); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_REMOVEREADERFROMGROUP " Removes a reader from an existing reader group. This function has no affect on the reader. Windows only, not supported by PCSC lite wrapper. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult = SCardRemoveReaderFromGroup(hcontext, 'SchlumbergerSema Reflex USB v.2 0', 'SCard$MyOwnGroup') if hresult != SCARD_S_SUCCESS: raise error, 'Unable to remove reader from group: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_REMOVEREADERFROMGROUP; %rename(SCardRemoveReaderFromGroup) _RemoveReaderFromGroup( SCARDCONTEXT hcontext, char* szReaderName, char* szGroupName); SCARDRETCODE _RemoveReaderFromGroup( SCARDCONTEXT hcontext, char* szReaderName, char* szGroupName); #endif // WIN32 /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_ISVALIDCONTEXT " This function determines whether a smart card context handle is still valid. After a smart card context handle has been set by SCardEstablishContext(), it may become not valid if the resource manager service has been shut down. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult = SCardIsValidContext(hcontext) if hresult != SCARD_S_SUCCESS: raise error, 'Invalid context: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_ISVALIDCONTEXT; %rename(SCardIsValidContext) _IsValidContext(SCARDCONTEXT hcontext); SCARDRETCODE _IsValidContext(SCARDCONTEXT hcontext); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_GETATTRIB " This function get an attribute from the IFD Handler. The possible attributes are: ======================================== ======= ======= Attribute Windows PSCS lite ======================================== ======= ======= SCARD_ATTR_ASYNC_PROTOCOL_TYPES Y SCARD_ATTR_ATR_STRING Y Y SCARD_ATTR_CHANNEL_ID Y Y SCARD_ATTR_CHARACTERISTICS Y Y SCARD_ATTR_CURRENT_BWT Y Y SCARD_ATTR_CURRENT_CLK Y Y SCARD_ATTR_CURRENT_CWT Y Y SCARD_ATTR_CURRENT_D Y Y SCARD_ATTR_CURRENT_EBC_ENCODING Y Y SCARD_ATTR_CURRENT_F Y Y SCARD_ATTR_CURRENT_IFSC Y Y SCARD_ATTR_CURRENT_IFSD Y Y SCARD_ATTR_CURRENT_IO_STATE Y Y SCARD_ATTR_CURRENT_N Y Y SCARD_ATTR_CURRENT_PROTOCOL_TYPE Y Y SCARD_ATTR_CURRENT_W Y Y SCARD_ATTR_DEFAULT_CLK Y Y SCARD_ATTR_DEFAULT_DATA_RATE Y Y SCARD_ATTR_DEVICE_FRIENDLY_NAME_A Y Y SCARD_ATTR_DEVICE_FRIENDLY_NAME_W Y Y SCARD_ATTR_DEVICE_IN_USE Y Y SCARD_ATTR_DEVICE_SYSTEM_NAME_A Y Y SCARD_ATTR_DEVICE_SYSTEM_NAME_W Y Y SCARD_ATTR_DEVICE_UNIT Y Y SCARD_ATTR_ESC_AUTHREQUEST Y Y SCARD_ATTR_ESC_CANCEL Y Y SCARD_ATTR_ESC_RESET Y Y SCARD_ATTR_EXTENDED_BWT Y Y SCARD_ATTR_ICC_INTERFACE_STATUS Y Y SCARD_ATTR_ICC_PRESENCE Y Y SCARD_ATTR_ICC_TYPE_PER_ATR Y Y SCARD_ATTR_MAXINPUT Y Y SCARD_ATTR_MAX_CLK Y Y SCARD_ATTR_MAX_DATA_RATE Y Y SCARD_ATTR_MAX_IFSD Y Y SCARD_ATTR_POWER_MGMT_SUPPORT Y Y SCARD_ATTR_SUPRESS_T1_IFS_REQUEST Y Y SCARD_ATTR_SYNC_PROTOCOL_TYPES Y SCARD_ATTR_USER_AUTH_INPUT_DEVICE Y Y SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE Y Y SCARD_ATTR_VENDOR_IFD_SERIAL_NO Y Y SCARD_ATTR_VENDOR_IFD_TYPE Y Y SCARD_ATTR_VENDOR_IFD_VERSION Y Y SCARD_ATTR_VENDOR_NAME Y Y ======================================== ======= ======= Not all the dwAttrId values listed above may be implemented in the IFD Handler you are using. And some dwAttrId values not listed here may be implemented. from smartcard.scard import * ... establish context and connect to card ... hresult, attrib = SCardGetAttrib(hcard, SCARD_ATTR_ATR_STRING) if hresult == SCARD_S_SUCCESS: for j in attrib: print '0x%.2X' % attrib, ... " %enddef %feature("docstring") DOCSTRING_GETATTRIB; %rename(SCardGetAttrib) _GetAttrib(SCARDHANDLE hcard, SCARDDWORDARG dwAttrId, BYTELIST* ATTRIBUTES); SCARDRETCODE _GetAttrib(SCARDHANDLE hcard, SCARDDWORDARG dwAttrId, BYTELIST* ATTRIBUTES); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_SETATTRIB " This function sets an attribute from the IFD Handler. Not all attributes are supported by all readers nor can they be set at all times. The possible attributes are: ======================================== ======= ======= Attribute Windows PSCS lite ======================================== ======= ======= SCARD_ATTR_ASYNC_PROTOCOL_TYPES Y SCARD_ATTR_ATR_STRING Y Y SCARD_ATTR_CHANNEL_ID Y Y SCARD_ATTR_CHARACTERISTICS Y Y SCARD_ATTR_CURRENT_BWT Y Y SCARD_ATTR_CURRENT_CLK Y Y SCARD_ATTR_CURRENT_CWT Y Y SCARD_ATTR_CURRENT_D Y Y SCARD_ATTR_CURRENT_EBC_ENCODING Y Y SCARD_ATTR_CURRENT_F Y Y SCARD_ATTR_CURRENT_IFSC Y Y SCARD_ATTR_CURRENT_IFSD Y Y SCARD_ATTR_CURRENT_IO_STATE Y Y SCARD_ATTR_CURRENT_N Y Y SCARD_ATTR_CURRENT_PROTOCOL_TYPE Y Y SCARD_ATTR_CURRENT_W Y Y SCARD_ATTR_DEFAULT_CLK Y Y SCARD_ATTR_DEFAULT_DATA_RATE Y Y SCARD_ATTR_DEVICE_FRIENDLY_NAME_A Y Y SCARD_ATTR_DEVICE_FRIENDLY_NAME_W Y Y SCARD_ATTR_DEVICE_IN_USE Y Y SCARD_ATTR_DEVICE_SYSTEM_NAME_A Y Y SCARD_ATTR_DEVICE_SYSTEM_NAME_W Y Y SCARD_ATTR_DEVICE_UNIT Y Y SCARD_ATTR_ESC_AUTHREQUEST Y Y SCARD_ATTR_ESC_CANCEL Y Y SCARD_ATTR_ESC_RESET Y Y SCARD_ATTR_EXTENDED_BWT Y Y SCARD_ATTR_ICC_INTERFACE_STATUS Y Y SCARD_ATTR_ICC_PRESENCE Y Y SCARD_ATTR_ICC_TYPE_PER_ATR Y Y SCARD_ATTR_MAXINPUT Y Y SCARD_ATTR_MAX_CLK Y Y SCARD_ATTR_MAX_DATA_RATE Y Y SCARD_ATTR_MAX_IFSD Y Y SCARD_ATTR_POWER_MGMT_SUPPORT Y Y SCARD_ATTR_SUPRESS_T1_IFS_REQUEST Y Y SCARD_ATTR_SYNC_PROTOCOL_TYPES Y SCARD_ATTR_USER_AUTH_INPUT_DEVICE Y Y SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE Y Y SCARD_ATTR_VENDOR_IFD_SERIAL_NO Y Y SCARD_ATTR_VENDOR_IFD_TYPE Y Y SCARD_ATTR_VENDOR_IFD_VERSION Y Y SCARD_ATTR_VENDOR_NAME Y Y ======================================== ======= ======= Not all the dwAttrId values listed above may be implemented in the IFD Handler you are using. And some dwAttrId values not listed here may be implemented. from smartcard.scard import * ... establish context and connect to card ... hresult, attrib = SCardSetAttrib(hcard, SCARD_ATTR_VENDOR_NAME, ['G', 'e', 'm', 'a', 'l', 't', 'o']) if hresult != SCARD_S_SUCCESS: print 'Failed to set attribute' ... " %enddef %feature("docstring") DOCSTRING_SETATTRIB; %rename(SCardSetAttrib) _SetAttrib(SCARDHANDLE hcard, SCARDDWORDARG dwAttrId, BYTELIST* ATTRIBUTESIN); SCARDRETCODE _SetAttrib(SCARDHANDLE hcard, SCARDDWORDARG dwAttrId, BYTELIST* ATTRIBUTESIN); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_CONTROL " This function sends a control command to the reader connected to by SCardConnect(). It returns a result and the control response. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, 'SchlumbergerSema Reflex USB v.2 0', SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0) CMD = [0x12, 0x34] hresult, response = SCardControl(hcard, 42, CMD) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to control: ' + SCardGetErrorMessage(hresult) " %enddef %feature("docstring") DOCSTRING_CONTROL; %rename(SCardControl) _Control( SCARDHANDLE hcard, SCARDDWORDARG dwControlCode, BYTELIST* INBUFFER, BYTELIST* OUTBUFFER ); SCARDRETCODE _Control( SCARDHANDLE hcard, SCARDDWORDARG dwControlCode, BYTELIST* INBUFFER, BYTELIST* OUTBUFFER ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_BEGINTRANSACTION " This function establishes a temporary exclusive access mode for doing a series of commands or transaction. You might want to use this when you are selecting a few files and then writing a large file so you can make sure that another application will not change the current file. If another application has a lock on this reader or this application is in SCARD_SHARE_EXCLUSIVE there will be no action taken. from smartcard.scard import * ... establish context ... hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, 'SchlumbergerSema Reflex USB v.2 0', SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0) if hresult!=SCARD_S_SUCCESS: raise error, 'unable to connect: ' + SCardGetErrorMessage(hresult) hresult = SCardBeginTransaction(hcard) if hresult != SCARD_S_SUCCESS: raise error, 'failed to begin transaction: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_BEGINTRANSACTION; %rename(SCardBeginTransaction) _BeginTransaction(SCARDHANDLE hcard); SCARDRETCODE _BeginTransaction(SCARDHANDLE hcard); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_CANCEL " This function cancels all pending blocking requests on the ScardGetStatusChange() function. from smartcard.scard import * ... establish context ... hresult = SCardCancel(hcard) if hresult != SCARD_S_SUCCESS: raise error, 'failed to cancel pending actions: ' + SCardGetErrorMessage(hresult) ..." %enddef %feature("docstring") DOCSTRING_CANCEL; %rename(SCardCancel) _Cancel(SCARDCONTEXT hcontext); SCARDRETCODE _Cancel(SCARDCONTEXT hcontext); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_CONNECT " This function establishes a connection to the friendly name of the reader specified in szReader. The first connection will power up and perform a reset on the card. Value of dwShareMode Meaning SCARD_SHARE_SHARED This application will allow others to share the reader SCARD_SHARE_EXCLUSIVE This application will NOT allow others to share the reader SCARD_SHARE_DIRECT Direct control of the reader, even without a card SCARD_SHARE_DIRECT can be used before using SCardControl() to send control commands to the reader even if a card is not present in the reader. Value of dwPreferredProtocols Meaning SCARD_PROTOCOL_T0 Use the T=0 protocol SCARD_PROTOCOL_T1 Use the T=1 protocol SCARD_PROTOCOL_RAW Use with memory type cards from smartcard.scard import * ... establish context ... hresult, readers = SCardListReaders(hcontext, 'NULL') if hresult != SCARD_S_SUCCESS: raise error, 'Failed to list readers:: ' + SCardGetErrorMessage(hresult) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, readers[0], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0) if hresult != SCARD_S_SUCCESS: raise error, 'unable to connect: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_CONNECT; %rename(SCardConnect) _Connect( SCARDCONTEXT hcontext, char* szReaderName, SCARDDWORDARG dwShareMode, SCARDDWORDARG dwPreferredProtocols, SCARDHANDLE* phcard, SCARDDWORDARG* pdwActiveProtocol ); SCARDRETCODE _Connect( SCARDCONTEXT hcontext, char* szReaderName, SCARDDWORDARG dwShareMode, SCARDDWORDARG dwPreferredProtocols, SCARDHANDLE* phcard, SCARDDWORDARG* pdwActiveProtocol ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_DISCONNECT " This function terminates a connection to the connection made through SCardConnect. disposition can have the following values: Value of disposition Meaning SCARD_LEAVE_CARD Do nothing SCARD_RESET_CARD Reset the card (warm reset) SCARD_UNPOWER_CARD Unpower the card (cold reset) SCARD_EJECT_CARD Eject the card from smartcard.scard import * ... establish context and connect to card ... hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) if hresult != SCARD_S_SUCCESS: raise error, 'failed to disconnect: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_DISCONNECT; %rename(SCardDisconnect) _Disconnect(SCARDHANDLE hcard, SCARDDWORDARG dwDisposition); SCARDRETCODE _Disconnect(SCARDHANDLE hcard, SCARDDWORDARG dwDisposition); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_ENDTRANSACTION " This function ends a previously begun transaction. The calling application must be the owner of the previously begun transaction or an error will occur. disposition can have the following values: The disposition action is not currently used in this release. Value of disposition Meaning SCARD_LEAVE_CARD Do nothing SCARD_RESET_CARD Reset the card SCARD_UNPOWER_CARD Unpower the card SCARD_EJECT_CARD Eject the card from smartcard.scard import * ... establish context, connect to card, begin transaction ... hresult = SCardEndTransaction(hcard, SCARD_LEAVE_CARD) if hresult != SCARD_S_SUCCESS: raise error, 'failed to end transaction: ' + SCardGetErrorMessage(hresult) " %enddef %feature("docstring") DOCSTRING_ENDTRANSACTION; %rename(SCardEndTransaction) _EndTransaction(SCARDHANDLE hcard, SCARDDWORDARG dwDisposition); SCARDRETCODE _EndTransaction(SCARDHANDLE hcard, SCARDDWORDARG dwDisposition); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_ESTABLISHCONTEXT " This function creates a communication context to the PC/SC Resource Manager. This must be the first function called in a PC/SC application. Value of dwScope Meaning SCARD_SCOPE_USER Operations performed within the scope of the User SCARD_SCOPE_TERMINAL Not used SCARD_SCOPE_GLOBAL Not used SCARD_SCOPE_SYSTEM Operations performed within the scope of the system from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to establish context: ' + SCardGetErrorMessage(hresult) " %enddef %feature("docstring") DOCSTRING_ESTABLISHCONTEXT; %rename(SCardEstablishContext) _EstablishContext(SCARDDWORDARG dwScope, SCARDCONTEXT* phcontext); SCARDRETCODE _EstablishContext(SCARDDWORDARG dwScope, SCARDCONTEXT* phcontext); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_GETSTATUSCHANGE " This function receives a structure or list of tuples containing reader states. A READERSTATE hast three fields (readername, state, atr). It then blocks for a change in state to occur on any of the OR'd values contained in the current state for a maximum blocking time of dwTimeout or forever if INFINITE is used. The new event state will be contained in state. A status change might be a card insertion or removal event, a change in ATR, etc. Value of state Meaning SCARD_STATE_UNAWARE The application is unaware of the current state, and would like to know. The use of this value results in an immediate return from state transition monitoring services. This is represented by all bits set to zero SCARD_STATE_IGNORE This reader should be ignored SCARD_STATE_CHANGED There is a difference between the state believed by the application, and the state known by the resource manager. When this bit is set, the application may assume a significant state change has occurred on this reader SCARD_STATE_UNKNOWN The given reader name is not recognized by the resource manager. If this bit is set, then SCARD_STATE_CHANGED and SCARD_STATE_IGNORE will also be set SCARD_STATE_UNAVAILABLE The actual state of this reader is not available. If this bit is set, then all the following bits are clear SCARD_STATE_EMPTY There is no card in the reader. If this bit is set, all the following bits will be clear SCARD_STATE_PRESENT There is a card in the reader SCARD_STATE_ATRMATCH There is a card in the reader with an ATR matching one of the target cards. If this bit is set, SCARD_STATE_PRESENT will also be set. This bit is only returned on the SCardLocateCards function SCARD_STATE_EXCLUSIVE The card in the reader is allocated for exclusive use by another application. If this bit is set, SCARD_STATE_PRESENT will also be set SCARD_STATE_INUSE The card in the reader is in use by one or more other applications, but may be connected to in shared mode. If this bit is set, SCARD_STATE_PRESENT will also be set SCARD_STATE_MUTE There is an unresponsive card in the reader from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, readers = SCardListReaders(hcontext, []) readerstates = [] cards = [ 'Schlumberger Cryptoflex 4k', 'Schlumberger Cryptoflex 8k', 'Schlumberger Cryptoflex 8k v2' ] for i in xrange(len(readers)): readerstates += [ (readers[i], SCARD_STATE_UNAWARE) ] hresult, newstates = SCardLocateCards(hcontext, cards, readerstates) print '----- Please insert or remove a card ------------' hresult, newstates = SCardGetStatusChange(hcontext, INFINITE, newstates) for i in newstates reader, eventstate, atr = i if eventstate & SCARD_STATE_ATRMATCH: print '\tCard found' if eventstate & SCARD_STATE_EMPTY: print '\tReader empty' " %enddef %feature("docstring") DOCSTRING_GETSTATUSCHANGE; %rename(SCardGetStatusChange) _GetStatusChange( SCARDCONTEXT hcontext, SCARDDWORDARG dwTimeout, READERSTATELIST* prsl); SCARDRETCODE _GetStatusChange( SCARDCONTEXT hcontext, SCARDDWORDARG dwTimeout, READERSTATELIST* prsl); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_LISTREADERS " This function returns a list of currently available readers on the system. A list of group can be provided in input to list readers in a given group only. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, readers = SCardListReaders(hcontext, []) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to list readers: ' + SCardGetErrorMessage(hresult) print 'PCSC Readers: ', readers hresult, readers = SCardListReaders(hcontext, ['SCard$T1ProtocolReaders', 'SCard$MyOwnGroup'] ... " %enddef %feature("docstring") DOCSTRING_LISTREADERS; %rename(SCardListReaders) _ListReaders( SCARDCONTEXT hcontext, STRINGLIST* READERGROUPSIN, STRINGLIST* READERSFOUND); SCARDRETCODE _ListReaders( SCARDCONTEXT hcontext, STRINGLIST* READERGROUPSIN, STRINGLIST* READERSFOUND); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_LISTREADERGROUPS " This function returns a list of currently available reader groups on the system. from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, readerGroups = SCardListReaderGroups(hcontext) if hresult != SCARD_S_SUCCESS: raise error, 'Unable to list reader groups: ' + SCardGetErrorMessage(hresult) print 'PCSC Reader groups: ', readerGroups " %enddef %feature("docstring") DOCSTRING_LISTREADERGROUPS; %rename(SCardListReaderGroups) _ListReaderGroups(SCARDCONTEXT hcontext, STRINGLIST* READERGROUPSOUT); SCARDRETCODE _ListReaderGroups(SCARDCONTEXT hcontext, STRINGLIST* READERGROUPSOUT); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_RECONNECT " This function reestablishes a connection to a reader that was previously connected to using SCardConnect(). In a multi application environment it is possible for an application to reset the card in shared mode. When this occurs any other application trying to access certain commands will be returned the value SCARD_W_RESET_CARD. When this occurs SCardReconnect() must be called in order to acknowledge that the card was reset and allow it to change it's state accordingly. Value of dwShareMode Meaning SCARD_SHARE_SHARED This application will allow others to share the reader SCARD_SHARE_EXCLUSIVE This application will NOT allow others to share the reader Value of dwPreferredProtocols Meaning SCARD_PROTOCOL_T0 Use the T=0 protocol SCARD_PROTOCOL_T1 Use the T=1 protocol SCARD_PROTOCOL_RAW Use with memory type cards dwPreferredProtocols is a bit mask of acceptable protocols for the connection. You can use (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if you do not have a preferred protocol. Value of dwInitialization Meaning SCARD_LEAVE_CARD Do nothing SCARD_RESET_CARD Reset the card (warm reset) SCARD_UNPOWER_CARD Unpower the card (cold reset) SCARD_EJECT_CARD Eject the card from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, 'SchlumbergerSema Reflex USB v.2 0', SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0) hresult, activeProtocol = SCardReconnect(hcard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0, SCARD_RESET_CARD) ... " %enddef %feature("docstring") DOCSTRING_RECONNECT; %rename(SCardReconnect) _Reconnect( SCARDHANDLE hcard, SCARDDWORDARG dwShareMode, SCARDDWORDARG dwPreferredProtocols, SCARDDWORDARG dwInitialization, SCARDDWORDARG* pdwActiveProtocol ); SCARDRETCODE _Reconnect( SCARDHANDLE hcard, SCARDDWORDARG dwShareMode, SCARDDWORDARG dwPreferredProtocols, SCARDDWORDARG dwInitialization, SCARDDWORDARG* pdwActiveProtocol ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_RELEASECONTEXT " " %enddef %feature("docstring") DOCSTRING_RELEASECONTEXT; %rename(SCardReleaseContext) _ReleaseContext(SCARDCONTEXT hcontext); SCARDRETCODE _ReleaseContext(SCARDCONTEXT hcontext); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_STATUS " This function returns the current status of the reader connected to by hcard. The reader friendly name is returned, as well as the state, protocol and ATR. The state is a DWORD possibly OR'd with the following values: Value of pdwState Meaning SCARD_ABSENT There is no card in the reader SCARD_PRESENT There is a card in the reader, but it has not been moved into position for use SCARD_SWALLOWED There is a card in the reader in position for use. The card is not powered SCARD_POWERED Power is being provided to the card, but the reader driver is unaware of the mode of the card SCARD_NEGOTIABLE The card has been reset and is awaiting PTS negotiation SCARD_SPECIFIC The card has been reset and specific communication protocols have been established Value of pdwProtocol Meaning SCARD_PROTOCOL_T0 Use the T=0 protocol SCARD_PROTOCOL_T1 Use the T=1 protocol from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, 'SchlumbergerSema Reflex USB v.2 0', SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0) hresult, reader, state, protocol, atr = SCardStatus(hcard) if hresult != SCARD_S_SUCCESS: raise error, 'failed to get status: ' + SCardGetErrorMessage(hresult) print 'Reader: ', reader print 'State: ', state print 'Protocol: ', protocol print 'ATR: ', for i in xrange(len(atr)): print '0x%.2X' % i, print "" ... " %enddef %feature("docstring") DOCSTRING_STATUS; %rename(SCardStatus) _Status( SCARDHANDLE hcard, STRING* pszReaderNameOut, SCARDDWORDARG* pdwState, SCARDDWORDARG* pdwProtocol, BYTELIST* ATROUT ); SCARDRETCODE _Status( SCARDHANDLE hcard, STRING* pszReaderNameOut, SCARDDWORDARG* pdwState, SCARDDWORDARG* pdwProtocol, BYTELIST* ATROUT ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_TRANSMIT " This function sends an APDU to the smart card contained in the reader connected to by SCardConnect(). It returns a result and the card APDU response. Value of pioSendPci Meaning SCARD_PCI_T0 Pre-defined T=0 PCI structure SCARD_PCI_T1 Pre-defined T=1 PCI structure from smartcard.scard import * hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, 'SchlumbergerSema Reflex USB v.2 0', SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0) SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] hresult, response = SCardTransmit(hcard, SCARD_PCI_T0, SELECT + DF_TELECOM) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to transmit: ' + SCardGetErrorMessage(hresult) " %enddef %feature("docstring") DOCSTRING_TRANSMIT; %rename(SCardTransmit) _Transmit( SCARDHANDLE hcard, unsigned long pioSendPci, BYTELIST* APDUCOMMAND, BYTELIST* APDURESPONSE ); SCARDRETCODE _Transmit( SCARDHANDLE hcard, unsigned long pioSendPci, BYTELIST* APDUCOMMAND, BYTELIST* APDURESPONSE ); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_SCARD_CTL_CODE " This function returns the value of a control code from smartcard.scard import * ... CM_IOCTL_GET_FEATURE_REQUEST = SCARD_CTL_CODE(3400) ... " %enddef %feature("docstring") DOCSTRING_SCARD_CTL_CODE; %rename(SCARD_CTL_CODE) _SCARD_CTL_CODE(long code); long _SCARD_CTL_CODE(long code); /////////////////////////////////////////////////////////////////////////////// %define DOCSTRING_GETERRORMESSAGE " This function return a human readable text for the given PC/SC error code. from smartcard.scard import * ... hresult, response = SCardTransmit(hcard, SCARD_PCI_T0, SELECT + DF_TELECOM) if hresult != SCARD_S_SUCCESS: raise error, 'Failed to transmit: ' + SCardGetErrorMessage(hresult) ... " %enddef %feature("docstring") DOCSTRING_GETERRORMESSAGE; %rename(SCardGetErrorMessage) _GetErrorMessage(long lErrCode); ERRORSTRING* _GetErrorMessage(long lErrCode); %inline %{ %} %{ PyObject *PyExc_SCardError=NULL; %} //---------------------------------------------------------------------- // This code gets added to the module initialization function //---------------------------------------------------------------------- %init %{ PyExc_SCardError = PyErr_NewException("scard.error", NULL, NULL); if (PyExc_SCardError != NULL) PyDict_SetItemString(d, "error", PyExc_SCardError); /* load the PCSC library */ winscard_init(); %} //---------------------------------------------------------------------- // This code is added to the scard.py python module //---------------------------------------------------------------------- %pythoncode %{ error = _scard.error %} %include PcscDefs.i #ifdef PCSCLITEyy %pythoncode %{ def SCardListCards(hcontext, atr, guidlist): return (SCARD_S_SUCCESS, []) def SCardLocateCards(hcontext, cardnames, readerstates): newreaderstates=[] for state in readerstates: newreaderstates.append((state[0], state[1], [])) return (SCARD_S_SUCCESS, newreaderstates) %} #endif #ifdef PCSCLITE %constant char* resourceManager = "pcsclite" ; #ifdef __APPLE__ #ifdef __LEOPARD__ %constant char* resourceManagerSubType = "pcsclite-leopard" ; #endif //__LEOPARD__ #ifdef __LION__ %constant char* resourceManagerSubType = "pcsclite-lion" ; #endif //__LION_ #else // !__APPLE__ %constant char* resourceManagerSubType = "pcsclite-linux" ; #endif // __APPLE__ #endif // PCSCLITE #ifdef WIN32 %constant char* resourceManager = "winscard" ; %constant char* resourceManagerSubType = "winscard-win32" ; #endif // WIN32 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/scard.rc0000644000175000017500000000047500000000000020163 0ustar00rousseaurousseau#include #define VER_FILEDESCRIPTION_STR "Python PCSC Module\0" #define VER_INTERNALNAME_STR "_scard.pyd" #define VER_ORIGINALFILENAME_STR "_scard.pyd" #define VER_FILETYPE VFT_DLL #define VER_FILESUBTYPE (0) #include "gemalto.ver" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/winscarddll.c0000644000175000017500000007015100000000000021211 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ #include #ifdef __APPLE__ #include #endif #include "pcsctypes.h" #include "winscarddll.h" #ifdef PCSCLITE #include #include #endif // PCSCLITE #ifndef NULL #define NULL ((void*)0) #endif //NULL // // these functions are only available on win32 PCSC // #ifdef WIN32 WINSCARDAPI HANDLE WINAPI _defaultSCARDACCESSSTARTEDEVENT(void) { return NULL; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDADDREADERTOGROUPA( IN SCARDCONTEXT hContext, IN LPCSTR szReaderName, IN LPCSTR szGroupName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDFORGETCARDTYPEA( IN SCARDCONTEXT hContext, IN LPCSTR szCardName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDFORGETREADERA( IN SCARDCONTEXT hContext, IN LPCSTR szReaderName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDFORGETREADERGROUPA( IN SCARDCONTEXT hContext, IN LPCSTR szGroupName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDGETPROVIDERIDA( IN SCARDCONTEXT hContext, IN LPCSTR szCard, OUT LPGUID pguidProviderId) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDGETCARDTYPEPROVIDERNAMEA( IN SCARDCONTEXT hContext, IN LPCSTR szCardName, IN SCARDDWORDARG dwProviderId, OUT LPTSTR szProvider, IN OUT SCARDDWORDARG* pcchProvider) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDINTRODUCECARDTYPEA( IN SCARDCONTEXT hContext, IN LPCSTR szCardName, IN LPCGUID pguidPrimaryProvider, IN LPCGUID rgguidInterfaces, IN SCARDDWORDARG dwInterfaceCount, IN LPCBYTE pbAtr, IN LPCBYTE pbAtrMask, IN SCARDDWORDARG cbAtrLen) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDINTRODUCEREADERA( IN SCARDCONTEXT hContext, IN LPCSTR szReaderName, IN LPCSTR szDeviceName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDINTRODUCEREADERGROUPA( IN SCARDCONTEXT hContext, IN LPCSTR szGroupName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDLISTCARDSA( IN SCARDCONTEXT hContext, IN LPCBYTE pbAtr, IN LPCGUID rgquidInterfaces, IN SCARDDWORDARG cguidInterfaceCount, OUT LPTSTR mszCards, IN OUT SCARDDWORDARG* pcchCards) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDLISTINTERFACESA( IN SCARDCONTEXT hContext, IN LPCSTR szCard, OUT LPGUID pguidInterfaces, IN OUT SCARDDWORDARG* pcguidInterfaces) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDLOCATECARDSA( IN SCARDCONTEXT hContext, IN LPCSTR mszCards, IN OUT LPSCARD_READERSTATEA rgReaderStates, IN SCARDDWORDARG cReaders) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDLOCATECARDSBYATRA( IN SCARDCONTEXT hContext, IN LPSCARD_ATRMASK rgAtrMasks, IN SCARDDWORDARG cAtrs, IN OUT LPSCARD_READERSTATEA rgReaderStates, IN SCARDDWORDARG cReaders) { return SCARD_E_NO_SERVICE; } WINSCARDAPI void WINAPI _defaultSCARDRELEASESTARTEDEVENT(void) { return; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDREMOVEREADERFROMGROUPA( IN SCARDCONTEXT hContext, IN LPCSTR szReaderName, IN LPCSTR szGroupName) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDSETCARDTYPEPROVIDERNAMEA( IN SCARDCONTEXT hContext, IN LPCSTR szCardName, IN SCARDDWORDARG dwProviderId, IN LPCSTR szProvider) { return SCARD_E_NO_SERVICE; } WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDSTATE( IN SCARDHANDLE hCard, OUT SCARDDWORDARG* pdwState, OUT SCARDDWORDARG* pdwProtocol, OUT LPBYTE pbAtr, IN OUT SCARDDWORDARG* pcbAtrLen) { return SCARD_E_NO_SERVICE; } SCARDACCESSSTARTEDEVENT mySCardAccessStartedEvent = _defaultSCARDACCESSSTARTEDEVENT; SCARDADDREADERTOGROUPA mySCardAddReaderToGroupA = _defaultSCARDADDREADERTOGROUPA; SCARDFORGETCARDTYPEA mySCardForgetCardTypeA = _defaultSCARDFORGETCARDTYPEA; SCARDFORGETREADERA mySCardForgetReaderA = _defaultSCARDFORGETREADERA; SCARDFORGETREADERGROUPA mySCardForgetReaderGroupA = _defaultSCARDFORGETREADERGROUPA; SCARDGETPROVIDERIDA mySCardGetProviderIdA = _defaultSCARDGETPROVIDERIDA; SCARDGETCARDTYPEPROVIDERNAMEA mySCardGetCardTypeProviderNameA = _defaultSCARDGETCARDTYPEPROVIDERNAMEA; SCARDINTRODUCECARDTYPEA mySCardIntroduceCardTypeA = _defaultSCARDINTRODUCECARDTYPEA; SCARDINTRODUCEREADERA mySCardIntroduceReaderA = _defaultSCARDINTRODUCEREADERA; SCARDINTRODUCEREADERGROUPA mySCardIntroduceReaderGroupA = _defaultSCARDINTRODUCEREADERGROUPA; SCARDLISTCARDSA mySCardListCardsA = _defaultSCARDLISTCARDSA; SCARDLISTINTERFACESA mySCardListInterfacesA = _defaultSCARDLISTINTERFACESA; SCARDLOCATECARDSA mySCardLocateCardsA = _defaultSCARDLOCATECARDSA; SCARDLOCATECARDSBYATRA mySCardLocateCardsByATRA = _defaultSCARDLOCATECARDSBYATRA; SCARDRELEASESTARTEDEVENT mySCardReleaseStartedEvent = _defaultSCARDRELEASESTARTEDEVENT; SCARDREMOVEREADERFROMGROUPA mySCardRemoveReaderFromGroupA = _defaultSCARDREMOVEREADERFROMGROUPA; SCARDSETCARDTYPEPROVIDERNAMEA mySCardSetCardTypeProviderNameA = _defaultSCARDSETCARDTYPEPROVIDERNAMEA; SCARDSTATE mySCardState = _defaultSCARDSTATE; #endif // WIN32 static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDISVALIDCONTEXT( IN SCARDCONTEXT hContext) { (void)hContext; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDGETATTRIB( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwAttrId, OUT LPBYTE pbAttr, IN OUT SCARDDWORDARG* pcbAttrLen) { (void)hCard; (void)dwAttrId; (void)pbAttr; (void)pcbAttrLen; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDSETATTRIB( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwAttrId, IN LPCBYTE pbAttr, IN SCARDDWORDARG cbAttrLen) { (void)hCard; (void)dwAttrId; (void)pbAttr; (void)cbAttrLen; return SCARD_E_NO_SERVICE; } SCARDISVALIDCONTEXT mySCardIsValidContext = _defaultSCARDISVALIDCONTEXT; SCARDGETATTRIB mySCardGetAttrib = _defaultSCARDGETATTRIB; SCARDSETATTRIB mySCardSetAttrib = _defaultSCARDSETATTRIB; static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDCONTROL( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwControlCode, IN LPCVOID lpInBuffer, IN SCARDDWORDARG nInBufferSize, OUT LPVOID lpOutBuffer, IN SCARDDWORDARG nOutBufferSize, OUT SCARDDWORDARG* lpBytesReturned) { (void)hCard; (void)dwControlCode; (void)lpInBuffer; (void)nInBufferSize; (void)lpOutBuffer; (void)nOutBufferSize; (void)lpBytesReturned; return SCARD_E_NO_SERVICE; } #ifdef PCSCLITE /////////////////////////////////////////////////////////////////////////////// // some pcsclite versions (e.g. on Max OS X Tiger) have no pcsc_stringify // this function was taken from pcsclite // static char* _defaultPCSCSTRINGIFYERROR( SCARDRETCODE pcscError ) { static char strError[75]; switch(pcscError ) { case SCARD_S_SUCCESS: strncpy( strError, "Command successful.", sizeof( strError ) ); break; case SCARD_E_CANCELLED: strncpy( strError, "Command cancelled.", sizeof( strError ) ); break; case SCARD_E_CANT_DISPOSE: strncpy( strError, "Cannot dispose handle.", sizeof( strError ) ); break; case SCARD_E_INSUFFICIENT_BUFFER: strncpy( strError, "Insufficient buffer.", sizeof( strError ) ); break; case SCARD_E_INVALID_ATR: strncpy( strError, "Invalid ATR.", sizeof( strError ) ); break; case SCARD_E_INVALID_HANDLE: strncpy( strError, "Invalid handle.", sizeof( strError ) ); break; case SCARD_E_INVALID_PARAMETER: strncpy( strError, "Invalid parameter given.", sizeof( strError ) ); break; case SCARD_E_INVALID_TARGET: strncpy( strError, "Invalid target given.", sizeof( strError ) ); break; case SCARD_E_INVALID_VALUE: strncpy( strError, "Invalid value given.", sizeof( strError ) ); break; case SCARD_E_NO_MEMORY: strncpy( strError, "Not enough memory.", sizeof( strError ) ); break; case SCARD_F_COMM_ERROR: strncpy( strError, "RPC transport error.", sizeof( strError ) ); break; case SCARD_F_INTERNAL_ERROR: strncpy( strError, "Internal error.", sizeof( strError ) ); break; case SCARD_F_UNKNOWN_ERROR: strncpy( strError, "Unknown error.", sizeof( strError ) ); break; case SCARD_F_WAITED_TOO_LONG: strncpy( strError, "Waited too long.", sizeof( strError ) ); break; case SCARD_E_UNKNOWN_READER: strncpy( strError, "Unknown reader specified.", sizeof( strError ) ); break; case SCARD_E_TIMEOUT: strncpy( strError, "Command timeout.", sizeof( strError ) ); break; case SCARD_E_SHARING_VIOLATION: strncpy( strError, "Sharing violation.", sizeof( strError ) ); break; case SCARD_E_NO_SMARTCARD: strncpy( strError, "No smart card inserted.", sizeof( strError ) ); break; case SCARD_E_UNKNOWN_CARD: strncpy( strError, "Unknown card.", sizeof( strError ) ); break; case SCARD_E_PROTO_MISMATCH: strncpy( strError, "Card protocol mismatch.", sizeof( strError ) ); break; case SCARD_E_NOT_READY: strncpy( strError, "Subsystem not ready.", sizeof( strError ) ); break; case SCARD_E_SYSTEM_CANCELLED: strncpy( strError, "System cancelled.", sizeof( strError ) ); break; case SCARD_E_NOT_TRANSACTED: strncpy( strError, "Transaction failed.", sizeof( strError ) ); break; case SCARD_E_READER_UNAVAILABLE: strncpy( strError, "Reader is unavailable.", sizeof( strError ) ); break; case SCARD_W_UNSUPPORTED_CARD: strncpy( strError, "Card is not supported.", sizeof( strError ) ); break; case SCARD_W_UNRESPONSIVE_CARD: strncpy( strError, "Card is unresponsive.", sizeof( strError ) ); break; case SCARD_W_UNPOWERED_CARD: strncpy( strError, "Card is unpowered.", sizeof( strError ) ); break; case SCARD_W_RESET_CARD: strncpy( strError, "Card was reset.", sizeof( strError ) ); break; case SCARD_W_REMOVED_CARD: strncpy( strError, "Card was removed.", sizeof( strError ) ); break; case SCARD_E_UNSUPPORTED_FEATURE: strncpy( strError, "Feature not supported.", sizeof( strError ) ); break; case SCARD_E_PCI_TOO_SMALL: strncpy( strError, "PCI struct too small.", sizeof( strError ) ); break; case SCARD_E_READER_UNSUPPORTED: strncpy( strError, "Reader is unsupported.", sizeof( strError ) ); break; case SCARD_E_DUPLICATE_READER: strncpy( strError, "Reader already exists.", sizeof( strError ) ); break; case SCARD_E_CARD_UNSUPPORTED: strncpy( strError, "Card is unsupported.", sizeof( strError ) ); break; case SCARD_E_NO_SERVICE: strncpy( strError, "Service not available.", sizeof( strError ) ); break; case SCARD_E_SERVICE_STOPPED: strncpy( strError, "Service was stopped.", sizeof( strError ) ); break; default: snprintf(strError, sizeof(strError)-1, "Unknown error: %ld, 0x%08lx", (long)pcscError, (long unsigned int)pcscError); }; // zero terminates string strError[sizeof(strError)-1] = '\0'; return strError; } #endif static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDBEGINTRANSACTION( IN SCARDHANDLE hCard) { (void)hCard; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDCANCEL( IN SCARDCONTEXT hContext) { (void)hContext; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDCONNECTA( IN SCARDCONTEXT hContext, IN LPCTSTR szReader, IN SCARDDWORDARG dwShareMode, IN SCARDDWORDARG dwPreferredProtocols, OUT LPSCARDHANDLE phCard, OUT SCARDDWORDARG* pdwActiveProtocol) { (void)hContext; (void)szReader; (void)dwShareMode; (void)dwPreferredProtocols; (void)phCard; (void)pdwActiveProtocol; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDDISCONNECT( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwDisposition) { (void)hCard; (void)dwDisposition; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDENDTRANSACTION( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwDisposition) { (void)hCard; (void)dwDisposition; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDESTABLISHCONTEXT( IN SCARDDWORDARG dwScope, IN LPCVOID pvReserved1, IN LPCVOID pvReserved2, OUT LPSCARDCONTEXT phContext) { (void)dwScope; (void)pvReserved1; (void)pvReserved2; (void)phContext; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDFREEMEMORY( IN SCARDCONTEXT hContext, IN LPCVOID pvMem) { (void)hContext; (void)pvMem; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDGETSTATUSCHANGEA( IN SCARDCONTEXT hContext, IN SCARDDWORDARG dwTimeout, IN OUT LPSCARD_READERSTATEA rgReaderStates, IN SCARDDWORDARG cReaders) { (void)hContext; (void)dwTimeout; (void)rgReaderStates; (void)cReaders; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDLISTREADERSA( IN SCARDCONTEXT hContext, IN LPCTSTR mszGroups, OUT LPTSTR mszReaders, IN OUT SCARDDWORDARG* pcchReaders) { (void)hContext; (void)mszGroups; (void)mszReaders; (void)pcchReaders; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDLISTREADERGROUPSA( IN SCARDCONTEXT hContext, OUT LPTSTR mszGroups, IN OUT SCARDDWORDARG* pcchGroups) { (void)hContext; (void)mszGroups; (void)pcchGroups; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDRECONNECT( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwShareMode, IN SCARDDWORDARG dwPreferredProtocols, IN SCARDDWORDARG dwInitialization, OUT SCARDDWORDARG* pdwActiveProtocol) { (void)hCard; (void)dwShareMode; (void)dwPreferredProtocols; (void)dwInitialization; (void)pdwActiveProtocol; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDRELEASECONTEXT( IN SCARDCONTEXT hContext) { (void)hContext; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDSTATUSA( IN SCARDHANDLE hCard, OUT LPTSTR szReaderName, IN OUT SCARDDWORDARG* pcchReaderLen, OUT SCARDDWORDARG* pdwState, OUT SCARDDWORDARG* pdwProtocol, OUT LPBYTE pbAtr, IN OUT SCARDDWORDARG* pcbAtrLen) { (void)hCard; (void)szReaderName; (void)pcchReaderLen; (void)pdwState; (void)pdwProtocol; (void)pbAtr; (void)pcbAtrLen; return SCARD_E_NO_SERVICE; } static WINSCARDAPI SCARDRETCODE WINAPI _defaultSCARDTRANSMIT( IN SCARDHANDLE hCard, IN LPCSCARD_IO_REQUEST pioSendPci, IN LPCBYTE pbSendBuffer, IN SCARDDWORDARG cbSendLength, IN OUT LPSCARD_IO_REQUEST pioRecvPci, OUT LPBYTE pbRecvBuffer, IN OUT SCARDDWORDARG* pcbRecvLength) { (void)hCard; (void)pioSendPci; (void)pbSendBuffer; (void)cbSendLength; (void)pioRecvPci; (void)pbRecvBuffer; (void)pcbRecvLength; return SCARD_E_NO_SERVICE; } SCARDBEGINTRANSACTION mySCardBeginTransaction = _defaultSCARDBEGINTRANSACTION; SCARDCANCEL mySCardCancel = _defaultSCARDCANCEL; SCARDCONNECTA mySCardConnectA = _defaultSCARDCONNECTA; SCARDCONTROL mySCardControl = _defaultSCARDCONTROL; SCARDDISCONNECT mySCardDisconnect = _defaultSCARDDISCONNECT; SCARDENDTRANSACTION mySCardEndTransaction = _defaultSCARDENDTRANSACTION; SCARDESTABLISHCONTEXT mySCardEstablishContext = _defaultSCARDESTABLISHCONTEXT; SCARDFREEMEMORY mySCardFreeMemory = _defaultSCARDFREEMEMORY; SCARDGETSTATUSCHANGEA mySCardGetStatusChangeA = _defaultSCARDGETSTATUSCHANGEA; SCARDLISTREADERSA mySCardListReadersA = _defaultSCARDLISTREADERSA; SCARDLISTREADERGROUPSA mySCardListReaderGroupsA = _defaultSCARDLISTREADERGROUPSA; SCARDRECONNECT mySCardReconnect = _defaultSCARDRECONNECT; SCARDRELEASECONTEXT mySCardReleaseContext = _defaultSCARDRELEASECONTEXT; SCARDSTATUSA mySCardStatusA = _defaultSCARDSTATUSA; SCARDTRANSMIT mySCardTransmit = _defaultSCARDTRANSMIT; #ifdef PCSCLITE PCSCSTRINGIFYERROR myPcscStringifyError = _defaultPCSCSTRINGIFYERROR; #endif // PCSCLITE void * myg_prgSCardT0Pci=NULL; void * myg_prgSCardT1Pci=NULL; void * myg_prgSCardRawPci=NULL; long winscard_init(void) { static BOOL bFirstCall=TRUE; static long lRetCode=SCARD_E_NO_SERVICE; #ifdef WIN32 #define GETPROCADDRESS(type,name) my##name=(type)GetProcAddress(hinstDLL, #name ); HINSTANCE hinstDLL=NULL; if( bFirstCall ) { bFirstCall=FALSE; hinstDLL = LoadLibrary( "winscard.dll" ); if( NULL!=hinstDLL ) { lRetCode=SCARD_S_SUCCESS; GETPROCADDRESS( SCARDADDREADERTOGROUPA , SCardAddReaderToGroupA ); GETPROCADDRESS( SCARDACCESSSTARTEDEVENT , SCardAccessStartedEvent ); GETPROCADDRESS( SCARDBEGINTRANSACTION , SCardBeginTransaction ); GETPROCADDRESS( SCARDCANCEL , SCardCancel ); GETPROCADDRESS( SCARDCONNECTA , SCardConnectA ); GETPROCADDRESS( SCARDCONTROL , SCardControl ); GETPROCADDRESS( SCARDDISCONNECT , SCardDisconnect ); GETPROCADDRESS( SCARDENDTRANSACTION , SCardEndTransaction ); GETPROCADDRESS( SCARDESTABLISHCONTEXT , SCardEstablishContext ); GETPROCADDRESS( SCARDFORGETCARDTYPEA , SCardForgetCardTypeA ); GETPROCADDRESS( SCARDFORGETREADERA , SCardForgetReaderA ); GETPROCADDRESS( SCARDFORGETREADERGROUPA , SCardForgetReaderGroupA ); GETPROCADDRESS( SCARDFREEMEMORY , SCardFreeMemory ); GETPROCADDRESS( SCARDGETCARDTYPEPROVIDERNAMEA , SCardGetCardTypeProviderNameA ); GETPROCADDRESS( SCARDGETATTRIB , SCardGetAttrib ); GETPROCADDRESS( SCARDGETPROVIDERIDA , SCardGetProviderIdA ); GETPROCADDRESS( SCARDGETSTATUSCHANGEA , SCardGetStatusChangeA ); GETPROCADDRESS( SCARDINTRODUCECARDTYPEA , SCardIntroduceCardTypeA ); GETPROCADDRESS( SCARDINTRODUCEREADERA , SCardIntroduceReaderA ); GETPROCADDRESS( SCARDINTRODUCEREADERGROUPA , SCardIntroduceReaderGroupA ); GETPROCADDRESS( SCARDISVALIDCONTEXT , SCardIsValidContext ); GETPROCADDRESS( SCARDLISTCARDSA , SCardListCardsA ); GETPROCADDRESS( SCARDLISTINTERFACESA , SCardListInterfacesA ); GETPROCADDRESS( SCARDLISTREADERSA , SCardListReadersA ); GETPROCADDRESS( SCARDLISTREADERGROUPSA , SCardListReaderGroupsA ); GETPROCADDRESS( SCARDLOCATECARDSA , SCardLocateCardsA ); GETPROCADDRESS( SCARDLOCATECARDSBYATRA , SCardLocateCardsByATRA ); GETPROCADDRESS( SCARDRECONNECT , SCardReconnect ); GETPROCADDRESS( SCARDRELEASECONTEXT , SCardReleaseContext ); GETPROCADDRESS( SCARDRELEASESTARTEDEVENT , SCardReleaseStartedEvent ); GETPROCADDRESS( SCARDREMOVEREADERFROMGROUPA , SCardRemoveReaderFromGroupA ); GETPROCADDRESS( SCARDSETATTRIB , SCardSetAttrib ); GETPROCADDRESS( SCARDSETCARDTYPEPROVIDERNAMEA , SCardSetCardTypeProviderNameA ); GETPROCADDRESS( SCARDSTATE , SCardState ); GETPROCADDRESS( SCARDSTATUSA , SCardStatusA ); GETPROCADDRESS( SCARDTRANSMIT , SCardTransmit ); myg_prgSCardT0Pci = GetProcAddress( hinstDLL, "g_rgSCardT0Pci" ); myg_prgSCardT1Pci = GetProcAddress( hinstDLL, "g_rgSCardT1Pci" ); myg_prgSCardRawPci = GetProcAddress( hinstDLL, "g_rgSCardRawPci" ); } } #endif // WIN32 #ifdef PCSCLITE #define GETPROCADDRESS( type, name, realname ) my##name=(type)dlsym( handle, #realname ); \ dlsym_error = dlerror(); \ if (NULL!=dlsym_error) \ { \ printf( "Failed to load symbol for: %s, %s!\n", #realname, (char*)dlsym_error ); \ } // some functions are not available on older releases of pcsc-lite, such // as SCardIsValidContext; don't complain if they are not located #define SILENTGETPROCADDRESS( type, name, realname ) my##name=(type)dlsym( handle, #realname ); \ dlsym_error = dlerror(); void* handle=NULL; char* dlsym_error; const char *lib = NULL; #ifdef __APPLE__ lib = "/System/Library/Frameworks/PCSC.framework/PCSC"; #else lib = "libpcsclite.so.1"; #endif if( bFirstCall ) { dlerror(); handle = dlopen( lib, RTLD_NOW ); if( NULL!=handle ) { lRetCode=SCARD_S_SUCCESS; GETPROCADDRESS( SCARDBEGINTRANSACTION , SCardBeginTransaction , SCardBeginTransaction ); GETPROCADDRESS( SCARDCANCEL , SCardCancel , SCardCancel ); GETPROCADDRESS( SCARDCONNECTA , SCardConnectA , SCardConnect ); GETPROCADDRESS( SCARDDISCONNECT , SCardDisconnect , SCardDisconnect ); GETPROCADDRESS( SCARDENDTRANSACTION , SCardEndTransaction , SCardEndTransaction ); GETPROCADDRESS( SCARDESTABLISHCONTEXT , SCardEstablishContext , SCardEstablishContext ); GETPROCADDRESS( SCARDGETSTATUSCHANGEA , SCardGetStatusChangeA , SCardGetStatusChange ); GETPROCADDRESS( SCARDLISTREADERSA , SCardListReadersA , SCardListReaders ); GETPROCADDRESS( SCARDLISTREADERGROUPSA , SCardListReaderGroupsA , SCardListReaderGroups ); GETPROCADDRESS( SCARDRECONNECT , SCardReconnect , SCardReconnect ); GETPROCADDRESS( SCARDRELEASECONTEXT , SCardReleaseContext , SCardReleaseContext ); GETPROCADDRESS( SCARDSTATUSA , SCardStatusA , SCardStatus ); GETPROCADDRESS( SCARDTRANSMIT , SCardTransmit , SCardTransmit ); SILENTGETPROCADDRESS( PCSCSTRINGIFYERROR , PcscStringifyError , pcsc_stringify_error ); #ifndef __APPLE__ GETPROCADDRESS( SCARDCONTROL, SCardControl, SCardControl ); #else // !__APPLE__ GETPROCADDRESS( SCARDCONTROL, SCardControl, SCardControl132 ); #endif // __APPLE__ SILENTGETPROCADDRESS( SCARDISVALIDCONTEXT , SCardIsValidContext , SCardIsValidContext ); GETPROCADDRESS( SCARDGETATTRIB , SCardGetAttrib , SCardGetAttrib ); GETPROCADDRESS( SCARDSETATTRIB , SCardSetAttrib , SCardSetAttrib ); myg_prgSCardT0Pci = dlsym( handle, "g_rgSCardT0Pci" ); myg_prgSCardT1Pci = dlsym( handle, "g_rgSCardT1Pci" ); myg_prgSCardRawPci = dlsym( handle, "g_rgSCardRawPci" ); dlsym_error = dlerror(); if( NULL!= dlsym_error ) { printf( "Failed to load symbol address from %s: %s!", lib, (char*)dlsym_error ); } } else { dlsym_error = dlerror(); if( NULL!= dlsym_error ) { printf( "Failed to dlopen %s: %s!", lib, (dlsym_error==NULL) ? "" : (char*)dlsym_error ); } } bFirstCall=FALSE; } #endif // PCSCLITE return lRetCode; }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/scard/winscarddll.h0000644000175000017500000002631500000000000021221 0ustar00rousseaurousseau/*============================================================================== Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================*/ #ifndef __WINSCARDDLL_H__ #define __WINSCARDDLL_H__ #ifdef WIN32 #include #endif #ifdef __APPLE__ #include #include #define LPCTSTR char* #else // !__APPLE__ #include #endif #ifdef PCSCLITE #define WINSCARDAPI #define WINAPI #define IN #define OUT #define LPSCARD_READERSTATEA SCARD_READERSTATE * #define SCARD_AUTOALLOCATE (DWORD)(-1) #ifndef FALSE #define FALSE (0==1) #endif // FALSE #ifndef TRUE #define TRUE (1==1) #endif #endif // PCSCLITE // // these functions are only available on win32 PCSC // #ifdef WIN32 typedef WINSCARDAPI HANDLE (WINAPI *SCARDACCESSSTARTEDEVENT)(void); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDADDREADERTOGROUPA)( IN SCARDCONTEXT hContext, IN LPCTSTR szReaderName, IN LPCTSTR szGroupName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDFORGETCARDTYPEA)( IN SCARDCONTEXT hContext, IN LPCSTR szCardName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDFORGETREADERA)( IN SCARDCONTEXT hContext, IN LPCSTR szReaderName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDFORGETREADERGROUPA)( IN SCARDCONTEXT hContext, IN LPCSTR szGroupName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDGETCARDTYPEPROVIDERNAMEA)( IN SCARDCONTEXT hContext, IN LPCSTR szCardName, IN SCARDDWORDARG dwProviderId, OUT LPTSTR szProvider, IN OUT SCARDDWORDARG* pcchProvider); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDGETPROVIDERIDA)( IN SCARDCONTEXT hContext, IN LPCSTR szCard, OUT LPGUID pguidProviderId); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDINTRODUCECARDTYPEA)( IN SCARDCONTEXT hContext, IN LPCSTR szCardName, IN LPCGUID pguidPrimaryProvider, IN LPCGUID rgguidInterfaces, IN SCARDDWORDARG dwInterfaceCount, IN LPCBYTE pbAtr, IN LPCBYTE pbAtrMask, IN SCARDDWORDARG cbAtrLen); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDINTRODUCEREADERA)( IN SCARDCONTEXT hContext, IN LPCSTR szReaderName, IN LPCSTR szDeviceName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDINTRODUCEREADERGROUPA)( IN SCARDCONTEXT hContext, IN LPCSTR szGroupName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDLISTCARDSA)( IN SCARDCONTEXT hContext, IN LPCBYTE pbAtr, IN LPCGUID rgquidInterfaces, IN SCARDDWORDARG cguidInterfaceCount, OUT LPTSTR mszCards, IN OUT SCARDDWORDARG* pcchCards); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDLISTINTERFACESA)( IN SCARDCONTEXT hContext, IN LPCSTR szCard, OUT LPGUID pguidInterfaces, IN OUT SCARDDWORDARG* pcguidInterfaces); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDLOCATECARDSA)( IN SCARDCONTEXT hContext, IN LPCSTR mszCards, IN OUT LPSCARD_READERSTATEA rgReaderStates, IN SCARDDWORDARG cReaders); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDLOCATECARDSBYATRA)( IN SCARDCONTEXT hContext, IN LPSCARD_ATRMASK rgAtrMasks, IN SCARDDWORDARG cAtrs, IN OUT LPSCARD_READERSTATEA rgReaderStates, IN SCARDDWORDARG cReaders); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDSETCARDTYPEPROVIDERNAMEA)( IN SCARDCONTEXT hContext, IN LPCSTR szCardName, IN SCARDDWORDARG dwProviderId, IN LPCSTR szProvider); typedef WINSCARDAPI void (WINAPI *SCARDRELEASESTARTEDEVENT)(void); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDREMOVEREADERFROMGROUPA)( IN SCARDCONTEXT hContext, IN LPCTSTR szReaderName, IN LPCTSTR szGroupName); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDSTATE)( IN SCARDHANDLE hCard, OUT SCARDDWORDARG* pdwState, OUT SCARDDWORDARG* pdwProtocol, OUT LPBYTE pbAtr, IN OUT SCARDDWORDARG* pcbAtrLen); extern SCARDACCESSSTARTEDEVENT mySCardAccessStartedEvent; extern SCARDADDREADERTOGROUPA mySCardAddReaderToGroupA; extern SCARDFORGETCARDTYPEA mySCardForgetCardTypeA; extern SCARDFORGETREADERA mySCardForgetReaderA; extern SCARDFORGETREADERGROUPA mySCardForgetReaderGroupA; extern SCARDGETCARDTYPEPROVIDERNAMEA mySCardGetCardTypeProviderNameA; extern SCARDGETPROVIDERIDA mySCardGetProviderIdA; extern SCARDINTRODUCECARDTYPEA mySCardIntroduceCardTypeA; extern SCARDINTRODUCEREADERA mySCardIntroduceReaderA; extern SCARDINTRODUCEREADERGROUPA mySCardIntroduceReaderGroupA; extern SCARDLISTCARDSA mySCardListCardsA; extern SCARDLISTINTERFACESA mySCardListInterfacesA; extern SCARDLOCATECARDSA mySCardLocateCardsA; extern SCARDLOCATECARDSBYATRA mySCardLocateCardsByATRA; extern SCARDRELEASESTARTEDEVENT mySCardReleaseStartedEvent; extern SCARDREMOVEREADERFROMGROUPA mySCardRemoveReaderFromGroupA; extern SCARDSETCARDTYPEPROVIDERNAMEA mySCardSetCardTypeProviderNameA; extern SCARDSTATE mySCardState; #endif // WIN32 typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDISVALIDCONTEXT)( IN SCARDCONTEXT hContext); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDGETATTRIB)( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwAttrId, OUT LPBYTE pbAttr, IN OUT SCARDDWORDARG* pcbAttrLen); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDSETATTRIB)( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwAttrId, IN LPCBYTE pbAttr, IN SCARDDWORDARG cbAttrLen); extern SCARDISVALIDCONTEXT mySCardIsValidContext; extern SCARDGETATTRIB mySCardGetAttrib; extern SCARDSETATTRIB mySCardSetAttrib; typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDCONTROL)( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwControlCode, IN LPCVOID lpInBuffer, IN SCARDDWORDARG nInBufferSize, OUT LPVOID lpOutBuffer, IN SCARDDWORDARG nOutBufferSize, OUT SCARDDWORDARG* lpBytesReturned); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDBEGINTRANSACTION)( IN SCARDHANDLE hCard); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDCANCEL)( IN SCARDCONTEXT hContext); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDCANCELTRANSACTION)( IN SCARDHANDLE hCard); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDCONNECTA)( IN SCARDCONTEXT hContext, IN LPCTSTR szReader, IN SCARDDWORDARG dwShareMode, IN SCARDDWORDARG dwPreferredProtocols, OUT LPSCARDHANDLE phCard, OUT SCARDDWORDARG* pdwActiveProtocol); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDDISCONNECT)( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwDisposition); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDENDTRANSACTION)( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwDisposition); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDESTABLISHCONTEXT)( IN SCARDDWORDARG dwScope, IN LPCVOID pvReserved1, IN LPCVOID pvReserved2, OUT LPSCARDCONTEXT phContext); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDFREEMEMORY)( IN SCARDCONTEXT hContext, IN LPCVOID pvMem); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDGETSTATUSCHANGEA)( IN SCARDCONTEXT hContext, IN SCARDDWORDARG dwTimeout, IN OUT LPSCARD_READERSTATEA rgReaderStates, IN SCARDDWORDARG cReaders); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDLISTREADERSA)( IN SCARDCONTEXT hContext, IN LPCTSTR mszGroups, OUT LPTSTR mszReaders, IN OUT SCARDDWORDARG* pcchReaders); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDLISTREADERGROUPSA)( IN SCARDCONTEXT hContext, OUT LPTSTR mszGroups, IN OUT SCARDDWORDARG* pcchGroups); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDRECONNECT)( IN SCARDHANDLE hCard, IN SCARDDWORDARG dwShareMode, IN SCARDDWORDARG dwPreferredProtocols, IN SCARDDWORDARG dwInitialization, OUT SCARDDWORDARG* pdwActiveProtocol); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDRELEASECONTEXT)( IN SCARDCONTEXT hContext); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDSTATUSA)( IN SCARDHANDLE hCard, OUT LPTSTR szReaderName, IN OUT SCARDDWORDARG* pcchReaderLen, OUT SCARDDWORDARG* pdwState, OUT SCARDDWORDARG* pdwProtocol, OUT LPBYTE pbAtr, IN OUT SCARDDWORDARG* pcbAtrLen); typedef WINSCARDAPI SCARDRETCODE (WINAPI *SCARDTRANSMIT)( IN SCARDHANDLE hCard, IN LPCSCARD_IO_REQUEST pioSendPci, IN LPCBYTE pbSendBuffer, IN SCARDDWORDARG cbSendLength, IN OUT LPSCARD_IO_REQUEST pioRecvPci, OUT LPBYTE pbRecvBuffer, IN OUT SCARDDWORDARG* pcbRecvLength); #ifdef PCSCLITE typedef WINSCARDAPI char* (WINAPI *PCSCSTRINGIFYERROR)( IN SCARDRETCODE pcscError); extern PCSCSTRINGIFYERROR myPcscStringifyError; #endif // PCSCLITE extern SCARDBEGINTRANSACTION mySCardBeginTransaction; extern SCARDCANCEL mySCardCancel; extern SCARDCONNECTA mySCardConnectA; extern SCARDCONTROL mySCardControl; extern SCARDDISCONNECT mySCardDisconnect; extern SCARDENDTRANSACTION mySCardEndTransaction; extern SCARDESTABLISHCONTEXT mySCardEstablishContext; extern SCARDFREEMEMORY mySCardFreeMemory; extern SCARDGETSTATUSCHANGEA mySCardGetStatusChangeA; extern SCARDLISTREADERSA mySCardListReadersA; extern SCARDLISTREADERGROUPSA mySCardListReaderGroupsA; extern SCARDRECONNECT mySCardReconnect; extern SCARDRELEASECONTEXT mySCardReleaseContext; extern SCARDSTATUSA mySCardStatusA; extern SCARDTRANSMIT mySCardTransmit; extern void * myg_prgSCardT0Pci; extern void * myg_prgSCardT1Pci; extern void * myg_prgSCardRawPci; long winscard_init(void); #endif // __WINSCARDDLL_H__ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/sw/0000755000175000017500000000000000000000000016070 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/sw/ErrorChecker.py0000644000175000017500000000326200000000000021023 0ustar00rousseaurousseau"""Base class for status word error checkers. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ class ErrorChecker(object): """Base class for status word error checking strategies. Error checking strategies are chained into an L{ErrorCheckingChain} to implement a Chain of Responsibility. Each strategy in the chain is called until an error is detected. The strategy raises a L{smartcard.sw.SWException} exception when an error is detected. Implementation derived from Bruce Eckel, Thinking in Python. The L{ErrorCheckingChain} implements the Chain Of Responsibility design pattern. """ def __call__(data, sw1, sw2): """Called to test data, sw1 and sw2 for error. @param data: apdu response data @param sw1, sw2: apdu data status words Derived classes must raise a L{smartcard.sw.SWException} upon error.""" pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/sw/ErrorCheckingChain.py0000644000175000017500000000670000000000000022135 0ustar00rousseaurousseau"""The error checking chain is a list of status word (sw1, sw2) error check strategies. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from sys import exc_info class ErrorCheckingChain(object): """The error checking chain is a list of response apdu status word (sw1, sw2) error check strategies. Each strategy in the chain is called until an error is detected. A L{smartcard.sw.SWException} exception is raised when an error is detected. No exception is raised if no error is detected. Implementation derived from Bruce Eckel, Thinking in Python. The L{ErrorCheckingChain} implements the Chain Of Responsibility design pattern. """ def __init__(self, chain, strategy): """constructor. Appends a strategy to the L{ErrorCheckingChain} chain.""" self.strategy = strategy self.chain = chain self.chain.append(self) self.excludes = [] def next(self): """Returns next error checking strategy.""" # Where this link is in the chain: location = self.chain.index(self) if not self.end(): return self.chain[location + 1] def addFilterException(self, exClass): """Add an exception filter to the error checking chain. @param exClass: the exception to exclude, e.g. L{smartcard.sw.SWExceptions.WarningProcessingException} A filtered exception will not be raised when the sw1,sw2 conditions that would raise the excption are met. """ self.excludes.append(exClass) if self.end(): return self.next().addFilterException(exClass) def end(self): """Returns True if this is the end of the error checking strategy chain.""" return (self.chain.index(self) + 1 >= len(self.chain)) def __call__(self, data, sw1, sw2): """Called to test data, sw1 and sw2 for error on the chain.""" try: self.strategy(data, sw1, sw2) except tuple(self.excludes) as exc: # The following addtional filter may look redundant, it isn't. # It checks that type(exc) is *equal* to any of self.excludes, # rather than equal-or-subclass to any of self.excludes. # This maintains backward compatibility with the behaviour of # pyscard <= 1.6.16. # if exception is filtered, return for exception in self.excludes: if exception == exc_info()[0]: return # otherwise reraise exception raise # if not done, call next strategy if self.end(): return return self.next()(data, sw1, sw2) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399696.0 pyscard-2.0.2/smartcard/sw/ISO7816_4ErrorChecker.py0000644000175000017500000001476300000000000022157 0ustar00rousseaurousseau"""ISO7816-4 error checking strategy. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.sw.ErrorChecker import ErrorChecker import smartcard.sw.SWExceptions iso7816_4SW = { 0x62: (smartcard.sw.SWExceptions.WarningProcessingException, {0x00: "Response padded/ More APDU commands expected", 0x81: "Part of returned data may be corrupted", 0x82: "End of file/record reached before reading Le bytes", 0x83: "File invalidated", 0x84: "FCI not correctly formatted", 0xFF: "Correct execution, response padded"}), 0x63: (smartcard.sw.SWExceptions.WarningProcessingException, {0x00: "Authentication failed", 0x81: "File filled up by the last write", 0xC0: "PIN verification failed. 0 tries before blocking PIN", 0xC1: "PIN verification failed. 1 tries before blocking PIN", 0xC2: "PIN verification failed. 2 tries before blocking PIN", 0xC3: "PIN verification failed. 3 tries before blocking PIN", 0xC4: "PIN verification failed. 4 tries before blocking PIN", 0xC5: "PIN verification failed. 5 tries before blocking PIN", 0xC6: "PIN verification failed. 6 tries before blocking PIN", 0xC7: "PIN verification failed. 7 tries before blocking PIN", 0xC8: "PIN verification failed. 8 tries before blocking PIN", 0xC9: "PIN verification failed. 9 tries before blocking PIN", 0xCA: "PIN verification failed. 10 tries before blocking PIN", 0xCB: "PIN verification failed. 11 tries before blocking PIN", 0xCC: "PIN verification failed. 12 tries before blocking PIN", 0xCD: "PIN verification failed. 13 tries before blocking PIN", 0xCE: "PIN verification failed. 14 tries before blocking PIN", 0xCF: "PIN verification failed. 15 tries before blocking PIN"}), 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException, {0x00: "Integrity error detected in EEPROM"}), 0x67: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Wrong length in Lc"}), 0x68: (smartcard.sw.SWExceptions.CheckingErrorException, {0x81: "Logical channel not supported", 0x82: "Secure messaging not supported"}), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, {0x81: "Command incompatible with file structure.", 0x82: "Security status not satisfied", 0x83: "Authentification method blocked", 0x84: "Referenced data invalid", 0x85: "Conditions of use not satisfied", 0x86: "Command not allowed (no current EF)", 0x87: "Secure messaging data object missing.", 0x88: "Secure messaging data object incorrect"}), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, {0x80: "Incorrect parameters in the data field", 0x81: "Function not supported", 0x82: "File not found", 0x83: "Record not found", 0x84: "Not enough memory space in the file", 0x85: "Lc inconsistent with TLV structure", 0x86: "Incorrect parameters P1-P2", 0x87: "Lc is inconsistent with P1-P2", 0x88: "Referenced data not found"}), 0x6B: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Incorrect parameters P1-P2"}), 0x6D: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Instruction (INS) not supported"}), 0x6E: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Class (CLA) not supported"}), 0x6F: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Fatal error"}), } class ISO7816_4ErrorChecker(ErrorChecker): """ISO7816-4 error checking strategy. This strategy raises the following exceptions: - sw1 sw2 - 62 00 81 82 83 84 FF WarningProcessingException - 63 00 81 C0->CF WarningProcessingException - 64 00 ExecutionErrorException - 67 00 CheckingErrorException - 68 81 82 CheckingErrorException - 69 81->88 99? c1? CheckingErrorException - 6a 80->88 CheckingErrorException - 6b 00 CheckingErrorException - 6d 00 CheckingErrorException - 6e 00 CheckingErrorException - 6f 00 CheckingErrorException This checker does not raise exceptions on undefined sw1 values, e.g.: - sw1 sw2 - 65 any - 66 any - 6c any and on undefined sw2 values, e.g.: - sw1 sw2 - 62 80 85 - 6b any except 00 Use another checker in the error checking chain, e.g., the ISO7816_4SW1ErrorChecker, to raise exceptions on these undefined values. """ def __call__(self, data, sw1, sw2): """Called to test data, sw1 and sw2 for error. @param data: apdu response data @param sw1, sw2: apdu data status words Derived classes must raise a L{smartcard.sw.SWException} upon error.""" if sw1 in iso7816_4SW: exception, sw2dir = iso7816_4SW[sw1] if type(sw2dir) == type({}): try: message = sw2dir[sw2] raise exception(data, sw1, sw2, message) except KeyError: pass if __name__ == '__main__': """Small sample illustrating the use of ISO7816_4ErrorChecker.""" ecs = ISO7816_4ErrorChecker() ecs([], 0x90, 0x00) try: ecs([], 0x6b, 0x00) except smartcard.sw.SWExceptions.CheckingErrorException as e: print(str(e) + " %x %x" % (e.sw1, e.sw2)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399700.0 pyscard-2.0.2/smartcard/sw/ISO7816_4_SW1ErrorChecker.py0000644000175000017500000000630600000000000022643 0ustar00rousseaurousseau"""ISO7816-4 sw1 only error checker. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.sw.ErrorChecker import ErrorChecker import smartcard.sw.SWExceptions iso7816_4SW1 = { 0x62: smartcard.sw.SWExceptions.WarningProcessingException, 0x63: smartcard.sw.SWExceptions.WarningProcessingException, 0x64: smartcard.sw.SWExceptions.ExecutionErrorException, 0x65: smartcard.sw.SWExceptions.ExecutionErrorException, 0x66: smartcard.sw.SWExceptions.SecurityRelatedException, 0x67: smartcard.sw.SWExceptions.CheckingErrorException, 0x68: smartcard.sw.SWExceptions.CheckingErrorException, 0x69: smartcard.sw.SWExceptions.CheckingErrorException, 0x6A: smartcard.sw.SWExceptions.CheckingErrorException, 0x6B: smartcard.sw.SWExceptions.CheckingErrorException, 0x6C: smartcard.sw.SWExceptions.CheckingErrorException, 0x6D: smartcard.sw.SWExceptions.CheckingErrorException, 0x6E: smartcard.sw.SWExceptions.CheckingErrorException, 0x6F: smartcard.sw.SWExceptions.CheckingErrorException, } class ISO7816_4_SW1ErrorChecker(ErrorChecker): """ISO7816-4 error checker based on status word sw1 only. This error checker raises the following exceptions: - sw1 sw2 - 62 any WarningProcessingException - 63 any WarningProcessingException - 64 any ExecutionErrorException - 65 any ExecutionErrorException - 66 any SecurityRelatedException - 67 any CheckingErrorException - 68 any CheckingErrorException - 69 any CheckingErrorException - 6a any CheckingErrorException - 6b any CheckingErrorException - 6c any CheckingErrorException - 6d any CheckingErrorException - 6e any CheckingErrorException - 6f any CheckingErrorException """ def __call__(self, data, sw1, sw2): """Called to test data, sw1 and sw2 for error. @param data: apdu response data @param sw1, sw2: apdu data status words """ if sw1 in iso7816_4SW1: exception = iso7816_4SW1[sw1] raise exception(data, sw1, sw2) if __name__ == '__main__': """Small sample illustrating the use of ISO7816_4_SW1ErrorChecker.""" ecs = ISO7816_4_SW1ErrorChecker() ecs([], 0x90, 0x00) try: ecs([], 0x66, 0x80) except smartcard.sw.SWExceptions.SecurityRelatedException as e: print(str(e) + " %x %x" % (e.sw1, e.sw2)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399702.0 pyscard-2.0.2/smartcard/sw/ISO7816_8ErrorChecker.py0000644000175000017500000001221300000000000022147 0ustar00rousseaurousseau"""ISO7816-8 error checker. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.sw.ErrorChecker import ErrorChecker import smartcard.sw.SWExceptions iso7816_8SW = { 0x63: (smartcard.sw.SWExceptions.WarningProcessingException, {0x00: "Authentication failed", 0xC0: "PIN verification failed. 0 retries before blocking PIN", 0xC1: "PIN verification failed. 1 retries before blocking PIN", 0xC2: "PIN verification failed. 2 retries before blocking PIN", 0xC3: "PIN verification failed. 3 retries before blocking PIN", 0xC4: "PIN verification failed. 4 retries before blocking PIN", 0xC5: "PIN verification failed. 5 retries before blocking PIN", 0xC6: "PIN verification failed. 6 retries before blocking PIN", 0xC7: "PIN verification failed. 7 retries before blocking PIN", 0xC8: "PIN verification failed. 8 retries before blocking PIN", 0xC9: "PIN verification failed. 9 retries before blocking PIN", 0xCA: "PIN verification failed. 10 retries before blocking PIN", 0xCB: "PIN verification failed. 11 retries before blocking PIN", 0xCC: "PIN verification failed. 12 retries before blocking PIN", 0xCD: "PIN verification failed. 13 retries before blocking PIN", 0xCE: "PIN verification failed. 14 retries before blocking PIN", 0xCF: "PIN verification failed. 15 retries before blocking PIN"}), 0x65: (smartcard.sw.SWExceptions.ExecutionErrorException, {0x81: "Memory failure (unsuccessful changing)"}), 0x66: (smartcard.sw.SWExceptions.SecurityRelatedException, {0x00: "The environment cannot be set or modified", 0x87: "Expected SM data objects missing", 0x88: "SM data objects incorrect"}), 0x67: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Wrong length (emtpy Lc field)"}), 0x68: (smartcard.sw.SWExceptions.CheckingErrorException, {0x83: "Final command expected", 0x84: "Command chaining not supported"}), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, {0x82: "Security status not satisfied", 0x83: "Authentification method blocked", 0x84: "Referenced data invalidated", 0x85: "Conditions of use not satisfied"}), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, {0x81: "Function not supported", 0x82: "File not found", 0x86: "Incorrect parameters P1-P2", 0x88: "Referenced data not found"}), } class ISO7816_8ErrorChecker(ErrorChecker): """ISO7816-8 error checker. This error checker raises the following exceptions: - sw1 sw2 - 63 00,c0-cf WarningProcessingException - 65 81 ExecutionErrorException - 66 00,87,88 SecurityRelatedException - 67 00 CheckingErrorException - 68 82,84 CheckingErrorException - 69 82,83,84,85 CheckingErrorException - 6A 81,82,86,88 CheckingErrorException This checker does not raise exceptions on undefined sw1 values, e.g.: - sw1 sw2 - 62 any - 6f any and on undefined sw2 values, e.g.: - sw1 sw2 - 66 81 82 - 67 any except 00 Use another checker in the error checking chain, e.g., the ISO7816_4SW1ErrorChecker or ISO7816_4ErrorChecker, to raise exceptions on these undefined values. """ def __call__(self, data, sw1, sw2): """Called to test data, sw1 and sw2 for error. @param data: apdu response data @param sw1, sw2: apdu data status words Derived classes must raise a L{smartcard.sw.SWException} upon error.""" if sw1 in iso7816_8SW: exception, sw2dir = iso7816_8SW[sw1] if type(sw2dir) == type({}): try: message = sw2dir[sw2] raise exception(data, sw1, sw2, message) except KeyError: pass if __name__ == '__main__': """Small sample illustrating the use of ISO7816_8ErrorChecker.""" ecs = ISO7816_8ErrorChecker() ecs([], 0x90, 0x00) ecs([], 0x6a, 0x83) try: ecs([], 0x66, 0x87) except smartcard.sw.SWExceptions.SecurityRelatedException as e: print(str(e) + " %x %x" % (e.sw1, e.sw2)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399704.0 pyscard-2.0.2/smartcard/sw/ISO7816_9ErrorChecker.py0000644000175000017500000000623100000000000022153 0ustar00rousseaurousseau"""ISO7816-9 error checker. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.sw.ErrorChecker import ErrorChecker import smartcard.sw.SWExceptions iso7816_9SW = { 0x62: (smartcard.sw.SWExceptions.WarningProcessingException, {0x82: "End of file/record reached"}), 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException, {0x00: "Execution error"}), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, {0x82: "Security status not satisfied"}), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, {0x80: "Incorrect parameters in data field", 0x84: "Not enough memory space", 0x89: "File already exists", 0x8A: "DF name already exists"}), } class ISO7816_9ErrorChecker(ErrorChecker): """ISO7816-8 error checker. This error checker raises the following exceptions: - sw1 sw2 - 62 82 WarningProcessingException - 64 00 ExecutionErrorException - 69 82 CheckingErrorException - 6A 80,84,89,8A CheckingErrorException This checker does not raise exceptions on undefined sw1 values, e.g.: - sw1 sw2 - 63 any - 6F any and on undefined sw2 values, e.g.: - sw1 sw2 - 62 81 83 - 64 any except 00 Use another checker in the error checking chain, e.g., the ISO7816_4SW1ErrorChecker or ISO7816_4ErrorChecker, to raise exceptions on these undefined values. """ def __call__(self, data, sw1, sw2): """Called to test data, sw1 and sw2 for error. @param data: apdu response data @param sw1, sw2: apdu data status words Derived classes must raise a L{smartcard.sw.SWException} upon error.""" if sw1 in iso7816_9SW: exception, sw2dir = iso7816_9SW[sw1] if type(sw2dir) == type({}): try: message = sw2dir[sw2] raise exception(data, sw1, sw2, message) except KeyError: pass if __name__ == '__main__': """Small sample illustrating the use of ISO7816_9ErrorChecker.""" ecs = ISO7816_9ErrorChecker() ecs([], 0x90, 0x00) ecs([], 0x6a, 0x81) try: ecs([], 0x6A, 0x8A) except smartcard.sw.SWExceptions.CheckingErrorException as e: print(str(e) + " %x %x" % (e.sw1, e.sw2)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/sw/SWExceptions.py0000644000175000017500000000541300000000000021040 0ustar00rousseaurousseau"""Status Word (SW) Exceptions This module defines the exceptions raised by status word errors or warnings. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ class SWException(Exception): """Base class for status word exceptions. Status word exceptions are generated when errors and warnings are detected in the sw1 and sw2 bytes of the response apdu. """ def __init__(self, data, sw1, sw2, message=""): self.message = message """response apdu data""" self.data = data """response apdu sw1""" self.sw1 = sw1 """response apdu sw2""" self.sw2 = sw2 def __str__(self): return repr('Status word exception: ' + self.message + '!') class WarningProcessingException(SWException): """Raised when a warning processing is detected from sw1, sw2. Examples of warning processing exception: sw1=62 or sw=63 (ISO7816-4).""" def __init__(self, data, sw1, sw2, message=""): SWException.__init__( self, data, sw1, sw2, "warning processing - " + message) class ExecutionErrorException(SWException): """Raised when an execution error is detected from sw1, sw2. Examples of execution error: sw1=64 or sw=65 (ISO7816-4).""" def __init__(self, data, sw1, sw2, message=""): SWException.__init__( self, data, sw1, sw2, "execution error - " + message) class SecurityRelatedException(SWException): """Raised when a security issue is detected from sw1, sw2. Examples of security issue: sw1=66 (ISO7816-4).""" def __init__(self, data, sw1, sw2, message=""): SWException.__init__( self, data, sw1, sw2, "security issue - " + message) class CheckingErrorException(SWException): """Raised when a checking error is detected from sw1, sw2. Examples of checking error: sw1=67 to 6F (ISO781604).""" def __init__(self, data, sw1, sw2, message=""): SWException.__init__( self, data, sw1, sw2, "checking error - " + message) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/sw/__init__.py0000644000175000017500000000162600000000000020206 0ustar00rousseaurousseau"""smartcard.sw module for status word error checking. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399707.0 pyscard-2.0.2/smartcard/sw/op21_ErrorChecker.py0000644000175000017500000001040400000000000021660 0ustar00rousseaurousseau"""Open Platform 2.1 error checker. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.sw.ErrorChecker import ErrorChecker import smartcard.sw.SWExceptions op21_SW = { 0x62: (smartcard.sw.SWExceptions.WarningProcessingException, {0x83: "Card life cycle is CARD_LOCKED"}), 0x63: (smartcard.sw.SWExceptions.WarningProcessingException, {0x00: "Authentication failed"}), 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException, {0x00: "Execution error"}), 0x65: (smartcard.sw.SWExceptions.ExecutionErrorException, {0x81: "Memory failure"}), 0x67: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Wrong length in Lc"}), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, {0x82: "Security status not satisfied", 0x85: "Conditions of use not satisfied"}), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, {0x80: "Incorrect values in command data", 0x81: "Function not supported", 0x82: "Application not found", 0x84: "Not enough memory space", 0x86: "Incorrect parameters P1-P2", 0x88: "Referenced data not found"}), 0x6D: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Instruction not supported"}), 0x6E: (smartcard.sw.SWExceptions.CheckingErrorException, {0x00: "Class not supported"}), 0x94: (smartcard.sw.SWExceptions.CheckingErrorException, {0x84: "Algorithm not supported", 0x85: "Invalid key check value"}), } class op21_ErrorChecker(ErrorChecker): """Open platform 2.1 error checker. This error checker raises the following exceptions: - sw1 sw2 - 62 83 WarningProcessingException - 63 00 WarningProcessingException - 64 00 ExecutionErrorException - 65 81 ExecutionErrorException - 67 00 CheckingErrorException - 69 82 85 CheckingErrorException - 6A 80 81 82 84 86 88 CheckingErrorException - 6D 00 CheckingErrorException - 6E 00 CheckingErrorException - 94 84 85 CheckingErrorException This checker does not raise exceptions on undefined sw1 values, e.g.: - sw1 sw2 - 63 any - 6F any and on undefined sw2 values, e.g.: - sw1 sw2 - 62 81 83 - 64 any except 00 Use another checker in the error checking chain to raise exceptions on these undefined values. """ def __call__(self, data, sw1, sw2): """Called to test data, sw1 and sw2 for error. @param data: apdu response data @param sw1, sw2: apdu data status words Derived classes must raise a L{smartcard.sw.SWException} upon error.""" if sw1 in op21_SW: exception, sw2dir = op21_SW[sw1] if type(sw2dir) == type({}): try: message = sw2dir[sw2] raise exception(data, sw1, sw2, message) except KeyError: pass if __name__ == '__main__': """Small sample illustrating the use of op21_ErrorChecker.""" ecs = op21_ErrorChecker() ecs([], 0x90, 0x00) ecs([], 0x94, 0x81) try: ecs([], 0x94, 0x84) except smartcard.sw.SWExceptions.CheckingErrorException as e: print(str(e) + "%x %x" % (e.sw1, e.sw2)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1230025 pyscard-2.0.2/smartcard/test/0000755000175000017500000000000000000000000016416 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399735.0 pyscard-2.0.2/smartcard/test/configcheck.py0000755000175000017500000000503600000000000021242 0ustar00rousseaurousseau#! /usr/bin/env python3 """Generates test suite smartcard configuration from connected readers and cards. The generated configuration is store in local_config.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ from smartcard.System import readers from smartcard.Exceptions import NoCardException from smartcard.util import toHexString def getATR(reader): cc = reader.createConnection() cc.connect() atr = cc.getATR() cc.disconnect() return atr def checklocalconfig(): try: f = open('local_config.py', 'r') except IOError: print('local_config.py not found; generating local_config.py...') else: print('regenerating local_config.py...') f.close() # generate local configuration f = open('local_config.py', 'w+') f.write('from smartcard.util import toHexString\n') f.write('expectedReaders = ') f.write(str(readers()) + '\n') expectedATRs = [] for reader in readers(): try: expectedATRs.append(getATR(reader)) except NoCardException: expectedATRs.append([]) f.write('expectedATRs = ') #for atr in expectedATRs: print `toHexString(atr)` f.write(repr(expectedATRs) + '\n') f.write('expectedATRinReader = {}\n') f.write('for i in range(len(expectedReaders)):\n') f.write(' expectedATRinReader[expectedReaders[i]] = expectedATRs[i]\n') f.write('expectedReaderForATR = {}\n') f.write('for i in range(len(expectedReaders)):\n') f.write(' expectedReaderForATR[toHexString(expectedATRs[i])] = ' + \ 'expectedReaders[i]\n') f.write('expectedReaderGroups = [\'SCard$DefaultReaders\']\n') f.close() if __name__ == '__main__': import sys checklocalconfig() sys.exit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/smartcard/test/framework/0000755000175000017500000000000000000000000020413 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762663.0 pyscard-2.0.2/smartcard/test/framework/local_config.py0000644000175000017500000000075300000000000023411 0ustar00rousseaurousseaufrom smartcard.util import toHexString expectedReaders = ['Gemalto PC Twin Reader 00 00'] expectedATRs = [[63, 47, 0, 128, 105, 175, 2, 4, 1, 49, 0, 0, 0, 14, 131, 62, 159, 22]] expectedATRinReader = {} for i in range(len(expectedReaders)): expectedATRinReader[expectedReaders[i]] = expectedATRs[i] expectedReaderForATR = {} for i in range(len(expectedReaders)): expectedReaderForATR[toHexString(expectedATRs[i])] = expectedReaders[i] expectedReaderGroups = ['SCard$DefaultReaders'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762663.0 pyscard-2.0.2/smartcard/test/framework/readme.txt0000644000175000017500000000313400000000000022412 0ustar00rousseaurousseau------------------------------------------------------------------------------- This directory contains the test suite for the pyscard framework. You will need two smart card readers and two smart cards to run the test suite. Insert the readers and the cards in the readers before executing the test suite. On the first execution of the test suite, the configcheck.py script in the parent directory will generate a localconfig.py file that will contain the current names of the readers and ATRs of the cards inserted in the readers. These data are used by the test suite. If you change the test configuration, i.e. add or remove readers or cards, or change the readers or cards, just delete localconfig.py and re-run the test suite. ------------------------------------------------------------------------------- This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ------------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399751.0 pyscard-2.0.2/smartcard/test/framework/testcase_ATR.py0000755000175000017500000000413300000000000023312 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for testing that we have at least two cards for the test suite. This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() # gemalto jython from smartcard import Session class testcase_ATR(unittest.TestCase): """Test ATR configuration for test suite""" def testcase_ATRconfig(self): # we have at list 2 readers (one is the simulator), e.g. # two potential ATRs self.assertTrue(len(expectedATRs) > 1) # we have at least two non empty ATRs count = 0 for atr in expectedATRs: if atr != []: count += 1 self.assertTrue(count > 1) def suite(): suite1 = unittest.makeSuite(testcase_ATR) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398847.0 pyscard-2.0.2/smartcard/test/framework/testcase_CAtr.py0000755000175000017500000001134300000000000023516 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.ATR This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # gemalto jython from smartcard.ATR import ATR class testcase_CAtr(unittest.TestCase): """Test APDU class and utilities""" def testcase_ATR1(self): """Usimera Classic 2.""" a = ATR([0x3B, 0x9E, 0x95, 0x80, 0x1F, 0xC3, 0x80, 0x31, 0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x29, 0x02, 0x01, 0x01, 0x81, 0xCD, 0xB9]) historicalbytes = [0x80, 0x31, 0xA0, 0x73, 0xBE, 0x21, 0x13, 0x67, 0x29, 0x02, 0x01, 0x01, 0x81, 0xCD] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), 0xB9) self.assertTrue(a.checksumOK) self.assertTrue(a.isT0Supported()) self.assertTrue(not a.isT1Supported()) self.assertTrue(a.isT15Supported()) def testcase_ATR2(self): """Palmera Protect V2.""" a = ATR([0x3B, 0x65, 0x00, 0x00, 0x9C, 0x02, 0x02, 0x01, 0x02]) historicalbytes = [0x9C, 0x02, 0x02, 0x01, 0x02] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), None) self.assertTrue(a.isT0Supported()) self.assertTrue(not a.isT1Supported()) self.assertTrue(not a.isT15Supported()) def testcase_ATR3(self): """Simera 3.13.""" a = ATR([0x3B, 0x16, 0x18, 0x20, 0x02, 0x01, 0x00, 0x80, 0x0D]) historicalbytes = [0x20, 0x02, 0x01, 0x00, 0x80, 0x0D] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), None) self.assertTrue(a.isT0Supported()) self.assertTrue(not a.isT1Supported()) self.assertTrue(not a.isT15Supported()) def testcase_ATR4(self): """SIMRock'n Tree""" a = ATR([0x3B, 0x77, 0x94, 0x00, 0x00, 0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22]) historicalbytes = [0x82, 0x30, 0x00, 0x13, 0x6C, 0x9F, 0x22] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), None) self.assertTrue(a.isT0Supported()) self.assertTrue(not a.isT1Supported()) self.assertTrue(not a.isT15Supported()) def testcase_ATR5(self): """Demo Vitale online IGEA340""" a = ATR([0x3F, 0x65, 0x25, 0x00, 0x52, 0x09, 0x6A, 0x90, 0x00]) historicalbytes = [0x52, 0x09, 0x6A, 0x90, 0x00] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), None) self.assertTrue(a.isT0Supported()) self.assertTrue(not a.isT1Supported()) self.assertTrue(not a.isT15Supported()) def testcase_ATR6(self): """Simagine 2002""" a = ATR([0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00, 0x0D]) historicalbytes = [0x20, 0x02, 0x01, 0x00, 0x00, 0x0D] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), None) def testcase_ATR7(self): """Protect V3 T=1""" a = ATR([0x3B, 0xE5, 0x00, 0x00, 0x81, 0x21, 0x45, 0x9C, 0x10, 0x01, 0x00, 0x80, 0x0D]) historicalbytes = [0x9C, 0x10, 0x01, 0x00, 0x80] self.assertEqual(a.getHistoricalBytes(), historicalbytes) self.assertEqual(a.getChecksum(), 0x0D) self.assertTrue(not a.isT0Supported()) self.assertTrue(a.isT1Supported()) self.assertTrue(not a.isT15Supported()) self.assertTrue(a.checksumOK) self.assertTrue(a.getTB1() == 0x00) self.assertTrue(a.getTC1() == 0x00) self.assertTrue(a.getTD1() == 0x81) self.assertTrue(a.TD[2 - 1] == 0x21) # TD2 self.assertTrue(a.TB[3 - 1] == 0x45) # TB3 def suite(): suite1 = unittest.makeSuite(testcase_CAtr) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399787.0 pyscard-2.0.2/smartcard/test/framework/testcase_Card.py0000755000175000017500000001060200000000000023533 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.Card This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.Exceptions import NoCardException from smartcard.Card import Card from smartcard.System import readers class testcase_Card(unittest.TestCase): """Test case for smartcard.Card.""" def testcase_CardDictionary(self): """Create a dictionnary with Card keys""" mydict = {} for reader in readers(): card = Card(reader, expectedATRinReader[str(reader)]) mydict[card] = reader for card in list(mydict.keys()): self.assertTrue(str(card.reader) in expectedReaders) def testcase_Card_FromReaders(self): """Create a Card from Readers and test that the response to SELECT DF_TELECOM has two bytes.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): card = Card(reader, expectedATRinReader[str(reader)]) cc = card.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect() response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "9f 20": 2, "6e 0": 3} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect) def testcase_Card_FromReaderStrings(self): """Create a Card from reader strings and test that the response to SELECT DF_TELECOM has two bytes.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cc = card.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect() response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "9f 20": 2, "6e 0": 3} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect) def testcase_Card_Eq_NotEq(self): """Test == and != for Cards.""" for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cardcopy = Card(str(reader), expectedATRinReader[str(reader)]) self.assertEqual(True, card == cardcopy) self.assertEqual(True, not card != cardcopy) for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cardcopy = Card(str(reader), [0, 0]) self.assertEqual(True, card != cardcopy) self.assertEqual(True, not card == cardcopy) def suite(): suite1 = unittest.makeSuite(testcase_CardConnection) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399775.0 pyscard-2.0.2/smartcard/test/framework/testcase_CardConnection.py0000755000175000017500000002266700000000000025571 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.CardConnection This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.Exceptions import CardConnectionException, NoCardException from smartcard.System import readers from smartcard.CardConnection import CardConnection from smartcard.scard import ( resourceManagerSubType, SCARD_SHARE_EXCLUSIVE, SCARD_LEAVE_CARD, SCARD_RESET_CARD, SCARD_UNPOWER_CARD ) class testcase_CardConnection(unittest.TestCase): """Test case for CardConnection.""" def testcase_CardConnection(self): """Test with default protocols the response to SELECT DF_TELECOM.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect() response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "6e 0": 2, "9f 20": 3, "9f 22": 4} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardConnectionT0(self): """Test with T0 the response to SELECT DF_TELECOM.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect(CardConnection.T0_protocol) response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "6e 0": 2, "9f 20": 3, "9f 22": 4} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardConnectionT1inConnect(self): """Test that connecting with T1 on a T0 card fails.""" for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: # should fail since the test card does not support T1 self.assertRaises( CardConnectionException, cc.connect, CardConnection.T1_protocol) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardConnectionT1inTransmit(self): """Test that T1 in transmit for a T0 card fails.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect() self.assertRaises( CardConnectionException, cc.transmit, SELECT + DF_TELECOM, CardConnection.T1_protocol) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardConnectionT0T1(self): """Test test with T0 | T1 the response to SELECT DF_TELECOM.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect( CardConnection.T0_protocol | CardConnection.T1_protocol) response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "6e 0": 2, "9f 20": 3, "9f 22": 4} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardConnectionT0inTransmit(self): """Test with T0 in transmit the response to SELECT DF_TELECOM.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect(CardConnection.T0_protocol) response, sw1, sw2 = cc.transmit( SELECT + DF_TELECOM, CardConnection.T0_protocol) expectedSWs = {"9f 1a": 1, "6e 0": 2, "9f 20": 3, "9f 22": 4} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardConnectionT0T1inTransmitMustFail(self): """Test with bad parameter in transmit the response to SELECT DF_TELECOM.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect( CardConnection.T0_protocol | CardConnection.T1_protocol) self.assertRaises( CardConnectionException, cc.transmit, SELECT + DF_TELECOM, CardConnection.T0_protocol | CardConnection.T1_protocol) else: self.assertRaises(NoCardException, cc.connect) cc.disconnect() def testcase_CardReconnectProtocol(self): """Test .reconnect()""" for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect( CardConnection.T0_protocol | CardConnection.T1_protocol) # reconnect in T=1 when a T=0 card (GPK 8K) shall fail self.assertRaises(CardConnectionException, cc.reconnect, protocol=CardConnection.T1_protocol) cc.disconnect() else: self.assertRaises(NoCardException, cc.connect) def testcase_CardReconnectMode(self): """Test .reconnect()""" for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect( CardConnection.T0_protocol | CardConnection.T1_protocol) # reconnect in exclusive mode should fail self.assertRaises(CardConnectionException, cc.reconnect, mode=SCARD_SHARE_EXCLUSIVE) cc.disconnect() else: self.assertRaises(NoCardException, cc.connect) def testcase_CardReconnectDisposition(self): """Test .reconnect()""" for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect( CardConnection.T0_protocol | CardConnection.T1_protocol) cc.reconnect(disposition=SCARD_LEAVE_CARD) cc.reconnect(disposition=SCARD_RESET_CARD) cc.reconnect(disposition=SCARD_UNPOWER_CARD) cc.disconnect() else: self.assertRaises(NoCardException, cc.connect) def testcase_CardReconnectNoConnect(self): """Test .reconnect()""" for reader in readers(): cc = reader.createConnection() if [] != expectedATRinReader[str(reader)]: # reconnect without connect first shall fail self.assertRaises(CardConnectionException, cc.reconnect) else: self.assertRaises(NoCardException, cc.connect) def suite(): suite1 = unittest.makeSuite(testcase_CardConnection) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399749.0 pyscard-2.0.2/smartcard/test/framework/testcase_CardMonitor.py0000755000175000017500000000623200000000000025107 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.CardMonitoring. This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import threading import unittest import time # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.CardMonitoring import CardMonitor, CardObserver from smartcard.util import toHexString # a simple card observer that prints inserted/removed cards class printobserver(CardObserver): def __init__(self, obsindex, testcase): self.obsindex = obsindex self.testcase = testcase def update(self, observable, actions): (addedcards, removedcards) = actions foundcards = {} self.testcase.assertEqual(removedcards, []) for card in addedcards: foundcards[toHexString(card.atr)] = 1 for atr in expectedATRs: if [] != atr and {} != foundcards: self.testcase.assertTrue(toHexString(atr) in foundcards) class testthread(threading.Thread): def __init__(self, obsindex, testcase): threading.Thread.__init__(self) self.obsindex = obsindex self.testcase = testcase self.cardmonitor = CardMonitor() self.observer = None def run(self): # create and register observer self.observer = printobserver(self.obsindex, self.testcase) self.cardmonitor.addObserver(self.observer) time.sleep(1) self.cardmonitor.deleteObserver(self.observer) class testcase_cardmonitor(unittest.TestCase): """Test smartcard framework card monitoring classes""" def testcase_cardmonitorthread(self): threads = [] for i in range(0, 4): t = testthread(i, self) threads.append(t) for t in threads: t.start() for t in threads: t.join() def suite(): suite1 = unittest.makeSuite(testcase_cardmonitorthread) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399756.0 pyscard-2.0.2/smartcard/test/framework/testcase_CardRequest.py0000755000175000017500000001222100000000000025103 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.CardRequest This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader, expectedReaderForATR except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.CardRequest import CardRequest from smartcard.CardType import ATRCardType, AnyCardType from smartcard.Exceptions import CardRequestTimeoutException from smartcard.PassThruCardService import PassThruCardService from smartcard.util import toHexString import smartcard.System class testcase_CardRequest(unittest.TestCase): """Test case for CardType.""" def testcase_CardRequestATRCardType(self): """Test smartcard.AnyCardType.""" for atr in expectedATRs: if [] != atr: ct = ATRCardType(atr) cr = CardRequest(timeout=10, cardType=ct) cs = cr.waitforcard() cs.connection.connect() self.assertEqual(atr, cs.connection.getATR()) self.assertEqual( cs.connection.getReader(), expectedReaderForATR[toHexString(atr)]) cs.connection.disconnect() def testcase_CardRequestAnyCardTypeInSelectedReader(self): """Test smartcard.AnyCardType.""" for reader in expectedReaders: atr = expectedATRinReader[reader] if [] != atr: ct = AnyCardType() cr = CardRequest(timeout=10.6, readers=[reader], cardType=ct) cs = cr.waitforcard() cs.connection.connect() self.assertEqual(atr, cs.connection.getATR()) self.assertEqual( cs.connection.getReader(), expectedReaderForATR[toHexString(atr)]) def testcase_CardRequestATRCardTypeTimeout(self): """Test smartcard.AnyCardType.""" for reader in expectedReaders: atr = expectedATRinReader[reader][:-1] ct = ATRCardType(atr) cr = CardRequest(timeout=1, readers=[reader], cardType=ct) self.assertRaises(CardRequestTimeoutException, cr.waitforcard) def testcase_CardRequestATRCardTypeTimeoutAnyReader(self): """Test smartcard.AnyCardType.""" readers = smartcard.System.readers() atr = expectedATRs[0][:-1] ct = ATRCardType(atr) cr = CardRequest(timeout=1.5, readers=readers, cardType=ct) self.assertRaises(CardRequestTimeoutException, cr.waitforcard) def testcase_CardRequestAnyCardTypeAnyReaderPassThru(self): """Test smartcard.AnyCardType.""" for reader in expectedReaders: atr = expectedATRinReader[reader] if [] != atr: ct = AnyCardType() cardservice = smartcard.PassThruCardService.PassThruCardService cr = CardRequest( timeout=10.6, readers=[reader], cardType=ct, cardServiceClass=cardservice) cs = cr.waitforcard() cs.connection.connect() self.assertEqual( cs.__class__, smartcard.PassThruCardService.PassThruCardService) self.assertEqual(atr, cs.connection.getATR()) self.assertEqual( cs.connection.getReader(), expectedReaderForATR[toHexString(atr)]) def testcase_CardRequestAnyCardTypeInSelectedReaderNewCard(self): """Test smartcard.AnyCardType.""" for reader in expectedReaders: atr = expectedATRinReader[reader] ct = AnyCardType() cr = CardRequest( newcardonly=True, timeout=1, readers=[reader], cardType=ct) self.assertRaises(CardRequestTimeoutException, cr.waitforcard) def suite(): suite1 = unittest.makeSuite(testcase_CardRequest) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399753.0 pyscard-2.0.2/smartcard/test/framework/testcase_CardService.py0000755000175000017500000000473200000000000025063 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.CardService This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() # gemalto jython from smartcard.CardService import CardService from smartcard.System import readers class testcase_CardService(unittest.TestCase): """Test case for CardService.""" def testcase_CardService(self): """Test the response to SELECT DF_TELECOM.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): if [] != expectedATRinReader[str(reader)]: cc = reader.createConnection() cs = CardService(cc) cs.connection.connect() response, sw1, sw2 = cs.connection.transmit( SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "6e 0": 2, "9f 20": 3, "9f 22": 4} self.assertEqual([], response) self.assertTrue( "%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) def suite(): suite1 = unittest.makeSuite(testcase_CardService) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399746.0 pyscard-2.0.2/smartcard/test/framework/testcase_CardType.py0000755000175000017500000001216500000000000024403 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.CardType This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.CardType import CardType, AnyCardType, ATRCardType from smartcard.Exceptions import InvalidATRMaskLengthException from smartcard.System import readers class testcase_CardType(unittest.TestCase): """Test case for CardType.""" def testcase_AnyCardType(self): """Test smartcard.AnyCardType.""" ct = AnyCardType() for reader in readers(): if [] != expectedATRinReader[str(reader)]: connection = reader.createConnection() connection.connect() self.assertEqual(True, ct.matches(connection.getATR())) self.assertEqual( True, ct.matches(connection.getATR(), reader)) connection.disconnect() def testcase_ATRCardTypeWithoutMask(self): """Test smartcard.ATRCardType without mask.""" for reader in readers(): if [] != expectedATRinReader[str(reader)]: ct = ATRCardType(expectedATRinReader[str(reader)]) connection = reader.createConnection() connection.connect() self.assertEqual(True, ct.matches(connection.getATR())) self.assertEqual( True, ct.matches(connection.getATR(), reader)) connection.disconnect() def testcase_ATRCardTypeMisMatchWithoutMask(self): """Test smartcard.ATRCardType mismatch without mask.""" for reader in readers(): if [] != expectedATRinReader[str(reader)]: atr = list(expectedATRinReader[str(reader)]) # change the last byte of the expected atr atr[-1] = 0xFF ct = ATRCardType(atr) connection = reader.createConnection() connection.connect() self.assertEqual(False, ct.matches(connection.getATR())) self.assertEqual( False, ct.matches(connection.getATR(), reader)) connection.disconnect() def testcase_ATRCardTypeWithMask(self): """Test smartcard.ATRCardType with mask.""" for reader in readers(): if [] != expectedATRinReader[str(reader)]: mask = [0xFF for x in expectedATRinReader[str(reader)]] # don't look to the last byte mask[-1] = 0x00 ct = ATRCardType(expectedATRinReader[str(reader)], mask) connection = reader.createConnection() connection.connect() atr = connection.getATR() connection.disconnect() # change a bit in the last byte atr[-1] = atr[-1] ^ 0xFF self.assertEqual(True, ct.matches(atr)) self.assertEqual(True, ct.matches(atr, reader)) def testcase_ATRCardTypeWithMaskMismatch(self): """Test smartcard.ATRCardType with mask and mismatch.""" for reader in readers(): if [] != expectedATRinReader[str(reader)]: mask = [0xFF for x in expectedATRinReader[str(reader)]] # don't look to the last byte mask[0] = mask[-1] = 0x00 ct = ATRCardType(expectedATRinReader[str(reader)], mask) connection = reader.createConnection() connection.connect() atr = connection.getATR() connection.disconnect() # change a bit in the :-2 byte atr[-2] = atr[-2] ^ 0xFF self.assertEqual(False, ct.matches(atr)) self.assertEqual(False, ct.matches(atr, reader)) def suite(): suite1 = unittest.makeSuite(testcase_CardType) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399780.0 pyscard-2.0.2/smartcard/test/framework/testcase_ErrorChecking.py0000755000175000017500000003173200000000000025416 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.sw This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import string # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] from smartcard.sw.ErrorCheckingChain import ErrorCheckingChain from smartcard.sw.ErrorChecker import ErrorChecker from smartcard.sw.ISO7816_4ErrorChecker import ISO7816_4ErrorChecker from smartcard.sw.ISO7816_4_SW1ErrorChecker import ISO7816_4_SW1ErrorChecker from smartcard.sw.ISO7816_8ErrorChecker import ISO7816_8ErrorChecker from smartcard.sw.ISO7816_9ErrorChecker import ISO7816_9ErrorChecker from smartcard.sw.op21_ErrorChecker import op21_ErrorChecker import smartcard.sw.SWExceptions try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() class CustomSWException(smartcard.sw.SWExceptions.SWException): """Test exception raised by TestErrorChecker.""" def __init__(self, data, sw1, sw2, message=""): smartcard.sw.SWExceptions.SWException.__init__(self, data, sw1, sw2) class TestErrorChecker(ErrorChecker): """Test error checking checker. This checker raises the following exception: sw1: 56 sw2: 55 CustomSWException sw1: 63 sw2: any WarningProcessingException """ def __call__(self, data, sw1, sw2): if 0x56 == sw1 and 0x55 == sw2: raise CustomSWException(data, sw1, sw2) elif 0x63 == sw1: raise CustomSWException(data, sw1, sw2) class testcase_ErrorChecking(unittest.TestCase): """Test case for smartcard.sw.* error checking.""" def failUnlessRaises(self, excClass, callableObj, *args, **kwargs): """override of unittest.TestCase.failUnlesRaises so that we return the exception object for testing fields.""" try: callableObj(*args, **kwargs) except excClass as e: return e else: if hasattr(excClass, '__name__'): excName = excClass.__name__ else: excName = str(excClass) raise self.failureException(excName) def testcase_ISO7816_4SW1ErrorChecker(self): """Test ISO7816_4_SW1ErrorChecker.""" ecs = ISO7816_4_SW1ErrorChecker() tiso7816_4SW1 = { 0x62: smartcard.sw.SWExceptions.WarningProcessingException, 0x63: smartcard.sw.SWExceptions.WarningProcessingException, 0x64: smartcard.sw.SWExceptions.ExecutionErrorException, 0x65: smartcard.sw.SWExceptions.ExecutionErrorException, 0x66: smartcard.sw.SWExceptions.SecurityRelatedException, 0x67: smartcard.sw.SWExceptions.CheckingErrorException, 0x68: smartcard.sw.SWExceptions.CheckingErrorException, 0x69: smartcard.sw.SWExceptions.CheckingErrorException, 0x6A: smartcard.sw.SWExceptions.CheckingErrorException, 0x6B: smartcard.sw.SWExceptions.CheckingErrorException, 0x6C: smartcard.sw.SWExceptions.CheckingErrorException, 0x6D: smartcard.sw.SWExceptions.CheckingErrorException, 0x6E: smartcard.sw.SWExceptions.CheckingErrorException, 0x6F: smartcard.sw.SWExceptions.CheckingErrorException, } for sw1 in range(0x00, 0xff + 1): sw2range = [] exception = None if sw1 in tiso7816_4SW1: exception = tiso7816_4SW1[sw1] for sw2 in range(0x00, 0xff + 1): if None != exception: self.assertRaises(exception, ecs, [], sw1, sw2) else: ecs([], sw1, sw2) def testcase_ISO7816_4ErrorChecker(self): """Test ISO7816_4ErrorChecker.""" ecs = ISO7816_4ErrorChecker() tiso7816_4SW = { 0x62: (smartcard.sw.SWExceptions.WarningProcessingException, [0x00, 0x81, 0x82, 0x83, 0x84, 0xff]), 0x63: (smartcard.sw.SWExceptions.WarningProcessingException, [0x00, 0x81] + list(range(0xc0, 0xcf + 1))), 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException, [0x00]), 0x67: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x68: (smartcard.sw.SWExceptions.CheckingErrorException, [0x81, 0x82]), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, list(range(0x81, 0x88 + 1))), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, list(range(0x80, 0x88 + 1))), 0x6B: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x6D: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x6E: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x6F: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), } for sw1 in range(0x00, 0xff + 1): sw2range = [] if sw1 in tiso7816_4SW: exception, sw2range = tiso7816_4SW[sw1] for sw2 in range(0x00, 0xff + 1): if sw2 in sw2range: self.assertRaises(exception, ecs, [], sw1, sw2) else: ecs([], sw1, sw2) def testcase_ISO7816_8ErrorChecker(self): """Test ISO7816_4ErrorChecker.""" ecs = ISO7816_8ErrorChecker() tiso7816_8SW = { 0x63: (smartcard.sw.SWExceptions.WarningProcessingException, [0x00] + list(range(0xc0, 0xcf + 1))), 0x65: (smartcard.sw.SWExceptions.ExecutionErrorException, [0x81]), 0x66: (smartcard.sw.SWExceptions.SecurityRelatedException, [0x00, 0x87, 0x88]), 0x67: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x68: (smartcard.sw.SWExceptions.CheckingErrorException, [0x83, 0x84]), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, list(range(0x82, 0x85 + 1))), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, [0x81, 0x82, 0x86, 0x88]), } for sw1 in range(0x00, 0xff + 1): sw2range = [] if sw1 in tiso7816_8SW: exception, sw2range = tiso7816_8SW[sw1] for sw2 in range(0x00, 0xff + 1): if sw2 in sw2range: self.assertRaises(exception, ecs, [], sw1, sw2) else: ecs([], sw1, sw2) def testcase_ISO7816_9ErrorChecker(self): """Test ISO7816_4ErrorChecker.""" ecs = ISO7816_9ErrorChecker() tiso7816_9SW = { 0x62: (smartcard.sw.SWExceptions.WarningProcessingException, [0x82]), 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException, [0x00]), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, [ 0x82]), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, [0x80, 0x84, 0x89, 0x8A]), } for sw1 in range(0x00, 0xff + 1): sw2range = [] if sw1 in tiso7816_9SW: exception, sw2range = tiso7816_9SW[sw1] for sw2 in range(0x00, 0xff + 1): if sw2 in sw2range: self.assertRaises(exception, ecs, [], sw1, sw2) else: ecs([], sw1, sw2) def testcase_op21_ErrorChecker(self): """Test op21_ErrorChecker.""" ecs = op21_ErrorChecker() top21_SW = { 0x62: (smartcard.sw.SWExceptions.WarningProcessingException, [ 0x83]), 0x63: (smartcard.sw.SWExceptions.WarningProcessingException, [0x00]), 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException, [ 0x00]), 0x65: (smartcard.sw.SWExceptions.ExecutionErrorException, [ 0x81]), 0x67: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x69: (smartcard.sw.SWExceptions.CheckingErrorException, [0x82, 0x85]), 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException, [0x80, 0x81, 0x82, 0x84, 0x86, 0x88]), 0x6D: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x6E: (smartcard.sw.SWExceptions.CheckingErrorException, [0x00]), 0x94: (smartcard.sw.SWExceptions.CheckingErrorException, [0x84, 0x85]), } for sw1 in range(0x00, 0xff + 1): sw2range = [] if sw1 in top21_SW: exception, sw2range = top21_SW[sw1] for sw2 in range(0x00, 0xff + 1): if sw2 in sw2range: self.assertRaises(exception, ecs, [], sw1, sw2) else: ecs([], sw1, sw2) def testcase_ISO78164_Test_ErrorCheckingChain(self): """Test error chain with ISO7816-4 checker followed by Test checker.""" errorchain = [] errorchain = [ErrorCheckingChain(errorchain, ISO7816_4ErrorChecker()), ErrorCheckingChain(errorchain, TestErrorChecker())] # ISO7816-4 is answering first on the next, i.e # WarningProcessingException for sw2 in [0x00, 0x81] + list(range(0xc0, 0xcf + 1)): self.assertRaises( smartcard.sw.SWExceptions.WarningProcessingException, errorchain[0], [], 0x63, sw2) def testcase_Test_ISO78164_ErrorCheckingChain(self): """Test error chain with Test checker followed by ISO7816-4 checker.""" errorchain = [] errorchain = [ErrorCheckingChain(errorchain, TestErrorChecker()), ErrorCheckingChain(errorchain, ISO7816_4ErrorChecker())] # TestErrorChecker is answering first, i.e. CustomSWException for sw2 in [0x00, 0x81] + list(range(0xc0, 0xcf + 1)): self.assertRaises(CustomSWException, errorchain[0], [], 0x63, sw2) def testcase_ErrorMessage(self): """Test correct exception error message.""" ecs = ISO7816_4ErrorChecker() e = self.failUnlessRaises( smartcard.sw.SWExceptions.CheckingErrorException, ecs, [], 0x69, 0x85) self.assertEqual( str(e), "'Status word exception: checking error - " + \ "Conditions of use not satisfied!'") e = self.failUnlessRaises( smartcard.sw.SWExceptions.CheckingErrorException, ecs, [], 0x6b, 0x00) self.assertEqual( str(e), "'Status word exception: checking error - " + \ "Incorrect parameters P1-P2!'") def testcase_ISO78164_Test_ErrorCheckingChain_filtering(self): """Test error chain with ISO7816-4 checker followed by Test checker.""" errorchain = [] errorchain = [ErrorCheckingChain(errorchain, ISO7816_8ErrorChecker()), ErrorCheckingChain(errorchain, ISO7816_4ErrorChecker()), ErrorCheckingChain( errorchain, ISO7816_4_SW1ErrorChecker())] # don't care about Warning Exceptions errorchain[0].addFilterException( smartcard.sw.SWExceptions.WarningProcessingException) for sw2 in range(0x00, 0xff): # should not raise errorchain[0]([], 0x62, sw2) errorchain[0]([], 0x63, sw2) # should raise self.assertRaises( smartcard.sw.SWExceptions.ExecutionErrorException, errorchain[0], [], 0x64, sw2) def suite(): suite1 = unittest.makeSuite(testcase_ErrorChecking) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399761.0 pyscard-2.0.2/smartcard/test/framework/testcase_ExclusiveCardConnection.py0000755000175000017500000001033500000000000027446 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.ExclusiveTransmitCardConnection. This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import sys import random import threading import time import unittest # define the apdus used in this script GET_RESPONSE = [0XA0, 0XC0, 00, 00] SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] from smartcard.CardConnection import CardConnection from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.CardMonitoring import CardMonitor, CardObserver from smartcard.CardRequest import CardRequest from smartcard.CardType import AnyCardType from smartcard.ExclusiveTransmitCardConnection import \ ExclusiveTransmitCardConnection from smartcard.util import toHexString def signalEvent(evt): '''A simple callback that signals an event.''' evt.set() class testthread(threading.Thread): '''A test thread that repetitevely sends APDUs to a card within a transaction.''' def __init__(self, threadindex): '''Connect to a card with an ExclusiveTransmitCardConnection.''' threading.Thread.__init__(self) self.threadindex = threadindex # request any card type cardtype = AnyCardType() cardrequest = CardRequest(timeout=5, cardType=cardtype) cardservice = cardrequest.waitforcard() # attach our decorator cardservice.connection = ExclusiveTransmitCardConnection( cardservice.connection) # uncomment to attach the console tracer #observer=ConsoleCardConnectionObserver() #cardservice.connection.addObserver(observer) # connect to the card cardservice.connection.connect() self.cardservice = cardservice # this event will signal the end of the thread self.evtStop = threading.Event() # this timer will set the event stop event in 30s timer = threading.Timer(30, signalEvent, [self.evtStop]) timer.start() self.countTransmitted = 0 def run(self): '''Transmit APDUS with a random interval to the card.''' connection = self.cardservice.connection while not self.evtStop.isSet(): try: connection.lock() apdu = SELECT + DF_TELECOM response, sw1, sw2 = connection.transmit(apdu) if 0x90 == (sw1 & 0xF0): apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = connection.transmit(apdu) finally: connection.unlock() self.countTransmitted = self.countTransmitted + 1 time.sleep(float(random.uniform(1, 3)) * 0.01) class testcase_cardmonitor(unittest.TestCase): """Test smartcard framework card monitoring classes""" def testcase_cardmonitorthread(self): threads = [] for i in range(0, 4): t = testthread(i) threads.append(t) for t in threads: t.start() for t in threads: t.join() for t in threads: if 0 == 1: print('Thread %d: transmitted %ld apdus.' % \ (t.threadindex, t.countTransmitted)) def suite(): suite1 = unittest.makeSuite(testcase_cardmonitorthread) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398852.0 pyscard-2.0.2/smartcard/test/framework/testcase_readergroups.py0000755000175000017500000001310600000000000025366 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.readers.ReaderGroups This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import platform import unittest from smartcard.System import readergroups from smartcard.scard import resourceManager if 'winscard' == resourceManager and \ -1 == platform.platform().find('Windows-7'): class testcase_readergroups(unittest.TestCase): """Test smartcard framework readersgroups.""" pinpadgroup = 'Pinpad$Readers' biogroup = 'Biometric$Readers' def testcase_readergroup_add(self): """tests groups=groups+[newgroups]""" # take a snapshot of current groups groupssnapshot = list(readergroups()) groups = readergroups() # add pinpad group groups = groups + [self.pinpadgroup] self.assertEqual(groups, groupssnapshot + [self.pinpadgroup]) # add pinpad a second time and biometric once groups = groups + [self.biogroup, self.pinpadgroup] self.assertEqual( groups, groupssnapshot + [self.pinpadgroup, self.biogroup]) # clean-up groups.remove(self.biogroup) groups.remove(self.pinpadgroup) def testcase_readergroup_iadd(self): """test groups+=[newgroups]""" # take a snapshot of current groups groupssnapshot = list(readergroups()) groups = readergroups() # add pinpad group groups += [self.pinpadgroup] self.assertEqual(groups, groupssnapshot + [self.pinpadgroup]) # add pinpad a second time and biometric once groups += [self.biogroup, self.pinpadgroup] self.assertEqual( groups, groupssnapshot + [self.pinpadgroup, self.biogroup]) # clean-up groups.remove(self.biogroup) groups.remove(self.pinpadgroup) def testcase_readergroup_radd(self): """test groups=[newgroups]+groups""" # take a snapshot of current groups groupssnapshot = list(readergroups()) groups = readergroups() # add pinpad group zgroups = [self.pinpadgroup] + groups self.assertEqual(groups, groupssnapshot) self.assertEqual(zgroups, groupssnapshot + [self.pinpadgroup]) self.assertTrue(isinstance(zgroups, type([]))) self.assertTrue(isinstance(groups, type(readergroups()))) # add pinpad a tiwce and biometric once zgroups = \ [self.pinpadgroup, self.biogroup, self.pinpadgroup] + groups self.assertEqual(groups, groupssnapshot) self.assertEqual( zgroups, groupssnapshot + [self.pinpadgroup, self.biogroup]) self.assertTrue(isinstance(zgroups, type([]))) self.assertTrue(isinstance(groups, type(readergroups()))) def testcase_readergroup_append(self): """test groups.append(newgroups)""" # take a snapshot of current groups groupssnapshot = list(readergroups()) groups = readergroups() # add pinpad group groups.append(self.pinpadgroup) self.assertEqual(groups, groupssnapshot + [self.pinpadgroup]) # add pinpad a second time groups.append(self.pinpadgroup) self.assertEqual(groups, groupssnapshot + [self.pinpadgroup]) # add biometric once groups.append(self.biogroup) self.assertEqual( groups, groupssnapshot + [self.pinpadgroup, self.biogroup]) # clean-up groups.remove(self.biogroup) groups.remove(self.pinpadgroup) def testcase_readergroup_insert(self): """test groups.insert(i,newgroups)""" # take a snapshot of current groups groupssnapshot = list(readergroups()) groups = readergroups() # add pinpad group groups.insert(0, self.pinpadgroup) self.assertEqual(groups, groupssnapshot + [self.pinpadgroup]) # add pinpad a second time groups.insert(1, self.pinpadgroup) self.assertEqual(groups, groupssnapshot + [self.pinpadgroup]) # add biometric once groups.insert(1, self.biogroup) self.assertEqual( groups, groupssnapshot + [self.pinpadgroup, self.biogroup]) # clean-up groups.remove(self.biogroup) groups.remove(self.pinpadgroup) def suite(): suite1 = unittest.makeSuite(testcase_readergroups) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399770.0 pyscard-2.0.2/smartcard/test/framework/testcase_readermonitor.py0000755000175000017500000000620300000000000025536 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.ReaderMonitoring This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import threading import unittest import time # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver # a simple reader observer that prints added/removed readers class printobserver(ReaderObserver): def __init__(self, obsindex, testcase): self.obsindex = obsindex self.testcase = testcase def update(self, observable, actions): (addedreaders, removedreaders) = actions foundreaders = {} self.testcase.assertEqual(removedreaders, []) for reader in addedreaders: foundreaders[str(reader)] = 1 if {} != foundreaders: for reader in expectedReaders: self.testcase.assertTrue(reader in foundreaders) class testthread(threading.Thread): def __init__(self, obsindex, testcase): threading.Thread.__init__(self) self.obsindex = obsindex self.testcase = testcase self.readermonitor = ReaderMonitor() self.observer = None def run(self): # create and register observer self.observer = printobserver(self.obsindex, self.testcase) self.readermonitor.addObserver(self.observer) time.sleep(1) self.readermonitor.deleteObserver(self.observer) class testcase_readermonitor(unittest.TestCase): """Test smartcard framework reader monitoring methods""" def testcase_readermonitorthread(self): threads = [] for i in range(0, 4): t = testthread(i, self) threads.append(t) for t in threads: t.start() for t in threads: t.join() def suite(): suite1 = unittest.makeSuite(testcase_readermonitorthread) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398856.0 pyscard-2.0.2/smartcard/test/framework/testcase_readermonitorstress.py0000755000175000017500000001342000000000000027001 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.ReaderMonitoring This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import random import threading import time import unittest from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver period = .1 # stats on virtual reader insertion/removal insertedreaderstats = {} removedreaderstats = {} # the virtual list of readers mutexvreaders = threading.RLock() virtualreaders = [] def getReaders(): '''Return virtual list of inserted readers. Replacement of smartcard.system.readers for testing purpose''' try: mutexvreaders.acquire() currentreaders = virtualreaders finally: mutexvreaders.release() readerEvent.set() return currentreaders # an event to signal test threads to end exitEvent = threading.Event() # an event to ensure only one insertion/removal between getReaders() calls readerEvent = threading.Event() readerEvent.clear() # test running time in seconds RUNNING_TIME = 15 # the count of registered observers OBS_COUNT = 100 class readerInsertionThread(threading.Thread): '''Simulate reader insertion every 2 to 4 periods.''' def __init__(self): threading.Thread.__init__(self) def run(self): while not exitEvent.isSet(): time.sleep(random.uniform(2 * period, 4 * period)) readerEvent.wait() newreader = random.choice('abcdefghijklmnopqrstuvwxyz') try: mutexvreaders.acquire() if newreader not in virtualreaders: virtualreaders.append(newreader) if newreader in insertedreaderstats: insertedreaderstats[newreader] += 1 else: insertedreaderstats[newreader] = 1 finally: readerEvent.clear() mutexvreaders.release() class readerRemovalThread(threading.Thread): '''Simulate reader removal every 5 to 6 periods.''' def __init__(self): threading.Thread.__init__(self) def run(self): while not exitEvent.isSet(): time.sleep(random.uniform(5 * period, 6 * period)) readerEvent.wait() try: mutexvreaders.acquire() if virtualreaders: oldreader = random.choice(virtualreaders) virtualreaders.remove(oldreader) if oldreader in removedreaderstats: removedreaderstats[oldreader] += 1 else: removedreaderstats[oldreader] = 1 finally: readerEvent.clear() mutexvreaders.release() class countobserver(ReaderObserver): '''A simple reader observer that counts added/removed readers.''' def __init__(self, obsindex): self.obsindex = obsindex self.insertedreaderstats = {} self.removedreaderstats = {} self.countnotified = 0 def update(self, observable, actions): (addedreaders, removedreaders) = actions self.countnotified += 1 for newreader in addedreaders: if newreader in self.insertedreaderstats: self.insertedreaderstats[newreader] += 1 else: self.insertedreaderstats[newreader] = 1 for oldreader in removedreaders: if oldreader in self.removedreaderstats: self.removedreaderstats[oldreader] += 1 else: self.removedreaderstats[oldreader] = 1 class testcase_readermonitorstress(unittest.TestCase): '''Test smartcard framework reader monitoring''' def testcase_readermonitorthread(self): # create thread that simulates reader insertion insertionthread = readerInsertionThread() # create thread that simulates reader removal removalthread = readerRemovalThread() readermonitor = ReaderMonitor(readerProc=getReaders, period=period) observers = [] for i in range(0, OBS_COUNT): observer = countobserver(i) readermonitor.addObserver(observer) observers.append(observer) # signal threads to start insertionthread.start() removalthread.start() # let reader insertion/removal threads run for a while # then signal threads to end time.sleep(RUNNING_TIME) exitEvent.set() # wait until all threads ended removalthread.join() insertionthread.join() time.sleep(2 * period) for observer in observers: self.assertEqual( observer.insertedreaderstats, insertedreaderstats) self.assertEqual( observer.removedreaderstats, removedreaderstats) def suite(): suite1 = unittest.makeSuite(testcase_readermonitorthread) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399767.0 pyscard-2.0.2/smartcard/test/framework/testcase_readers.py0000755000175000017500000000725300000000000024317 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.readers. This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.System import readers, readergroups from smartcard import listReaders from smartcard.scard import resourceManager class testcase_readers(unittest.TestCase): """Test smartcard framework readers factory methods""" def testcase_enoughreaders(self): self.assertTrue(len(readers()) > 1) def testcase_readers(self): foundreaders = {} for reader in readers(): foundreaders[str(reader)] = 1 for reader in expectedReaders: self.assertTrue(reader in foundreaders) def testcase_hashreaders(self): foundreaders = {} for reader in readers(): foundreaders[reader] = 1 for reader in list(foundreaders.keys()): self.assertTrue(reader in readers()) def testcase_legacyreaders(self): foundreaders = {} for reader in listReaders(): foundreaders[reader] = 1 for reader in expectedReaders: self.assertTrue(reader in foundreaders) def testcase_readers_in_readergroup(self): foundreaders = {} for reader in readers(['SCard$DefaultReaders']): foundreaders[str(reader)] = 1 for reader in expectedReaders: self.assertTrue(reader in foundreaders) def testcase_readers_in_readergroup_empty(self): foundreaders = {} for reader in readers([]): foundreaders[str(reader)] = 1 for reader in expectedReaders: self.assertTrue(reader in foundreaders) if 'winscard' == resourceManager: def testcase_readers_in_readergroup_nonexistent(self): foundreaders = {} for reader in readers(['dummy$group']): foundreaders[reader] = 1 for reader in expectedReaders: self.assertTrue(not reader in foundreaders) self.assertEqual(0, len(foundreaders)) def testcase_readergroups(self): foundreadergroups = {} for readergroup in readergroups(): foundreadergroups[readergroup] = 1 for readergroup in expectedReaderGroups: self.assertTrue(readergroup in foundreadergroups) def suite(): suite1 = unittest.makeSuite(testcase_readers) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398860.0 pyscard-2.0.2/smartcard/test/framework/testcase_ulist.py0000755000175000017500000001030100000000000024016 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for ulist This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.ulist import ulist class C(ulist): def __onadditem__(self, item): #print '+', item pass def __onremoveitem__(self, item): #print '-', item pass class testcase_ulist(unittest.TestCase): """Test smartcard.ulist.""" def testcase_ulist_init(self): """tests constructor""" c = C([1, 2, 3, 3, 4, 5, 5]) self.assertEqual([1, 2, 3, 4, 5], c) c = C(['one', 'two', 'three', 'one']) self.assertEqual(['one', 'two', 'three'], c) def testcase_ulist_add(self): """tests l=l+other""" seed = [1, 2, 3] c = C(seed) self.assertEqual(seed, c) c = c + [] self.assertEqual(seed, c) c = c + 4 self.assertEqual(seed + [4], c) c = c + 4 self.assertEqual(seed + [4], c) c = c + 'word' self.assertEqual(seed + [4] + ['word'], c) seed = ['one', 'two', 'three'] c = C(seed) self.assertEqual(seed, c) c = c + ['four', 'five'] self.assertEqual(seed + ['four', 'five'], c) def testcase_ulist_iadd(self): """tests l+=other""" seed = [1, 2, 3] c = C(seed) self.assertEqual(seed, c) c += [] self.assertEqual(seed, c) c += 4 self.assertEqual(seed + [4], c) c += 4 self.assertEqual(seed + [4], c) c += [4, 3, 2, 1] self.assertEqual(seed + [4], c) c += 'word' self.assertEqual(seed + [4] + ['word'], c) seed = ['one', 'two', 'three'] c = C(seed) self.assertEqual(seed, c) c += ['four', 'five'] self.assertEqual(seed + ['four', 'five'], c) def testcase_ulist_radd(self): """tests l=other+l""" seed = [1, 2, 3] c = C(seed) self.assertEqual(seed, c) l = [] + c self.assertEqual(seed, l) l = [3] + c self.assertEqual(seed, c) self.assertEqual(seed, l) l = [3, 3, 4, 4] + c self.assertEqual(seed, c) self.assertEqual(seed + [4], l) l = [4] + ['word'] + c self.assertEqual(seed, c) self.assertEqual(seed + [4] + ['word'], l) def testcase_ulist_append(self): seed = [1, 2, 3] c = C(seed) c.append(4) self.assertEqual(seed + [4], c) c.append(4) self.assertEqual(seed + [4], c) c.append('word') self.assertEqual(seed + [4] + ['word'], c) def testcase_ulist_insert(self): seed = [1, 2, 3] c = C(seed) c.insert(0, 0) self.assertEqual([0] + seed, c) c.insert(1, 0) self.assertEqual([0] + seed, c) def testcase_ulist_pop(self): seed = [1, 2, 3] c = C(seed) c.pop() self.assertEqual(c, [1, 2]) c.pop(1) self.assertEqual(c, [1]) def testcase_ulist_remove(self): seed = [1, 2, 3] c = C(seed) c.remove(2) self.assertEqual(c, [1, 3]) c.remove(1) self.assertEqual(c, [3]) def suite(): suite1 = unittest.makeSuite(testcase_ulist) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398862.0 pyscard-2.0.2/smartcard/test/framework/testcase_utils.py0000755000175000017500000001256500000000000024034 0ustar00rousseaurousseau#! /usr/bin/env python3 # -*- coding: iso-8859-1 -*- """Unit tests for smartcard.utils This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.util import * class testcase_utils(unittest.TestCase): """Test smartcard.utils.""" def testcase_asciitostring(self): """tests ASCIIToString""" self.assertEqual( toASCIIString( [0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x20, 0x31, 0x30, 0x31]), "Number 101") def testcase_bytesto338(self): """tests toGSM3_38Bytes""" self.assertEqual( toGSM3_38Bytes("@Pascal"), [0x00, 0x06, 0x50, 0x61, 0x73, 0x63, 0x61, 0x6C]) def testcase_padd(self): """tests padd""" self.assertEqual( [0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], padd([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3], 16)) self.assertEqual([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3], padd([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3], 9)) self.assertEqual([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3], padd([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3], 8)) self.assertEqual([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3, 0xFF], padd([0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3], 10)) def testcase_toasciibytes(self): """tests toASCIIBytes""" self.assertEqual( [0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x20, 0x31, 0x30, 0x31], toASCIIBytes("Number 101")) self.assertEqual( toASCIIString(toASCIIBytes("Number 101")), "Number 101") def testcase_tobytestring(self): """tests toByteString""" self.assertEqual( [59, 101, 0, 0, 156, 17, 1, 1, 3], toBytes("3B 65 00 00 9C 11 01 01 03")) self.assertEqual( [59, 101, 0, 0, 156, 17, 1, 1, 3], toBytes("3B6500009C11010103")) self.assertEqual( [59, 101, 0, 0, 156, 17, 1, 1, 3], toBytes("3B65 0000 9C11 010103")) self.assertEqual( [59, 101, 0, 0, 156, 17, 1, 1, 3], toBytes("3B65 \t\t0000 \t9C11 \t0101\t03 \t\n")) def testcase_tohexstring(self): """tests toHexString""" self.assertEqual( "3B 65 00 00 9C 11 01 01 03", toHexString([59, 101, 0, 0, 156, 17, 1, 1, 3])) bytes = [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03] self.assertEqual( "3B, 65, 00, 00, 9C, 11, 01, 01, 03", toHexString(bytes, COMMA)) self.assertEqual("3B6500009C11010103", toHexString(bytes, PACK)) self.assertEqual( "0x3B 0x65 0x00 0x00 0x9C 0x11 0x01 0x01 0x03", toHexString(bytes, HEX)) self.assertEqual( "0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03", toHexString(bytes, HEX | COMMA)) self.assertEqual( "0X3B 0X65 0X00 0X00 0X9C 0X11 0X01 0X01 0X03", toHexString(bytes, HEX | UPPERCASE)) self.assertEqual( "0X3B, 0X65, 0X00, 0X00, 0X9C, 0X11, 0X01, 0X01, 0X03", toHexString(bytes, HEX | UPPERCASE | COMMA)) bytes = [59, 101, 0, 0, 156, 17, 1, 1, 3] self.assertEqual( "3B, 65, 00, 00, 9C, 11, 01, 01, 03", toHexString(bytes, COMMA)) self.assertEqual( "3B6500009C11010103", toHexString(bytes, PACK)) self.assertEqual( "0x3B 0x65 0x00 0x00 0x9C 0x11 0x01 0x01 0x03", toHexString(bytes, HEX)) self.assertEqual( "0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03", toHexString(bytes, HEX | COMMA)) self.assertEqual( "0X3B 0X65 0X00 0X00 0X9C 0X11 0X01 0X01 0X03", toHexString(bytes, HEX | UPPERCASE)) self.assertEqual( "0X3B, 0X65, 0X00, 0X00, 0X9C, 0X11, 0X01, 0X01, 0X03", toHexString(bytes, HEX | UPPERCASE | COMMA)) def testcase_tohexstring_empty(self): """tests toHexString""" self.assertEqual("", toHexString()) self.assertEqual("", toHexString([])) def testcase_tohexstring_nobytes(self): """tests toHexString""" self.assertRaises(TypeError, toHexString, 'bad input') self.assertRaises(TypeError, toHexString, ['bad', 'input']) def suite(): suite1 = unittest.makeSuite(testcase_utils) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398869.0 pyscard-2.0.2/smartcard/test/framework/testsuite_framework.py0000755000175000017500000000353100000000000025100 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit test suite for smartcard python framework. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import sys import unittest # so that we can locate configcheck sys.path += ['..'] import configcheck def suite(): modules_to_test = ( 'testcase_ATR', 'testcase_Card', 'testcase_CardConnection', 'testcase_CardMonitor', 'testcase_CardRequest', 'testcase_CardService', 'testcase_CardType', 'testcase_CAtr', 'testcase_ErrorChecking', 'testcase_ExclusiveCardConnection', 'testcase_readers', 'testcase_readergroups', 'testcase_readermonitor', 'testcase_readermonitorstress', 'testcase_ulist', 'testcase_utils', ) testsuite_framework = unittest.TestSuite() for module in map(__import__, modules_to_test): testsuite_framework.addTest(unittest.findTestCases(module)) return testsuite_framework if __name__ == '__main__': configcheck.checklocalconfig() unittest.main(defaultTest='suite') ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/smartcard/test/frameworkpcsc/0000755000175000017500000000000000000000000021264 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/test/frameworkpcsc/local_config.py0000644000175000017500000000075300000000000024262 0ustar00rousseaurousseaufrom smartcard.util import toHexString expectedReaders = ['Gemalto PC Twin Reader 00 00'] expectedATRs = [[63, 47, 0, 128, 105, 175, 2, 4, 1, 49, 0, 0, 0, 14, 131, 62, 159, 22]] expectedATRinReader = {} for i in range(len(expectedReaders)): expectedATRinReader[expectedReaders[i]] = expectedATRs[i] expectedReaderForATR = {} for i in range(len(expectedReaders)): expectedReaderForATR[toHexString(expectedATRs[i])] = expectedReaders[i] expectedReaderGroups = ['SCard$DefaultReaders'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762664.0 pyscard-2.0.2/smartcard/test/frameworkpcsc/readme.txt0000644000175000017500000000316100000000000023263 0ustar00rousseaurousseau------------------------------------------------------------------------------- This directory contains the test suite for the pcsc part of the pyscard framework. You will need two smart card readers and two smart cards to run the test suite. Insert the readers and the cards in the readers before executing the test suite. On the first execution of the test suite, the configcheck.py script in the parent directory will generate a localconfig.py file that will contain the current names of the readers and ATRs of the cards inserted in the readers. These data are used by the test suite. If you change the test configuration, i.e. add or remove readers or cards, or change the readers or cards, just delete localconfig.py and re-run the test suite. ------------------------------------------------------------------------------- This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ------------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399816.0 pyscard-2.0.2/smartcard/test/frameworkpcsc/testcase_pcscreadergroups.py0000755000175000017500000001412600000000000027113 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for smartcard.pcsc.readers This test case can be executed individually, or with all other test cases thru testsuite_framework.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders from local_config import expectedReaderGroups, expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() from smartcard.pcsc.PCSCReaderGroups import PCSCReaderGroups from smartcard.pcsc.PCSCReader import PCSCReader from smartcard.scard import resourceManager if 'winscard' == resourceManager: class testcase_readergroups(unittest.TestCase): """Test smartcard framework readers factory methods""" def setUp(self): groups = PCSCReaderGroups().instance groups.remove('Pinpad$Readers') groups.remove('Biometric$Readers') def testcase_add(self): """Test for groups=groups+newgroups""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups = groups + newgroup self.assertEqual(groups, groupssnapshot + [newgroup]) groups.remove(newgroup) def testcase_addlist(self): """Test for groups=groups+[newgroups]""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroups = ['Pinpad$Readers', 'Biometric$Readers'] groups = groups + newgroups self.assertEqual(groups, groupssnapshot + newgroups) for group in newgroups: groups.remove(group) def testcase_iadd(self): """Test for groups+=newgroup""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups += newgroup self.assertEqual(groups, groupssnapshot + [newgroup]) groups.remove(newgroup) def testcase_iaddlist(self): """Test for groups+=[newgroups]""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroups = ['Pinpad$Readers', 'Biometric$Readers'] groups += newgroups self.assertEqual(groups, groupssnapshot + newgroups) for group in newgroups: groups.remove(group) def testcase_append(self): """Test for groups.append(newgroup)""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups.append(newgroup) self.assertEqual(groups, groupssnapshot + [newgroup]) groups.remove(newgroup) def testcase_insert(self): """Test for groups.insert(newgroup)""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups.insert(0, newgroup) self.assertEqual(groups, [newgroup] + groupssnapshot) groups.remove(newgroup) def testcase_removereadergroup_pop(self): """Test for groups.pop()""" groupssnapshot = list(PCSCReaderGroups().instance) groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups.insert(0, newgroup) self.assertEqual(groups, [newgroup] + groupssnapshot) groups.pop(0) self.assertEqual(groups, groupssnapshot) def testcase_addreadertogroup(self): """Test for adding readers to group""" groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups.insert(0, newgroup) for r in PCSCReader.readers('SCard$DefaultReaders'): r.addtoreadergroup(newgroup) self.assertEqual( PCSCReader.readers( 'SCard$DefaultReaders'), PCSCReader.readers(newgroup)) groups.pop(0) self.assertEqual([], PCSCReader.readers(newgroup)) def testcase_removereaderfromgroup(self): """Test for removing readers from group""" groups = PCSCReaderGroups().instance newgroup = 'Pinpad$Readers' groups.insert(0, newgroup) for r in PCSCReader.readers('SCard$DefaultReaders'): r.addtoreadergroup(newgroup) self.assertEqual( PCSCReader.readers( 'SCard$DefaultReaders'), PCSCReader.readers(newgroup)) for r in PCSCReader.readers('SCard$DefaultReaders'): r.removefromreadergroup(newgroup) self.assertEqual([], PCSCReader.readers(newgroup)) groups.pop(0) self.assertEqual([], PCSCReader.readers(newgroup)) def suite(): suite1 = unittest.makeSuite(testcase_readergroups) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398833.0 pyscard-2.0.2/smartcard/test/frameworkpcsc/testsuite_frameworkpcsc.py0000755000175000017500000000262500000000000026625 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit test suite for smartcard python framework over pcsc. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import sys import unittest # so that we can locate configcheck sys.path += ['..'] import configcheck def suite(): modules_to_test = ( 'testcase_pcscreadergroups', ) testsuite_framework = unittest.TestSuite() for module in map(__import__, modules_to_test): testsuite_framework.addTest(unittest.findTestCases(module)) return testsuite_framework if __name__ == '__main__': configcheck.checklocalconfig() unittest.main(defaultTest='suite') ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/smartcard/test/scard/0000755000175000017500000000000000000000000017512 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762663.0 pyscard-2.0.2/smartcard/test/scard/local_config.py0000644000175000017500000000075300000000000022510 0ustar00rousseaurousseaufrom smartcard.util import toHexString expectedReaders = ['Gemalto PC Twin Reader 00 00'] expectedATRs = [[63, 47, 0, 128, 105, 175, 2, 4, 1, 49, 0, 0, 0, 14, 131, 62, 159, 22]] expectedATRinReader = {} for i in range(len(expectedReaders)): expectedATRinReader[expectedReaders[i]] = expectedATRs[i] expectedReaderForATR = {} for i in range(len(expectedReaders)): expectedReaderForATR[toHexString(expectedATRs[i])] = expectedReaders[i] expectedReaderGroups = ['SCard$DefaultReaders'] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762663.0 pyscard-2.0.2/smartcard/test/scard/readme.txt0000644000175000017500000000320500000000000021510 0ustar00rousseaurousseau------------------------------------------------------------------------------- This directory contains the test suite for the smartcard.scard wrapper of the C language SCardXXX API. You will need two smart card readers and two smart cards to run the test suite. Insert the readers and the cards in the readers before executing the test suite. On the first execution of the test suite, the configcheck.py script in the parent directory will generate a localconfig.py file that will contain the current names of the readers and ATRs of the cards inserted in the readers. These data are used by the test suite. If you change the test configuration, i.e. add or remove readers or cards, or change the readers or cards, just delete localconfig.py and re-run the test suite. ------------------------------------------------------------------------------- This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ------------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399809.0 pyscard-2.0.2/smartcard/test/scard/testcase_getatr.py0000755000175000017500000000571200000000000023255 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardConnect/SCardStatus/SCardDisconnect This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.scard import * # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() class testcase_getATR(unittest.TestCase): """Test scard API for ATR retrieval""" def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) hresult, self.readers = SCardListReaders(self.hcontext, []) self.assertEqual(hresult, 0) def tearDown(self): hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) def _getATR(self, r): if r < len(expectedATRs) and [] != expectedATRs[r]: hresult, hcard, dwActiveProtocol = SCardConnect( self.hcontext, self.readers[r], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) self.assertEqual(hresult, 0) try: hresult, reader, state, protocol, atr = SCardStatus(hcard) self.assertEqual(hresult, 0) self.assertEqual(reader, expectedReaders[r]) self.assertEqual(atr, expectedATRs[r]) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) self.assertEqual(hresult, 0) def test_getATR0(self): testcase_getATR._getATR(self, 0) def test_getATR1(self): testcase_getATR._getATR(self, 1) def test_getATR2(self): testcase_getATR._getATR(self, 2) def test_getATR3(self): testcase_getATR._getATR(self, 3) def suite(): suite1 = unittest.makeSuite(testcase_getATR) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399795.0 pyscard-2.0.2/smartcard/test/scard/testcase_getattrib.py0000755000175000017500000000735400000000000023760 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardConnect/SCardGetAttrib/SCardDisconnect. This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import struct import unittest from smartcard.scard import * # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() class testcase_getAttrib(unittest.TestCase): """Test scard API for SCardGetAttrib""" def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) hresult, self.readers = SCardListReaders(self.hcontext, []) self.assertEqual(hresult, 0) def tearDown(self): hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) def _getAttrib(self, r): if r < len(expectedATRs) and [] != expectedATRs[r]: hresult, hcard, dwActiveProtocol = SCardConnect( self.hcontext, self.readers[r], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) self.assertEqual(hresult, 0) try: hresult, reader, state, protocol, atr = SCardStatus(hcard) self.assertEqual(hresult, 0) self.assertEqual(reader, expectedReaders[r]) self.assertEqual(atr, expectedATRs[r]) if 'SCARD_ATTR_ATR_STRING' in scard.__dict__: hresult, attrib = SCardGetAttrib( hcard, SCARD_ATTR_ATR_STRING) self.assertEqual(hresult, 0) self.assertEqual(expectedATRs[r], attrib) if 'winscard' == resourceManager: hresult, attrib = SCardGetAttrib( hcard, SCARD_ATTR_DEVICE_SYSTEM_NAME_A) self.assertEqual(hresult, 0) trimmedAttrib = attrib[:-1] self.assertEqual( expectedReaders[r], apply(struct.pack, ['<' + 'B' * len(trimmedAttrib)] + \ trimmedAttrib)) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) self.assertEqual(hresult, 0) def test_getATR0(self): testcase_getAttrib._getAttrib(self, 0) def test_getATR1(self): testcase_getAttrib._getAttrib(self, 1) def test_getATR3(self): testcase_getAttrib._getAttrib(self, 2) def test_getATR4(self): testcase_getAttrib._getAttrib(self, 3) def suite(): suite1 = unittest.makeSuite(testcase_getAttrib) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398881.0 pyscard-2.0.2/smartcard/test/scard/testcase_geterrormessage.py0000755000175000017500000000462100000000000025163 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardGetErrorMessage. This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.scard import * import sys class testcase_geterrormessage(unittest.TestCase): """Test scard API for ATR retrieval with SCardLocateCards""" def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) def tearDown(self): hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) def test_getErrorMessage(self): hresult, readers = SCardListReaders(self.hcontext, []) self.assertEqual(hresult, 0) # we need a long on Python 2.x like 123L # but Python 3 do not support the 123L notation any more hresult = SCardReleaseContext(pow(2,63) >> 60) if 'win32' == sys.platform: self.assertEqual(( SCARD_E_INVALID_HANDLE == hresult or \ ERROR_INVALID_HANDLE == hresult), True) else: self.assertEqual((SCARD_E_INVALID_HANDLE == hresult), True) self.assertEqual(( SCardGetErrorMessage(hresult).rstrip() == \ 'Invalid handle.'.rstrip() or \ SCardGetErrorMessage(hresult).rstrip() == \ 'The handle is invalid.'.rstrip()), True) def suite(): suite1 = unittest.makeSuite(testcase_geterrormessage) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398882.0 pyscard-2.0.2/smartcard/test/scard/testcase_listcards.py0000755000175000017500000002343100000000000023755 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardIntroduceCardType/SCardListCards/SCardListInterfaces This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest import platform from smartcard.scard import * import smartcard.guid if 'winscard' == resourceManager: class testcase_listcards(unittest.TestCase): """Test scard API for ATR retrieval""" # setup for all unit tests: establish context and introduce # a dummy card interface def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) self.dummycardname = 'dummycard' self.dummycardATR = \ [0x3B, 0x75, 0x94, 0x00, 0x00, 0x62, 0x02, 0x02, 0x01, 0x01] self.dummycardMask = \ [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] self.dummycardguid1 = \ smartcard.guid.strToGUID( '{AD4F1667-EA75-4124-84D4-641B3B197C65}') self.dummycardguid2 = \ smartcard.guid.strToGUID( '{382AE95A-7C2C-449c-A179-56C6DE6FF3BC}') testcase_listcards.__introduceinterface(self) # teardown for all unit tests: release context and forget # dummy card interface def tearDown(self): testcase_listcards.__forgetinterface(self) hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) # introduce a dummy card interface # card ATR same as e-gate def __introduceinterface(self): hresult = SCardForgetCardType(self.hcontext, self.dummycardname) dummycardPrimaryGUID = self.dummycardguid1 dummycardGUIDS = self.dummycardguid1 + self.dummycardguid2 hresult = SCardIntroduceCardType( self.hcontext, self.dummycardname, dummycardPrimaryGUID, dummycardGUIDS, self.dummycardATR, self.dummycardMask) self.assertEqual(hresult, 0) # forget dummy card interface def __forgetinterface(self): hresult = SCardForgetCardType(self.hcontext, self.dummycardname) self.assertEqual(hresult, 0) # locate a known card # Cryptoflex 8k v2 is present in standard Windows 2000 def test_listcryptoflexbyatr(self): if -1 != platform.platform().find('Windows-7'): dmyATR = \ [0x3B, 0x75, 0x94, 0x00, 0x00, 0x62, 0x02, 0x02, 0x01, 0x01] dmyName = ['dummycard'] hresult, card = SCardListCards(self.hcontext, dmyATR, []) self.assertEqual(hresult, 0) self.assertEqual(card, dmyName) elif -1 != platform.platform().find('Windows-Vista-6.0'): axaltodotnetATR = \ [ 0x3B, 0x16, 0x96, 0x41, 0x73, 0x74, 0x72, 0x69, 0x64 ] axaltodotnetName = ['Axalto Cryptoflex .NET'] hresult, card = SCardListCards(self.hcontext, axaltodotnetATR, []) self.assertEqual(hresult, 0) self.assertEqual(card, axaltodotnetName) else: slbCryptoFlex8kv2ATR = \ [0x3B, 0x95, 0x15, 0x40, 0x00, 0x68, 0x01, 0x02, 0x00, 0x00] slbCryptoFlex8kv2Name = ['Schlumberger Cryptoflex 8K v2'] hresult, card = SCardListCards( self.hcontext, slbCryptoFlex8kv2ATR, []) self.assertEqual(hresult, 0) self.assertEqual(card, slbCryptoFlex8kv2Name) # locate dummy card by interface def test_listdummycardbyguid(self): guidstolocate = self.dummycardguid2 + self.dummycardguid1 locatedcardnames = [self.dummycardname] hresult, card = SCardListCards(self.hcontext, [], guidstolocate) self.assertEqual(hresult, 0) self.assertEqual(card, locatedcardnames) # list our dummy card interfaces and check # that they match the introduced interfaces def test_listdummycardinterfaces(self): hresult, interfaces = SCardListInterfaces( self.hcontext, self.dummycardname) self.assertEqual(hresult, 0) self.assertEqual(2, len(interfaces)) self.assertEqual(self.dummycardguid1, interfaces[0]) self.assertEqual(self.dummycardguid2, interfaces[1]) # locate all cards and interfaces in the system def test_listallcards(self): if -1 != platform.platform().find('Windows-7'): expectedCards = ['Identity Device (Microsoft Generic Profile)', 'Identity Device (NIST SP 800-73 [PIV])'] elif -1 != platform.platform().find('Windows-Vista-6.0'): expectedCards = [ 'Axalto Cryptoflex .NET', 'Infineon SICRYPT CardModule Card', 'dummycard' ] else: # dummycard has been introduced in the test setup and # will be removed in the test teardown. Other cards are # the cards present by default on Windows 2000 expectedCards = ['dummycard', 'GemSAFE Smart Card (8K)', 'Schlumberger Cryptoflex 4K', 'Schlumberger Cryptoflex 8K', 'Schlumberger Cryptoflex 8K v2'] hresult, cards = SCardListCards(self.hcontext, [], []) self.assertEqual(hresult, 0) foundCards = {} for i in range(len(cards)): foundCards[cards[i]] = 1 for i in expectedCards: self.assertTrue(i in foundCards) # dummycard has a primary provider, # other cards have no primary provider if 'Windows-7-6.1.7600' == platform.platform(): expectedPrimaryProviderResult = { 'dummycard': [0, self.dummycardguid1], 'Identity Device (Microsoft Generic Profile)': \ [2, None], 'Identity Device (NIST SP 800-73 [PIV])': \ [2, None]} else: expectedPrimaryProviderResult = { 'dummycard': [0, self.dummycardguid1], 'GemSAFE': [2, None], 'Schlumberger Cryptoflex 4k': [2, None], 'Schlumberger Cryptoflex 8k': [2, None], 'Schlumberger Cryptoflex 8k v2': [2, None]} for i in range(len(cards)): hresult, providername = SCardGetCardTypeProviderName( self.hcontext, cards[i], SCARD_PROVIDER_PRIMARY) if cards[i] in expectedPrimaryProviderResult: self.assertEqual( hresult, expectedPrimaryProviderResult[cards[i]][0]) if hresult == 0: self.assertEqual( providername, smartcard.guid.GUIDToStr( expectedPrimaryProviderResult[cards[i]][1])) # dummycard has no CSP, other cards have a CSP if 'Windows-7-6.1.7600' == platform.platform(): expectedProviderCSPResult = { 'dummycard': [2, None], 'Identity Device (Microsoft Generic Profile)': \ [0, 'Microsoft Base Smart Card Crypto Provider'], 'Identity Device (NIST SP 800-73 [PIV])': \ [0, 'Microsoft Base Smart Card Crypto Provider']} else: expectedProviderCSPResult = { 'dummycard': [2, None], 'GemSAFE': [0, 'Gemplus GemSAFE Card CSP v1.0'], 'Schlumberger Cryptoflex 4k': \ [0, 'Schlumberger Cryptographic Service Provider'], 'Schlumberger Cryptoflex 8k': \ [0, 'Schlumberger Cryptographic Service Provider'], 'Schlumberger Cryptoflex 8k v2': \ [0, 'Schlumberger Cryptographic Service Provider']} for i in range(len(cards)): hresult, providername = SCardGetCardTypeProviderName( self.hcontext, cards[i], SCARD_PROVIDER_CSP) if cards[i] in expectedProviderCSPResult: self.assertEqual( hresult, expectedProviderCSPResult[cards[i]][0]) self.assertEqual( providername, expectedProviderCSPResult[cards[i]][1]) def suite(): suite1 = unittest.makeSuite(testcase_listcards) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399802.0 pyscard-2.0.2/smartcard/test/scard/testcase_locatecards.py0000755000175000017500000001066500000000000024256 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardLocateCards. This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import platform import unittest from smartcard.scard import * # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedReaders from local_config import expectedATRinReader except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() class testcase_locatecards(unittest.TestCase): """Test scard API for ATR retrieval with SCardLocateCards""" def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) def tearDown(self): hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) def test_locateCards(self): hresult, readers = SCardListReaders(self.hcontext, []) self.assertEqual(hresult, 0) foundReaders = {} for reader in readers: foundReaders[reader] = 1 for reader in expectedReaders: self.assertTrue(reader in foundReaders) if 'winscard' == resourceManager: hresult, cards = SCardListCards(self.hcontext, [], []) self.assertEqual(hresult, 0) readerstates = [] for i in range(len(readers)): readerstates += [(readers[i], SCARD_STATE_UNAWARE)] hresult, newstates = SCardLocateCards( self.hcontext, cards, readerstates) self.assertEqual(hresult, 0) if -1 == platform.platform().find('Windows-7'): dictexpectedreaders = {} for reader in expectedReaders: dictexpectedreaders[reader] = 1 for reader, eventstate, atr in newstates: if reader in dictexpectedreaders and \ [] != expectedATRinReader[reader]: self.assertEqual(expectedATRinReader[reader], atr) self.assertTrue(eventstate & SCARD_STATE_PRESENT) self.assertTrue(eventstate & SCARD_STATE_CHANGED) # 10ms delay, so that time-out always occurs hresult, newstates = SCardGetStatusChange( self.hcontext, 10, newstates) self.assertEqual(hresult, SCARD_E_TIMEOUT) self.assertEqual( SCardGetErrorMessage(hresult), 'The user-specified timeout value has expired. ') elif 'pcsclite' == resourceManager: readerstates = [] for i in range(len(readers)): readerstates += [(readers[i], SCARD_STATE_UNAWARE)] hresult, newstates = SCardGetStatusChange( self.hcontext, 0, readerstates) self.assertEqual(hresult, 0) dictexpectedreaders = {} for reader in expectedReaders: dictexpectedreaders[reader] = 1 for reader, eventstate, atr in newstates: if reader in dictexpectedreaders and \ [] != expectedATRinReader[reader]: self.assertEqual(expectedATRinReader[reader], atr) self.assertTrue(eventstate & SCARD_STATE_PRESENT) self.assertTrue(eventstate & SCARD_STATE_CHANGED) def suite(): suite1 = unittest.makeSuite(testcase_locatecards) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399807.0 pyscard-2.0.2/smartcard/test/scard/testcase_readergroups.py0000755000175000017500000001074400000000000024472 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardxxx readers and readergroups methods. This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.scard import * # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedReaders except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() expectedGroups = ['SCard$DefaultReaders'] class testcase_readergroups(unittest.TestCase): """Test scard reader groups API""" def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) def tearDown(self): hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) def test_listReaders(self): # list current readers and compare with expected list hresult, readers = SCardListReaders(self.hcontext, []) self.assertEqual(hresult, 0) for i in range(len(expectedReaders)): self.assertEqual(readers[i], expectedReaders[i]) # list current reader groups and compare with expected list hresult, readerGroups = SCardListReaderGroups(self.hcontext) self.assertEqual(hresult, 0) for i in range(len(expectedGroups)): self.assertEqual(readerGroups[i], expectedGroups[i]) if 'winscard' == resourceManager: # add a new group newgroup = 'SCard$MyOwnGroup' expectedGroups.append(newgroup) hresult = SCardIntroduceReaderGroup(self.hcontext, newgroup) self.assertEqual(hresult, 0) dummyreader = readers[0] + ' alias' hresult = SCardIntroduceReader( self.hcontext, dummyreader, readers[0]) self.assertEqual(hresult, 0) hresult = SCardAddReaderToGroup( self.hcontext, dummyreader, newgroup) self.assertEqual(hresult, 0) hresult, readerGroups = SCardListReaderGroups(self.hcontext) self.assertEqual(hresult, 0) for i in range(len(expectedGroups)): self.assertEqual(readerGroups[i], expectedGroups[i]) # list readers in new group hresult, newreaders = SCardListReaders(self.hcontext, [newgroup]) self.assertEqual(hresult, 0) self.assertEqual(newreaders[0], dummyreader) # remove reader from new group hresult = SCardRemoveReaderFromGroup( self.hcontext, dummyreader, newgroup) self.assertEqual(hresult, 0) hresult, readerGroups = SCardListReaderGroups(self.hcontext) self.assertEqual(hresult, 0) expectedGroups.remove(newgroup) for i in range(len(expectedGroups)): self.assertEqual(readerGroups[i], expectedGroups[i]) hresult = SCardForgetReaderGroup(self.hcontext, newgroup) self.assertEqual(hresult, 0) hresult, readerGroups = SCardListReaderGroups(self.hcontext) self.assertEqual(hresult, 0) for i in range(len(expectedGroups)): self.assertEqual(readerGroups[i], expectedGroups[i]) hresult = SCardForgetReader(self.hcontext, dummyreader) self.assertEqual(hresult, 0) def suite(): suite1 = unittest.makeSuite(testcase_readergroups) return unittest.TestSuite((suite1)) if __name__ == '__main__': # When this module is executed from the command-line, run all its tests unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398888.0 pyscard-2.0.2/smartcard/test/scard/testcase_returncodes.py0000755000175000017500000000702000000000000024316 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for return codes This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2009 gemalto Author: Ludovic Rousseau, mailto:ludovic.rousseau@free.fr This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.scard import * class testcase_returncodes(unittest.TestCase): """Test scard API for return codes """ def test_getReturnCodes(self): errors = ( SCARD_S_SUCCESS, SCARD_F_INTERNAL_ERROR, SCARD_E_CANCELLED, SCARD_E_INVALID_HANDLE, SCARD_E_INVALID_PARAMETER, SCARD_E_INVALID_TARGET, SCARD_E_NO_MEMORY, SCARD_F_WAITED_TOO_LONG, SCARD_E_INSUFFICIENT_BUFFER, SCARD_E_UNKNOWN_READER, SCARD_E_TIMEOUT, SCARD_E_SHARING_VIOLATION, SCARD_E_NO_SMARTCARD, SCARD_E_UNKNOWN_CARD, SCARD_E_CANT_DISPOSE, SCARD_E_PROTO_MISMATCH, SCARD_E_NOT_READY, SCARD_E_INVALID_VALUE, SCARD_E_SYSTEM_CANCELLED, SCARD_F_COMM_ERROR, SCARD_F_UNKNOWN_ERROR, SCARD_E_INVALID_ATR, SCARD_E_NOT_TRANSACTED, SCARD_E_READER_UNAVAILABLE, SCARD_E_PCI_TOO_SMALL, SCARD_E_READER_UNSUPPORTED, SCARD_E_DUPLICATE_READER, SCARD_E_CARD_UNSUPPORTED, SCARD_E_NO_SERVICE, SCARD_E_SERVICE_STOPPED, SCARD_E_UNEXPECTED, SCARD_E_ICC_INSTALLATION, SCARD_E_ICC_CREATEORDER, SCARD_E_UNSUPPORTED_FEATURE, SCARD_E_DIR_NOT_FOUND, SCARD_E_FILE_NOT_FOUND, SCARD_E_NO_DIR, SCARD_E_NO_FILE, SCARD_E_NO_ACCESS, SCARD_E_WRITE_TOO_MANY, SCARD_E_BAD_SEEK, SCARD_E_INVALID_CHV, SCARD_E_UNKNOWN_RES_MNG, SCARD_E_NO_SUCH_CERTIFICATE, SCARD_E_CERTIFICATE_UNAVAILABLE, SCARD_E_NO_READERS_AVAILABLE, SCARD_E_COMM_DATA_LOST, SCARD_E_NO_KEY_CONTAINER, SCARD_E_SERVER_TOO_BUSY, SCARD_W_UNSUPPORTED_CARD, SCARD_W_UNRESPONSIVE_CARD, SCARD_W_UNPOWERED_CARD, SCARD_W_RESET_CARD, SCARD_W_REMOVED_CARD, SCARD_W_SECURITY_VIOLATION, SCARD_W_WRONG_CHV, SCARD_W_CHV_BLOCKED, SCARD_W_EOF, SCARD_W_CANCELLED_BY_USER, SCARD_W_CARD_NOT_AUTHENTICATED, ) #for e in errors: # print(hex((e+0x100000000) & 0xFFFFFFFF), SCardGetErrorMessage(e)) def suite(): suite1 = unittest.makeSuite(testcase_returncodes) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623399804.0 pyscard-2.0.2/smartcard/test/scard/testcase_transaction.py0000755000175000017500000000643100000000000024313 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit tests for SCardBeginTransaction/SCardEndTransaction. This test case can be executed individually, or with all other test cases thru testsuite_scard.py. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import unittest from smartcard.scard import * # import local_config for reader/card configuration # configcheck.py is generating local_config.py in # the test suite. import sys sys.path += ['..'] try: from local_config import expectedATRs, expectedReaders except ImportError: print('execute test suite first to generate the local_config.py file') sys.exit() class testcase_transaction(unittest.TestCase): """Test scard API for SCardBegin/EndTransaction""" def setUp(self): hresult, self.hcontext = SCardEstablishContext(SCARD_SCOPE_USER) self.assertEqual(hresult, 0) hresult, self.readers = SCardListReaders(self.hcontext, []) self.assertEqual(hresult, 0) def tearDown(self): hresult = SCardReleaseContext(self.hcontext) self.assertEqual(hresult, 0) def _transaction(self, r): if r < len(expectedATRs) and [] != expectedATRs[r]: hresult, hcard, dwActiveProtocol = SCardConnect( self.hcontext, self.readers[r], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) self.assertEqual(hresult, 0) try: hresult = SCardBeginTransaction(hcard) self.assertEqual(hresult, 0) hresult, reader, state, protocol, atr = SCardStatus(hcard) self.assertEqual(hresult, 0) self.assertEqual(reader, expectedReaders[r]) self.assertEqual(atr, expectedATRs[r]) hresult = SCardEndTransaction(hcard, SCARD_LEAVE_CARD) self.assertEqual(hresult, 0) finally: hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD) self.assertEqual(hresult, 0) def test_transaction_reader0(self): testcase_transaction._transaction(self, 0) def test_transaction_reader1(self): testcase_transaction._transaction(self, 1) def test_transaction_reader2(self): testcase_transaction._transaction(self, 2) def test_transaction_reader3(self): testcase_transaction._transaction(self, 3) def suite(): suite1 = unittest.makeSuite(testcase_transaction) return unittest.TestSuite((suite1)) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398891.0 pyscard-2.0.2/smartcard/test/scard/testsuite_scard.py0000755000175000017500000000310600000000000023274 0ustar00rousseaurousseau#! /usr/bin/env python3 """Unit test suite for scard python module. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import sys import unittest # so that we can locate configcheck sys.path += ['..'] import configcheck def suite(): modules_to_test = ( 'testcase_getatr', 'testcase_getattrib', 'testcase_geterrormessage', 'testcase_listcards', 'testcase_locatecards', 'testcase_readergroups', 'testcase_returncodes', 'testcase_transaction') testsuite_scard = unittest.TestSuite() for module in map(__import__, modules_to_test): testsuite_scard.addTest(unittest.findTestCases(module)) return testsuite_scard if __name__ == '__main__': configcheck.checklocalconfig() unittest.main(defaultTest='suite') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762665.0 pyscard-2.0.2/smartcard/ulist.py0000644000175000017500000000745200000000000017161 0ustar00rousseaurousseau"""ulist is a subclass of list where items cannot appear twice in the list. [1,2,2,3,3,4] is a valid list, whereas in ulist we can only have [1,2,3,4]. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ class ulist(list): """ulist ensures that all items are unique and provides an __onadditem__ hook to perform custom action in subclasses.""" # # override list methods # def __init__(self, initlist=None): if initlist is not None and initlist != []: list.__init__(self, [initlist[0]]) for item in initlist[1:]: if not list.__contains__(self, item): list.append(self, item) else: list.__init__(self, initlist) def __add__(self, other): newother = self.__remove_duplicates(other) self.__appendother__(newother) return self.__class__(list(self) + list(newother)) def __iadd__(self, other): newother = self.__remove_duplicates(other) self.__appendother__(newother) list.__iadd__(self, newother) return self def __radd__(self, other): newother = self.__remove_duplicates(other) return list.__add__(self, newother) def append(self, item): if not list.__contains__(self, item): list.append(self, item) self.__onadditem__(item) def insert(self, i, item): if not list.__contains__(self, item): list.insert(self, i, item) self.__onadditem__(item) def pop(self, i=-1): item = list.pop(self, i) self.__onremoveitem__(item) return item def remove(self, item): list.remove(self, item) self.__onremoveitem__(item) # # non list methods # def __remove_duplicates(self, _other): """Remove from other items already in list.""" if not isinstance(_other, type(self)) \ and not isinstance(_other, type(list)) \ and not isinstance(_other, type([])): other = [_other] else: other = list(_other) # remove items already in self newother = [] for i in range(0, len(other)): item = other.pop(0) if not list.__contains__(self, item): newother.append(item) # remove duplicate items in other other = [] if newother != []: other.append(newother[0]) for i in range(1, len(newother)): item = newother.pop() if not other.__contains__(item): other.append(item) return other def __appendother__(self, other): """Append other to object.""" for item in other: self.__onadditem__(item) def __onadditem__(self, item): """Called for each item added. Override in subclasses for adding custom action.""" pass def __onremoveitem__(self, item): """Called for each item removed. Override in subclasses for adding custom action.""" pass ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/util/0000755000175000017500000000000000000000000016414 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1586873833.0 pyscard-2.0.2/smartcard/util/__init__.py0000644000175000017500000002053400000000000020531 0ustar00rousseaurousseau# -*- coding: iso-8859-1 -*- """smartcard.util package __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ PACK = 1 HEX = 2 UPPERCASE = 4 COMMA = 8 def padd(bytelist, length, padding='FF'): """ Padds a byte list with a constant byte value (default is x0FF) @param bytelist: the byte list to padd @param length: the total length of the resulting byte list; no padding if length is smaller than the byte list length @param padding: padding value (default is 0xff) @return: the padded bytelist >>> padd([59, 101, 0, 0, 156, 17, 1, 1, 3], 16) [59, 101, 0, 0, 156, 17, 1, 1, 3, 255, 255, 255, 255, 255, 255, 255] >>> padd([59, 101, 0, 0, 156, 17, 1, 1, 3], 12, '80') [59, 101, 0, 0, 156, 17, 1, 1, 3, 128, 128, 128] >>> padd([59, 101, 0, 0, 156, 17, 1, 1, 3], 8) [59, 101, 0, 0, 156, 17, 1, 1, 3] """ if len(bytelist) < length: for index in range(length - len(bytelist)): bytelist.append(eval('0x' + padding)) return bytelist def toASCIIBytes(stringtoconvert): """Returns a list of ASCII bytes from a string. @param stringtoconvert: the string to convert into a byte list @return: a byte list of the ASCII codes of the string characters L{toASCIIBytes()} is the reverse of L{toASCIIString()} >>> toASCIIBytes("Number 101") [78, 117, 109, 98, 101, 114, 32, 49, 48, 49] """ return list(map(ord, list(stringtoconvert))) def toASCIIString(bytelist): """Returns a string representing a list of ASCII bytes. @param bytelist: list of ASCII bytes to convert into a string @return: a string from the ASCII code list L{toASCIIString()} is the reverse of L{toASCIIBytes()} >>> toASCIIString([0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x31,0x30,0x31]) 'Number 101' >>> toASCIIString([0x01, 0x20, 0x80, 0x7E, 0xF0]) ". .~." """ res = list() for b in bytelist: if b < 32 or b > 127: c = '.' else: c = chr(b) res.append(c) return ''.join(res) def toBytes(bytestring): """Returns a list of bytes from a byte string bytestring: a byte string >>> toBytes("3B 65 00 00 9C 11 01 01 03") [59, 101, 0, 0, 156, 17, 1, 1, 3] >>> toBytes("3B6500009C11010103") [59, 101, 0, 0, 156, 17, 1, 1, 3] >>> toBytes("3B6500 009C1101 0103") [59, 101, 0, 0, 156, 17, 1, 1, 3] """ packedstring = bytestring.replace(' ', '').replace(' ','').replace('\n', '') try: return list(map(lambda x: int(''.join(x), 16), zip(*[iter(packedstring)] * 2))) except (KeyError, ValueError): raise TypeError('not a string representing a list of bytes') """GSM3.38 character conversion table.""" __dic_GSM_3_38__ = { u'@': 0x00, # @ At symbol u'': 0x01, # Britain pound symbol u'$': 0x02, # $ Dollar symbol u'': 0x03, # Yen symbol u'': 0x04, # e accent grave u'': 0x05, # e accent aigu u'': 0x06, # u accent grave u'': 0x07, # i accent grave u'': 0x08, # o accent grave u'': 0x09, # C majuscule cedille u'\n': 0x0A, # LF Line Feed u'': 0x0B, # O majuscule barr u'': 0x0C, # o minuscule barr u'\r': 0x0D, # CR Carriage Return u'': 0x0E, # Angstroem majuscule u'': 0x0F, # Angstroem minuscule u'_': 0x11, # underscore u'': 0x1C, # majuscule ae u'': 0x1D, # minuscule ae u'': 0x1E, # s dur allemand u'': 0x1F, # majuscule u' ': 0x20, u'!': 0x21, u'"': 0x22, # guillemet u'#': 0x23, u'': 0x24, # carr u'': 0x40, # point d'exclamation renvers u'': 0x5B, # majuscule A trema u'': 0x7B, # minuscule a trema u'': 0x5C, # majuscule O trema u'': 0x7C, # minuscule o trema u'': 0x5D, # majuscule N tilda espagnol u'': 0x7D, # minuscule n tilda espagnol u'': 0x5E, # majuscule U trema u'': 0x7E, # minuscule u trema u'': 0x5F, # signe paragraphe u'': 0x60, # point interrogation renvers u'': 0x7F, # a accent grave } def toGSM3_38Bytes(stringtoconvert): """Returns a list of bytes from a string using GSM 3.38 conversion table. @param stringtoconvert: string to convert @return: a list of bytes >>> toGSM3_38Bytes("@Pascal") [0, 6, 80, 97, 115, 99, 97, 108] """ if isinstance(stringtoconvert, bytes): stringtoconvert = stringtoconvert.decode('iso8859-1') result = [] for char in stringtoconvert: if ((char >= "%") and (char <= "?")): result.append(ord(char)) elif ((char >= "A") and (char <= "Z")): result.append(ord(char)) elif ((char >= "a") and (char <= "z")): result.append(ord(char)) else: result.append(__dic_GSM_3_38__[char]) return result def toHexString(bytes=[], format=0): """Returns an hex string representing bytes @param bytes: a list of bytes to stringify, e.g. [59, 22, 148, 32, 2, 1, 0, 0, 13] @param format: a logical OR of - COMMA: add a comma between bytes - HEX: add the 0x chars before bytes - UPPERCASE: use 0X before bytes (need HEX) - PACK: remove blanks >>> vals = [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03] >>> toHexString(vals) '3B 65 00 00 9C 11 01 01 03' >>> toHexString(vals, COMMA) '3B, 65, 00, 00, 9C, 11, 01, 01, 03' >>> toHexString(vals, HEX) '0x3B 0x65 0x00 0x00 0x9C 0x11 0x01 0x01 0x03' >>> toHexString(vals, HEX | COMMA) '0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03' >>> toHexString(vals, PACK) >>> toHexString(vals, HEX | UPPERCASE) '0X3B 0X65 0X00 0X00 0X9C 0X11 0X01 0X01 0X03' >>> toHexString(vals, HEX | UPPERCASE | COMMA) '0X3B, 0X65, 0X00, 0X00, 0X9C, 0X11, 0X01, 0X01, 0X03' """ for byte in tuple(bytes): pass if type(bytes) is not list: raise TypeError('not a list of bytes') if bytes == None or bytes == []: return "" else: pformat = "%-0.2X" if COMMA & format: separator = "," else: separator = "" if not PACK & format: separator = separator + " " if HEX & format: if UPPERCASE & format: pformat = "0X" + pformat else: pformat = "0x" + pformat return (separator.join(map(lambda a: pformat % ((a + 256) % 256), bytes))).rstrip() # FIXME This appears to duplicate toASCIIString() def HexListToBinString(hexlist): """ >>> HexListToBinString([78, 117, 109, 98, 101, 114, 32, 49, 48, 49]) 'Number 101' """ return ''.join(map(chr, hexlist)) # FIXME This appears to duplicate to ASCIIBytes() def BinStringToHexList(binstring): """ >>> BinStringToHexList("Number 101") [78, 117, 109, 98, 101, 114, 32, 49, 48, 49] """ return list(map(ord, binstring)) def hl2bs(hexlist): """An alias for HexListToBinString >>> hl2bs([78, 117, 109, 98, 101, 114, 32, 49, 48, 49]) 'Number 101' """ return HexListToBinString(hexlist) def bs2hl(binstring): """An alias for BinStringToHexList >>> bs2hl("Number 101") [78, 117, 109, 98, 101, 114, 32, 49, 48, 49] """ return BinStringToHexList(binstring) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/wx/0000755000175000017500000000000000000000000016075 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/APDUHexValidator.py0000644000175000017500000000405400000000000021516 0ustar00rousseaurousseau# -*- coding: iso-8859-15 -*- """ A wxValidator that matches APDU in hexadecimal such as:: A4 A0 00 00 02 A4A0000002 __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import re import string import wx # a regexp to match ATRs and APDUs hexbyte = "[0-9a-fA-F]{1,2}" apduregexp = re.compile("((%s)[ ]*)*" % hexbyte) class APDUHexValidator(wx.PyValidator): '''A wxValidator that matches APDU in hexadecimal such as: A4 A0 00 00 02 A4A0000002''' def __init__(self): wx.PyValidator.__init__(self) self.Bind(wx.EVT_CHAR, self.OnChar) def Clone(self): return APDUHexValidator() def Validate(self, win): tc = self.GetWindow() value = tc.GetValue() if not apduregexp.match(value): return False return True def OnChar(self, event): key = event.GetKeyCode() if wx.WXK_SPACE == key or chr(key) in string.hexdigits: value = event.GetEventObject().GetValue() + chr(key) if apduregexp.match(value): event.Skip() return if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: event.Skip() return if not wx.Validator_IsSilent(): wx.Bell() return ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/APDUTracerPanel.py0000644000175000017500000000512000000000000021317 0ustar00rousseaurousseau"""Graphical APDU Tracer. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ # wxPython GUI modules (http://www.wxpython.org) import wx from smartcard.CardConnectionObserver import CardConnectionObserver from smartcard.util import toHexString [ wxID_APDUTEXTCTRL, ] = [wx.NewId() for x in range(1)] class APDUTracerPanel(wx.Panel, CardConnectionObserver): def __init__(self, parent): wx.Panel.__init__(self, parent, -1) boxsizer = wx.BoxSizer(wx.HORIZONTAL) self.apdutextctrl = wx.TextCtrl( self, wxID_APDUTEXTCTRL, "", pos=wx.DefaultPosition, style=wx.TE_MULTILINE | wx.TE_READONLY) boxsizer.Add(self.apdutextctrl, 1, wx.EXPAND | wx.ALL, 5) self.SetSizer(boxsizer) self.SetAutoLayout(True) self.Bind(wx.EVT_TEXT_MAXLEN, self.OnMaxLength, self.apdutextctrl) def OnMaxLength(self, evt): '''Reset text buffer when max length is reached.''' self.apdutextctrl.SetValue("") evt.Skip() def update(self, cardconnection, ccevent): '''CardConnectionObserver callback.''' apduline = "" if 'connect' == ccevent.type: apduline += 'connecting to ' + cardconnection.getReader() elif 'disconnect' == ccevent.type: apduline += 'disconnecting from ' + cardconnection.getReader() elif 'command' == ccevent.type: apduline += '> ' + toHexString(ccevent.args[0]) elif 'response' == ccevent.type: if [] == ccevent.args[0]: apduline += "< %-2X %-2X" % tuple(ccevent.args[-2:]) else: apduline += "< " + toHexString(ccevent.args[0]) + \ "%-2X %-2X" % tuple(ccevent.args[-2:]) self.apdutextctrl.AppendText(apduline + "\n") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/CardAndReaderTreePanel.py0000644000175000017500000004016400000000000022673 0ustar00rousseaurousseau"""wxPython panel display cards/readers as a TreeCtrl. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ # smartcard imports from threading import RLock from smartcard.Exceptions import CardConnectionException, NoCardException from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver from smartcard.CardMonitoring import CardMonitor, CardObserver from smartcard.util import toHexString import smartcard.wx.SimpleSCardApp from smartcard.wx import ICO_SMARTCARD, ICO_READER # wxPython GUI modules (http://www.wxpython.org) import wx class BaseCardTreeCtrl(wx.TreeCtrl): """Base class for the smart card and reader tree controls.""" def __init__(self, parent, ID=wx.NewId(), pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, clientpanel=None): """Constructor. Initializes a smartcard or reader tree control.""" wx.TreeCtrl.__init__( self, parent, ID, pos, size, wx.TR_SINGLE | wx.TR_NO_BUTTONS) self.clientpanel = clientpanel self.parent = parent isz = (16, 16) il = wx.ImageList(isz[0], isz[1]) self.capindex = il.Add( wx.ArtProvider_GetBitmap(wx.ART_HELP_BOOK, wx.ART_OTHER, isz)) self.fldrindex = il.Add( wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz)) self.fldropenindex = il.Add( wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz)) if None != ICO_SMARTCARD: self.cardimageindex = il.Add( wx.Bitmap(ICO_SMARTCARD, wx.BITMAP_TYPE_ICO)) if None != ICO_READER: self.readerimageindex = il.Add( wx.Bitmap(ICO_READER, wx.BITMAP_TYPE_ICO)) self.il = il self.SetImageList(self.il) def Repaint(self): self.Refresh() wx.PostEvent(self, wx.PaintEvent()) class CardTreeCtrl(BaseCardTreeCtrl): """The CardTreeCtrl monitors inserted cards and notifies the application client dialog of any card activation.""" def __init__(self, parent, ID=wx.NewId(), pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, clientpanel=None): """Constructor. Create a smartcard tree control.""" BaseCardTreeCtrl.__init__(self, parent, ID, pos, size, wx.TR_SINGLE | wx.TR_NO_BUTTONS, clientpanel) self.root = self.AddRoot("Smartcards") self.SetPyData(self.root, None) self.SetItemImage(self.root, self.fldrindex, wx.TreeItemIcon_Normal) self.SetItemImage( self.root, self.fldropenindex, wx.TreeItemIcon_Expanded) self.Expand(self.root) def OnAddCards(self, addedcards): """Called when a card is inserted. Adds a smart card to the smartcards tree.""" parentnode = self.root for cardtoadd in addedcards: childCard = self.AppendItem(parentnode, toHexString(cardtoadd.atr)) self.SetItemText(childCard, toHexString(cardtoadd.atr)) self.SetPyData(childCard, cardtoadd) self.SetItemImage( childCard, self.cardimageindex, wx.TreeItemIcon_Normal) self.SetItemImage( childCard, self.cardimageindex, wx.TreeItemIcon_Expanded) self.Expand(childCard) self.Expand(self.root) self.EnsureVisible(self.root) self.Repaint() def OnRemoveCards(self, removedcards): """Called when a card is removed. Removes a card from the tree.""" parentnode = self.root for cardtoremove in removedcards: (childCard, cookie) = self.GetFirstChild(parentnode) while childCard.IsOk(): if self.GetItemText(childCard) == \ toHexString(cardtoremove.atr): self.Delete(childCard) (childCard, cookie) = self.GetNextChild(parentnode, cookie) self.Expand(self.root) self.EnsureVisible(self.root) self.Repaint() class ReaderTreeCtrl(BaseCardTreeCtrl): """The ReaderTreeCtrl monitors inserted cards and readers and notifies the application client dialog of any card activation.""" def __init__(self, parent, ID=wx.NewId(), pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, clientpanel=None): """Constructor. Create a reader tree control.""" BaseCardTreeCtrl.__init__( self, parent, ID, pos, size, wx.TR_SINGLE | wx.TR_NO_BUTTONS, clientpanel) self.mutex = RLock() self.root = self.AddRoot("Smartcard Readers") self.SetPyData(self.root, None) self.SetItemImage( self.root, self.fldrindex, wx.TreeItemIcon_Normal) self.SetItemImage( self.root, self.fldropenindex, wx.TreeItemIcon_Expanded) self.Expand(self.root) def AddATR(self, readernode, atr): """Add an ATR to a reader node.""" capchild = self.AppendItem(readernode, atr) self.SetPyData(capchild, None) self.SetItemImage( capchild, self.cardimageindex, wx.TreeItemIcon_Normal) self.SetItemImage( capchild, self.cardimageindex, wx.TreeItemIcon_Expanded) self.Expand(capchild) return capchild def GetATR(self, reader): """Return the ATR of the card inserted into the reader.""" atr = "no card inserted" try: if not type(reader) is str: connection = reader.createConnection() connection.connect() atr = toHexString(connection.getATR()) connection.disconnect() except NoCardException: pass except CardConnectionException: pass return atr def OnAddCards(self, addedcards): """Called when a card is inserted. Adds the smart card child to the reader node.""" self.mutex.acquire() try: parentnode = self.root for cardtoadd in addedcards: (childReader, cookie) = self.GetFirstChild(parentnode) found = False while childReader.IsOk() and not found: if self.GetItemText(childReader) == str(cardtoadd.reader): (childCard, cookie2) = self.GetFirstChild(childReader) self.SetItemText(childCard, toHexString(cardtoadd.atr)) self.SetPyData(childCard, cardtoadd) found = True else: (childReader, cookie) = self.GetNextChild( parentnode, cookie) # reader was not found, add reader node # this happens when card monitoring thread signals # added cards before reader monitoring thread signals # added readers if not found: childReader = self.AppendItem( parentnode, str(cardtoadd.reader)) self.SetPyData(childReader, cardtoadd.reader) self.SetItemImage( childReader, self.readerimageindex, wx.TreeItemIcon_Normal) self.SetItemImage( childReader, self.readerimageindex, wx.TreeItemIcon_Expanded) childCard = self.AddATR( childReader, toHexString(cardtoadd.atr)) self.SetPyData(childCard, cardtoadd) self.Expand(childReader) self.Expand(self.root) finally: self.mutex.release() self.EnsureVisible(self.root) self.Repaint() def OnAddReaders(self, addedreaders): """Called when a reader is inserted. Adds the smart card reader to the smartcard readers tree.""" self.mutex.acquire() try: parentnode = self.root for readertoadd in addedreaders: # is the reader already here? found = False (childReader, cookie) = self.GetFirstChild(parentnode) while childReader.IsOk() and not found: if self.GetItemText(childReader) == str(readertoadd): found = True else: (childReader, cookie) = self.GetNextChild( parentnode, cookie) if not found: childReader = self.AppendItem(parentnode, str(readertoadd)) self.SetPyData(childReader, readertoadd) self.SetItemImage( childReader, self.readerimageindex, wx.TreeItemIcon_Normal) self.SetItemImage( childReader, self.readerimageindex, wx.TreeItemIcon_Expanded) self.AddATR( childReader, self.GetATR(readertoadd)) self.Expand(childReader) self.Expand(self.root) finally: self.mutex.release() self.EnsureVisible(self.root) self.Repaint() def OnRemoveCards(self, removedcards): """Called when a card is removed. Removes the card from the tree.""" self.mutex.acquire() try: parentnode = self.root for cardtoremove in removedcards: (childReader, cookie) = self.GetFirstChild(parentnode) found = False while childReader.IsOk() and not found: if self.GetItemText(childReader) == \ str(cardtoremove.reader): (childCard, cookie2) = self.GetFirstChild(childReader) self.SetItemText(childCard, 'no card inserted') found = True else: (childReader, cookie) = \ self.GetNextChild(parentnode, cookie) self.Expand(self.root) finally: self.mutex.release() self.EnsureVisible(self.root) self.Repaint() def OnRemoveReaders(self, removedreaders): """Called when a reader is removed. Removes the reader from the smartcard readers tree.""" self.mutex.acquire() try: parentnode = self.root for readertoremove in removedreaders: (childReader, cookie) = self.GetFirstChild(parentnode) while childReader.IsOk(): if self.GetItemText(childReader) == str(readertoremove): self.Delete(childReader) else: (childReader, cookie) = \ self.GetNextChild(parentnode, cookie) self.Expand(self.root) finally: self.mutex.release() self.EnsureVisible(self.root) self.Repaint() class CardAndReaderTreePanel(wx.Panel): """Panel containing the smart card and reader tree controls.""" class _CardObserver(CardObserver): """Inner CardObserver. Gets notified of card insertion removal by the CardMonitor.""" def __init__(self, cardtreectrl): self.cardtreectrl = cardtreectrl def update(self, observable, handlers): """CardObserver callback that is notified when cards are added or removed.""" addedcards, removedcards = handlers self.cardtreectrl.OnRemoveCards(removedcards) self.cardtreectrl.OnAddCards(addedcards) class _ReaderObserver(ReaderObserver): """Inner ReaderObserver. Gets notified of reader insertion/removal by the ReaderMonitor.""" def __init__(self, readertreectrl): self.readertreectrl = readertreectrl def update(self, observable, handlers): """ReaderObserver callback that is notified when readers are added or removed.""" addedcards, removedcards = handlers self.readertreectrl.OnRemoveReaders(removedreaders) self.readertreectrl.OnAddReaders(addedreaders) def __init__(self, parent, appstyle, clientpanel): """Constructor. Create a smartcard and reader tree control on the left-hand side of the application main frame. @param parent: the tree panel parent @param appstyle: a combination of the following styles (bitwise or |) - TR_SMARTCARD: display a smartcard tree panel - TR_READER: display a reader tree panel - default is TR_DEFAULT = TR_SMARTCARD @param clientpanel: the client panel to notify of smartcard and reader events """ wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) sizer = wx.BoxSizer(wx.VERTICAL) # create the smartcard tree if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD: self.cardtreectrl = CardTreeCtrl(self, clientpanel=clientpanel) # create the smartcard insertion observer self.cardtreecardobserver = self._CardObserver(self.cardtreectrl) # register as a CardObserver; we will ge # notified of added/removed cards self.cardmonitor = CardMonitor() self.cardmonitor.addObserver(self.cardtreecardobserver) sizer.Add( self.cardtreectrl, flag=wx.EXPAND | wx.ALL, proportion=1) # create the reader tree if appstyle & smartcard.wx.SimpleSCardApp.TR_READER: self.readertreectrl = ReaderTreeCtrl( self, clientpanel=clientpanel) # create the reader insertion observer self.readertreereaderobserver = self._ReaderObserver( self.readertreectrl) # register as a ReaderObserver; we will ge # notified of added/removed readers self.readermonitor = ReaderMonitor() self.readermonitor.addObserver(self.readertreereaderobserver) # create the smartcard insertion observer self.readertreecardobserver = self._CardObserver( self.readertreectrl) # register as a CardObserver; we will get # notified of added/removed cards self.cardmonitor = CardMonitor() self.cardmonitor.addObserver(self.readertreecardobserver) sizer.Add( self.readertreectrl, flag=wx.EXPAND | wx.ALL, proportion=1) self.SetSizer(sizer) self.SetAutoLayout(True) def OnDestroy(self, event): """Called on panel destruction.""" # deregister observers if hasattr(self, 'cardmonitor'): self.cardmonitor.deleteObserver(self.cardtreecardobserver) if hasattr(self, 'readermonitor'): self.readermonitor.deleteObserver(self.readertreereaderobserver) self.cardmonitor.deleteObserver(self.readertreecardobserver) event.Skip() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/ReaderToolbar.py0000644000175000017500000000712400000000000021200 0ustar00rousseaurousseau"""wxPython toolbar with reader icons implementing ReaderObserver. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import wx from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver from smartcard.wx import ICO_SMARTCARD, ICO_READER class ReaderComboBox(wx.ComboBox, ReaderObserver): def __init__(self, parent): """Constructor. Registers as ReaderObserver to get notifications of reader insertion/removal.""" wx.ComboBox.__init__(self, parent, wx.NewId(), size=(170, -1), style=wx.CB_DROPDOWN | wx.CB_SORT, choices=[]) # register as a ReaderObserver; we will get # notified of added/removed readers self.readermonitor = ReaderMonitor() self.readermonitor.addObserver(self) def update(self, observable, handlers): """Toolbar ReaderObserver callback that is notified when readers are added or removed.""" addedreaders, removedreaders = handlers for reader in addedreaders: item = self.Append(str(reader)) self.SetClientData(item, reader) for reader in removedreaders: item = self.FindString(str(reader)) if wx.NOT_FOUND != item: self.Delete(item) selection = self.GetSelection() #if wx.NOT_FOUND == selection: # self.SetSelection(0) class ReaderToolbar(wx.ToolBar): """ReaderToolbar. Contains controls to select a reader from a listbox and connect to the cards.""" def __init__(self, parent): """Constructor, creating the reader toolbar.""" wx.ToolBar.__init__( self, parent, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.SIMPLE_BORDER | wx.TB_HORIZONTAL | wx.TB_FLAT | wx.TB_TEXT, name='Reader Toolbar') # create bitmaps for toolbar tsize = (16, 16) if None != ICO_READER: bmpReader = wx.Bitmap(ICO_READER, wx.BITMAP_TYPE_ICO) else: bmpReader = wx.ArtProvider_GetBitmap( wx.ART_HELP_BOOK, wx.ART_OTHER, tsize) if None != ICO_SMARTCARD: bmpCard = wx.Bitmap(ICO_SMARTCARD, wx.BITMAP_TYPE_ICO) else: bmpCard = wx.ArtProvider_GetBitmap( wx.ART_HELP_BOOK, wx.ART_OTHER, tsize) self.readercombobox = ReaderComboBox(self) # create and add controls self.AddSimpleTool( 10, bmpReader, "Select smart card reader", "Select smart card reader") self.AddControl(self.readercombobox) self.AddSeparator() self.AddSimpleTool( 20, bmpCard, "Connect to smartcard", "Connect to smart card") self.AddSeparator() self.Realize() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/SimpleSCardApp.py0000644000175000017500000000612400000000000021261 0ustar00rousseaurousseau"""Simple wxPython wxApp for smartcard. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import wx from smartcard.wx.SimpleSCardAppFrame import SimpleSCardAppFrame TR_SMARTCARD = 0x001 TR_READER = 0x002 TB_SMARTCARD = 0x004 TB_READER = 0x008 PANEL_APDUTRACER = 0x010 TR_DEFAULT = TR_SMARTCARD class SimpleSCardApp(wx.App): """The SimpleSCardApp class represents the smart card application. SimpleSCardApp is a subclass of wx.App. """ def __init__(self, appname='', apppanel=None, appstyle=TR_DEFAULT, appicon=None, pos=(-1, -1), size=(-1, -1)): """Constructor for simple smart card application. @param appname: the application name @param apppanel: the application panel to display in the application frame @param appicon: the application icon file; the default is no icon @param appstyle: a combination of the following styles (bitwise or |) - TR_SMARTCARD: display a smartcard tree panel - TR_READER: display a reader tree panel - TB_SMARTCARD: display a smartcard toolbar - TB_SMARTCARD: display a reader toolbar - PANEL_APDUTRACER: display an APDU tracer panel - default is TR_DEFAULT = TR_SMARTCARD @param pos: the application position as a (x,y) tupple; default is (-1,-1) @param size: the application window size as a (x,y) tuple; default is (-1,-1) Example: C{app = SimpleSCardApp( appname = 'A simple smartcard application', apppanel = testpanel.MyPanel, appstyle = TR_READER | TR_SMARTCARD, appicon = 'resources\mysmartcard.ico')} """ self.appname = appname self.apppanel = apppanel self.appstyle = appstyle self.appicon = appicon self.pos = pos self.size = size wx.App.__init__(self, False) def OnInit(self): """Create and display application frame.""" self.frame = SimpleSCardAppFrame( self.appname, self.apppanel, self.appstyle, self.appicon, self.pos, self.size) self.frame.Show(True) self.SetTopWindow(self.frame) return True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/SimpleSCardAppEventObserver.py0000644000175000017500000000413400000000000023772 0ustar00rousseaurousseau"""Smartcard event observer. __author__ = "gemalto http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ class SimpleSCardAppEventObserver(object): """This interface defines the event handlers called by the SimpleSCardApp.""" def __init__(self): self.selectedcard = None self.selectedreader = None # callbacks from SimpleCardAppFrame controls def OnActivateCard(self, card): """Called when a card is activated in the reader tree control or toolbar.""" self.selectedcard = card def OnActivateReader(self, reader): """Called when a reader is activated in the reader tree control or toolbar.""" self.selectedreader = reader def OnDeactivateCard(self, card): """Called when a card is deactivated in the reader tree control or toolbar.""" pass def OnDeselectCard(self, card): """Called when a card is selected in the reader tree control or toolbar.""" self.selectedcard = None def OnSelectCard(self, card): """Called when a card is selected in the reader tree control or toolbar.""" self.selectedcard = card def OnSelectReader(self, reader): """Called when a reader is selected in the reader tree control or toolbar.""" self.selectedreader = reader ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/SimpleSCardAppFrame.py0000644000175000017500000003146700000000000022244 0ustar00rousseaurousseau"""Simple wxpython frame for smart card application. __author__ = "gemalto http://www.gemalto.com" __date__ = "November 2006" __version__ = "1.4.0" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import os.path import wx import smartcard.wx from smartcard.wx import APDUTracerPanel from smartcard.wx import CardAndReaderTreePanel from smartcard.wx import ReaderToolbar import smartcard from smartcard.wx.SimpleSCardAppEventObserver import \ SimpleSCardAppEventObserver [ wxID_SIMPLESCARDAPP_FRAME, ] = [wx.NewId() for x in range(1)] class BlankPanel(wx.Panel, SimpleSCardAppEventObserver): '''A blank panel in case no panel is provided to SimpleSCardApp.''' def __init__(self, parent): wx.Panel.__init__(self, parent, -1) sizer = wx.GridSizer(1, 1) self.SetSizer(sizer) self.SetAutoLayout(True) class TreeAndUserPanelPanel(wx.Panel): '''The panel that contains the Card/Reader TreeCtrl and the user provided Panel.''' def __init__(self, parent, apppanelclass, appstyle): """ Constructor. Creates the panel with two panels: - the left-hand panel is holding the smartcard and/or reader tree - the right-hand panel is holding the application dialog @param apppanelclass: the class of the panel to instantiate in the L{SimpleSCardAppFrame} @param appstyle: a combination of the following styles (bitwise or |) - TR_SMARTCARD: display a smartcard tree panel - TR_READER: display a reader tree panel - TB_SMARTCARD: display a smartcard toolbar - TB_SMARTCARD: display a reader toolbar - default is TR_DEFAULT = TR_SMARTCARD """ wx.Panel.__init__(self, parent, -1) self.parent = parent self.selectedcard = None boxsizer = wx.BoxSizer(wx.HORIZONTAL) # create user dialog if None != apppanelclass: self.dialogpanel = apppanelclass(self) else: self.dialogpanel = BlankPanel(self) # create card/reader tree control if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD or \ appstyle & smartcard.wx.SimpleSCardApp.TR_READER: self.readertreepanel = \ CardAndReaderTreePanel.CardAndReaderTreePanel( self, appstyle, self.dialogpanel) boxsizer.Add(self.readertreepanel, 1, wx.EXPAND | wx.ALL, 5) boxsizer.Add(self.dialogpanel, 2, wx.EXPAND | wx.ALL) if appstyle & smartcard.wx.SimpleSCardApp.TR_READER: self.Bind( wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateReader, self.readertreepanel.readertreectrl) self.Bind( wx.EVT_TREE_SEL_CHANGED, self.OnSelectReader, self.readertreepanel.readertreectrl) self.Bind( wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnReaderRightClick, self.readertreepanel.readertreectrl) self.Bind( wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.readertreepanel.readertreectrl) if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD: self.Bind( wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateCard, self.readertreepanel.cardtreectrl) self.Bind( wx.EVT_TREE_SEL_CHANGED, self.OnSelectCard, self.readertreepanel.cardtreectrl) self.Bind( wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnCardRightClick, self.readertreepanel.cardtreectrl) self.SetSizer(boxsizer) self.SetAutoLayout(True) def ActivateCard(self, card): """Activate a card.""" if not hasattr(card, 'connection'): card.connection = card.createConnection() if None != self.parent.apdutracerpanel: card.connection.addObserver(self.parent.apdutracerpanel) card.connection.connect() self.dialogpanel.OnActivateCard(card) def DeactivateCard(self, card): """Deactivate a card.""" if hasattr(card, 'connection'): card.connection.disconnect() if None != self.parent.apdutracerpanel: card.connection.deleteObserver(self.parent.apdutracerpanel) delattr(card, 'connection') self.dialogpanel.OnDeactivateCard(card) def OnActivateCard(self, event): """Called when the user activates a card in the tree.""" item = event.GetItem() if item: itemdata = self.readertreepanel.cardtreectrl.GetItemPyData(item) if isinstance(itemdata, smartcard.Card.Card): self.ActivateCard(itemdata) else: self.dialogpanel.OnDeselectCard(itemdata) def OnActivateReader(self, event): """Called when the user activates a reader in the tree.""" item = event.GetItem() if item: itemdata = self.readertreepanel.readertreectrl.GetItemPyData(item) if isinstance(itemdata, smartcard.Card.Card): self.ActivateCard(itemdata) elif isinstance(itemdata, smartcard.reader.Reader.Reader): self.dialogpanel.OnActivateReader(itemdata) event.Skip() def OnItemCollapsed(self, event): item = event.GetItem() self.readertreepanel.readertreectrl.Expand(item) def OnCardRightClick(self, event): """Called when user right-clicks a node in the card tree control.""" item = event.GetItem() if item: itemdata = self.readertreepanel.cardtreectrl.GetItemPyData(item) if isinstance(itemdata, smartcard.Card.Card): self.selectedcard = itemdata if not hasattr(self, "connectID"): self.connectID = wx.NewId() self.disconnectID = wx.NewId() self.Bind(wx.EVT_MENU, self.OnConnect, id=self.connectID) self.Bind( wx.EVT_MENU, self.OnDisconnect, id=self.disconnectID) menu = wx.Menu() if not hasattr(self.selectedcard, 'connection'): menu.Append(self.connectID, "Connect") else: menu.Append(self.disconnectID, "Disconnect") self.PopupMenu(menu) menu.Destroy() def OnReaderRightClick(self, event): """Called when user right-clicks a node in the reader tree control.""" item = event.GetItem() if item: itemdata = self.readertreepanel.readertreectrl.GetItemPyData(item) if isinstance(itemdata, smartcard.Card.Card): self.selectedcard = itemdata if not hasattr(self, "connectID"): self.connectID = wx.NewId() self.disconnectID = wx.NewId() self.Bind(wx.EVT_MENU, self.OnConnect, id=self.connectID) self.Bind( wx.EVT_MENU, self.OnDisconnect, id=self.disconnectID) menu = wx.Menu() if not hasattr(self.selectedcard, 'connection'): menu.Append(self.connectID, "Connect") else: menu.Append(self.disconnectID, "Disconnect") self.PopupMenu(menu) menu.Destroy() def OnConnect(self, event): if isinstance(self.selectedcard, smartcard.Card.Card): self.ActivateCard(self.selectedcard) def OnDisconnect(self, event): if isinstance(self.selectedcard, smartcard.Card.Card): self.DeactivateCard(self.selectedcard) def OnSelectCard(self, event): """Called when the user selects a card in the tree.""" item = event.GetItem() if item: itemdata = self.readertreepanel.cardtreectrl.GetItemPyData(item) if isinstance(itemdata, smartcard.Card.Card): self.dialogpanel.OnSelectCard(itemdata) else: self.dialogpanel.OnDeselectCard(itemdata) def OnSelectReader(self, event): """Called when the user selects a reader in the tree.""" item = event.GetItem() if item: itemdata = self.readertreepanel.readertreectrl.GetItemPyData(item) if isinstance(itemdata, smartcard.Card.Card): self.dialogpanel.OnSelectCard(itemdata) elif isinstance(itemdata, smartcard.reader.Reader.Reader): self.dialogpanel.OnSelectReader(itemdata) else: self.dialogpanel.OnDeselectCard(itemdata) class SimpleSCardAppFrame(wx.Frame): """The main frame of the simple smartcard application.""" def __init__(self, appname, apppanelclass, appstyle, appicon, pos=(-1, -1), size=(-1, -1), ): """ Constructor. Creates the frame with two panels: - the left-hand panel is holding the smartcard and/or reader tree - the right-hand panel is holding the application dialog @param appname: name of the application @param apppanelclass: the class of the panel to instantiate in the L{SimpleSCardAppFrame} @param appstyle: a combination of the following styles (bitwise or |) - TR_SMARTCARD: display a smartcard tree panel - TR_READER: display a reader tree panel - TB_SMARTCARD: display a smartcard toolbar - TB_SMARTCARD: display a reader toolbar - PANEL_APDUTRACER: display an APDU tracer panel - default is TR_DEFAULT = TR_SMARTCARD @param pos: the application position as a (x,y) tupple; default is (-1,-1) @param size: the application window size as a (x,y) tuple; default is (-1,-1) """ wx.Frame.__init__(self, None, wxID_SIMPLESCARDAPP_FRAME, appname, pos=pos, size=size, style=wx.DEFAULT_FRAME_STYLE) if appicon: _icon = wx.Icon(appicon, wx.BITMAP_TYPE_ICO) self.SetIcon(_icon) elif os.path.exists(smartcard.wx.ICO_SMARTCARD): _icon = wx.Icon(smartcard.wx.ICO_SMARTCARD, wx.BITMAP_TYPE_ICO) self.SetIcon(_icon) boxsizer = wx.BoxSizer(wx.VERTICAL) self.treeuserpanel = TreeAndUserPanelPanel( self, apppanelclass, appstyle) boxsizer.Add(self.treeuserpanel, 3, wx.EXPAND | wx.ALL) # create a toolbar if required if appstyle & smartcard.wx.SimpleSCardApp.TB_SMARTCARD: self.toolbar = ReaderToolbar.ReaderToolbar(self) self.SetToolBar(self.toolbar) else: self.toolbar = None # create an apdu tracer console if required if appstyle & smartcard.wx.SimpleSCardApp.PANEL_APDUTRACER: self.apdutracerpanel = APDUTracerPanel.APDUTracerPanel(self) boxsizer.Add(self.apdutracerpanel, 1, wx.EXPAND | wx.ALL) else: self.apdutracerpanel = None self.SetSizer(boxsizer) self.SetAutoLayout(True) self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) if appstyle & smartcard.wx.SimpleSCardApp.TB_SMARTCARD: self.Bind( wx.EVT_COMBOBOX, self.OnReaderComboBox, self.toolbar.readercombobox) def OnCloseFrame(self, evt): """Called when frame is closed, i.e. on wx.EVT_CLOSE""" evt.Skip() def OnExit(self, evt): """Called when frame application exits.""" self.Close(True) evt.Skip() def OnReaderComboBox(self, event): """Called when the user activates a reader in the toolbar combo box.""" cb = event.GetEventObject() reader = cb.GetClientData(cb.GetSelection()) if isinstance(reader, smartcard.reader.Reader.Reader): self.treeuserpanel.dialogpanel.OnActivateReader(reader) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/__init__.py0000644000175000017500000000337200000000000020213 0ustar00rousseaurousseau"""wxpython smartcard utility module. __author__ = "http://www.gemalto.com" Copyright 2001-2012 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. pyscard is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. pyscard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with pyscard; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ import imp import os.path import sys def main_is_frozen(): return(hasattr(sys, "frozen") or \ hasattr(sys, "importers") or \ imp.is_frozen("__main__")) ICO_SMARTCARD = None ICO_READER = None # running from a script, i.e. not running from standalone exe built with py2exe if not main_is_frozen(): ICO_SMARTCARD = os.path.join( os.path.dirname(__file__), 'resources', 'smartcard.ico') ICO_READER = os.path.join( os.path.dirname(__file__), 'resources', 'reader.ico') # runing from a standalone exe built with py2exe # resources expected images directory else: if os.path.exists(os.path.join("images", 'smartcard.ico')): ICO_SMARTCARD = os.path.join("images", 'smartcard.ico') if os.path.exists(os.path.join("images", 'reader.ico')): ICO_READER = os.path.join("images", 'reader.ico') ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1149986 pyscard-2.0.2/smartcard/wx/resources/0000755000175000017500000000000000000000000020107 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/resources/reader.ico0000644000175000017500000000047600000000000022054 0ustar00rousseaurousseau(( `ff`p38`x p`xppxxppxpxxxxpxpxp @?././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762666.0 pyscard-2.0.2/smartcard/wx/resources/smartcard.ico0000644000175000017500000000047600000000000022572 0ustar00rousseaurousseau(( 333s333{wwwwwws{s{swwwwsw{ww{w{swwwws{s{sww{wwws{{././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1632343237.1270046 pyscard-2.0.2/test/0000755000175000017500000000000000000000000014436 5ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1571762662.0 pyscard-2.0.2/test/__init__.py0000644000175000017500000000000000000000000016535 0ustar00rousseaurousseau././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398971.0 pyscard-2.0.2/test/test_ATR.py0000644000175000017500000001012000000000000016467 0ustar00rousseaurousseau# -*- coding: utf-8 -*- import sys import unittest from smartcard.ATR import ATR from smartcard.Exceptions import SmartcardException from smartcard.util import toBytes if sys.version_info >= (3, 0): from io import StringIO else: from StringIO import StringIO class TestUtil(unittest.TestCase): def setUp(self): self.held, sys.stdout = sys.stdout, StringIO() def test_ATR1(self): atr = [0x3F, 0x65, 0x25, 0x00, 0x2C, 0x09, 0x69, 0x90, 0x00] data_out = """TB1: 25 TC1: 0 supported protocols T=0 T=0 supported: True T=1 supported: False clock rate conversion factor: 372 bit rate adjustment factor: 1 maximum programming current: 50 programming voltage: 30 guard time: 0 nb of interface bytes: 2 nb of historical bytes: 5 """ a = ATR(atr) a.dump() output = sys.stdout.getvalue() self.assertEqual(output, data_out) def test_ATR2(self): atr = [0x3F, 0x65, 0x25, 0x08, 0x93, 0x04, 0x6C, 0x90, 0x00] data_out = """TB1: 25 TC1: 8 supported protocols T=0 T=0 supported: True T=1 supported: False clock rate conversion factor: 372 bit rate adjustment factor: 1 maximum programming current: 50 programming voltage: 30 guard time: 8 nb of interface bytes: 2 nb of historical bytes: 5 """ a = ATR(atr) a.dump() output = sys.stdout.getvalue() self.assertEqual(output, data_out) def test_ATR3(self): atr = [0x3B, 0x16, 0x94, 0x7C, 0x03, 0x01, 0x00, 0x00, 0x0D] data_out = """TA1: 94 supported protocols T=0 T=0 supported: True T=1 supported: False clock rate conversion factor: 512 bit rate adjustment factor: 8 maximum programming current: 50 programming voltage: 5 guard time: None nb of interface bytes: 1 nb of historical bytes: 6 """ a = ATR(atr) a.dump() output = sys.stdout.getvalue() self.assertEqual(output, data_out) def test_ATR4(self): atr = [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03] data_out = """TB1: 0 TC1: 0 supported protocols T=0 T=0 supported: True T=1 supported: False clock rate conversion factor: 372 bit rate adjustment factor: 1 maximum programming current: 25 programming voltage: 5 guard time: 0 nb of interface bytes: 2 nb of historical bytes: 5 """ a = ATR(atr) a.dump() output = sys.stdout.getvalue() self.assertEqual(output, data_out) def test_ATR5(self): atr = [0x3B, 0xE3, 0x00, 0xFF, 0x81, 0x31, 0x52, 0x45, 0xA1, 0xA2, 0xA3, 0x1B] data_out = """TB1: 0 TC1: ff TD1: 81 TD2: 31 TA3: 52 TB3: 45 supported protocols T=1 T=0 supported: False T=1 supported: True checksum: 27 clock rate conversion factor: 372 bit rate adjustment factor: 1 maximum programming current: 25 programming voltage: 5 guard time: 255 nb of interface bytes: 6 nb of historical bytes: 3 """ a = ATR(atr) a.dump() output = sys.stdout.getvalue() self.assertEqual(output, data_out) def test_ATR6(self): atr = [0x3B, 0xE5, 0x00, 0x00, 0x81, 0x21, 0x45, 0x9C, 0x10, 0x01, 0x00, 0x80, 0x0D] data_out = """TB1: 0 TC1: 0 TD1: 81 TD2: 21 TB3: 45 supported protocols T=1 T=0 supported: False T=1 supported: True checksum: 13 clock rate conversion factor: 372 bit rate adjustment factor: 1 maximum programming current: 25 programming voltage: 5 guard time: 0 nb of interface bytes: 5 nb of historical bytes: 5 """ a = ATR(atr) a.dump() output = sys.stdout.getvalue() self.assertEqual(output, data_out) def test_ATR_TS(self): atr = [0x42] self.assertRaises(SmartcardException, ATR, atr) def test_ATR_get(self): atr = "3B F2 95 12 34 01 36 06" a = ATR(toBytes(atr)) self.assertEqual(a.getTA1(), 0x95) self.assertEqual(a.getTB1(), 0x12) self.assertEqual(a.getTC1(), 0x34) self.assertEqual(a.getTD1(), 0x01) self.assertEqual(a.getHistoricalBytes(), [0x36, 0x06]) self.assertFalse(a.isT15Supported()) self.assertEqual(str(a), atr) if __name__ == '__main__': unittest.main(buffer=True) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632343066.0 pyscard-2.0.2/test/test_Exceptions.py0000644000175000017500000000356600000000000020202 0ustar00rousseaurousseau# -*- coding: utf-8 -*- # to execute: # $ cd test # $ python -m unittest import unittest from smartcard.Exceptions import * from smartcard.scard import * from distutils.util import get_platform class TestUtil(unittest.TestCase): def test_Exceptions(self): exc = SmartcardException() self.assertEqual(exc.hresult, -1) def test_ListReadersException(self): exc = ListReadersException(0) self.assertEqual(exc.hresult, 0) text = str(exc) if not get_platform().startswith('win'): self.assertEqual(text, "Failed to list readers: Command successful. (0x00000000)") exc = ListReadersException(0x42) self.assertEqual(exc.hresult, 0x42) text = str(exc) if not get_platform().startswith('win'): self.assertEqual(text, "Failed to list readers: Unknown error: 0x00000042 (0x00000042)") exc = ListReadersException(SCARD_S_SUCCESS) self.assertEqual(exc.hresult, 0) exc = ListReadersException(SCARD_E_NO_SERVICE) self.assertEqual(exc.hresult, SCARD_E_NO_SERVICE) text = str(exc) if not get_platform().startswith('win'): self.assertEqual(text, "Failed to list readers: Service not available. (0x8010001D)") def test_NoReadersException(self): exc = NoReadersException() self.assertEqual(exc.hresult, -1) text = str(exc) self.assertEqual(text, "No reader found") def test_InvalidReaderException(self): exc = InvalidReaderException("foobar") self.assertEqual(exc.hresult, -1) text = str(exc) self.assertEqual(text, "Invalid reader: foobar") def test_CardConnectionException(self): exc= CardConnectionException() self.assertEqual(exc.hresult, -1) text = str(exc) self.assertEqual(text, "") if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398981.0 pyscard-2.0.2/test/test_SCardGetErrorMessage.py0000644000175000017500000000202600000000000022022 0ustar00rousseaurousseau# -*- coding: utf-8 -*- # to execute: # $ cd test # $ python -m unittest import unittest from smartcard.scard import SCardGetErrorMessage from smartcard.scard import SCARD_S_SUCCESS, SCARD_F_INTERNAL_ERROR from distutils.util import get_platform class TestError(unittest.TestCase): def test_SCardGetErrorMessage(self): res = SCardGetErrorMessage(SCARD_S_SUCCESS) # do not test on Windows # the error messages are different and localized if get_platform() in ('win32', 'win-amd64'): return expected = "Command successful." self.assertEqual(res, expected) res = SCardGetErrorMessage(SCARD_F_INTERNAL_ERROR) expected = "Internal error." self.assertEqual(res, expected) res = SCardGetErrorMessage(1) expected = "Unknown error: 0x00000001" # macOS bug not yet fixed macos_bug_expected = "Unkown error: 0x00000001" self.assertIn(res, [expected, macos_bug_expected]) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1623398986.0 pyscard-2.0.2/test/test_util.py0000644000175000017500000001151700000000000017031 0ustar00rousseaurousseau# -*- coding: utf-8 -*- # to execute: # $ cd test # $ python -m unittest import unittest from smartcard.util import * class TestUtil(unittest.TestCase): def test_toBytes(self): data_in = "3B 65 00 00 9C 11 01 01 03" data_out = [59, 101, 0, 0, 156, 17, 1, 1, 3] self.assertEqual(toBytes(data_in), data_out) data_in = "3B6500009C11010103" self.assertEqual(toBytes(data_in), data_out) data_in = "3B6500 009C1101 0103" self.assertEqual(toBytes(data_in), data_out) data_in = ''' 3B 65 00 00 9C 11 01 01 03 ''' self.assertEqual(toBytes(data_in), data_out) data_in = "zz" self.assertRaises(TypeError, toBytes, data_in) def test_padd(self): data_in = toBytes("3B 65 00 00 9C 11 01 01 03") data_out = [0x3B, 0x65, 0, 0, 0x9C, 0x11, 1, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] self.assertEqual(padd(data_in, 16), data_out) def test_toASCIIBytes(self): data_in = "Number 101" data_out = [0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x20, 0x31, 0x30, 0x31] self.assertEqual(toASCIIBytes(data_in), data_out) def test_toASCIIString(self): data_in = [0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x20, 0x31, 0x30, 0x31] data_out = "Number 101" self.assertEqual(toASCIIString(data_in), data_out) data_in = [0x01, 0x20, 0x80, 0x7E, 0xF0] data_out = ". .~." self.assertEqual(toASCIIString(data_in), data_out) def test_toGSM3_38Bytes(self): data_in = "@Pascal" data_out = [0x00, 0x50, 0x61, 0x73, 0x63, 0x61, 0x6C] self.assertEqual(toGSM3_38Bytes(data_in), data_out) data_in = u"@ùPascal" data_out = [0x00, 0x06, 0x50, 0x61, 0x73, 0x63, 0x61, 0x6C] self.assertEqual(toGSM3_38Bytes(data_in), data_out) data_in = u"@ùPascal".encode('iso8859-1') data_out = [0x00, 0x06, 0x50, 0x61, 0x73, 0x63, 0x61, 0x6C] self.assertEqual(toGSM3_38Bytes(data_in), data_out) data_in = "1234" data_out = [0x31, 0x32, 0x33, 0x34] self.assertEqual(toGSM3_38Bytes(data_in), data_out) def test_toHexString(self): data_in = [] data_out = "" self.assertEqual(toHexString(data_in), data_out) data_in = 42 self.assertRaises(TypeError, toHexString, data_in) data_in = [0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03] data_out = "3B 65 00 00 9C 11 01 01 03" self.assertEqual(toHexString(data_in), data_out) data_out = "3B, 65, 00, 00, 9C, 11, 01, 01, 03" self.assertEqual(toHexString(data_in, COMMA), data_out) data_out = "0x3B 0x65 0x00 0x00 0x9C 0x11 0x01 0x01 0x03" self.assertEqual(toHexString(data_in, HEX), data_out) data_out = "0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03" self.assertEqual(toHexString(data_in, HEX | COMMA), data_out) data_out = "0X3B 0X65 0X00 0X00 0X9C 0X11 0X01 0X01 0X03" self.assertEqual(toHexString(data_in, HEX | UPPERCASE), data_out) data_out = "0X3B, 0X65, 0X00, 0X00, 0X9C, 0X11, 0X01, 0X01, 0X03" self.assertEqual(toHexString(data_in, HEX | UPPERCASE | COMMA), data_out) data_out = "3B6500009C11010103" self.assertEqual(toHexString(data_in, PACK), data_out) data_out = "3B,65,00,00,9C,11,01,01,03" self.assertEqual(toHexString(data_in, COMMA | PACK), data_out) data_out = "0x3B0x650x000x000x9C0x110x010x010x03" self.assertEqual(toHexString(data_in, HEX | PACK), data_out) data_out = "0x3B,0x65,0x00,0x00,0x9C,0x11,0x01,0x01,0x03" self.assertEqual(toHexString(data_in, HEX | COMMA | PACK), data_out) data_out = "0X3B0X650X000X000X9C0X110X010X010X03" self.assertEqual(toHexString(data_in, HEX | UPPERCASE | PACK), data_out) data_out = "0X3B,0X65,0X00,0X00,0X9C,0X11,0X01,0X01,0X03" self.assertEqual(toHexString(data_in, HEX | UPPERCASE | COMMA | PACK), data_out) def test_HexListToBinString(self): data_in = [1, 2, 3] data_out = "\x01\x02\x03" self.assertEqual(HexListToBinString(data_in), data_out) def test_BinStringToHexList(self): data_in = "\x01\x02\x03" data_out = [1, 2, 3] self.assertEqual(BinStringToHexList(data_in), data_out) def test_hl2bs(self): data_in = [78, 117, 109, 98, 101, 114, 32, 49, 48, 49] data_out = 'Number 101' self.assertEqual(hl2bs(data_in), data_out) def test_bs2hl(self): data_in = 'Number 101' data_out = [78, 117, 109, 98, 101, 114, 32, 49, 48, 49] self.assertEqual(bs2hl(data_in), data_out) if __name__ == '__main__': unittest.main()