blob: 34c97c252a30803582b0516e0db382784cd91867 [file] [log] [blame]
Christina Quaste64aa5b2015-04-14 15:07:33 +02001#!/usr/bin/env python
2
Christina Quast79c2a3a2015-04-14 14:55:13 +02003# Code ported from simtrace host program apdu_split.c
4#
5# (C) 2010 by Harald Welte <hwelte@hmw-consulting.de>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2
9# as published by the Free Software Foundation
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16from enum import Enum
17
Christina Quastd4c8b512015-04-14 15:53:13 +020018class apdu_states(Enum):
Christina Quaste64aa5b2015-04-14 15:07:33 +020019 APDU_S_CLA = 1
20 APDU_S_INS = 2
21 APDU_S_P1 = 3
22 APDU_S_P2 = 4
23 APDU_S_P3 = 5
24 APDU_S_DATA = 6
25 APDU_S_DATA_SINGLE = 7
26 APDU_S_SW1 = 8
27 APDU_S_SW2 = 9
28 APDU_S_FIN = 10
Christina Quast79c2a3a2015-04-14 14:55:13 +020029
Christina Quastd4c8b512015-04-14 15:53:13 +020030class Apdu_splitter:
31
32 def __init__(self):
33 self.state = apdu_states.APDU_S_CLA
34 self.buf = []
Christina Quast79c2a3a2015-04-14 14:55:13 +020035
36 def func_APDU_S_INS(self, c):
37 self.ins = c
Christina Quast51925a62015-04-14 21:04:14 +020038 self.buf.append(c)
39 self.state = apdu_states(self.state.value + 1)
Christina Quast79c2a3a2015-04-14 14:55:13 +020040
41 def func_APDU_S_CLA_P1_P2(self, c):
42 self.buf.append(c)
Christina Quastd4c8b512015-04-14 15:53:13 +020043 self.state = apdu_states(self.state.value + 1)
Christina Quast79c2a3a2015-04-14 14:55:13 +020044
Christina Quaste64aa5b2015-04-14 15:07:33 +020045 def func_APDU_S_P3(self, c):
Christina Quast79c2a3a2015-04-14 14:55:13 +020046 self.buf.append(c)
Christina Quast51925a62015-04-14 21:04:14 +020047 self.data_remaining = 256 if c == 0 else c
Christina Quastd4c8b512015-04-14 15:53:13 +020048 self.state = apdu_states.APDU_S_SW1
Christina Quast79c2a3a2015-04-14 14:55:13 +020049
50 def func_APDU_S_DATA(self, c):
51 self.buf.append(c)
Christina Quast9547e9f2015-04-14 22:18:30 +020052 self.data.append(c)
Christina Quast79c2a3a2015-04-14 14:55:13 +020053 self.data_remaining -= 1
Christina Quast51925a62015-04-14 21:04:14 +020054 if self.data_remaining == 0:
Christina Quastd4c8b512015-04-14 15:53:13 +020055 self.state = apdu_states.APDU_S_SW1;
Christina Quast79c2a3a2015-04-14 14:55:13 +020056
57 def func_APDU_S_DATA_SINGLE(self, c):
58 self.buf.append(c)
59 self.data_remaining -= 1
Christina Quastd4c8b512015-04-14 15:53:13 +020060 self.state = apdu_states.APDU_S_SW1
Christina Quast79c2a3a2015-04-14 14:55:13 +020061
62 def func_APDU_S_SW1(self, c):
Christina Quaste64aa5b2015-04-14 15:07:33 +020063 if (c == 0x60):
Christina Quast79c2a3a2015-04-14 14:55:13 +020064 print("APDU_S_SW1: NULL")
65 else:
66 # check for 'all remaining' type ACK
67 if c == self.ins or c == self.ins + 1 or c == ~(self.ins+1):
68 print("ACK")
Christina Quastd4c8b512015-04-14 15:53:13 +020069 self.state = apdu_states.APDU_S_DATA
Christina Quast9547e9f2015-04-14 22:18:30 +020070 self.data = []
Christina Quast79c2a3a2015-04-14 14:55:13 +020071 else:
72 # check for 'only next byte' type ACK */
Christina Quaste64aa5b2015-04-14 15:07:33 +020073 if c == ~(self.ins):
Christina Quastd4c8b512015-04-14 15:53:13 +020074 self.state = apdu_states.APDU_S_DATA_SINGLE
Christina Quast79c2a3a2015-04-14 14:55:13 +020075 else:
76 # must be SW1
Christina Quast9547e9f2015-04-14 22:18:30 +020077 self.sw1 = c
Christina Quast79c2a3a2015-04-14 14:55:13 +020078 self.buf.append(c)
Christina Quastd4c8b512015-04-14 15:53:13 +020079 self.state = apdu_states.APDU_S_SW2
Christina Quast79c2a3a2015-04-14 14:55:13 +020080
Christina Quaste64aa5b2015-04-14 15:07:33 +020081 def func_APDU_S_SW2(self, c):
Christina Quast79c2a3a2015-04-14 14:55:13 +020082 self.buf.append(c)
Christina Quast9547e9f2015-04-14 22:18:30 +020083 self.sw2 = c
Christina Quast51925a62015-04-14 21:04:14 +020084 print("APDU:", hex(self.ins), ' '.join(hex(x) for x in self.buf))
Christina Quast9547e9f2015-04-14 22:18:30 +020085 self.state = apdu_states.APDU_S_FIN
Christina Quaste64aa5b2015-04-14 15:07:33 +020086
87 Apdu_S = {
Christina Quastd4c8b512015-04-14 15:53:13 +020088 apdu_states.APDU_S_CLA : func_APDU_S_CLA_P1_P2,
89 apdu_states.APDU_S_INS : func_APDU_S_INS,
90 apdu_states.APDU_S_P1 : func_APDU_S_CLA_P1_P2,
91 apdu_states.APDU_S_P2 : func_APDU_S_CLA_P1_P2,
92 apdu_states.APDU_S_P3 : func_APDU_S_P3,
93 apdu_states.APDU_S_DATA : func_APDU_S_DATA,
94 apdu_states.APDU_S_DATA_SINGLE : func_APDU_S_DATA_SINGLE,
95 apdu_states.APDU_S_SW1 : func_APDU_S_SW1,
96 apdu_states.APDU_S_SW2 : func_APDU_S_SW2 }
97
98 def split(self, c):
99 self.Apdu_S[self.state](self, c)
Christina Quaste64aa5b2015-04-14 15:07:33 +0200100
101
102if __name__ == '__main__':
Christina Quast51925a62015-04-14 21:04:14 +0200103 msg1 = [0xA0, 0xA4, 0x00, 0x00, 0x02, 0xA4, 0x7F, 0x20, 0x9F, 0x16]
104 msg2 = [0xA0, 0xC0, 0x00, 0x00, 0x16, 0xC0,
105 0x00, 0x00, 0x00, 0x00, 0x7F, 0x20,
106 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x09, 0x91, 0x00, 0x17, 0x04, 0x00, 0x00, 0x00,
108 0x83, 0x8A, 0x90, 0x00]
Christina Quast9547e9f2015-04-14 22:18:30 +0200109 apdus = []
110 apdu = Apdu_splitter()
Christina Quast51925a62015-04-14 21:04:14 +0200111 for c in msg2 + msg1:
Christina Quast9547e9f2015-04-14 22:18:30 +0200112 apdu.split(c)
113 if apdu.state == apdu_states.APDU_S_FIN:
114 apdus.append(apdu)
115 apdu = Apdu_splitter()
116 for a in apdus:
117 print(' '.join(hex(x) for x in a.buf))