serial number support is not at compile time

This commit is contained in:
NIIBE Yutaka 2011-02-08 14:20:20 +09:00
parent 21bcf76d36
commit 677fc00489
10 changed files with 179 additions and 53 deletions

View File

@ -1,3 +1,24 @@
2011-02-08 NIIBE Yutaka <gniibe@fsij.org>
* tool/gnuk_put_binary.py: Renamed (was: gnuk_update_binary.py).
(gnuk_token.cmd_write_binary): New.
(main): Support writing serial number.
* GNUK_SERIAL_NUMBER: Renamed (was: FSIJ_SERIAL_NUMBER).
* src/config.h.in (@SERIAL_DEFINE@): Removed.
* src/gnuk.h (FILEID_SERIAL_NO): New.
* src/openpgp.c (INS_WRITE_BINARY, cmd_write_binary): New.
* src/configure: Remove --with-fixed-serial support.
* src/openpgp-do.c (do_openpgpcard_aid): Remove support of
SERIAL_NUMBER_IN_AID.
* src/flash.c (flash_write_binary): Support FILEID_SERIAL_NO.
2011-02-04 NIIBE Yutaka <gniibe@fsij.org>
* tool/gnuk_update_binary.py: Support updating random bits.

View File

@ -1,2 +0,0 @@
# Email # 4-byte serial number, separated by ':'
gniibe@fsij.org 00:00:00:01

2
GNUK_SERIAL_NUMBER Normal file
View File

@ -0,0 +1,2 @@
# Email # 6-byte serial number, separated by ':'
gniibe@fsij.org f5:17:00:00:00:01

View File

@ -2,7 +2,6 @@
#ifdef DEBUG
#define ENABLE_VIRTUAL_COM_PORT 1
#endif
@SERIAL_DEFINE@
@DFU_DEFINE@
@PINPAD_DEFINE@
@PINPAD_MORE_DEFINE@

21
src/configure vendored
View File

@ -24,7 +24,6 @@ help=no
target=OLIMEX_STM32_H103
verbose=no
with_dfu=default
with_fixed_serial=no
debug=no
pinpad=no
@ -62,10 +61,6 @@ for option; do
with_dfu=yes ;;
--without-dfu)
with_dfu=no ;;
--with-fixed-serial)
with_fixed_serial=yes ;;
--without-fixed-serial)
with_fixed_serial=no ;;
*)
echo "Unrecognized option \`$option'" >&2
echo "Try \`$0 --help' for more information." >&2
@ -94,7 +89,6 @@ Configuration:
--enable-pinpad={cir,dial}
PIN input device support [no]
--with-dfu build image for DFU [<target specific>]
--with-fixed-serial Use fixed serial number [no: chip unique ID]
EOF
exit 0
fi
@ -135,20 +129,6 @@ STM8S_DISCOVERY)
;;
esac
# --with-fixed-serial option
if test "$with_fixed_serial" = "no"; then
echo "Using chip unique ID for card AID"
SERIAL_DEFINE="#undef SERIAL_NUMBER_IN_AID"
else
echo "Using fixed serial number (at compile time) for card AID"
if test "x$MAIL" = "x"; then
echo "ERROR: Please set MAIL shell variable to select FSIJ serial number" >&2
exit 1
fi
SERIAL=`sed -n -e "/^$MAIL/s/^.* \(..\):\(..\):\(..\):\(..\)/0x\1, 0x\2, 0x\3, 0x\4/p" ../FSIJ_SERIAL_NUMBER`
SERIAL_DEFINE="#define SERIAL_NUMBER_IN_AID $SERIAL"
fi
# --enable-debug option
if test "$debug" = "yes"; then
DEBUG_MAKE_OPTION="ENABLE_DEBUG=1"
@ -201,6 +181,5 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
-e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
-e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
-e "s/@SERIAL_DEFINE@/$SERIAL_DEFINE/" \
< config.h.in > config.h
exit 0

View File

@ -646,6 +646,11 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
maxsize = FLASH_PAGE_SIZE;
p = &random_bits_start;
}
else if (file_id == FILEID_SERIAL_NO)
{
maxsize = 6;
p = &openpgpcard_aid[8];
}
else
return -1;

View File

@ -118,6 +118,7 @@ extern void flash_reset_counter (uint8_t counter_tag_nr);
#define FILEID_CH_CERTIFICATE 0
#define FILEID_RANDOM 1
#define FILEID_SERIAL_NO 2
extern int flash_erase_binary (uint8_t file_id);
extern int flash_write_binary (uint8_t file_id, const uint8_t *data, uint16_t len, uint16_t offset);
@ -305,7 +306,7 @@ extern uint8_t pw1_keystring[KEYSTRING_SIZE_PW1];
#define OPENPGP_CARD_INITIAL_PW3 "12345678"
#endif
extern const uint8_t openpgpcard_aid[17] __attribute__ ((aligned (1)));
extern const uint8_t openpgpcard_aid[14];
extern int gpg_get_pw1_lifetime (void);

View File

@ -406,23 +406,17 @@ do_kgtime_all (uint16_t tag, int with_tag)
return 1;
}
const uint8_t openpgpcard_aid_template[] = {
const uint8_t openpgpcard_aid[] = {
0xd2, 0x76, 0x00, 0x01, 0x24, 0x01,
0x02, 0x00, /* Version 2.0 */
#if defined(SERIAL_NUMBER_IN_AID)
0xf5, 0x17, /* Manufacturer: FSIJ */
SERIAL_NUMBER_IN_AID
#else
0xff, 0xfe, /* Random bytes */
#endif
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* To be overwritten */
/* v. id */ /* serial number */
};
static int
do_openpgpcard_aid (uint16_t tag, int with_tag)
{
#if !defined(SERIAL_NUMBER_IN_AID)
const uint8_t *u = unique_device_id ();
#endif
const uint16_t *vid_p = (const uint16_t *)&openpgpcard_aid[8];
if (with_tag)
{
@ -430,14 +424,28 @@ do_openpgpcard_aid (uint16_t tag, int with_tag)
*res_p++ = 16;
}
memcpy (res_p, openpgpcard_aid_template, sizeof (openpgpcard_aid_template));
res_p += sizeof (openpgpcard_aid_template);
#if !defined(SERIAL_NUMBER_IN_AID)
memcpy (res_p, u, 4);
res_p += 4;
#endif
if (*vid_p == 0xffff || *vid_p == 0x0000)
{
const uint8_t *u = unique_device_id ();
memcpy (res_p, openpgpcard_aid, 8);
res_p += 8;
/* vid == 0xfffe: serial number is random byte */
*res_p++ = 0xff;
*res_p++ = 0xfe;
memcpy (res_p, u, 4);
res_p += 4;
}
else
{
memcpy (res_p, openpgpcard_aid, 14);
res_p += 14;
}
*res_p++ = 0;
*res_p++ = 0;
return 1;
}

View File

@ -38,6 +38,7 @@
#define INS_SELECT_FILE 0xa4
#define INS_READ_BINARY 0xb0
#define INS_GET_DATA 0xca
#define INS_WRITE_BINARY 0xd0
#define INS_UPDATE_BINARY 0xd6
#define INS_PUT_DATA 0xda
#define INS_PUT_DATA_ODD 0xdb /* For key import */
@ -916,6 +917,68 @@ cmd_update_binary (void)
}
static void
cmd_write_binary (void)
{
int len = cmd_APDU[4];
int data_start = 5;
uint16_t offset;
int r;
if (len == 0)
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
DEBUG_INFO (" - WRITE BINARY\r\n");
if (gpg_passwd_locked (PW_ERR_PW3) || !ac_check_status (AC_ADMIN_AUTHORIZED))
{
DEBUG_INFO ("security error.");
GPG_SECURITY_FAILURE ();
return;
}
if ((cmd_APDU[2] & 0x80))
if ((cmd_APDU[2] & 0x7f) == FILEID_SERIAL_NO)
{
file_selection = FILE_EF_CH_CERTIFICATE + (cmd_APDU[2] & 0x7f);
offset = 0;
}
else
{
GPG_NO_FILE ();
return;
}
else
{
if (file_selection != FILEID_SERIAL_NO)
{
GPG_COMMAND_NOT_ALLOWED ();
return;
}
offset = (cmd_APDU[2] << 8) | cmd_APDU[3];
}
DEBUG_SHORT (len);
DEBUG_SHORT (offset);
r = flash_write_binary (file_selection - FILE_EF_CH_CERTIFICATE,
&cmd_APDU[data_start], len, offset);
if (r < 0)
{
DEBUG_INFO ("memory error.\r\n");
GPG_MEMORY_FAILURE ();
return;
}
GPG_SUCCESS ();
DEBUG_INFO ("WRITE BINARY done.\r\n");
}
struct command
{
uint8_t command;
@ -932,6 +995,7 @@ const struct command cmds[] = {
{ INS_SELECT_FILE, cmd_select_file },
{ INS_READ_BINARY, cmd_read_binary },
{ INS_GET_DATA, cmd_get_data },
{ INS_WRITE_BINARY, cmd_write_binary}, /* Not in OpenPGP card protocol */
{ INS_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
{ INS_PUT_DATA, cmd_put_data },
{ INS_PUT_DATA_ODD, cmd_put_data },

View File

@ -1,7 +1,7 @@
#! /usr/bin/python
"""
gnuk_update_binary.py - a tool to put binary to Gnuk Token
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
@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from intel_hex import *
from struct import *
import sys, time, os
import sys, time, os, binascii
# INPUT: binary file
@ -166,6 +166,21 @@ class gnuk_token:
if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, "cmd_verify"
def cmd_write_binary(self, fileid, data):
count = 0
data_len = len(data)
while count*256 < data_len:
if count == 0:
cmd_data = iso7816_compose(0xd0, 0x80+fileid, 0x00, data[:256])
else:
cmd_data = iso7816_compose(0xd0, count, 0x00, data[256*count:256*(count+1)])
sw = self.icc_send_cmd(cmd_data)
if len(sw) != 2:
raise ValueError, "cmd_write_binary"
if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, "cmd_write_binary"
count += 1
def cmd_update_binary(self, fileid, data):
count = 0
data_len = len(data)
@ -218,12 +233,7 @@ def get_device():
return dev, config, alt
raise ValueError, "Device not found"
def main(fileid, filename):
f = open(filename)
data = f.read()
f.close()
print "%s: %d" % (filename, len(data))
data += "\x90\x00"
def main(fileid, is_update, data):
dev, config, intf = get_device()
print "Device: ", dev.filename
print "Configuration: ", config.value
@ -234,7 +244,10 @@ def main(fileid, filename):
elif icc.icc_get_status() == 1:
icc.icc_power_on()
icc.cmd_verify(3, "12345678")
icc.cmd_update_binary(fileid, data)
if is_update:
icc.cmd_update_binary(fileid, data)
else:
icc.cmd_write_binary(fileid, data)
icc.cmd_select_openpgp()
data = data[:-2]
data_in_device = icc.cmd_get_data(0x7f, 0x21)
@ -243,10 +256,46 @@ def main(fileid, filename):
return 0
if __name__ == '__main__':
if os.path.basename(sys.argv[1] == "random_bits"):
fileid = 1
if sys.argv[1] == '-u':
is_update = True
sys.argv.pop(1)
else:
is_update = False
if sys.argv[1] == '-s':
fileid = 2 # serial number
filename = sys.argv[2]
f = open(filename)
email = os.environ['MAIL']
serial_data_hex = None
for line in f.readlines():
field = string.split(line)
if field[0] == os.environ['MAIL']:
serial_data_hex = field[1].replace(':','')
f.close()
if not serial_data_hex:
print "No serial number"
exit 1
print "Writing serial number"
data = binascii.unhexlify(serial_data_hex)
elif sys.argv[1] == '-r':
fileid = 1 # Random number bits
if len(sys.argv) == 3:
filename = sys.argv[2]
f = open(filename)
else:
filename = stdin
f = sys.stdin
data = f.read()
f.close()
print "%s: %d" % (filename, len(data))
print "Updating random bits"
else:
fileid = 0 # Card holder certificate
filename = sys.argv[2]
f = open(filename)
data = f.read()
f.close()
print "%s: %d" % (filename, len(data))
data += "\x90\x00"
print "Updating card holder certificate"
main(fileid, sys.argv[1])
main(fileid, is_update, data)