blob: 50f1ed5e29554bdcd1bf29f20d10000951650c38 [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 Quast79c2a3a2015-04-14 14:55:13 +020030
Christina Quastd4c8b512015-04-14 15:53:13 +020031class Apdu_splitter:
32
33 def __init__(self):
34 self.state = apdu_states.APDU_S_CLA
35 self.buf = []
Christina Quast79c2a3a2015-04-14 14:55:13 +020036
37 def func_APDU_S_INS(self, c):
38 self.ins = c
39
40 def func_APDU_S_CLA_P1_P2(self, c):
41 self.buf.append(c)
Christina Quastd4c8b512015-04-14 15:53:13 +020042 self.state = apdu_states(self.state.value + 1)
Christina Quast79c2a3a2015-04-14 14:55:13 +020043
Christina Quaste64aa5b2015-04-14 15:07:33 +020044 def func_APDU_S_P3(self, c):
Christina Quast79c2a3a2015-04-14 14:55:13 +020045 self.buf.append(c)
Christina Quaste64aa5b2015-04-14 15:07:33 +020046 self.data_remaining = 256 if c == 0 else c
Christina Quastd4c8b512015-04-14 15:53:13 +020047 self.state = apdu_states.APDU_S_SW1
Christina Quast79c2a3a2015-04-14 14:55:13 +020048
49 def func_APDU_S_DATA(self, c):
50 self.buf.append(c)
51 self.data_remaining -= 1
52 if data_remaining == 0:
Christina Quastd4c8b512015-04-14 15:53:13 +020053 self.state = apdu_states.APDU_S_SW1;
Christina Quast79c2a3a2015-04-14 14:55:13 +020054
55 def func_APDU_S_DATA_SINGLE(self, c):
56 self.buf.append(c)
57 self.data_remaining -= 1
Christina Quastd4c8b512015-04-14 15:53:13 +020058 self.state = apdu_states.APDU_S_SW1
Christina Quast79c2a3a2015-04-14 14:55:13 +020059
60 def func_APDU_S_SW1(self, c):
Christina Quaste64aa5b2015-04-14 15:07:33 +020061 if (c == 0x60):
Christina Quast79c2a3a2015-04-14 14:55:13 +020062 print("APDU_S_SW1: NULL")
63 else:
64 # check for 'all remaining' type ACK
65 if c == self.ins or c == self.ins + 1 or c == ~(self.ins+1):
66 print("ACK")
Christina Quastd4c8b512015-04-14 15:53:13 +020067 self.state = apdu_states.APDU_S_DATA
Christina Quast79c2a3a2015-04-14 14:55:13 +020068 else:
69 # check for 'only next byte' type ACK */
Christina Quaste64aa5b2015-04-14 15:07:33 +020070 if c == ~(self.ins):
Christina Quastd4c8b512015-04-14 15:53:13 +020071 self.state = apdu_states.APDU_S_DATA_SINGLE
Christina Quast79c2a3a2015-04-14 14:55:13 +020072 else:
73 # must be SW1
74 self.buf.append(c)
Christina Quastd4c8b512015-04-14 15:53:13 +020075 self.state = apdu_states.APDU_S_SW2
Christina Quast79c2a3a2015-04-14 14:55:13 +020076
Christina Quaste64aa5b2015-04-14 15:07:33 +020077 def func_APDU_S_SW2(self, c):
Christina Quast79c2a3a2015-04-14 14:55:13 +020078 self.buf.append(c)
Christina Quaste64aa5b2015-04-14 15:07:33 +020079 print("APDU:", self.buf)
Christina Quastd4c8b512015-04-14 15:53:13 +020080 self.state = apdu_states.APDU_S_FIN
Christina Quaste64aa5b2015-04-14 15:07:33 +020081
82 Apdu_S = {
Christina Quastd4c8b512015-04-14 15:53:13 +020083 apdu_states.APDU_S_CLA : func_APDU_S_CLA_P1_P2,
84 apdu_states.APDU_S_INS : func_APDU_S_INS,
85 apdu_states.APDU_S_P1 : func_APDU_S_CLA_P1_P2,
86 apdu_states.APDU_S_P2 : func_APDU_S_CLA_P1_P2,
87 apdu_states.APDU_S_P3 : func_APDU_S_P3,
88 apdu_states.APDU_S_DATA : func_APDU_S_DATA,
89 apdu_states.APDU_S_DATA_SINGLE : func_APDU_S_DATA_SINGLE,
90 apdu_states.APDU_S_SW1 : func_APDU_S_SW1,
91 apdu_states.APDU_S_SW2 : func_APDU_S_SW2 }
92
93 def split(self, c):
94 self.Apdu_S[self.state](self, c)
Christina Quaste64aa5b2015-04-14 15:07:33 +020095
96
97if __name__ == '__main__':
98 msg = [0xA0, 0xA4, 0x00, 0x00, 0x02]
99 apdus = Apdu_splitter()
100
101 for c in msg:
Christina Quastd4c8b512015-04-14 15:53:13 +0200102 print(hex(c))
Christina Quaste64aa5b2015-04-14 15:07:33 +0200103 apdus.split(c)
104
105