TPDU reader works now
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 7 Oct 2016 07:39:20 +0000 (16:39 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 7 Oct 2016 07:39:20 +0000 (16:39 +0900)
tests/card_reader.py
tests/openpgp_card.py
tests/test_empty_card.py

index 67f4276..d3d360f 100644 (file)
@@ -60,8 +60,9 @@ def compose_r_block(nr, edc_error=0):
         pcb |= 0x01
     return bytes([0, pcb, 0, pcb])
 
-def is_r_block_no_error(blk):
-    return ((blk[1] & 0xC0) == 0x80 and (blk[1] & 0x2f) == 0x00)
+def is_r_block_no_error_or_other(blk):
+    return (((blk[1] & 0xC0) == 0x80 and (blk[1] & 0x2f) == 0x00)) or \
+        ((blk[1] & 0xC0) != 0x80)
 
 def is_s_block_time_ext(blk):
     return (blk[1] == 0xC3)
@@ -76,7 +77,7 @@ def is_edc_error(blk):
     # to be implemented
     return 0
 
-def i_block_content(blk)
+def i_block_content(blk):
     return blk[3:-1]
 
 class CardReader(object):
@@ -175,12 +176,13 @@ class CardReader(object):
             # TPDU reader configuration
             self.ns = 0
             self.nr = 0
+            # Set PPS
             pps = b"\xFF\x11\x18\xF6"
             status, chain, ret_pps = self.ccid_send_data_block(pps)
-            #
+            # Set parameters
             param = b"\x18\x10\xFF\x75\x00\xFE\x00"
             # ^--- This shoud be adapted by ATR string, see update_param_by_atr
-            msg = ccid_compose(0x6d, self.__seq, rsv=0x1, data=param)
+            msg = ccid_compose(0x61, self.__seq, rsv=0x1, data=param)
             self.__dev.write(self.__bulkout, msg, self.__timeout)
             self.increment_seq()
             status, chain, ret_param = self.ccid_get_result()
@@ -258,13 +260,13 @@ class CardReader(object):
             while True:
                 self.send_tpdu(info=blk,more=1)
                 rblk = self.recv_tpdu()
-                if is_r_block_no_error(rblk):
+                if is_r_block_no_error_or_other(rblk):
                     break
             self.ns = self.ns ^ 1
         while True:
             self.send_tpdu(info=cmd)
             blk = self.recv_tpdu()
-            if is_r_block_no_error(blk):
+            if is_r_block_no_error_or_other(blk):
                 break
         self.ns = self.ns ^ 1
         res = b""
index c1dd769..5f30d42 100644 (file)
@@ -115,7 +115,7 @@ class OpenPGP_Card(object):
             count += 1
 
     def cmd_select_openpgp(self):
-        cmd_data = iso7816_compose(0xa4, 0x04, 0x0c, b"\xD2\x76\x00\x01\x24\x01")
+        cmd_data = iso7816_compose(0xa4, 0x04, 0x00, b"\xD2\x76\x00\x01\x24\x01")
         sw = self.__reader.send_cmd(cmd_data)
         if len(sw) != 2:
             raise ValueError(sw)
@@ -124,15 +124,18 @@ class OpenPGP_Card(object):
         return True
 
     def cmd_get_data(self, tagh, tagl):
-        cmd_data = iso7816_compose(0xca, tagh, tagl, b"")
+        cmd_data = iso7816_compose(0xca, tagh, tagl, b"", le=254)
         sw = self.__reader.send_cmd(cmd_data)
-        if len(sw) != 2:
+        if len(sw) < 2:
             raise ValueError(sw)
-        if sw[0] == 0x90 and sw[1] == 0x00:
-            return b""
-        elif sw[0] != 0x61:
+        if sw[0] == 0x61:
+            return self.cmd_get_response(sw[1])
+        elif sw[-2] == 0x90 and sw[-1] == 0x00:
+            return sw[0:-2]
+        if sw[0] == 0x6a and sw[1] == 0x88:
+            return None
+        else:
             raise ValueError("%02x%02x" % (sw[0], sw[1]))
-        return self.cmd_get_response(sw[1])
 
     def cmd_change_reference_data(self, who, data):
         cmd_data = iso7816_compose(0x24, 0x00, 0x80+who, data)
index 76847a1..c7774f7 100644 (file)
@@ -47,7 +47,7 @@ def get_data_object(card, tag):
     return card.cmd_get_data(tagh, tagl)
 
 def check_null(data_object):
-    return len(data_object) == 0
+    return data_object == None or len(data_object) == 0
 
 def test_login(card):
     login = get_data_object(card, 0x5e)
@@ -71,15 +71,15 @@ def test_url(card):
 
 def test_ds_counter(card):
     c = get_data_object(card, 0x93)
-    assert c == b'\x00\x00\x00'
+    assert c == None or c == b'\x00\x00\x00'
 
 def test_pw1_status(card):
     s = get_data_object(card, 0xc4)
-    assert s == b'\x00\x7f\x7f\x7f\x03\x03\x03'
+    assert match(b'\x00...\x03[\x00\x03]\x03', s, DOTALL)
 
 def test_fingerprint_0(card):
     fprlist = get_data_object(card, 0xC5)
-    assert fprlist == EMPTY_60
+    assert fprlist == None or fprlist == EMPTY_60
 
 def test_fingerprint_1(card):
     fpr = get_data_object(card, 0xC7)
@@ -95,7 +95,7 @@ def test_fingerprint_3(card):
 
 def test_ca_fingerprint_0(card):
     cafprlist = get_data_object(card, 0xC6)
-    assert cafprlist == EMPTY_60
+    assert cafprlist == None or cafprlist == EMPTY_60
 
 def test_ca_fingerprint_1(card):
     cafp = get_data_object(card, 0xCA)
@@ -111,7 +111,7 @@ def test_ca_fingerprint_3(card):
 
 def test_timestamp_0(card):
     t = get_data_object(card, 0xCD)
-    assert t == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+    assert t == None or t == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
 
 def test_timestamp_1(card):
     t = get_data_object(card, 0xCE)
@@ -139,23 +139,24 @@ def test_verify_pw3(card):
 
 def test_historical_bytes(card):
     h = get_data_object(card, 0x5f52)
-    assert h == b'\x00\x31\x84\x73\x80\x01\x80\x00\x90\x00'
+    assert h == b'\x001\xc5s\xc0\x01@\x05\x90\x00' or \
+           h == b'\x00\x31\x84\x73\x80\x01\x80\x00\x90\x00'
 
 def test_extended_capabilities(card):
     a = get_data_object(card, 0xc0)
-    assert match(b'[\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00', a)
+    assert a == None or match(b'[\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00', a)
 
 def test_algorithm_attributes_1(card):
     a = get_data_object(card, 0xc1)
-    assert a == b'\x01\x08\x00\x00\x20\x00'
+    assert a == None or a == b'\x01\x08\x00\x00\x20\x00'
 
 def test_algorithm_attributes_2(card):
     a = get_data_object(card, 0xc2)
-    assert a == b'\x01\x08\x00\x00\x20\x00'
+    assert a == None or a == b'\x01\x08\x00\x00\x20\x00'
 
 def test_algorithm_attributes_3(card):
     a = get_data_object(card, 0xc3)
-    assert a == b'\x01\x08\x00\x00\x20\x00'
+    assert a == None or a == b'\x01\x08\x00\x00\x20\x00'
 
 def test_AID(card):
     a = get_data_object(card, 0x4f)