DO management change #1.

This commit is contained in:
NIIBE Yutaka
2010-11-04 10:33:20 +09:00
parent 5a4c630186
commit 25422095c3
4 changed files with 92 additions and 38 deletions

View File

@@ -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> 2010-11-03 NIIBE Yutaka <gniibe@fsij.org>
Bug fixes. Bug fixes.

4
README
View File

@@ -55,6 +55,10 @@ It is known not-working well:
* For some version of kernel and libccid, --enable-debug can't * For some version of kernel and libccid, --enable-debug can't
work well. Please disable DEBUG option if it doesn't work well. 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 Targets
======= =======

View File

@@ -262,7 +262,45 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
void void
flash_do_release (const uint8_t *do_data) 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 * uint8_t *

View File

@@ -111,7 +111,7 @@ static const uint8_t do_pw_status_bytes_template[] __attribute__ ((aligned (1)))
enum do_type { enum do_type {
DO_FIXED, DO_FIXED,
DO_VAR, DO_VAR,
DO_CN_READ, DO_CMP_READ,
DO_PROC_READ, DO_PROC_READ,
DO_PROC_WRITE, DO_PROC_WRITE,
DO_PROC_READWRITE, DO_PROC_READWRITE,
@@ -126,9 +126,8 @@ struct do_table_entry {
}; };
static uint8_t *res_p; 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); static const struct do_table_entry *get_do_entry (uint16_t tag);
#define GNUK_DO_PRVKEY_SIG 0xff01 #define GNUK_DO_PRVKEY_SIG 0xff01
@@ -243,11 +242,11 @@ copy_tag (uint16_t tag)
} }
static int 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: For now, no life cycle management, just return template as is. */
/* XXX: Supporing TERMINATE DF / ACTIVATE FILE, we need to fix here */ /* 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; return 0;
} }
@@ -255,7 +254,7 @@ do_hist_bytes (uint16_t tag)
#define SIZE_KGTIME 4 #define SIZE_KGTIME 4
static int static int
do_fp_all (uint16_t tag) do_fp_all (uint16_t tag, int with_tag)
{ {
const uint8_t *data; const uint8_t *data;
@@ -290,7 +289,7 @@ do_fp_all (uint16_t tag)
} }
static int static int
do_cafp_all (uint16_t tag) do_cafp_all (uint16_t tag, int with_tag)
{ {
const uint8_t *data; const uint8_t *data;
@@ -325,7 +324,7 @@ do_cafp_all (uint16_t tag)
} }
static int static int
do_kgtime_all (uint16_t tag) do_kgtime_all (uint16_t tag, int with_tag)
{ {
const uint8_t *data; const uint8_t *data;
@@ -359,7 +358,8 @@ do_kgtime_all (uint16_t tag)
} }
static int 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]; 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 (); GPG_SUCCESS ();
} }
static const uint16_t const cn_ch_data[] = { static const uint16_t const cmp_ch_data[] = {
3, 3,
GPG_DO_NAME, GPG_DO_NAME,
GPG_DO_LANGUAGE, GPG_DO_LANGUAGE,
GPG_DO_SEX, GPG_DO_SEX,
}; };
static const uint16_t const cn_app_data[] = { static const uint16_t const cmp_app_data[] = {
10, 10,
GPG_DO_AID, GPG_DO_AID,
GPG_DO_HIST_BYTES, 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 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 static const struct do_table_entry
gpg_do_table[] = { 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_DEC, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr },
{ GPG_DO_ALG_AUT, 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 */ /* Compound data: Read access only */
{ GPG_DO_CH_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ch_data }, { GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
{ GPG_DO_APP_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_app_data }, { GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data },
{ GPG_DO_SS_TEMP, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ss_temp }, { GPG_DO_SS_TEMP, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ss_temp },
/* Simple data: write access only */ /* Simple data: write access only */
{ GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED, { GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED,
proc_resetting_code }, proc_resetting_code },
@@ -934,7 +934,7 @@ get_do_entry (uint16_t tag)
} }
static void 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; int len;
@@ -973,7 +973,7 @@ copy_do_1 (uint16_t tag, const uint8_t *do_data)
} }
static int 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) if (do_p == NULL)
return 0; return 0;
@@ -989,7 +989,7 @@ copy_do (const struct do_table_entry *do_p)
if (do_data == NULL) if (do_data == NULL)
return 0; return 0;
else else
copy_do_1 (do_p->tag, do_data); copy_do_1 (do_p->tag, do_data, with_tag);
break; break;
} }
case DO_VAR: case DO_VAR:
@@ -998,30 +998,29 @@ copy_do (const struct do_table_entry *do_p)
if (do_data == NULL) if (do_data == NULL)
return 0; return 0;
else else
copy_do_1 (do_p->tag, do_data); copy_do_1 (do_p->tag, do_data, with_tag);
break; break;
} }
case DO_CN_READ: case DO_CMP_READ:
{ {
int i; int i;
const uint16_t *cn_data = (const uint16_t *)do_p->obj; const uint16_t *cmp_data = (const uint16_t *)do_p->obj;
int num_components = cn_data[0]; int num_components = cmp_data[0];
uint8_t *len_p; uint8_t *len_p;
copy_tag (do_p->tag); copy_tag (do_p->tag);
*res_p++ = 0x81; *res_p++ = 0x81; /* Assume it's less than 256 */
len_p = res_p; len_p = res_p;
*res_p++ = 0; /* for now */ *res_p++ = 0; /* for now */
with_tag = 1;
for (i = 0; i < num_components; i++) for (i = 0; i < num_components; i++)
{ {
uint16_t tag0; uint16_t tag0;
const struct do_table_entry *do0_p; const struct do_table_entry *do0_p;
tag0 = cn_data[i+1]; tag0 = cmp_data[i+1];
do0_p = get_do_entry (tag0); do0_p = get_do_entry (tag0);
if (copy_do (do0_p) < 0) if (copy_do (do0_p, 1) < 0)
return -1; return -1;
} }
@@ -1030,16 +1029,16 @@ copy_do (const struct do_table_entry *do_p)
} }
case DO_PROC_READ: 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: case DO_PROC_READWRITE:
{ {
int (*rw_func)(uint16_t, uint8_t *, int, int) int (*rw_func)(uint16_t, int, uint8_t *, int, int)
= (int (*)(uint16_t, uint8_t *, int, int))do_p->obj; = (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: case DO_PROC_WRITE:
return -1; return -1;
@@ -1058,14 +1057,13 @@ gpg_do_get_data (uint16_t tag)
const struct do_table_entry *do_p = get_do_entry (tag); const struct do_table_entry *do_p = get_do_entry (tag);
res_p = res_APDU; res_p = res_APDU;
with_tag = 0;
DEBUG_INFO (" "); DEBUG_INFO (" ");
DEBUG_SHORT (tag); DEBUG_SHORT (tag);
if (do_p) if (do_p)
{ {
if (copy_do (do_p) < 0) if (copy_do (do_p, 0) < 0)
/* Overwriting partially written result */ /* Overwriting partially written result */
GPG_SECURITY_FAILURE (); GPG_SECURITY_FAILURE ();
else else
@@ -1098,7 +1096,7 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len)
switch (do_p->do_type) switch (do_p->do_type)
{ {
case DO_FIXED: case DO_FIXED:
case DO_CN_READ: case DO_CMP_READ:
case DO_PROC_READ: case DO_PROC_READ:
GPG_SECURITY_FAILURE (); GPG_SECURITY_FAILURE ();
break; break;
@@ -1112,6 +1110,8 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len)
if (len == 0) if (len == 0)
/* make DO empty */ /* make DO empty */
*do_data_p = NULL; *do_data_p = NULL;
else if (len > 255)
GPG_MEMORY_FAILURE();
else else
{ {
uint8_t nr = do_tag_to_nr (tag); 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: case DO_PROC_READWRITE:
{ {
int (*rw_func)(uint16_t, const uint8_t *, int, int) int (*rw_func)(uint16_t, int, const uint8_t *, int, int)
= (int (*)(uint16_t, const uint8_t *, int, int))do_p->obj; = (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; break;
} }
case DO_PROC_WRITE: case DO_PROC_WRITE: