DO management change #1.
This commit is contained in:
12
ChangeLog
12
ChangeLog
@@ -1,3 +1,15 @@
|
||||
2010-11-04 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (DO_CMP_READ): Renamed.
|
||||
(cmp_ch_data, cmp_app_data, cmp_ss_temp): Likewise.
|
||||
(with_tag): Removed static global variable.
|
||||
(do_hist_bytes, do_fp_all, do_cafp_all, do_kgtime_all)
|
||||
(rw_pw_status, copy_do_1, copy_do, gpg_do_get_data): Added
|
||||
with_tag argument.
|
||||
(gpg_do_put_data): length > 255 will be error.
|
||||
|
||||
* src/flash.c (flash_do_release): Fill zero.
|
||||
|
||||
2010-11-03 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
Bug fixes.
|
||||
|
||||
4
README
4
README
@@ -55,6 +55,10 @@ It is known not-working well:
|
||||
* For some version of kernel and libccid, --enable-debug can't
|
||||
work well. Please disable DEBUG option if it doesn't work well.
|
||||
|
||||
Not (yet) supported feature(s):
|
||||
|
||||
* card holder certificate (its size matters (> 1KiB?), if we support)
|
||||
|
||||
|
||||
Targets
|
||||
=======
|
||||
|
||||
40
src/flash.c
40
src/flash.c
@@ -262,7 +262,45 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
||||
void
|
||||
flash_do_release (const uint8_t *do_data)
|
||||
{
|
||||
(void)do_data;
|
||||
uint32_t addr = (uint32_t)do_data;
|
||||
int state = 0;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
/* Fill 0x0000 for "tag and check" word */
|
||||
if (flash_program_halfword (addr - 2, 0) != FLASH_COMPLETE)
|
||||
return;
|
||||
|
||||
if (do_data[0] < 127)
|
||||
{
|
||||
len = do_data[0] - 1;
|
||||
addr += 2;
|
||||
}
|
||||
else if (do_data[0] == 0x81)
|
||||
{
|
||||
len = do_data[1];
|
||||
addr += 2;
|
||||
}
|
||||
else /* 0x82 */
|
||||
{
|
||||
len = ((do_data[1] << 8) | do_data[2]) - 1;
|
||||
addr += 4;
|
||||
}
|
||||
|
||||
/* Fill zero */
|
||||
for (i = 0; i < len/2; i ++)
|
||||
{
|
||||
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
||||
return;
|
||||
addr += 2;
|
||||
}
|
||||
|
||||
if ((len & 1))
|
||||
{
|
||||
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
||||
return;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
|
||||
@@ -111,7 +111,7 @@ static const uint8_t do_pw_status_bytes_template[] __attribute__ ((aligned (1)))
|
||||
enum do_type {
|
||||
DO_FIXED,
|
||||
DO_VAR,
|
||||
DO_CN_READ,
|
||||
DO_CMP_READ,
|
||||
DO_PROC_READ,
|
||||
DO_PROC_WRITE,
|
||||
DO_PROC_READWRITE,
|
||||
@@ -126,9 +126,8 @@ struct do_table_entry {
|
||||
};
|
||||
|
||||
static uint8_t *res_p;
|
||||
static int with_tag;
|
||||
|
||||
static void copy_do_1 (uint16_t tag, const uint8_t *do_data);
|
||||
static void copy_do_1 (uint16_t tag, const uint8_t *do_data, int with_tag);
|
||||
static const struct do_table_entry *get_do_entry (uint16_t tag);
|
||||
|
||||
#define GNUK_DO_PRVKEY_SIG 0xff01
|
||||
@@ -243,11 +242,11 @@ copy_tag (uint16_t tag)
|
||||
}
|
||||
|
||||
static int
|
||||
do_hist_bytes (uint16_t tag)
|
||||
do_hist_bytes (uint16_t tag, int with_tag)
|
||||
{
|
||||
/* XXX: For now, no life cycle management, just return template as is. */
|
||||
/* XXX: Supporing TERMINATE DF / ACTIVATE FILE, we need to fix here */
|
||||
copy_do_1 (tag, historical_bytes);
|
||||
copy_do_1 (tag, historical_bytes, with_tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -255,7 +254,7 @@ do_hist_bytes (uint16_t tag)
|
||||
#define SIZE_KGTIME 4
|
||||
|
||||
static int
|
||||
do_fp_all (uint16_t tag)
|
||||
do_fp_all (uint16_t tag, int with_tag)
|
||||
{
|
||||
const uint8_t *data;
|
||||
|
||||
@@ -290,7 +289,7 @@ do_fp_all (uint16_t tag)
|
||||
}
|
||||
|
||||
static int
|
||||
do_cafp_all (uint16_t tag)
|
||||
do_cafp_all (uint16_t tag, int with_tag)
|
||||
{
|
||||
const uint8_t *data;
|
||||
|
||||
@@ -325,7 +324,7 @@ do_cafp_all (uint16_t tag)
|
||||
}
|
||||
|
||||
static int
|
||||
do_kgtime_all (uint16_t tag)
|
||||
do_kgtime_all (uint16_t tag, int with_tag)
|
||||
{
|
||||
const uint8_t *data;
|
||||
|
||||
@@ -359,7 +358,8 @@ do_kgtime_all (uint16_t tag)
|
||||
}
|
||||
|
||||
static int
|
||||
rw_pw_status (uint16_t tag, const uint8_t *data, int len, int is_write)
|
||||
rw_pw_status (uint16_t tag, int with_tag,
|
||||
const uint8_t *data, int len, int is_write)
|
||||
{
|
||||
const uint8_t *do_data = do_ptr[NR_DO_PW_STATUS];
|
||||
|
||||
@@ -784,14 +784,14 @@ proc_key_import (const uint8_t *data, int len)
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
|
||||
static const uint16_t const cn_ch_data[] = {
|
||||
static const uint16_t const cmp_ch_data[] = {
|
||||
3,
|
||||
GPG_DO_NAME,
|
||||
GPG_DO_LANGUAGE,
|
||||
GPG_DO_SEX,
|
||||
};
|
||||
|
||||
static const uint16_t const cn_app_data[] = {
|
||||
static const uint16_t const cmp_app_data[] = {
|
||||
10,
|
||||
GPG_DO_AID,
|
||||
GPG_DO_HIST_BYTES,
|
||||
@@ -802,7 +802,7 @@ static const uint16_t const cn_app_data[] = {
|
||||
GPG_DO_FP_ALL, GPG_DO_CAFP_ALL, GPG_DO_KGTIME_ALL
|
||||
};
|
||||
|
||||
static const uint16_t const cn_ss_temp[] = { 1, GPG_DO_DS_COUNT };
|
||||
static const uint16_t const cmp_ss_temp[] = { 1, GPG_DO_DS_COUNT };
|
||||
|
||||
static const struct do_table_entry
|
||||
gpg_do_table[] = {
|
||||
@@ -848,9 +848,9 @@ gpg_do_table[] = {
|
||||
{ GPG_DO_ALG_DEC, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr },
|
||||
{ GPG_DO_ALG_AUT, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr },
|
||||
/* Compound data: Read access only */
|
||||
{ GPG_DO_CH_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ch_data },
|
||||
{ GPG_DO_APP_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_app_data },
|
||||
{ GPG_DO_SS_TEMP, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ss_temp },
|
||||
{ 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_SS_TEMP, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ss_temp },
|
||||
/* Simple data: write access only */
|
||||
{ GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED,
|
||||
proc_resetting_code },
|
||||
@@ -934,7 +934,7 @@ get_do_entry (uint16_t tag)
|
||||
}
|
||||
|
||||
static void
|
||||
copy_do_1 (uint16_t tag, const uint8_t *do_data)
|
||||
copy_do_1 (uint16_t tag, const uint8_t *do_data, int with_tag)
|
||||
{
|
||||
int len;
|
||||
|
||||
@@ -973,7 +973,7 @@ copy_do_1 (uint16_t tag, const uint8_t *do_data)
|
||||
}
|
||||
|
||||
static int
|
||||
copy_do (const struct do_table_entry *do_p)
|
||||
copy_do (const struct do_table_entry *do_p, int with_tag)
|
||||
{
|
||||
if (do_p == NULL)
|
||||
return 0;
|
||||
@@ -989,7 +989,7 @@ copy_do (const struct do_table_entry *do_p)
|
||||
if (do_data == NULL)
|
||||
return 0;
|
||||
else
|
||||
copy_do_1 (do_p->tag, do_data);
|
||||
copy_do_1 (do_p->tag, do_data, with_tag);
|
||||
break;
|
||||
}
|
||||
case DO_VAR:
|
||||
@@ -998,30 +998,29 @@ copy_do (const struct do_table_entry *do_p)
|
||||
if (do_data == NULL)
|
||||
return 0;
|
||||
else
|
||||
copy_do_1 (do_p->tag, do_data);
|
||||
copy_do_1 (do_p->tag, do_data, with_tag);
|
||||
break;
|
||||
}
|
||||
case DO_CN_READ:
|
||||
case DO_CMP_READ:
|
||||
{
|
||||
int i;
|
||||
const uint16_t *cn_data = (const uint16_t *)do_p->obj;
|
||||
int num_components = cn_data[0];
|
||||
const uint16_t *cmp_data = (const uint16_t *)do_p->obj;
|
||||
int num_components = cmp_data[0];
|
||||
uint8_t *len_p;
|
||||
|
||||
copy_tag (do_p->tag);
|
||||
*res_p++ = 0x81;
|
||||
*res_p++ = 0x81; /* Assume it's less than 256 */
|
||||
len_p = res_p;
|
||||
*res_p++ = 0; /* for now */
|
||||
with_tag = 1;
|
||||
|
||||
for (i = 0; i < num_components; i++)
|
||||
{
|
||||
uint16_t tag0;
|
||||
const struct do_table_entry *do0_p;
|
||||
|
||||
tag0 = cn_data[i+1];
|
||||
tag0 = cmp_data[i+1];
|
||||
do0_p = get_do_entry (tag0);
|
||||
if (copy_do (do0_p) < 0)
|
||||
if (copy_do (do0_p, 1) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1030,16 +1029,16 @@ copy_do (const struct do_table_entry *do_p)
|
||||
}
|
||||
case DO_PROC_READ:
|
||||
{
|
||||
int (*do_func)(uint16_t) = (int (*)(uint16_t))do_p->obj;
|
||||
int (*do_func)(uint16_t, int) = (int (*)(uint16_t, int))do_p->obj;
|
||||
|
||||
return do_func (do_p->tag);
|
||||
return do_func (do_p->tag, with_tag);
|
||||
}
|
||||
case DO_PROC_READWRITE:
|
||||
{
|
||||
int (*rw_func)(uint16_t, uint8_t *, int, int)
|
||||
= (int (*)(uint16_t, uint8_t *, int, int))do_p->obj;
|
||||
int (*rw_func)(uint16_t, int, uint8_t *, int, int)
|
||||
= (int (*)(uint16_t, int, uint8_t *, int, int))do_p->obj;
|
||||
|
||||
return rw_func (do_p->tag, NULL, 0, 0);
|
||||
return rw_func (do_p->tag, with_tag, NULL, 0, 0);
|
||||
}
|
||||
case DO_PROC_WRITE:
|
||||
return -1;
|
||||
@@ -1058,14 +1057,13 @@ gpg_do_get_data (uint16_t tag)
|
||||
const struct do_table_entry *do_p = get_do_entry (tag);
|
||||
|
||||
res_p = res_APDU;
|
||||
with_tag = 0;
|
||||
|
||||
DEBUG_INFO (" ");
|
||||
DEBUG_SHORT (tag);
|
||||
|
||||
if (do_p)
|
||||
{
|
||||
if (copy_do (do_p) < 0)
|
||||
if (copy_do (do_p, 0) < 0)
|
||||
/* Overwriting partially written result */
|
||||
GPG_SECURITY_FAILURE ();
|
||||
else
|
||||
@@ -1098,7 +1096,7 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len)
|
||||
switch (do_p->do_type)
|
||||
{
|
||||
case DO_FIXED:
|
||||
case DO_CN_READ:
|
||||
case DO_CMP_READ:
|
||||
case DO_PROC_READ:
|
||||
GPG_SECURITY_FAILURE ();
|
||||
break;
|
||||
@@ -1112,6 +1110,8 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len)
|
||||
if (len == 0)
|
||||
/* make DO empty */
|
||||
*do_data_p = NULL;
|
||||
else if (len > 255)
|
||||
GPG_MEMORY_FAILURE();
|
||||
else
|
||||
{
|
||||
uint8_t nr = do_tag_to_nr (tag);
|
||||
@@ -1126,10 +1126,10 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len)
|
||||
}
|
||||
case DO_PROC_READWRITE:
|
||||
{
|
||||
int (*rw_func)(uint16_t, const uint8_t *, int, int)
|
||||
= (int (*)(uint16_t, const uint8_t *, int, int))do_p->obj;
|
||||
int (*rw_func)(uint16_t, int, const uint8_t *, int, int)
|
||||
= (int (*)(uint16_t, int, const uint8_t *, int, int))do_p->obj;
|
||||
|
||||
rw_func (tag, data, len, 1);
|
||||
rw_func (tag, 0, data, len, 1);
|
||||
break;
|
||||
}
|
||||
case DO_PROC_WRITE:
|
||||
|
||||
Reference in New Issue
Block a user