fix gnuk_put_binary

This commit is contained in:
NIIBE Yutaka
2012-06-05 11:18:41 +09:00
parent bfa4952f31
commit 37b1992f10
3 changed files with 56 additions and 55 deletions

View File

@@ -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]