Add UIF Data Object support for Acknowledge Button.
This commit is contained in:
14
ChangeLog
14
ChangeLog
@@ -1,3 +1,17 @@
|
|||||||
|
2018-09-27 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/gnuk.h (NR_DO_UIF_SIG, NR_DO_UIF_DEC, NR_DO_UIF_AUT): New.
|
||||||
|
* src/openpgp-do.c (rw_uif) [ACKBTN_SUPPORT]: New.
|
||||||
|
(GPG_DO_UIF_SIG, GPG_DO_UIF_DEC, GPG_DO_UIF_AUT): New.
|
||||||
|
(feature_mngmnt) [ACKBTN_SUPPORT]: New.
|
||||||
|
(cmp_app_data, cmp_discretionary): Add ACKBTN_SUPPORT.
|
||||||
|
(gpg_do_table): Add for GPG_DO_UIF_SIG, GPG_DO_UIF_DEC,
|
||||||
|
GPG_DO_UIF_AUT, and GPG_DO_FEATURE_MNGMNT.
|
||||||
|
(gpg_do_get_uif) [ACKBTN_SUPPORT]: New.
|
||||||
|
(gpg_data_scan): Handle uif_flags.
|
||||||
|
* src/openpgp.c (process_command_apdu) [ACKBTN_SUPPORT]: Add user
|
||||||
|
interaction handling.
|
||||||
|
|
||||||
2018-09-27 NIIBE Yutaka <gniibe@fsij.org>
|
2018-09-27 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* src/gnuk.h (LED_WAIT_FOR_BUTTON): New.
|
* src/gnuk.h (LED_WAIT_FOR_BUTTON): New.
|
||||||
|
|||||||
11
src/gnuk.h
11
src/gnuk.h
@@ -124,8 +124,8 @@ const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
|
|||||||
|
|
||||||
enum kind_of_key {
|
enum kind_of_key {
|
||||||
GPG_KEY_FOR_SIGNING = 0,
|
GPG_KEY_FOR_SIGNING = 0,
|
||||||
GPG_KEY_FOR_DECRYPTION,
|
GPG_KEY_FOR_DECRYPTION = 1,
|
||||||
GPG_KEY_FOR_AUTHENTICATION,
|
GPG_KEY_FOR_AUTHENTICATION = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum size_of_key {
|
enum size_of_key {
|
||||||
@@ -297,6 +297,7 @@ void gpg_increment_digital_signature_counter (void);
|
|||||||
void gpg_do_get_initial_pw_setting (int is_pw3, int *r_len,
|
void gpg_do_get_initial_pw_setting (int is_pw3, int *r_len,
|
||||||
const uint8_t **r_p);
|
const uint8_t **r_p);
|
||||||
int gpg_do_kdf_check (int len, int how_many);
|
int gpg_do_kdf_check (int len, int how_many);
|
||||||
|
int gpg_do_get_uif (enum kind_of_key kk);
|
||||||
|
|
||||||
|
|
||||||
void fatal (uint8_t code) __attribute__ ((noreturn));
|
void fatal (uint8_t code) __attribute__ ((noreturn));
|
||||||
@@ -380,9 +381,9 @@ extern uint8_t admin_authorized;
|
|||||||
#define NR_KEY_ALGO_ATTR_AUT 0xf3
|
#define NR_KEY_ALGO_ATTR_AUT 0xf3
|
||||||
/*
|
/*
|
||||||
* Representation of User Interaction Flag:
|
* Representation of User Interaction Flag:
|
||||||
* 0 (UIF disabled): No record in flash memory
|
* 0 (UIF disabled): 0xf?00 or No record in flash memory
|
||||||
* 1 (UIF enabled): 0xf?ff
|
* 1 (UIF enabled): 0xf?01
|
||||||
* 2 (UIF permanently enabled): 0xf?00
|
* 2 (UIF permanently enabled): 0xf?02
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define NR_DO_UIF_SIG 0xf6
|
#define NR_DO_UIF_SIG 0xf6
|
||||||
|
|||||||
@@ -135,11 +135,13 @@ static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
|
|||||||
0x01, 0x00,
|
0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
/* General Feature Management */
|
/* General Feature Management */
|
||||||
static const uint8_t feature_mngmnt[] __attribute__ ((aligned (1))) = {
|
static const uint8_t feature_mngmnt[] __attribute__ ((aligned (1))) = {
|
||||||
3,
|
3,
|
||||||
0x81, 0x01, 0x20,
|
0x81, 0x01, 0x20,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Algorithm Attributes */
|
/* Algorithm Attributes */
|
||||||
#define OPENPGP_ALGO_RSA 0x01
|
#define OPENPGP_ALGO_RSA 0x01
|
||||||
@@ -813,6 +815,64 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t uif_flags; /* Six bits of flags */
|
||||||
|
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
|
int
|
||||||
|
gpg_do_get_uif (enum kind_of_key kk)
|
||||||
|
{
|
||||||
|
return ((uif_flags >> (kk * 2)) & 3) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rw_uif (uint16_t tag, int with_tag, const uint8_t *data, int len, int is_write)
|
||||||
|
{
|
||||||
|
uint8_t nr;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
if (tag != GPG_DO_UIF_SIG || tag != GPG_DO_UIF_DEC || tag != GPG_DO_UIF_AUT)
|
||||||
|
return 0; /* Failure */
|
||||||
|
|
||||||
|
nr = (tag - GPG_DO_UIF_SIG) + NR_DO_UIF_SIG;
|
||||||
|
v = (uif_flags >> ((tag - GPG_DO_UIF_SIG) * 2)) & 3;
|
||||||
|
if (is_write)
|
||||||
|
{
|
||||||
|
const uint8_t *p;
|
||||||
|
|
||||||
|
if (len != 2 || data[1] != 0x20)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (v == 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (data[0] != 0x00 || data[0] != 0x01 || data[0] != 0x02)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p = flash_enum_write (nr, data[0]);
|
||||||
|
if (p == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uif_flags &= ~(3 << ((nr - NR_DO_UIF_SIG) * 2));
|
||||||
|
uif_flags |= (data[0] & 3) << ((nr - NR_DO_UIF_SIG) * 2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (with_tag)
|
||||||
|
{
|
||||||
|
copy_tag (tag);
|
||||||
|
*res_p++ = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*res_p++ = v;
|
||||||
|
*res_p++ = 0x20;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define SIZE_OF_KDF_DO_MIN 90
|
#define SIZE_OF_KDF_DO_MIN 90
|
||||||
#define SIZE_OF_KDF_DO_MAX 110
|
#define SIZE_OF_KDF_DO_MAX 110
|
||||||
#define OPENPGP_KDF_ITERSALTED_S2K 3
|
#define OPENPGP_KDF_ITERSALTED_S2K 3
|
||||||
@@ -1620,20 +1680,32 @@ static const uint16_t cmp_ch_data[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t cmp_app_data[] = {
|
static const uint16_t cmp_app_data[] = {
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
4,
|
4,
|
||||||
|
#else
|
||||||
|
3,
|
||||||
|
#endif
|
||||||
GPG_DO_AID,
|
GPG_DO_AID,
|
||||||
GPG_DO_HIST_BYTES,
|
GPG_DO_HIST_BYTES,
|
||||||
GPG_DO_DISCRETIONARY,
|
GPG_DO_DISCRETIONARY,
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
GPG_DO_FEATURE_MNGMNT,
|
GPG_DO_FEATURE_MNGMNT,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t cmp_discretionary[] = {
|
static const uint16_t cmp_discretionary[] = {
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
11,
|
11,
|
||||||
|
#else
|
||||||
|
8,
|
||||||
|
#endif
|
||||||
GPG_DO_EXTCAP,
|
GPG_DO_EXTCAP,
|
||||||
GPG_DO_ALG_SIG, GPG_DO_ALG_DEC, GPG_DO_ALG_AUT,
|
GPG_DO_ALG_SIG, GPG_DO_ALG_DEC, GPG_DO_ALG_AUT,
|
||||||
GPG_DO_PW_STATUS,
|
GPG_DO_PW_STATUS,
|
||||||
GPG_DO_FP_ALL, GPG_DO_CAFP_ALL, GPG_DO_KGTIME_ALL,
|
GPG_DO_FP_ALL, GPG_DO_CAFP_ALL, GPG_DO_KGTIME_ALL,
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
GPG_DO_UIF_SIG, GPG_DO_UIF_DEC, GPG_DO_UIF_AUT
|
GPG_DO_UIF_SIG, GPG_DO_UIF_DEC, GPG_DO_UIF_AUT
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t cmp_ss_temp[] = { 1, GPG_DO_DS_COUNT };
|
static const uint16_t cmp_ss_temp[] = { 1, GPG_DO_DS_COUNT };
|
||||||
@@ -1672,15 +1744,19 @@ gpg_do_table[] = {
|
|||||||
rw_algorithm_attr },
|
rw_algorithm_attr },
|
||||||
{ 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 },
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
{ GPG_DO_UIF_SIG, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
|
{ GPG_DO_UIF_SIG, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
|
||||||
{ GPG_DO_UIF_DEC, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
|
{ GPG_DO_UIF_DEC, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
|
||||||
{ GPG_DO_UIF_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
|
{ GPG_DO_UIF_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
|
||||||
|
#endif
|
||||||
{ GPG_DO_KDF, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
{ GPG_DO_KDF, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
||||||
rw_kdf },
|
rw_kdf },
|
||||||
/* Fixed data */
|
/* Fixed data */
|
||||||
{ GPG_DO_HIST_BYTES, DO_FIXED, AC_ALWAYS, AC_NEVER, historical_bytes },
|
{ 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 },
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
{ GPG_DO_FEATURE_MNGMNT, DO_FIXED, AC_ALWAYS, AC_NEVER, feature_mngmnt },
|
{ GPG_DO_FEATURE_MNGMNT, DO_FIXED, AC_ALWAYS, AC_NEVER, feature_mngmnt },
|
||||||
|
#endif
|
||||||
/* 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 },
|
||||||
{ GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data },
|
{ GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data },
|
||||||
@@ -1719,6 +1795,7 @@ gpg_data_scan (const uint8_t *do_start, const uint8_t *do_end)
|
|||||||
pw_err_counter_p[PW_ERR_PW3] = NULL;
|
pw_err_counter_p[PW_ERR_PW3] = NULL;
|
||||||
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
|
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
|
||||||
digital_signature_counter = 0;
|
digital_signature_counter = 0;
|
||||||
|
uif_flags = 0;
|
||||||
|
|
||||||
/* When the card is terminated no data objects are valid. */
|
/* When the card is terminated no data objects are valid. */
|
||||||
if (do_start == NULL)
|
if (do_start == NULL)
|
||||||
@@ -1777,6 +1854,12 @@ gpg_data_scan (const uint8_t *do_start, const uint8_t *do_end)
|
|||||||
algo_attr_aut_p = p - 1;
|
algo_attr_aut_p = p - 1;
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
|
case NR_DO_UIF_SIG:
|
||||||
|
case NR_DO_UIF_DEC:
|
||||||
|
case NR_DO_UIF_AUT:
|
||||||
|
uif_flags &= ~(3 << ((nr - NR_DO_UIF_SIG) * 2));
|
||||||
|
uif_flags |= (second_byte & 3) << ((nr - NR_DO_UIF_SIG) * 2);
|
||||||
|
break;
|
||||||
case NR_COUNTER_123:
|
case NR_COUNTER_123:
|
||||||
p++;
|
p++;
|
||||||
if (second_byte <= PW_ERR_PW3)
|
if (second_byte <= PW_ERR_PW3)
|
||||||
|
|||||||
@@ -1506,6 +1506,9 @@ process_command_apdu (void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t cmd = INS (apdu);
|
uint8_t cmd = INS (apdu);
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
|
uint8_t was_signing = (P1 (apdu) == 0x9e && P2 (apdu) == 0x9a);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < NUM_CMDS; i++)
|
for (i = 0; i < NUM_CMDS; i++)
|
||||||
if (cmds[i].command == cmd)
|
if (cmds[i].command == cmd)
|
||||||
@@ -1537,7 +1540,21 @@ process_command_apdu (void)
|
|||||||
GPG_NO_INS ();
|
GPG_NO_INS ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (cmd == INS_PSO) | (cmd == INS_INTERNAL_AUTHENTICATE);
|
#ifdef ACKBTN_SUPPORT
|
||||||
|
if (cmd == INS_PSO)
|
||||||
|
{
|
||||||
|
if (was_signing)
|
||||||
|
return gpg_do_get_uif (GPG_KEY_FOR_SIGNING);
|
||||||
|
else
|
||||||
|
return gpg_do_get_uif (GPG_KEY_FOR_DECRYPTION);
|
||||||
|
}
|
||||||
|
else if (cmd == INS_INTERNAL_AUTHENTICATE)
|
||||||
|
return gpg_do_get_uif (GPG_KEY_FOR_AUTHENTICATION);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|||||||
Reference in New Issue
Block a user