Skip to content

Commit

Permalink
Implement OmapiTest.testLongSelectResponse()
Browse files Browse the repository at this point in the history
The response to SELECT command for AID 32 must be encoded in BER-TLV
format correctly. The added test case confirms that.
  • Loading branch information
cheeriotb committed Nov 17, 2018
1 parent ee11c0b commit 22ed30b
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions shadysim/sects.py
Expand Up @@ -28,6 +28,39 @@ class CommandInterface(object):
def __init__(self, transport):
self.transport = transport

def extract_value(self, response):
tag_first = int(response[0:2], 16)
response = response[2:]

# If all the bits 1-5 in the first byte are 1, the tag is encoded in the long format.
# The tag number is encoded in the following octets,
# where bit 8 of each is 1 if there are more octets, and bits 1–7 encode the tag number.
if (tag_first & 0x1F) == 0x1F:
while True:
tag_subsequent = int(response[0:2], 16)
response = response[2:]
if (tag_subsequent & 0x80) != 0x80:
break

length = 0
length_byte = int(response[0:2], 16)
response = response[2:]

# The long form consist of 1 initial octet followed by 1 or more subsequent octets,
# containing the length. In the initial octet, bit 8 is 1,
# and bits 1–7 (excluding the values 0 and 127) encode the number of octets that follow.
if length_byte > 127:
length_size = length_byte - 128
while length_size:
length_byte = int(response[0:2], 16)
response = response[2:]
length = (length << 8) + length_byte
length_size -= 1
else:
length = length_byte

return (response[:length * 2], response[length * 2:])

def send_terminal_profile(self):
(response, sw) = self.transport.send_apdu('A010000011FFFF000000000000000000000000000000')
if sw[0:2] == '91':
Expand Down Expand Up @@ -55,6 +88,17 @@ def select_application(self, channel_number, aid):
raise RuntimeError('Unexpected SW for SELECT : ' + sw);
return response

def select_application_with_check_response(self, channel_number, aid):
response = self.select_application(channel_number, aid)

# The length of the select response shall be greater than 2 bytes
if len(response) < 3:
raise RuntimeError('The size of the response data is wrong : ' + response)

(target, remain) = self.extract_value(response)
while len(target) > 0:
(value, target) = self.extract_value(target)

def send_apdu_on_channel(self, channel_number, apdu):
if len(apdu) < (4 * 2):
raise ValueError("Specified C-APDU is too short : " + apdu)
Expand Down Expand Up @@ -154,8 +198,19 @@ def testTransmitApdu(self):

print('finished: ' + sys._getframe().f_code.co_name)

def testLongSelectResponse(self):
print('started: ' + sys._getframe().f_code.co_name)
aid = 'A000000476416E64726F696443545332'

channel_number = self.commandif.open_logical_channel()
response = self.commandif.select_application_with_check_response(channel_number, aid)
self.commandif.close_logical_channel(channel_number)

print('finished: ' + sys._getframe().f_code.co_name)

def execute_all(self):
self.testTransmitApdu()
self.testLongSelectResponse()

parser = argparse.ArgumentParser(description='Android Secure Element CTS')
parser.add_argument('-p', '--pcsc', nargs='?', const=0, type=int)
Expand Down

0 comments on commit 22ed30b

Please sign in to comment.