auth and keystring handling improvement (1)
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2013-10-09 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/ac.c (verify_admin_00): New. Add authentication by loading
|
||||
signature key.
|
||||
(verify_admin_0): Use verify_admin_00.
|
||||
|
||||
* src/openpgp.c (cmd_change_password): Admin keystring handling as
|
||||
same as user's.
|
||||
|
||||
2013-10-08 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (modify_binary): Allow odd size of certificate.
|
||||
|
||||
45
src/ac.c
45
src/ac.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ac.c -- Check access condition
|
||||
*
|
||||
* Copyright (C) 2010, 2012 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2012, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -186,6 +186,32 @@ calc_md (int count, const uint8_t *salt, const uint8_t *pw, int pw_len,
|
||||
sha256_finish (&sha256_ctx, md);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
verify_admin_00 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
const uint8_t *ks)
|
||||
{
|
||||
int pw_len;
|
||||
int r1, r2;
|
||||
uint8_t keystring[KEYSTRING_MD_SIZE];
|
||||
|
||||
pw_len = ks[0];
|
||||
if ((pw_len_known >= 0 && pw_len_known != pw_len) || buf_len < pw_len)
|
||||
return -1;
|
||||
|
||||
s2k (BY_ADMIN, pw, pw_len, keystring);
|
||||
r1 = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_ADMIN, keystring);
|
||||
r2 = 0;
|
||||
|
||||
if (r1 < 0 || r2 < 0)
|
||||
return -1;
|
||||
else if (r1 == 0 && r2 == 0)
|
||||
if (ks != NULL && memcmp (ks+1, keystring, KEYSTRING_MD_SIZE) != 0)
|
||||
return -1;
|
||||
|
||||
return pw_len;
|
||||
}
|
||||
|
||||
uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
|
||||
uint8_t admin_authorized;
|
||||
|
||||
@@ -198,22 +224,11 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known)
|
||||
pw3_keystring = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
|
||||
if (pw3_keystring != NULL)
|
||||
{
|
||||
int count;
|
||||
uint8_t md[KEYSTRING_MD_SIZE];
|
||||
const uint8_t *salt;
|
||||
|
||||
if (gpg_pw_locked (PW_ERR_PW3))
|
||||
return 0;
|
||||
|
||||
pw_len = pw3_keystring[0];
|
||||
if ((pw_len_known >= 0 && pw_len_known != pw_len) || pw_len > buf_len)
|
||||
goto failure;
|
||||
|
||||
salt = &pw3_keystring[1];
|
||||
count = decode_iterate_count (pw3_keystring[1+8]);
|
||||
calc_md (count, salt, pw, pw_len, md);
|
||||
|
||||
if (memcmp (md, &pw3_keystring[1+8+1], KEYSTRING_MD_SIZE) != 0)
|
||||
pw_len = verify_admin_00 (pw, buf_len, pw_len_known, pw3_keystring);
|
||||
if (pw_len < 0)
|
||||
{
|
||||
failure:
|
||||
gpg_pw_increment_err_counter (PW_ERR_PW3);
|
||||
@@ -221,7 +236,7 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known)
|
||||
}
|
||||
|
||||
admin_authorized = BY_ADMIN;
|
||||
success: /* OK, the user is now authenticated */
|
||||
success: /* OK, the admin is now authenticated. */
|
||||
gpg_pw_reset_err_counter (PW_ERR_PW3);
|
||||
return pw_len;
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ extern void s2k (int who, const unsigned char *input, unsigned int ilen,
|
||||
#define KEYSTRING_SIZE_RC (KEYSTRING_PASSLEN_SIZE+KEYSTRING_MD_SIZE)
|
||||
#define KEYSTRING_SIZE_PW3 (KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE \
|
||||
+KEYSTRING_ITER_SIZE+KEYSTRING_MD_SIZE)
|
||||
#define KEYSTRING_SIZE (KEYSTRING_PASSLEN_SIZE+KEYSTRING_MD_SIZE)
|
||||
|
||||
extern void gpg_do_clear_prvkey (enum kind_of_key kk);
|
||||
extern int gpg_do_load_prvkey (enum kind_of_key kk, int who, const uint8_t *keystring);
|
||||
|
||||
@@ -578,7 +578,7 @@ proc_resetting_code (const uint8_t *data, int len)
|
||||
else if (r == 0)
|
||||
{
|
||||
DEBUG_INFO ("done (no prvkey).\r\n");
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_RC, new_ks0, KEYSTRING_SIZE_RC);
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_RC, new_ks0, KEYSTRING_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -255,6 +255,7 @@ cmd_change_password (void)
|
||||
int who = p2 - 0x80;
|
||||
int who_old;
|
||||
int r;
|
||||
int pw3_null = 0;
|
||||
|
||||
DEBUG_INFO ("Change PW\r\n");
|
||||
DEBUG_BYTE (who);
|
||||
@@ -328,9 +329,9 @@ cmd_change_password (void)
|
||||
newpw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
|
||||
memcpy (newpw, OPENPGP_CARD_INITIAL_PW3, newpw_len);
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, NULL, 0);
|
||||
pw3_null = 1;
|
||||
}
|
||||
else
|
||||
gpg_set_pw3 (newpw, newpw_len);
|
||||
|
||||
who_old = admin_authorized;
|
||||
}
|
||||
}
|
||||
@@ -352,7 +353,7 @@ cmd_change_password (void)
|
||||
}
|
||||
else if (r == 0 && who == BY_USER) /* no prvkey */
|
||||
{
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1);
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE);
|
||||
ac_reset_pso_cds ();
|
||||
ac_reset_other ();
|
||||
if (admin_authorized == BY_USER)
|
||||
@@ -370,9 +371,21 @@ cmd_change_password (void)
|
||||
DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
else /* r >= 0 && who == BY_ADMIN */
|
||||
#if 0
|
||||
else if (r > 0 && who == BY_ADMIN)
|
||||
{
|
||||
DEBUG_INFO ("done.\r\n");
|
||||
if (!pw3_null)
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, 1);
|
||||
ac_reset_admin ();
|
||||
DEBUG_INFO ("Changed length of DO_KEYSTRING_PW3.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
#endif
|
||||
else /* r == 0 && who == BY_ADMIN */ /* no prvkey */
|
||||
{
|
||||
if (!pw3_null)
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, KEYSTRING_SIZE);
|
||||
DEBUG_INFO ("Changed DO_KEYSTRING_PW3.\r\n");
|
||||
ac_reset_admin ();
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
@@ -462,8 +475,7 @@ cmd_reset_user_password (void)
|
||||
if (memcmp (ks_rc+1, old_ks, KEYSTRING_MD_SIZE) != 0)
|
||||
goto sec_fail;
|
||||
DEBUG_INFO ("done (no prvkey).\r\n");
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
|
||||
KEYSTRING_SIZE_PW1);
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE);
|
||||
ac_reset_pso_cds ();
|
||||
ac_reset_other ();
|
||||
if (admin_authorized == BY_USER)
|
||||
@@ -514,8 +526,7 @@ cmd_reset_user_password (void)
|
||||
else if (r == 0)
|
||||
{
|
||||
DEBUG_INFO ("done (no privkey).\r\n");
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
|
||||
KEYSTRING_SIZE_PW1);
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE);
|
||||
ac_reset_pso_cds ();
|
||||
ac_reset_other ();
|
||||
if (admin_authorized == BY_USER)
|
||||
|
||||
Reference in New Issue
Block a user