Ejemplo n.º 1
0
def upload(pathtocap, aid, blocksize=250, clains='80E8'):
    ''' Upload a cap file.
    
        will send INSTALL for load & LOAD Command
    '''
    caps = a2b(api_cap.CAPFile(pathtocap).readAllCap(GP_List))
    lgth = len(caps)
    c4 = a2b('C4' + getBERTLVlengthfield(lgth)) + caps
    lgth = len(c4)

    blocks = [c4[i:i + blocksize] for i in range(0, lgth, blocksize)]
    assert len(''.join(blocks)) == lgth
    assert len(blocks) <= 0x100
    apdus = [
        ''.join([clains, '00%.2X' % i,
                 '%.2X' % len(b),
                 b2a(b)]) for i, b in enumerate(blocks)
    ]

    lastblock = apdus[-1]
    apdus[-1] = '80E880' + lastblock[6:]

    installforload(aid)

    for apdu in apdus[:-1]:
        api_pcsc.send(apdu, expectData='', expectSW='9000', name='LOAD')
    api_pcsc.send(apdus[-1], expectData='00', expectSW='9000', name='LOAD')
Ejemplo n.º 2
0
def installforinstall(loadfileaid,
                      moduleaid,
                      appletaid,
                      privileges='00',
                      param='',
                      token='',
                      header='80E60400'):
    ''' 9.5.2.3.2  Data Field for INSTALL [for install]

        Mandatory  1  Length of Executable Load File AID 
        Mandatory  5-16  Executable Load File AID 
        Mandatory  1  Length of Executable Module AID 
        Mandatory 5-16  Executable Module AID 
        Mandatory  1  Length of Application AID 
        Mandatory 5-16  Application AID 
        Mandatory  1  Length of Application Privileges 
        Mandatory 1  Application Privileges 
        Mandatory  1  Length of install parameters field 
        Mandatory 2-n  Install parameters field 
        Mandatory  1  Length of Install Token 
        Conditional  0-n  Install Token
    '''
    lst = (loadfileaid, moduleaid, appletaid, privileges, ('C9' + lv(param)),
           token)
    data = ''.join(map(lv, lst))
    apdu = header + lv(data)

    return api_pcsc.send(apdu,
                         expectSW='9000',
                         info='',
                         name='INSTALL for install')
Ejemplo n.º 3
0
def installforload(aid,
                   securitydomainaid=CardManagerAID,
                   datablockhash='',
                   param='',
                   token='',
                   header='80E60200'):
    ''' 9.5.2.3.1  Data Field for INSTALL [for load]

        Mandatory  1  Length of Load File AID 
        Mandatory 5-16  Load File AID 
        Mandatory  1  Length of Security Domain AID 
        Conditional  0-16  Security Domain AID 
        Mandatory  1  Length of Load File Data Block Hash 
        Conditional  0-n  Load File Data Block Hash 
        Mandatory  1  Length of load parameters field 
        Conditional  0-n  Load parameters field 
        Mandatory  1  Length of Load Token 
        Conditional 0-n  Load Token
    '''
    lst = (aid, securitydomainaid, datablockhash, param, token)
    data = ''.join(map(lv, lst))
    apdu = header + lv(data)

    return api_pcsc.send(apdu,
                         expectData='00',
                         expectSW='9000',
                         info='',
                         name='INSTALL for load')
Ejemplo n.º 4
0
def extauth(s_enc,
            s_mac,
            seq,
            cardchallenge,
            hostchallenge,
            level='00',
            expectSW='9000',
            info='',
            name='GP, EXTERNAL AUTHENTICATE'):
    ''' 

        See <E.5.2  EXTERNAL AUTHENTICATE Command> of [1].
    '''

    sk_enc = getEncryptSkey(s_enc, seq)
    sk_cmac = getCMACSkey(s_mac, seq)
    hostcryptogram = computeHostCryptogram(sk_enc, seq, hostchallenge,
                                           cardchallenge)

    header = '8482%s0010' % level
    pt = header + hostcryptogram
    cmac = generateCMAC(pt, sk_cmac)
    apdu = pt + cmac

    return api_pcsc.send(apdu, expectSW=expectSW, info=info, name=name)
Ejemplo n.º 5
0
 def erasepage(self, start, end, erasevector=False):
     if not erasevector:
         if start == 0:
             raise ValueError(u'请注意!请谨慎擦除CIU98428F的首页')
     return api_pcsc.send('BFEE00FF04%.4X%.4X' %
                          (start & 0xFFFF, end & 0xFFFF),
                          info='Erase Page')
Ejemplo n.º 6
0
 def setseed(self, seed):
     ''' seed should be hexdigits string '''
     lgth = len(seed) / 2
     r, sw = api_pcsc.send('00010000%.2X%s' % (lgth & 0xFF, seed.upper()),
                           expectSW='9000',
                           name='set SEED')
     return self  # return self to enable chain-operation
Ejemplo n.º 7
0
 def exchange_raw(self, rawdata, expected_length):
     ''' 6.3.5.7. CONTACT_EXCHANGE_RAW
     '''
     lgth = len(rawdata) / 2
     msb1, lsb1 = '%.2X'%((lgth>>8)&0xFF), '%.2X'%(lgth&0xFF)
     msb2, lsb2 = '%.2X'%((expected_length>>8)&0xFF), '%.2X'%(expected_length&0xFF)
     apdu = '10' +lsb1+msb1 +lsb2+msb2 + rawdata
     return api_pcsc.send(self.ESCAPE + '%.2X'%(len(apdu)/2) + apdu, expectSW='9000', name='CONTACT_EXCHANGE_RAW')
Ejemplo n.º 8
0
 def plaindownload(self, start, data):
     lgth = len(data)
     if lgth > 256 * 2:
         raise ValueError(u'写入数据太长 %d/2,一条APDU最多允许256字节' % lgth)
     else:
         apdu = 'B' + data[-2] + '7' + data[-1] + '%.4X' % (
             start & 0xFFFF) + '%.2X' % (lgth / 2 - 1) + data[:-2]
         return api_pcsc.send(apdu,
                              info='Plain Download, %d bytes' % (lgth / 2))
Ejemplo n.º 9
0
 def enable_class(self, a, b, c):
     ''' 6.3.5.1. CONTACT_GET_SET_PWR_UP_SEQUENCE
     '''
     bitmap = 0
     bitmap = bitmap|0x01 if a else bitmap&0xFE
     bitmap = bitmap|0x02 if b else bitmap&0xFD
     bitmap = bitmap|0x04 if c else bitmap&0xFB
     apdu = '04' + '09' + '%.2X'%(bitmap&0xFF)
     return api_pcsc.send(self.ESCAPE + '03' + apdu, expectSW='9000', name='CONTACT_GET_SET_PWR_UP_SEQUENCE')
Ejemplo n.º 10
0
def deleteaid(aid, related=False, expectSW='9000'):
    ''' The DELETE command is used to delete a uniquely identifiable object such as an Executable Load File, an 
        Application, optionally an Executable Load File and its related Applications.

        Deletion of Key is not yet supported.
    '''
    header = '80E40080' if related else '80E40000'
    data = '4F' + lv(aid)
    apdu = header + lv(data)
    return api_pcsc.send(apdu, expectSW=expectSW, info='', name='Delete AID')
Ejemplo n.º 11
0
def select(aid,
           expectData='',
           expectSW='9000',
           info='',
           name='GP, Select AID',
           header='00A40400'):
    ''' Select File (INS : 'A4')
    '''
    return api_pcsc.send(header + lv(aid),
                         expectData=expectData,
                         expectSW=expectSW,
                         info=info,
                         name=name)
Ejemplo n.º 12
0
 def set_clock_divison(self, divison):
     ''' 6.3.5.8. CONTACT_GET_SET_CLK_FREQUENCY
             DIVISOR VALUE   SCCLK Frequency
             12              4 MHz
             10              4.8 MHz
             8               6 MHz
             7               6.8 MHz
             6               8 MHz
             5               9.6 MHz
             4               12 MHz
             3               16 MHz
     '''
     apdu = '1F' + '%.2X' % (divison&0xFF)
     return api_pcsc.send(self.ESCAPE + '02' + apdu, expectSW='9000', name='CONTACT_SET_CLK_FREQUENCY')
Ejemplo n.º 13
0
def initupdate(key_version_number='00',
               host_challenge='',
               s_enc='',
               apduheader='8050000008',
               expectData='',
               expectSW='9000',
               info='',
               name='GP, INITIALIZE-UPDATE'):
    ''' 
        key_version_number: the Key Version Number within the Security Domain to
            be used to initiate the Secure Channel Session. If this value is
            zero, the first available key chosen by the Security Domain will be used.

        Returns a tuple of 2 element: ((kdiv, kver, scpid, seq, cardchallenge, cardcryptogram, hostchallenge), sw).

        Key diversification data  10 bytes 
        Key version number  1 bytes 
        Secure Channel Protocol identifier 1 bytes 
        Sequence Counter  2 bytes 
        Card challenge  6 bytes 
        Card cryptogram  8 bytes
        Host challenge 8 bytes

        See <E.5.1  INITIALIZE UPDATE Command> of [1].
    '''

    if host_challenge:
        r = host_challenge[:]
    else:
        r = api_general.randhex(8)

    apdu = apduheader + r
    response_data, sw = api_pcsc.send(apdu,
                                      expectSW=expectSW,
                                      info=info,
                                      name=name)
    ret = a2b(response_data)
    kdiv, kver, scpid, seq, cardchallenge, cardcryptogram = [
        b2a(ret[a:b])
        for a, b in ((0, 10), (10, 11), (11, 12), (12, 14), (14, 20), (20, 28))
    ]
    if s_enc:
        sk_enc = getEncryptSkey(s_enc, seq)
        verifyCardCryptogram(r, seq, cardchallenge, cardcryptogram, sk_enc)

    t = (kdiv, kver, scpid, seq, cardchallenge, cardcryptogram, r)
    LogMessage(
        'Init-update, (kdiv, kver, scpid, seq, cardchallenge, cardcryptogram, hostchallenge): %s'
        % str(t).upper())
    return t, sw
Ejemplo n.º 14
0
    def cipherdownload(self, start, data, key=KEY):
        lgth = len(data)
        lgth1 = (lgth / 2 + 7) % 8  # 填充后长度
        if lgth > 256 * 2 or lgth1 > 256:
            raise ValueError(u'写入数据太长 %d/2,一条APDU最多允许256字节' % lgth)
        else:
            data1 = a2b(data)
            if len(data1) % 8:
                padding = '\xFF' * (8 - len(data1) % 8)
                data1 = data1 + padding
            des = DES.new(a2b(key), DES.MODE_ECB, None)
            cipher = b2a(des.encrypt(a2b(data1)))

            apdu = 'B' + cipher[-2] + 'B' + cipher[-1] + '%.4X' % (
                start & 0xFFFF) + '%.2X' % (len(cipher) - 1) + cipher[:-2]
            return api_pcsc.send(apdu,
                                 info='Write Flash, %d bytes, %s' %
                                 (lgth / 2, data))
Ejemplo n.º 15
0
 def setKey(self, mode, val):  #0 : des_64 1:des_128 2:des_192
     return api_pcsc.send('0000%.2X00%.2X%s' % (mode, len(val) / 2, val),
                          name='setkey')
Ejemplo n.º 16
0
 def seticv(self, icv):
     return api_pcsc.send('0001000008%s' % icv, name='seticv')
Ejemplo n.º 17
0
 def initDec(self, mode, paddingMode):
     return api_pcsc.send('0004%.2X%.2X00' % (mode, paddingMode),
                          name='initDec')
Ejemplo n.º 18
0
 def buildCipher(self, cipher, mode):
     return api_pcsc.send('000A%.2X%.2X00' % (cipher, mode),
                          name='buildcipher')
Ejemplo n.º 19
0
 def clearKey(self, nkey):  #0 : des_64 1:des_128 2:des_192
     return api_pcsc.send('0008%.2X0000' % nkey, name='clearKey')
Ejemplo n.º 20
0
 def update(self):
     return api_pcsc.send('0006000000', name='update')
Ejemplo n.º 21
0
 def chooseKey(self, nkey):  #0 : des_64 1:des_128 2:des_192
     return api_pcsc.send('0002%.2X0000' % nkey, name='chooseKey')
Ejemplo n.º 22
0
 def checkdata(self, start, end, crc, expectSW='9000'):
     return api_pcsc.send('BF42000006%.4X%.4X%s' %
                          (start & 0xFFFF, end & 0xFFFF, crc),
                          expectSW=expectSW,
                          info='Check Data')
Ejemplo n.º 23
0
 def dofinal(self, data):
     return api_pcsc.send('00050000%.2X%s' % (len(data) / 2, data),
                          name='dofinal')
Ejemplo n.º 24
0
 def request(self):
     return api_pcsc.send('BF48020020', info='Read Factory Information')
Ejemplo n.º 25
0
 def getAlgorithm(self, mode):
     return api_pcsc.send('000700%.2X01' % mode, name='getAlgorithm')
Ejemplo n.º 26
0
 def verifypin(self, pin=PIN, expectSW='9000'):
     return api_pcsc.send('BF20000108' + pin,
                          expectSW=expectSW,
                          info='Verify PIN')
Ejemplo n.º 27
0
 def buildKey(self, deskey, key_lgth):
     return api_pcsc.send('0009%.2X%.2X00' % (deskey, key_lgth),
                          name='buildKey')
Ejemplo n.º 28
0
 def changepin(self, old, new):
     return api_pcsc.send('BF24000010' + old + new, info='Change PIN')
Ejemplo n.º 29
0
 def send(self, apdu, expectData='', expectSW=SW_NO_ERROR):
     ''' 对pcsc send函数的简单封装,设定期望状态字为9000
     '''
     return api_pcsc.send(apdu, expectData='', expectSW=expectSW)
Ejemplo n.º 30
0
 def changekey(self, old, new):
     des = DES.new(a2b(old), DES.MODE_ECB, None)
     cipher = des.encrypt(a2b(new + '80' + '00' * 7))
     return api_pcsc.send('BF24010010' + b2a(cipher),
                          info='Change Key, new key ' + new)