Prevent observation of PW3 emptiness
This commit is contained in:
12
ChangeLog
12
ChangeLog
@@ -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.
|
||||
|
||||
41
src/ac.c
41
src/ac.c
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user