def test_taglist(): data = unformat_bytes("82") taglist = TagList.unmarshal(data) assert len(taglist) == 1 data = unformat_bytes("82 9F 42") taglist = TagList.unmarshal(data) assert len(taglist) == 2
def test_taglist(self): data = unformat_bytes('82') taglist = TagList.unmarshal(data) self.assertEqual(len(taglist), 1) data = unformat_bytes('82 9F 42') taglist = TagList.unmarshal(data) self.assertEqual(len(taglist), 2)
def test_arqc_req_payment(self): # Payment of £1234.56, account number of 78901234 req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70], value=1234.56, challenge=78901234) data = unformat_bytes('''80 AE 80 00 1D 00 00 00 12 34 56 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 78 90 12 34 00''') self.assertEqual(req.marshal(), data) # Payment of £15.00, account number of 78901234 req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70], value=15.00, challenge=78901234) data = unformat_bytes('''80 AE 80 00 1D 00 00 00 00 15 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 78 90 12 34 00''') self.assertEqual(req.marshal(), data)
def test_length_parsing(): data = unformat_bytes("42 01 03") tlv = TLV.unmarshal(data) assert tlv[0x42][0] == 3 data = unformat_bytes("42 81 01 07") tlv = TLV.unmarshal(data) assert tlv[0x42][0] == 7 data = unformat_bytes("42 82 00 01 07") tlv = TLV.unmarshal(data) assert tlv[0x42][0] == 7 data = unformat_bytes("42 83 00 00 01 07") tlv = TLV.unmarshal(data) assert tlv[0x42][0] == 7
def test_arqc_req_challenge(): # Challenge of 78901234 req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70], challenge=78901234) data = unformat_bytes( """80 AE 80 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 78 90 12 34 00""") assert req.marshal() == data
def test_pinsentry_equivalence(self): # Real response from barclays-pinsentry.c, with its calculated response data = unformat_bytes( '80 12 80 09 5F 0F 9D 37 98 E9 3F 12 9A 06 0A 0A 03 A4 90 00 90 00' ) res = RAPDU.unmarshal(data) self.assertEqual(get_cap_value(res), 46076570)
def test_real_response_rmtf2(): # Real response from a new (2018) Barclays card using RMTF2 response format. data = unformat_bytes( """77 1E 9F 27 01 80 9F 36 02 00 16 9F 26 08 29 9C C8 F1 0B 9B C8 30 9F 10 07 06 0B 0A 03 A4 90 00""") res = RAPDU.unmarshal(data) assert get_cap_value(res, ipb=BARCLAYS_IPB, psn=None) == 36554800
def test_arqc_req(self): # Comparing with a valid test request from barclays_pinsentry.c req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70]) data = unformat_bytes( '''80 AE 80 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00 00''') self.assertEqual(req.marshal(), data)
def test_arqc_req(): # Comparing with a valid test request from barclays_pinsentry.c req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70]) data = unformat_bytes( """80 AE 80 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00 00""") assert req.marshal() == data
def test_real_response_rmtf1(): # Real response from barclays-pinsentry.c, with its calculated response. # This was an older card which used the RMTF1 response format data = unformat_bytes( "80 12 80 09 5F 0F 9D 37 98 E9 3F 12 9A 06 0A 0A 03 A4 90 00 90 00") res = RAPDU.unmarshal(data) assert get_cap_value(res, ipb=BARCLAYS_IPB, psn=None) == 46076570
def test_arqc_req_challenge(self): # Challenge of 78901234 req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70], challenge=78901234) data = unformat_bytes( '''80 AE 80 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 78 90 12 34 00''') self.assertEqual(req.marshal(), data)
def test_length_parsing(self): data = unformat_bytes("42 01 03") tlv = TLV.unmarshal(data) self.assertEqual(tlv[0x42][0], 3) data = unformat_bytes("42 81 01 07") tlv = TLV.unmarshal(data) self.assertEqual(tlv[0x42][0], 7) data = unformat_bytes("42 82 00 01 07") tlv = TLV.unmarshal(data) self.assertEqual(tlv[0x42][0], 7) data = unformat_bytes("42 83 00 00 01 07") tlv = TLV.unmarshal(data) self.assertEqual(tlv[0x42][0], 7)
class TestDOL(TestCase): # Barclays debit CDOL1 dol_data = unformat_bytes( '9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04') def test_dol(self): dol = DOL.unmarshal(self.dol_data) self.assertIn(0x9A, dol) self.assertEqual(dol[0x9A], 3) self.assertIn((0x9F, 0x37), dol) self.assertEqual(dol[(0x9F, 0x37)], 4) self.assertEqual(dol.size(), 29) def test_serialise(self): dol = DOL.unmarshal(self.dol_data) # Parameters to GENERATE APPLICATION CRYPTOGRAM from barclays-pinsentry.c: data = unformat_bytes( '''00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00''') tlv = dol.unserialise(data) self.assertEqual(tlv[0x9A], [1, 1, 1]) # Re-serialise by round trip self.assertEqual(dol.serialise(tlv), data) # Serialise with partial data source = { Tag(0x9A): [0x01, 0x01, 0x01], Tag(0x95): [0x80, 0x00, 0x00, 0x00, 0x00] } serialised = dol.serialise(source) self.assertEqual(serialised, data) def test_serialise_long_data(self): dol = DOL.unmarshal(self.dol_data) # First tag is too long for the DOL source = { Tag(0x9A): [0x01, 0x01, 0x01, 0x02], Tag(0x95): [0x80, 0x00, 0x00, 0x00, 0x00] } with self.assertRaises(Exception): dol.serialise(source) def test_unserialise(self): dol = DOL.unmarshal(self.dol_data) # Incorrect length data data = unformat_bytes( '''00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00''') with self.assertRaises(Exception): dol.unserialise(data)
def test_arqc_req_payment(): # Payment of £1234.56, account number of 78901234 req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70], value=1234.56, challenge=78901234) data = unformat_bytes( """80 AE 80 00 1D 00 00 00 12 34 56 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 78 90 12 34 00""") assert req.marshal() == data # Payment of £15.00, account number of 78901234 req = get_arqc_req(TLV.unmarshal(APP_DATA)[0x70], value=15.00, challenge=78901234) data = unformat_bytes( """80 AE 80 00 1D 00 00 00 00 15 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 78 90 12 34 00""") assert req.marshal() == data
def test_unmarshal(): pdu = CAPDU.unmarshal( unformat_bytes("00 A4 04 00 07 A0 00 00 00 03 80 02")) assert type(pdu) is SelectCommand assert pdu.p1 == 0x04 assert pdu.p2 == 0x00 assert len(pdu.data) == 0x07 assert pdu.le is None pdu = CAPDU.unmarshal( unformat_bytes("""80 AE 80 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00""" )) assert type(pdu) is GenerateApplicationCryptogramCommand assert pdu.p1 == 0x80 assert pdu.p2 == 0x00 assert len(pdu.data) == 0x1D assert pdu.le is None
def test_unserialise(self): dol = DOL.unmarshal(self.dol_data) # Incorrect length data data = unformat_bytes( '''00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00''') with self.assertRaises(Exception): dol.unserialise(data)
def test_tlv(self): data = unformat_bytes( '''6F 1D 84 07 A0 00 00 00 03 80 02 A5 12 50 08 42 41 52 43 4C 41 59 53 87 01 00 5F 2D 02 65 6E''') tlv = TLV.unmarshal(data) self.assertIn(0x50, tlv[Tag.FCI][Tag.FCI_PROP]) data = unformat_bytes( '''77 1E 9F 27 01 80 9F 36 02 00 05 9F 26 08 6E CF 93 47 C1 A9 24 71 9F 10 07 06 0B 0A 03 A4 90 00''') tlv = TLV.unmarshal(data) self.assertIn(Tag.RMTF2, tlv) self.assertIn((0x9F, 0x26), tlv[Tag.RMTF2]) self.assertEqual(tlv[Tag.RMTF2][(0x9F, 0x26)], unformat_bytes('6E CF 93 47 C1 A9 24 71')) data = unformat_bytes('9F 17 01 03') tlv = TLV.unmarshal(data) self.assertEqual(tlv[(0x9F, 0x17)][0], 3)
def test_unmarshal(self): pdu = CAPDU.unmarshal(unformat_bytes("00 A4 04 00 07 A0 00 00 00 03 80 02")) self.assertIs(type(pdu), SelectCommand) self.assertEqual(pdu.p1, 0x04) self.assertEqual(pdu.p2, 0x00) self.assertEqual(len(pdu.data), 0x07) self.assertEqual(pdu.le, None) pdu = CAPDU.unmarshal( unformat_bytes( """80 AE 80 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00""" ) ) self.assertIs(type(pdu), GenerateApplicationCryptogramCommand) self.assertEqual(pdu.p1, 0x80) self.assertEqual(pdu.p2, 0x00) self.assertEqual(len(pdu.data), 0x1D) self.assertEqual(pdu.le, None)
def test_retry(self): r_data = unformat_bytes( """6F 1D 84 07 A0 00 00 00 03 80 02 A5 12 50 08 42 41 52 43 4C 41 59 53 87 01 00 5F 2D 02 65 6E""" ) responses = [([], 0x61, 0x1F), (r_data, 0x90, 0x00)] conn = MockConnection(responses) tp = TransmissionProtocol(conn) res = tp.exchange(SelectCommand([0xA0, 0x00, 0x00, 0x00, 0x03, 0x80, 0x02])) self.assertIs(type(res), SuccessResponse)
def test_unserialise(): dol = DOL.unmarshal(dol_data) # Incorrect length data data = unformat_bytes( """00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00""" ) with pytest.raises(Exception): dol.unserialise(data)
def test_dol(): dol = DOL.unmarshal(dol_data) assert 0x9A in dol assert (0x9F, 0x37) in dol assert dol.size() == 29 # This DOL has a repeated 0x9A entry, for some reason. Apparently this is allowed. data = unformat_bytes( "9F 66 04 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9A 03" ) dol = DOL.unmarshal(data) assert len([t for t in dol if t[0] == 0x9A]) == 2
def test_tlv(self): data = unformat_bytes( """6F 1D 84 07 A0 00 00 00 03 80 02 A5 12 50 08 42 41 52 43 4C 41 59 53 87 01 00 5F 2D 02 65 6E""") tlv = TLV.unmarshal(data) self.assertIn(0x50, tlv[Tag.FCI][Tag.FCI_PROP]) data = unformat_bytes( """77 1E 9F 27 01 80 9F 36 02 00 05 9F 26 08 6E CF 93 47 C1 A9 24 71 9F 10 07 06 0B 0A 03 A4 90 00""") tlv = TLV.unmarshal(data) self.assertIn(Tag.RMTF2, tlv) self.assertIn((0x9F, 0x26), tlv[Tag.RMTF2]) self.assertEqual(tlv[Tag.RMTF2][(0x9F, 0x26)], unformat_bytes("6E CF 93 47 C1 A9 24 71")) data = unformat_bytes("9F 17 01 03") tlv = TLV.unmarshal(data) self.assertEqual(tlv[(0x9F, 0x17)][0], 3) data = unformat_bytes("DF DF 39 01 07") tlv = TLV.unmarshal(data) self.assertEqual(tlv[(0xDF, 0xDF, 0x39)][0], 7)
def test_tlv(): data = unformat_bytes( """6F 1D 84 07 A0 00 00 00 03 80 02 A5 12 50 08 42 41 52 43 4C 41 59 53 87 01 00 5F 2D 02 65 6E""" ) tlv = TLV.unmarshal(data) assert 0x50 in tlv[Tag.FCI][Tag.FCI_PROP] data = unformat_bytes( """77 1E 9F 27 01 80 9F 36 02 00 05 9F 26 08 6E CF 93 47 C1 A9 24 71 9F 10 07 06 0B 0A 03 A4 90 00""" ) tlv = TLV.unmarshal(data) assert Tag.RMTF2 in tlv assert (0x9F, 0x26) in tlv[Tag.RMTF2] assert tlv[Tag.RMTF2][(0x9F, 0x26)] == unformat_bytes("6E CF 93 47 C1 A9 24 71") data = unformat_bytes("9F 17 01 03") tlv = TLV.unmarshal(data) assert tlv[(0x9F, 0x17)][0] == 3 data = unformat_bytes("DF DF 39 01 07") tlv = TLV.unmarshal(data) assert tlv[(0xDF, 0xDF, 0x39)][0] == 7
def test_duplicate_tags(self): # An ADF entry with a number of records: data = unformat_bytes( '''70 4A 61 16 4F 07 A0 00 00 00 29 10 10 50 08 4C 49 4E 4B 20 41 54 4D 87 01 01 61 18 4F 07 A0 00 00 00 03 10 10 50 0A 56 49 53 41 20 44 45 42 49 54 87 01 02 61 16 4F 07 A0 00 00 00 03 80 02 50 08 42 41 52 43 4C 41 59 53 87 01 00''') tlv = TLV.unmarshal(data) self.assertIn(Tag.RECORD, tlv) self.assertIn(Tag.APP, tlv[Tag.RECORD]) # We expect this to be a list of TLV objects self.assertIs(list, type(tlv[Tag.RECORD][Tag.APP])) self.assertEqual(len(tlv[Tag.RECORD][Tag.APP]), 3) repr(tlv)
def test_duplicate_tags(): # An ADF entry with a number of records: data = unformat_bytes( """70 4A 61 16 4F 07 A0 00 00 00 29 10 10 50 08 4C 49 4E 4B 20 41 54 4D 87 01 01 61 18 4F 07 A0 00 00 00 03 10 10 50 0A 56 49 53 41 20 44 45 42 49 54 87 01 02 61 16 4F 07 A0 00 00 00 03 80 02 50 08 42 41 52 43 4C 41 59 53 87 01 00""" ) tlv = TLV.unmarshal(data) assert Tag.RECORD in tlv assert Tag.APP in tlv[Tag.RECORD] # We expect this to be a list of TLV objects assert type(tlv[Tag.RECORD][Tag.APP]) is list assert len(tlv[Tag.RECORD][Tag.APP]) == 3 repr(tlv)
def test_serialise(self): dol = DOL.unmarshal(self.dol_data) # Parameters to GENERATE APPLICATION CRYPTOGRAM from barclays-pinsentry.c: data = unformat_bytes( '''00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00''') tlv = dol.unserialise(data) self.assertEqual(tlv[0x9A], [1, 1, 1]) # Re-serialise by round trip self.assertEqual(dol.serialise(tlv), data) # Serialise with partial data source = { Tag(0x9A): [0x01, 0x01, 0x01], Tag(0x95): [0x80, 0x00, 0x00, 0x00, 0x00] } serialised = dol.serialise(source) self.assertEqual(serialised, data)
def test_serialise(): dol = DOL.unmarshal(dol_data) # Parameters to GENERATE APPLICATION CRYPTOGRAM from barclays-pinsentry.c: data = unformat_bytes( """00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 01 01 01 00 00 00 00 00""" ) tlv = dol.unserialise(data) assert tlv[0x9A] == [1, 1, 1] # Re-serialise by round trip assert dol.serialise(tlv) == data # Serialise with partial data source = { Tag(0x9A): [0x01, 0x01, 0x01], Tag(0x95): [0x80, 0x00, 0x00, 0x00, 0x00], } serialised = dol.serialise(source) assert serialised == data
def test_main(self): data = unformat_bytes( '00 00 00 00 00 00 00 00 41 03 1E 03 02 03 1F 03') print(CVMList.unmarshal(data))
def test_read_tag(self): read_tag(unformat_bytes('82')) == [0x82] read_tag(unformat_bytes('9F 42')) == [0x9F, 0x42]
def test_invalid_tlv(self): # An actual bit of data found on a card. 0x61 indicates that it's TLV format but # no following bytes make it invalid. data = unformat_bytes('61') self.assertEqual(TLV.unmarshal(data), [0x61])