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> 2011-02-04 NIIBE Yutaka <gniibe@fsij.org>
* tool/gnuk_update_binary.py: Support updating random bits. * 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 #ifdef DEBUG
#define ENABLE_VIRTUAL_COM_PORT 1 #define ENABLE_VIRTUAL_COM_PORT 1
#endif #endif
@SERIAL_DEFINE@
@DFU_DEFINE@ @DFU_DEFINE@
@PINPAD_DEFINE@ @PINPAD_DEFINE@
@PINPAD_MORE_DEFINE@ @PINPAD_MORE_DEFINE@

21
src/configure vendored
View File

@ -24,7 +24,6 @@ help=no
target=OLIMEX_STM32_H103 target=OLIMEX_STM32_H103
verbose=no verbose=no
with_dfu=default with_dfu=default
with_fixed_serial=no
debug=no debug=no
pinpad=no pinpad=no
@ -62,10 +61,6 @@ for option; do
with_dfu=yes ;; with_dfu=yes ;;
--without-dfu) --without-dfu)
with_dfu=no ;; with_dfu=no ;;
--with-fixed-serial)
with_fixed_serial=yes ;;
--without-fixed-serial)
with_fixed_serial=no ;;
*) *)
echo "Unrecognized option \`$option'" >&2 echo "Unrecognized option \`$option'" >&2
echo "Try \`$0 --help' for more information." >&2 echo "Try \`$0 --help' for more information." >&2
@ -94,7 +89,6 @@ Configuration:
--enable-pinpad={cir,dial} --enable-pinpad={cir,dial}
PIN input device support [no] PIN input device support [no]
--with-dfu build image for DFU [<target specific>] --with-dfu build image for DFU [<target specific>]
--with-fixed-serial Use fixed serial number [no: chip unique ID]
EOF EOF
exit 0 exit 0
fi fi
@ -135,20 +129,6 @@ STM8S_DISCOVERY)
;; ;;
esac 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 # --enable-debug option
if test "$debug" = "yes"; then if test "$debug" = "yes"; then
DEBUG_MAKE_OPTION="ENABLE_DEBUG=1" 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_DEFINE@/$PINPAD_DEFINE/" \
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \ -e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
-e "s/@DFU_DEFINE@/$DFU_DEFINE/" \ -e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
-e "s/@SERIAL_DEFINE@/$SERIAL_DEFINE/" \
< config.h.in > config.h < config.h.in > config.h
exit 0 exit 0

View File

@ -646,6 +646,11 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
maxsize = FLASH_PAGE_SIZE; maxsize = FLASH_PAGE_SIZE;
p = &random_bits_start; p = &random_bits_start;
} }
else if (file_id == FILEID_SERIAL_NO)
{
maxsize = 6;
p = &openpgpcard_aid[8];
}
else else
return -1; 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_CH_CERTIFICATE 0
#define FILEID_RANDOM 1 #define FILEID_RANDOM 1
#define FILEID_SERIAL_NO 2
extern int flash_erase_binary (uint8_t file_id); 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); 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" #define OPENPGP_CARD_INITIAL_PW3 "12345678"
#endif #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); extern int gpg_get_pw1_lifetime (void);

View File

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

View File

@ -38,6 +38,7 @@
#define INS_SELECT_FILE 0xa4 #define INS_SELECT_FILE 0xa4
#define INS_READ_BINARY 0xb0 #define INS_READ_BINARY 0xb0
#define INS_GET_DATA 0xca #define INS_GET_DATA 0xca
#define INS_WRITE_BINARY 0xd0
#define INS_UPDATE_BINARY 0xd6 #define INS_UPDATE_BINARY 0xd6
#define INS_PUT_DATA 0xda #define INS_PUT_DATA 0xda
#define INS_PUT_DATA_ODD 0xdb /* For key import */ #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 struct command
{ {
uint8_t command; uint8_t command;
@ -932,6 +995,7 @@ const struct command cmds[] = {
{ INS_SELECT_FILE, cmd_select_file }, { INS_SELECT_FILE, cmd_select_file },
{ INS_READ_BINARY, cmd_read_binary }, { INS_READ_BINARY, cmd_read_binary },
{ INS_GET_DATA, cmd_get_data }, { 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_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
{ INS_PUT_DATA, cmd_put_data }, { INS_PUT_DATA, cmd_put_data },
{ INS_PUT_DATA_ODD, cmd_put_data }, { INS_PUT_DATA_ODD, cmd_put_data },

View File

@ -1,7 +1,7 @@
#! /usr/bin/python #! /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. This tool is for importing certificate, updating random number, etc.
Copyright (C) 2011 Free Software Initiative of Japan 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 intel_hex import *
from struct import * from struct import *
import sys, time, os import sys, time, os, binascii
# INPUT: binary file # INPUT: binary file
@ -166,6 +166,21 @@ class gnuk_token:
if not (sw[0] == 0x90 and sw[1] == 0x00): if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, "cmd_verify" 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): def cmd_update_binary(self, fileid, data):
count = 0 count = 0
data_len = len(data) data_len = len(data)
@ -218,12 +233,7 @@ def get_device():
return dev, config, alt return dev, config, alt
raise ValueError, "Device not found" raise ValueError, "Device not found"
def main(fileid, filename): def main(fileid, is_update, data):
f = open(filename)
data = f.read()
f.close()
print "%s: %d" % (filename, len(data))
data += "\x90\x00"
dev, config, intf = get_device() dev, config, intf = get_device()
print "Device: ", dev.filename print "Device: ", dev.filename
print "Configuration: ", config.value print "Configuration: ", config.value
@ -234,7 +244,10 @@ def main(fileid, filename):
elif icc.icc_get_status() == 1: elif icc.icc_get_status() == 1:
icc.icc_power_on() icc.icc_power_on()
icc.cmd_verify(3, "12345678") icc.cmd_verify(3, "12345678")
if is_update:
icc.cmd_update_binary(fileid, data) icc.cmd_update_binary(fileid, data)
else:
icc.cmd_write_binary(fileid, data)
icc.cmd_select_openpgp() icc.cmd_select_openpgp()
data = data[:-2] data = data[:-2]
data_in_device = icc.cmd_get_data(0x7f, 0x21) data_in_device = icc.cmd_get_data(0x7f, 0x21)
@ -243,10 +256,46 @@ def main(fileid, filename):
return 0 return 0
if __name__ == '__main__': if __name__ == '__main__':
if os.path.basename(sys.argv[1] == "random_bits"): if sys.argv[1] == '-u':
fileid = 1 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" print "Updating random bits"
else: else:
fileid = 0 # Card holder certificate 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" print "Updating card holder certificate"
main(fileid, sys.argv[1]) main(fileid, is_update, data)