support factory_reset.
This commit is contained in:
21
ChangeLog
21
ChangeLog
@@ -1,3 +1,24 @@
|
|||||||
|
2016-10-14 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/usb-ccid.c (ccid_power_on) [LIFE_CYCLE_MANAGEMENT_SUPPORT]:
|
||||||
|
Change LCS value in ATR at run time.
|
||||||
|
|
||||||
|
* src/openpgp.c (gpg_init): Handle FILE_CARD_TERMINATED.
|
||||||
|
(cmd_select_file): Don't return AID.
|
||||||
|
(cmd_activate_file, cmd_terminate_df): New.
|
||||||
|
(process_command_apdu): Let return GPG_NO_RECORD() when
|
||||||
|
not selected.
|
||||||
|
|
||||||
|
* src/openpgp-do.c (gpg_do_terminate): New.
|
||||||
|
(gpg_data_scan): Handle p_start is NULL.
|
||||||
|
(do_hist_bytes): Remove.
|
||||||
|
|
||||||
|
* src/flash.c (flash_data): Change the value from 0x0000.
|
||||||
|
(flash_init): Support termination state. Fix handling
|
||||||
|
of the boundary case where gen0 is 0xfffe.
|
||||||
|
(flash_terminate, flash_activate): New.
|
||||||
|
(flash_copying_gc): Skip 0xffff for generation number.
|
||||||
|
|
||||||
2016-10-13 Niibe Yutaka <gniibe@fsij.org>
|
2016-10-13 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* src/status-code.h: Rename from openpgp.h.
|
* src/status-code.h: Rename from openpgp.h.
|
||||||
|
|||||||
16
NEWS
16
NEWS
@@ -1,5 +1,21 @@
|
|||||||
Gnuk NEWS - User visible changes
|
Gnuk NEWS - User visible changes
|
||||||
|
|
||||||
|
* Major changes in Gnuk 1.2.2
|
||||||
|
|
||||||
|
Released 2016-10-14, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** Change of SELECT FILE behavior
|
||||||
|
Gnuk used to reply AID upon SELECT FILE command. Now, to be compatible
|
||||||
|
to original OpenPGP card, it returns nothing but status code of 9000.
|
||||||
|
|
||||||
|
** Added feature of Factory Reset as compile time option
|
||||||
|
Original OpenPGP card has the feature, and Gnuk is now configurable to
|
||||||
|
support the feature.
|
||||||
|
|
||||||
|
** Upgrade of Chopstx
|
||||||
|
We use Chopstx 1.2.
|
||||||
|
|
||||||
|
|
||||||
* Major changes in Gnuk 1.2.1
|
* Major changes in Gnuk 1.2.1
|
||||||
|
|
||||||
Released 2016-07-11, by NIIBE Yutaka
|
Released 2016-07-11, by NIIBE Yutaka
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ void ac_fini (void);
|
|||||||
|
|
||||||
|
|
||||||
void set_res_sw (uint8_t sw1, uint8_t sw2);
|
void set_res_sw (uint8_t sw1, uint8_t sw2);
|
||||||
|
extern uint8_t file_selection;
|
||||||
extern const uint8_t historical_bytes[];
|
extern const uint8_t historical_bytes[];
|
||||||
extern uint16_t data_objects_number_of_bytes;
|
extern uint16_t data_objects_number_of_bytes;
|
||||||
|
|
||||||
|
|||||||
@@ -90,10 +90,10 @@ uint16_t data_objects_number_of_bytes;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Compile time vars:
|
* Compile time vars:
|
||||||
* Historical Bytes (template), Extended Capabilities.
|
* Historical Bytes, Extended Capabilities.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Historical Bytes (template) */
|
/* Historical Bytes */
|
||||||
const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||||
10,
|
10,
|
||||||
0x00,
|
0x00,
|
||||||
@@ -102,7 +102,12 @@ const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
|||||||
0x80, 0x01, 0x80, /* Full DF name */
|
0x80, 0x01, 0x80, /* Full DF name */
|
||||||
/* 1-byte */
|
/* 1-byte */
|
||||||
/* Command chaining, No extended Lc and Le */
|
/* Command chaining, No extended Lc and Le */
|
||||||
0x00, 0x90, 0x00 /* Status info (no life cycle management) */
|
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||||
|
0x05,
|
||||||
|
#else
|
||||||
|
0x00,
|
||||||
|
#endif
|
||||||
|
0x90, 0x00 /* Status info */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Extended Capabilities */
|
/* Extended Capabilities */
|
||||||
@@ -485,23 +490,6 @@ copy_tag (uint16_t tag)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
do_hist_bytes (uint16_t tag, int with_tag)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Currently, we support no life cycle management. In case of Gnuk,
|
|
||||||
* user could flash the MCU with SWD/JTAG, instead. It is also
|
|
||||||
* possible for user to do firmware upgrade through USB.
|
|
||||||
*
|
|
||||||
* Thus, here, it just returns the template as is.
|
|
||||||
*
|
|
||||||
* In future (when Gnuk will be on the real smartcard),
|
|
||||||
* we can support life cycle management by implementing
|
|
||||||
* TERMINATE DF / ACTIVATE FILE and fix code around here.
|
|
||||||
*/
|
|
||||||
copy_do_1 (tag, historical_bytes, with_tag);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SIZE_FP 20
|
#define SIZE_FP 20
|
||||||
#define SIZE_KGTIME 4
|
#define SIZE_KGTIME 4
|
||||||
@@ -1513,7 +1501,6 @@ gpg_do_table[] = {
|
|||||||
{ GPG_DO_NAME, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[12] },
|
{ GPG_DO_NAME, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[12] },
|
||||||
{ GPG_DO_LANGUAGE, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[13] },
|
{ GPG_DO_LANGUAGE, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[13] },
|
||||||
/* Pseudo DO READ: calculated */
|
/* Pseudo DO READ: calculated */
|
||||||
{ GPG_DO_HIST_BYTES, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_hist_bytes },
|
|
||||||
{ GPG_DO_FP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_fp_all },
|
{ GPG_DO_FP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_fp_all },
|
||||||
{ GPG_DO_CAFP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_cafp_all },
|
{ GPG_DO_CAFP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_cafp_all },
|
||||||
{ GPG_DO_KGTIME_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_kgtime_all },
|
{ GPG_DO_KGTIME_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_kgtime_all },
|
||||||
@@ -1530,6 +1517,7 @@ gpg_do_table[] = {
|
|||||||
{ GPG_DO_ALG_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
{ GPG_DO_ALG_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
||||||
rw_algorithm_attr },
|
rw_algorithm_attr },
|
||||||
/* Fixed data */
|
/* Fixed data */
|
||||||
|
{ GPG_DO_HIST_BYTES, DO_FIXED, AC_ALWAYS, AC_NEVER, historical_bytes },
|
||||||
{ GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
|
{ GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
|
||||||
/* Compound data: Read access only */
|
/* Compound data: Read access only */
|
||||||
{ GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
|
{ GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ set_res_sw (uint8_t sw1, uint8_t sw2)
|
|||||||
#define FILE_CARD_TERMINATED_OPENPGP 254
|
#define FILE_CARD_TERMINATED_OPENPGP 254
|
||||||
#define FILE_CARD_TERMINATED 255
|
#define FILE_CARD_TERMINATED 255
|
||||||
|
|
||||||
static uint8_t file_selection;
|
uint8_t file_selection;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gpg_init (void)
|
gpg_init (void)
|
||||||
@@ -765,18 +765,9 @@ cmd_select_file (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
file_selection = FILE_DF_OPENPGP;
|
file_selection = FILE_DF_OPENPGP;
|
||||||
if ((P2 (apdu) & 0x0c) == 0x0c) /* No FCI */
|
|
||||||
GPG_SUCCESS ();
|
/* Behave just like original OpenPGP card. */
|
||||||
else
|
GPG_SUCCESS ();
|
||||||
{
|
|
||||||
gpg_do_get_data (0x004f, 1); /* AID */
|
|
||||||
memmove (res_APDU+2, res_APDU, res_APDU_size);
|
|
||||||
res_APDU[0] = 0x6f;
|
|
||||||
res_APDU[1] = 0x12;
|
|
||||||
res_APDU[2] = 0x84; /* overwrite: DF name */
|
|
||||||
res_APDU_size += 2;
|
|
||||||
GPG_SUCCESS ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (apdu.cmd_apdu_data_len == 2
|
else if (apdu.cmd_apdu_data_len == 2
|
||||||
&& apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
|
&& apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
|
||||||
|
|||||||
@@ -795,6 +795,10 @@ ccid_power_on (struct ccid *c)
|
|||||||
memcpy (p + CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
|
memcpy (p + CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
|
||||||
memcpy (p + CCID_MSG_HEADER_SIZE + sizeof (ATR_head),
|
memcpy (p + CCID_MSG_HEADER_SIZE + sizeof (ATR_head),
|
||||||
historical_bytes + 1, historical_bytes[0]);
|
historical_bytes + 1, historical_bytes[0]);
|
||||||
|
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||||
|
if (file_selection == 255)
|
||||||
|
p[CCID_MSG_HEADER_SIZE + sizeof (ATR_head) + 7] = 0x03;
|
||||||
|
#endif
|
||||||
for (i = 1; i < (int)size_atr - 1; i++)
|
for (i = 1; i < (int)size_atr - 1; i++)
|
||||||
xor_check ^= p[CCID_MSG_HEADER_SIZE + i];
|
xor_check ^= p[CCID_MSG_HEADER_SIZE + i];
|
||||||
p[CCID_MSG_HEADER_SIZE+size_atr-1] = xor_check;
|
p[CCID_MSG_HEADER_SIZE+size_atr-1] = xor_check;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Feature: command GET DATA
|
|||||||
|
|
||||||
Scenario: data object historical bytes
|
Scenario: data object historical bytes
|
||||||
When requesting historical bytes: 5f52
|
When requesting historical bytes: 5f52
|
||||||
Then you should get: \x00\x31\x84\x73\x80\x01\x80\x00\x90\x00
|
Then data should match: \x00\x31\x84\x73\x80\x01\x80[\x00\x05]\x90\x00
|
||||||
|
|
||||||
Scenario: data object extended capabilities
|
Scenario: data object extended capabilities
|
||||||
When requesting extended capabilities: c0
|
When requesting extended capabilities: c0
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Feature: command GET DATA
|
|||||||
|
|
||||||
Scenario: data object historical bytes
|
Scenario: data object historical bytes
|
||||||
When requesting historical bytes: 5f52
|
When requesting historical bytes: 5f52
|
||||||
Then you should get: \x00\x31\x84\x73\x80\x01\x80\x00\x90\x00
|
Then data should match: \x00\x31\x84\x73\x80\x01\x80[\x00\x05]\x90\x00
|
||||||
|
|
||||||
Scenario: data object extended capabilities
|
Scenario: data object extended capabilities
|
||||||
When requesting extended capabilities: c0
|
When requesting extended capabilities: c0
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Feature: command GET DATA
|
|||||||
|
|
||||||
Scenario: data object historical bytes
|
Scenario: data object historical bytes
|
||||||
When requesting historical bytes: 5f52
|
When requesting historical bytes: 5f52
|
||||||
Then you should get: \x00\x31\x84\x73\x80\x01\x80\x00\x90\x00
|
Then data should match: \x00\x31\x84\x73\x80\x01\x80[\x00\x05]\x90\x00
|
||||||
|
|
||||||
Scenario: data object extended capabilities
|
Scenario: data object extended capabilities
|
||||||
When requesting extended capabilities: c0
|
When requesting extended capabilities: c0
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ def test_verify_pw3(card):
|
|||||||
def test_historical_bytes(card):
|
def test_historical_bytes(card):
|
||||||
h = get_data_object(card, 0x5f52)
|
h = get_data_object(card, 0x5f52)
|
||||||
assert h == b'\x001\xc5s\xc0\x01@\x05\x90\x00' or \
|
assert h == b'\x001\xc5s\xc0\x01@\x05\x90\x00' or \
|
||||||
h == b'\x00\x31\x84\x73\x80\x01\x80\x00\x90\x00'
|
h == b'\x00\x31\x84\x73\x80\x01\x80\x00\x90\x00' or \
|
||||||
|
h == b'\x00\x31\x84\x73\x80\x01\x80\x05\x90\x00'
|
||||||
|
|
||||||
def test_extended_capabilities(card):
|
def test_extended_capabilities(card):
|
||||||
a = get_data_object(card, 0xc0)
|
a = get_data_object(card, 0xc0)
|
||||||
|
|||||||
Reference in New Issue
Block a user