PCSC wrapper samples

Using the smartcard framework is the preferred way to write Python smart card application. You can however use the smartcard.scard library to write your Python smart card application if you want to write your own Python framework, or if you want to access some features of the SCardXXX C API not available in the smartcard framework.

The smartcard.scard module is a native extension module wrapping Windows smart card base components (also known as PCSC) on Windows, and pcsc-lite on Linux and Mac OS X, whereas the smartcard framework is a pure Python framework hiding scard complexity and PCSC.

send a Control Code to a card or reader

#! /usr/bin/env python
"""
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 __future__ import print_function
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)

get the ATR of a card

#! /usr/bin/env python
"""
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 __future__ import print_function
from smartcard.scard import *
import smartcard.util

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.')

import sys
if 'win32' == sys.platform:
    print('press Enter to continue')
    sys.stdin.read(1)

get the attributes of a card

#! /usr/bin/env python
"""
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
"""

from __future__ import print_function
import struct
from smartcard.scard import *
import smartcard.util

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.')

import sys
if 'win32' == sys.platform:
    print('press Enter to continue')
    sys.stdin.read(1)

wait for card insertion/removal

#! /usr/bin/env python
"""
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 __future__ import print_function
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)

list the cards introduced in the system

#! /usr/bin/env python
"""
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 __future__ import print_function
from smartcard.scard import *

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')


import sys
if 'win32' == sys.platform:
    print('press Enter to continue')
    sys.stdin.read(1)

list the interfaces supported by a card

#! /usr/bin/env python
"""
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
"""

from __future__ import print_function
import platform
from smartcard.scard import *
import smartcard.guid

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')


import sys
if 'win32' == sys.platform:
    print('press Enter to continue')
    sys.stdin.read(1)

locate cards in the system

#! /usr/bin/env python
"""
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 __future__ import print_function
from smartcard.scard import *

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')


import sys
if 'win32' == sys.platform:
    print('press Enter to continue')
    sys.stdin.read(1)

manage readers and reader groups

#! /usr/bin/env python
"""
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 __future__ import print_function
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)

list smart card readers

#! /usr/bin/env python
"""
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 __future__ import print_function
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)

select the DF_TELECOM of a SIM card

#! /usr/bin/env python
"""
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 __future__ import print_function
from smartcard.scard import *
import smartcard.util

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)

import sys
if 'win32' == sys.platform:
    print('press Enter to continue')
    sys.stdin.read(1)

perform a simple smart card transaction

#! /usr/bin/env python
"""
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 __future__ import print_function
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)