Beispiel #1
0
    def __init__(self, cardConnectionComponent):
        """Construct a new remote card connection.

        connection: the reader connection
        """
        Pyro.core.ObjBase.__init__(self)
        CardConnectionDecorator.__init__(self, cardConnectionComponent)
Beispiel #2
0
    def mut_auth(self, SL, logCh=0, **kw):
        """ Perform mutual authentication.
Optional paramters in kw:
 - host_challenge
 """
        # select SD
        self.scp.logCh = logCh
        aid = self.scp.SD_AID
        cla = self.scp.CLA(False, 0)
        apdu = [ cla, 0xA4, 0x04, 0, len( aid ) ] + \
               [ ord( x ) for x in aid ]
        resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        if sw1 == 0x61:
            apdu = [cla, 0xC0, 0, 0, sw2]
            resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        sw = (sw1 << 8) + sw2
        if sw != 0x9000: raise ISOException(sw)

        # Initial update
        host_challenge = kw.get('host_challenge', '\0' * 8)
        apdu = self.scp.initUpdate(host_challenge, logCh)
        resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        if sw1 == 0x61:
            apdu = [cla, 0xC0, 0, 0, sw2]
            resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        sw = (sw1 << 8) + sw2
        if sw != 0x9000: raise ISOException(sw)
        # parse response to initial update in order to derive keys
        self.scp.parseInitUpdateResp(resp)

        # External authenticate
        apdu = self.scp.extAuth(SL)
        resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        sw = (sw1 << 8) + sw2
        if sw != 0x9000: raise ISOException(sw)
Beispiel #3
0
    def __init__(self, cardConnectionComponent):
        """Construct a new remote card connection.

        connection: the reader connection
        """
        Pyro.core.ObjBase.__init__(self)
        CardConnectionDecorator.__init__(self, cardConnectionComponent)
    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 None != component.hcard:
                    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
Beispiel #5
0
    def mut_auth( self, SL, logCh = 0, **kw ):
        """ Perform mutual authentication.
Optional paramters in kw:
 - host_challenge
 """
        # select SD
        self.scp.logCh = logCh
        aid = self.scp.SD_AID
        cla = self.scp.CLA( False, 0 )
        apdu = [ cla, 0xA4, 0x04, 0, len( aid ) ] + \
               [ ord( x ) for x in aid ]
        resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        if sw1 == 0x61:
            apdu = [ cla, 0xC0, 0, 0, sw2 ]
            resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        sw = ( sw1 << 8 ) + sw2
        if sw != 0x9000 : raise ISOException( sw )

        # Initial update
        host_challenge = kw.get( 'host_challenge', '\0'*8 )
        apdu = self.scp.initUpdate( host_challenge, logCh )
        resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        if sw1 == 0x61:
            apdu = [ cla, 0xC0, 0, 0, sw2 ]
            resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        sw = ( sw1 << 8 ) + sw2
        if sw != 0x9000 : raise ISOException( sw )
        # parse response to initial update in order to derive keys
        self.scp.parseInitUpdateResp( resp )

        # External authenticate
        apdu = self.scp.extAuth( SL )
        resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        sw = ( sw1 << 8 ) + sw2
        if sw != 0x9000 : raise ISOException( sw )
Beispiel #6
0
def read_sector(connection: CardConnectionDecorator, sector_num: int):
    COMMAND = [
        0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, sector_num * 4, 0x60, 0x00
    ]
    data, sw1, sw2 = connection.transmit(COMMAND)
    if (sw1, sw2) == (0x90, 0x0):
        pass
    elif (sw1, sw2) == (0x63, 0x0):
        COMMAND[8] = 0x61
        data, sw1, sw2 = connection.transmit(COMMAND)
        if (sw1, sw2) == (0x90, 0x0):
            pass
        else:
            return False
    sector_data = b""
    for block in range(sector_num * 4, sector_num * 4 + 4):
        COMMAND = [0xFF, 0xB0, 0x00]
        COMMAND.append(block)
        COMMAND.append(16)
        data, sw1, sw2 = connection.transmit(COMMAND)
        sector_data += bytes(data)
    print((sw1, sw2))
    if (sw1, sw2) == (0x90, 0x0):
        return sector_data
    else:
        return False
    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
Beispiel #8
0
 def __init__(self, connection, **kw):
     self.scp = SCP02(**kw)
     self.connection = connection
     CardConnectionDecorator.__init__(self, connection)
     if 'GAFdict' in kw:
         assert isinstance(kw['GAFdict'], dict), "GAF dictionary expected"
         self.objects = kw['GAFdict']
     else:
         self.objects = {}
Beispiel #9
0
 def send(self, templ, **kw):
     objects = self.objects.copy()
     objects.update(kw)
     sapdu = GAF(templ).eval(**objects)
     apdu = s2l(sapdu)
     assert 5 <= len(apdu) and len(apdu) <= 260, "Wrong APDU length %d, '%s'" % (len(apdu), hexlify(sapdu))
     resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
     if sw1 == 0x6C and len(apdu) == 5:
         apdu[4] = sw2
         resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
     elif sw1 == 0x61:
         apdu = [0, 0xC0, 0, 0, sw2]
         resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
     sw = (sw1 << 8) + sw2
     return l2s(resp), sw
 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
Beispiel #11
0
def getuid(connection: CardConnectionDecorator):
    data, sw1, sw2 = connection.transmit(cmdMap["getuid"])
    uid = toHexString(data).replace(" ", "")
    if (sw1, sw2) == (0x90, 0x0):
        return uid
    else:
        return None
Beispiel #12
0
 def send( self, templ, **kw ):
     objects = self.objects.copy()
     objects.update( kw )
     sapdu = GAF( templ ).eval( **objects )
     apdu = s2l( sapdu )
     assert 5 <= len( apdu ) and len( apdu ) <= 260,\
         "Wrong APDU length %d, '%s'" % ( len(apdu), hexlify( sapdu ))
     resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
     if sw1 == 0x6C and len( apdu ) == 5:
         apdu[4] = sw2
         resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
     elif sw1 == 0x61:
         apdu = [ 0, 0xC0, 0, 0, sw2 ]
         resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
     sw = ( sw1 << 8 ) + sw2
     return l2s( resp ), sw
Beispiel #13
0
 def transmit(self, apdu, protocol=None):
     """ Wrap APDU and transmit to the card. """
     apdu_w = self.scp.wrapAPDU(apdu)
     resp, sw1, sw2 = CardConnectionDecorator.transmit(
         self, apdu_w, protocol)
     if sw1 == 0x61:
         resp, sw1, sw2 = self.getResponse(sw2)
     return resp, sw1, sw2
Beispiel #14
0
 def transmit( self, apdu, protocol=None):
     """ Wrap APDU and transmit to the card. """
     apdu_w = self.scp.wrapAPDU( apdu )
     resp, sw1, sw2 = CardConnectionDecorator.transmit( self,
                                                        apdu_w, protocol )
     if sw1 == 0x61:
         resp, sw1, sw2 = self.getResponse( sw2 )
     return resp, sw1, sw2
Beispiel #15
0
 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
Beispiel #16
0
    def mut_auth( self, SL, **kw ):
        """ Perform mutual authentication.
Optional paramters in kw:
logCh          - logical channel (u8, default 0)
host_challenge - string 8B long
aid            - AID to select (string, default self.scp)
                 (SD_AID for calculation is self.scp.SD_AID)
 """
        # select SD
        logCh = kw.get( 'logCh', 0 )
        assert 0 <= logCh and logCh < 20
        self.scp.logCh = logCh
        aid = kw.get( 'aid', self.scp.SD_AID )
        assert 5 <= len( aid ) and len( aid ) <= 16
        cla = self.scp.CLA( False, b8 = 0 )
        apdu = [ cla, 0xA4, 0x04, 0, len( aid ) ] + \
               [ ord( x ) for x in aid ]
        resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        if sw1 == 0x61:
            apdu = [ cla, 0xC0, 0, 0, sw2 ]
            resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        sw = ( sw1 << 8 ) + sw2
        if sw != 0x9000:
            raise ISOerror( "NOK: SW = %04X", sw )

        # Initial update
        host_challenge = kw.get( 'host_challenge', '\0'*8 )
        assert len( host_challenge ) == 8
        apdu = self.scp.initUpdate( host_challenge, logCh )
        resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        # Case 4 command, expects 61xx
        assert sw1 == 0x61
        resp, sw1, sw2 = self.getResponse( sw2 )
        sw = ( sw1 << 8 ) + sw2
        if sw != 0x9000:
            raise ISOerror( "NOK: SW = %04X", sw )
        # check response to initial update, may raise exception
        self.scp.parseInitUpdateResp( resp )

        # External authenticate
        apdu = self.scp.extAuth( SL )
        resp, sw1, sw2 = CardConnectionDecorator.transmit( self, apdu )
        sw = ( sw1 << 8 ) + sw2
        if sw != 0x9000:
            raise ISOerror( "NOK: SW = %04X", sw )
Beispiel #17
0
    def send(self, templ, **kw):
        """ Evaluate GAF and transmit as APDU
templ   - a GAF template to evaluate
kw      - GAF dictionary (updates dictionary from SCP02Connection.__init__)
Return (resp, SW) as (str, int)"""
        objects = self.objects.copy()
        objects.update(kw)
        papdu = s2l(GAF(templ).eval(**objects))
        apdu = self.scp.wrapAPDU(papdu)
        resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        if sw1 == 0x6C and len(papdu) == 5:
            papdu[4] = sw2
            apdu = self.scp.wrapAPDU(papdu)
            resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        elif sw1 == 0x61:
            resp, sw1, sw2 = self.getResponse(sw2)
        resp, sw1, sw2 = self.scp.unwrapResp(resp, sw1, sw2)
        sw = (sw1 << 8) + sw2
        return l2s(resp), sw
Beispiel #18
0
def getinfo(connection: CardConnectionDecorator) -> dict:
    atr = ATR(connection.getATR())
    hb = toHexString(atr.getHistoricalBytes())
    cardname = hb[-17:-12]
    name = cardnameMap.get(cardname, "Unknown " + str(cardname))
    return {
        "Name": name,
        "T0": atr.isT0Supported(),
        "T1": atr.isT1Supported(),
        "T15": atr.isT15Supported()
    }
Beispiel #19
0
def loadkey(connection: CardConnectionDecorator, key: str):
    COMMAND = cmdMap.get("loadkey")
    load_key = [key[0:2], key[2:4], key[4:6], key[6:8], key[8:10], key[10:12]]
    for i in range(6):
        load_key[i] = int(load_key[i], 16)
    COMMAND.extend(load_key)
    data, sw1, sw2 = connection.transmit(COMMAND)
    if (sw1, sw2) == (0x90, 0x0):
        return True
    elif (sw1, sw2) == (0x63, 0x0):
        return False
Beispiel #20
0
    def send(self, templ, **kw):
        """ Evaluate GAF and transmit as APDU
templ   - a GAF template to evaluate
kw      - GAF dictionary (updates dictionary from GAFConnection.__init__)
Return ( resp, SW ) as ( str, int )"""
        objects = self.objects.copy()
        objects.update(kw)
        sapdu = GAF(templ).eval(**objects)
        apdu = s2l(sapdu)
        assert 5 <= len( apdu ) and len( apdu ) <= 260,\
            "Wrong APDU length %d, '%s'" % ( len(apdu), hexlify( sapdu ))
        resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        if sw1 == 0x6C and len(apdu) == 5:
            apdu[4] = sw2
            resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        elif sw1 == 0x61:
            apdu = [0, 0xC0, 0, 0, sw2]
            resp, sw1, sw2 = CardConnectionDecorator.transmit(self, apdu)
        sw = (sw1 << 8) + sw2
        return l2s(resp), sw
Beispiel #21
0
 def __init__( self, connection, **kw ):
     self.scp = SCP03( **kw )
     self.connection = connection
     CardConnectionDecorator.__init__( self, connection )
Beispiel #22
0
def unmute(connection: CardConnectionDecorator):
    data, sw1, sw2 = connection.transmit(cmdMap["unmute"])
    if (sw1, sw2) == (0x90, 0x0):
        return True
    else:
        return False
 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:]
Beispiel #25
0
def firmver(connection: CardConnectionDecorator):
    data, sw1, sw2 = connection.transmit(cmdMap["firmver"])
    version = ''.join(chr(i) for i in data) + chr(sw1) + chr(sw2)
    return version
Beispiel #26
0
 def getATR(self):
     """Replace first BYTE of ATR by 3F"""
     atr = CardConnectionDecorator.getATR(self)
     return [0x3f] + atr[1:]
Beispiel #27
0
 def getResponse( self, sw2 ):
     """ Get Response from the last APDU."""
     apdu = [ self.scp.CLA( False, 0 ), 0xC0, 0, 0, sw2 ]
     return CardConnectionDecorator.transmit( self, apdu )
Beispiel #28
0
 def __init__(self, connection, **kw):
     self.objects = kw
     self.connection = connection
     CardConnectionDecorator.__init__(self, connection)
 def __init__(self, cardconnection):
     CardConnectionDecorator.__init__(self, cardconnection)
Beispiel #30
0
 def getResponse(self, sw2):
     """ Get Response from the last APDU."""
     apdu = [self.scp.CLA(False, 0), 0xC0, 0, 0, sw2]
     return CardConnectionDecorator.transmit(self, apdu)
Beispiel #31
0
 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
Beispiel #32
0
 def createConnection(self):
     """Return a card connection thru PCSC reader."""
     return CardConnectionDecorator(PCSCCardConnection(self.name))
Beispiel #33
0
 def __init__( self, connection, **kw ):
     self.scp = SCP02( **kw )
     self.connection = connection
     CardConnectionDecorator.__init__( self, connection )
 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
Beispiel #35
0
 def __init__(self, connection, **kw):
     self.objects = kw
     self.connection = connection
     CardConnectionDecorator.__init__(self, connection)