fix gnuk_put_binary
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
2012-06-05 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
Firmware update key handling.
|
||||
* tool/gnuk_put_binary.py (GnukToken.cmd_get_response): Handle
|
||||
larger data such as card holder certificate.
|
||||
(GnukToken.cmd_write_binary): Bug fix for cert do write.
|
||||
(GnukToken.cmd_read_binary): New.
|
||||
(main): Support firmware update key.
|
||||
|
||||
Take advantage of the Thumb-2 "rbit" instruction.
|
||||
* regnual/regnual.c (fetch): Reverse bits.
|
||||
* src/usb_ctrl.c (rbit): New. Deleted reverse32.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
gnuk_put_binary.py - a tool to put binary to Gnuk Token
|
||||
This tool is for importing certificate, updating random number, etc.
|
||||
|
||||
Copyright (C) 2011 Free Software Initiative of Japan
|
||||
Copyright (C) 2011, 2012 Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -44,11 +44,17 @@ class GnukToken(object):
|
||||
self.connection = cardservice.connection
|
||||
|
||||
def cmd_get_response(self, expected_len):
|
||||
apdu = [0x00, 0xc0, 0x00, 0x00, expected_len]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
result = []
|
||||
while True:
|
||||
apdu = [0x00, 0xc0, 0x00, 0x00, expected_len]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
result += response
|
||||
if sw1 == 0x90 and sw2 == 0x00:
|
||||
return result
|
||||
elif sw1 != 0x61:
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
else:
|
||||
expected_len = sw2
|
||||
|
||||
def cmd_verify(self, who, passwd):
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, len(passwd)] + s2l(passwd)
|
||||
@@ -56,6 +62,15 @@ class GnukToken(object):
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_read_binary(self, fileid):
|
||||
apdu = [0x00, 0xb0, 0x80+fileid, 0x00]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
|
||||
def cmd_write_binary(self, fileid, data, is_update):
|
||||
count = 0
|
||||
data_len = len(data)
|
||||
@@ -66,7 +81,7 @@ class GnukToken(object):
|
||||
while count*256 < data_len:
|
||||
if count == 0:
|
||||
d = data[:256]
|
||||
if len(d) <= 255:
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, len(d)] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, 0x80+fileid, 0x00, 255] + s2l(d[:255])
|
||||
@@ -74,18 +89,18 @@ class GnukToken(object):
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1 ] + s2l(d[255:])
|
||||
else:
|
||||
d = data[256*count:256*(count+1)]
|
||||
if len(d) <= 255:
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, count, 0x00, len(d)] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, count, 0x00, 255] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1] + s2l(d[255:])
|
||||
apdu = [0x00, ins, count, 0x00, 1] + s2l(d[255:])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
if is_update:
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
raise ValueError, ("update failure: %02x%02x" % (sw1, sw2))
|
||||
else:
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
raise ValueError, ("write failure: %02x%02x" % (sw1, sw2))
|
||||
count += 1
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
@@ -124,15 +139,17 @@ def main(fileid, is_update, data, passwd):
|
||||
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd)
|
||||
gnuk.cmd_write_binary(fileid, data, is_update)
|
||||
gnuk.cmd_select_openpgp()
|
||||
if fileid == 0:
|
||||
gnuk.cmd_select_openpgp()
|
||||
data_in_device = gnuk.cmd_get_data(0x00, 0x4f)
|
||||
for d in data_in_device:
|
||||
print "%02x" % d,
|
||||
print
|
||||
compare(data, data_in_device[8:])
|
||||
elif fileid >= 1 and fileid <= 4:
|
||||
data_in_device = gnuk.cmd_read_binary(fileid)
|
||||
compare(data, data_in_device)
|
||||
elif fileid == 5:
|
||||
gnuk.cmd_select_openpgp()
|
||||
data_in_device = gnuk.cmd_get_data(0x7f, 0x21)
|
||||
compare(data, data_in_device)
|
||||
|
||||
@@ -167,6 +184,13 @@ if __name__ == '__main__':
|
||||
exit(1)
|
||||
print "Writing serial number"
|
||||
data = binascii.unhexlify(serial_data_hex)
|
||||
elif sys.argv[1] == '-k': # firmware update key
|
||||
keyno = sys.argv[2]
|
||||
fileid = 1 + int(keyno)
|
||||
filename = sys.argv[3]
|
||||
f = open(filename)
|
||||
data = f.read()
|
||||
f.close()
|
||||
else:
|
||||
fileid = 5 # Card holder certificate
|
||||
filename = sys.argv[1]
|
||||
|
||||
@@ -180,24 +180,28 @@ class gnuk_token:
|
||||
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
|
||||
return self.cmd_get_response(sw[1])
|
||||
|
||||
def cmd_write_binary(self, fileid, data):
|
||||
def cmd_write_binary(self, fileid, data, is_update):
|
||||
count = 0
|
||||
data_len = len(data)
|
||||
if is_update:
|
||||
ins = 0xd6
|
||||
else:
|
||||
ins = 0xd0
|
||||
while count*256 < data_len:
|
||||
if count == 0:
|
||||
if len(data) < 128:
|
||||
cmd_data0 = iso7816_compose(0xd0, 0x80+fileid, 0x00, data[:128])
|
||||
cmd_data0 = iso7816_compose(ins, 0x80+fileid, 0x00, data[:128])
|
||||
cmd_data1 = None
|
||||
else:
|
||||
cmd_data0 = iso7816_compose(0xd0, 0x80+fileid, 0x00, data[:128], 0x10)
|
||||
cmd_data1 = iso7816_compose(0xd0, 0x80+fileid, 0x00, data[128:256])
|
||||
cmd_data0 = iso7816_compose(ins, 0x80+fileid, 0x00, data[:128], 0x10)
|
||||
cmd_data1 = iso7816_compose(ins, 0x80+fileid, 0x00, data[128:256])
|
||||
else:
|
||||
if len(data[256*count:256*count+128]) < 128:
|
||||
cmd_data0 = iso7816_compose(0xd0, count, 0x00, data[256*count:256*count+128])
|
||||
cmd_data0 = iso7816_compose(ins, count, 0x00, data[256*count:256*count+128])
|
||||
cmd_data1 = None
|
||||
else:
|
||||
cmd_data0 = iso7816_compose(0xd0, count, 0x00, data[256*count:256*count+128], 0x10)
|
||||
cmd_data1 = iso7816_compose(0xd0, count, 0x00, data[256*count+128:256*(count+1)])
|
||||
cmd_data0 = iso7816_compose(ins, count, 0x00, data[256*count:256*count+128], 0x10)
|
||||
cmd_data1 = iso7816_compose(ins, count, 0x00, data[256*count+128:256*(count+1)])
|
||||
sw = self.icc_send_cmd(cmd_data0)
|
||||
if len(sw) != 2:
|
||||
raise ValueError, "cmd_write_binary 0"
|
||||
@@ -211,37 +215,6 @@ class gnuk_token:
|
||||
raise ValueError, "cmd_write_binary 1"
|
||||
count += 1
|
||||
|
||||
def cmd_update_binary(self, fileid, data):
|
||||
count = 0
|
||||
data_len = len(data)
|
||||
while count*256 < data_len:
|
||||
if count == 0:
|
||||
if len(data) < 128:
|
||||
cmd_data0 = iso7816_compose(0xd6, 0x80+fileid, 0x00, data[:128])
|
||||
cmd_data1 = None
|
||||
else:
|
||||
cmd_data0 = iso7816_compose(0xd6, 0x80+fileid, 0x00, data[:128], 0x10)
|
||||
cmd_data1 = iso7816_compose(0xd6, 0x80+fileid, 0x00, data[128:256])
|
||||
else:
|
||||
if len(data[256*count:256*count+128]) < 128:
|
||||
cmd_data0 = iso7816_compose(0xd6, count, 0x00, data[256*count:256*count+128])
|
||||
cmd_data1 = None
|
||||
else:
|
||||
cmd_data0 = iso7816_compose(0xd6, count, 0x00, data[256*count:256*count+128], 0x10)
|
||||
cmd_data1 = iso7816_compose(0xd6, count, 0x00, data[256*count+128:256*(count+1)])
|
||||
sw = self.icc_send_cmd(cmd_data0)
|
||||
if len(sw) != 2:
|
||||
raise ValueError, "cmd_update_binary 0"
|
||||
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||
raise ValueError, "cmd_update_binary 0"
|
||||
if cmd_data1:
|
||||
sw = self.icc_send_cmd(cmd_data1)
|
||||
if len(sw) != 2:
|
||||
raise ValueError, "cmd_update_binary 1"
|
||||
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||
raise ValueError, "cmd_update_binary 1"
|
||||
count += 1
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
cmd_data = iso7816_compose(0xa4, 0x04, 0x0c, "\xD2\x76\x00\x01\x24\x01")
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
@@ -298,10 +271,7 @@ def main(fileid, is_update, data, passwd):
|
||||
elif icc.icc_get_status() == 1:
|
||||
icc.icc_power_on()
|
||||
icc.cmd_verify(BY_ADMIN, passwd)
|
||||
if is_update:
|
||||
icc.cmd_update_binary(fileid, data)
|
||||
else:
|
||||
icc.cmd_write_binary(fileid, data)
|
||||
icc.cmd_write_binary(fileid, data, is_update)
|
||||
icc.cmd_select_openpgp()
|
||||
if fileid == 0:
|
||||
data_in_device = icc.cmd_get_data(0x00, 0x4f)
|
||||
|
||||
Reference in New Issue
Block a user