Prevent observation of PW3 emptiness

This commit is contained in:
NIIBE Yutaka
2011-05-10 09:11:40 +09:00
parent a9ea672cf3
commit 79c9ad9fd4
5 changed files with 73 additions and 23 deletions

View File

@@ -1,3 +1,15 @@
2011-05-10 NIIBE Yutaka <gniibe@fsij.org>
Prevent observation of PW3 is emptiness by PW3's error counter.
Support verify_admin by PW1 when PW3 is empty.
* src/ac.c (admin_authorized): New.
(verify_admin_0): Set admin_authorized.
* src/openpgp-do.c (proc_resetting_code): Use admin_authorized.
(gpg_do_write_prvkey): Clear dek_encrypted_3 when keystring_admin
is NULL.
(proc_key_import): Checking admin_authorized, set keystring_admin.
* src/openpgp.c (cmd_reset_user_password): Use admin_authorized.
2011-04-18 NIIBE Yutaka <gniibe@fsij.org>
* gnuk.svg: Updated.

View File

@@ -161,6 +161,9 @@ calc_md (int count, const uint8_t *salt, const uint8_t *pw, int pw_len,
memset (&sha1_ctx, 0, sizeof (sha1_ctx));
}
uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
uint8_t admin_authorized;
int
verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known)
{
@@ -191,25 +194,51 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known)
gpg_increment_pw_err_counter (PW_ERR_PW3);
return -1;
}
else
admin_authorized = BY_ADMIN;
success:
/* OK, the user is now authenticated */
gpg_reset_pw_err_counter (PW_ERR_PW3);
return pw_len;
}
else
/* For empty PW3, pass phrase should be OPENPGP_CARD_INITIAL_PW3 */
{
const uint8_t *ks_pw1;
uint8_t pw1_keystring[KEYSTRING_SIZE_PW1];
ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
if (ks_pw1 == NULL)
{ /*
* For empty PW3 with empty PW1, pass phrase should be
* OPENPGP_CARD_INITIAL_PW3
*/
if ((pw_len_known >=0
&& pw_len_known != strlen (OPENPGP_CARD_INITIAL_PW3))
|| buf_len < (int)strlen (OPENPGP_CARD_INITIAL_PW3)
|| strncmp ((const char *)pw, OPENPGP_CARD_INITIAL_PW3,
strlen (OPENPGP_CARD_INITIAL_PW3)) != 0)
/* It is failure, but we don't try to lock for the case of empty PW3 */
return -1;
goto failure;
pw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
admin_authorized = BY_ADMIN;
goto success;
}
else /* empty PW3, but PW1 exists */
{
pw_len = ks_pw1[0];
if (pw_len_known < 0 && pw_len_known != pw_len)
goto failure;
return pw_len;
pw1_keystring[0] = pw_len;
sha1 (pw, pw_len, pw1_keystring+1);
if (gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER,
pw1_keystring + 1) < 0)
goto failure;
admin_authorized = BY_USER;
goto success;
}
}
}
void
@@ -229,8 +258,6 @@ gpg_set_pw3 (const uint8_t *newpw, int newpw_len)
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, ks, KEYSTRING_SIZE_PW3);
}
uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
int
verify_admin (const uint8_t *pw, int pw_len)
{

View File

@@ -211,6 +211,7 @@ extern void fatal (uint8_t code) __attribute__ ((noreturn));
#define FATAL_RANDOM 2
extern uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
extern uint8_t admin_authorized;
/*** Flash memory tag values ***/
#define NR_NONE 0x00

View File

@@ -525,7 +525,7 @@ proc_resetting_code (const uint8_t *data, int len)
newpw = data;
sha1 (newpw, newpw_len, new_ks);
new_ks0[0] = newpw_len;
r = gpg_change_keystring (BY_ADMIN, old_ks, BY_RESETCODE, new_ks);
r = gpg_change_keystring (admin_authorized, old_ks, BY_RESETCODE, new_ks);
if (r < -2)
{
DEBUG_INFO ("memory error.\r\n");
@@ -656,7 +656,7 @@ static int8_t num_prv_keys;
static int
gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
const uint8_t *keystring)
const uint8_t *keystring_admin)
{
uint8_t nr = get_do_ptr_nr_for_kk (kk);
const uint8_t *p;
@@ -752,7 +752,10 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
else
memset (pd->dek_encrypted_2, 0, DATA_ENCRYPTION_KEY_SIZE);
encrypt (keystring, pd->dek_encrypted_3, DATA_ENCRYPTION_KEY_SIZE);
if (keystring_admin)
encrypt (keystring_admin, pd->dek_encrypted_3, DATA_ENCRYPTION_KEY_SIZE);
else
memset (pd->dek_encrypted_3, 0, DATA_ENCRYPTION_KEY_SIZE);
p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data));
do_ptr[nr - NR_DO__FIRST__] = p;
@@ -834,6 +837,13 @@ proc_key_import (const uint8_t *data, int len)
{
int r;
enum kind_of_key kk;
const uint8_t *pw3_keystring;
const uint8_t *keystring_admin;
if (admin_authorized == BY_ADMIN)
keystring_admin = keystring_md_pw3;
else
keystring_admin = NULL;
DEBUG_BINARY (data, len);
@@ -869,7 +879,7 @@ proc_key_import (const uint8_t *data, int len)
/* It should starts with 00 01 00 01 (E) */
/* Skip E, 4-byte */
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_md_pw3);
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_admin);
if (r < 0)
return 0;
else
@@ -941,8 +951,8 @@ gpg_do_table[] = {
{ GPG_DO_KEY_IMPORT, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED,
proc_key_import },
#if 0
/* Card holder certificate */
{ GPG_DO_CH_CERTIFICATE, DO_PROC_READ, AC_ALWAYS, AC_NEVER, NULL },
/* Card holder certificate is handled in special way, as its size is big */
{ GPG_DO_CH_CERTIFICATE, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, NULL },
#endif
};

View File

@@ -537,7 +537,7 @@ cmd_reset_user_password (void)
newpw = pw;
sha1 (newpw, newpw_len, new_ks);
new_ks0[0] = newpw_len;
r = gpg_change_keystring (BY_ADMIN, old_ks, BY_USER, new_ks);
r = gpg_change_keystring (admin_authorized, old_ks, BY_USER, new_ks);
if (r < -2)
{
DEBUG_INFO ("memory error.\r\n");