auth and keystring handling improvement (2)

This commit is contained in:
NIIBE Yutaka
2013-10-09 11:47:06 +09:00
parent b31e688536
commit 5d80525552
5 changed files with 37 additions and 9 deletions

View File

@@ -1,3 +1,11 @@
2013-10-09 Niibe Yutaka <gniibe@fsij.org>
* src/ac.c (verify_user_0, verify_admin_00): Handle PW_LEN_MASK.
* src/openpgp-do.c (proc_resetting_code, gpg_do_write_prvkey):
Likewise.
* src/openpgp.c (cmd_change_password, cmd_reset_user_password):
Handle PW_LEN_KEYSTRING_BIT.
2013-10-09 Niibe Yutaka <gniibe@fsij.org>
* src/ac.c (verify_admin_00): New. Add authentication by loading

View File

@@ -80,7 +80,7 @@ verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len, int pw_len_known,
goto success_one_step;
}
else
pw_len = ks_pw1[0];
pw_len = ks_pw1[0] & PW_LEN_MASK;
if ((pw_len_known >= 0 && pw_len_known != pw_len)
|| buf_len < pw_len)
@@ -195,7 +195,7 @@ verify_admin_00 (const uint8_t *pw, int buf_len, int pw_len_known,
int r1, r2;
uint8_t keystring[KEYSTRING_MD_SIZE];
pw_len = ks[0];
pw_len = ks[0] & PW_LEN_MASK;
if ((pw_len_known >= 0 && pw_len_known != pw_len) || buf_len < pw_len)
return -1;

View File

@@ -169,6 +169,14 @@ struct prvkey_data {
#define BY_RESETCODE 2
#define BY_ADMIN 3
/*
* Maximum length of pass phrase is 127.
* We use the top bit (0x80) to encode if keystring is available within DO.
*/
#define PW_LEN_MAX 127
#define PW_LEN_MASK 0x7f
#define PW_LEN_KEYSTRING_BIT 0x80
extern void s2k (int who, const unsigned char *input, unsigned int ilen,
unsigned char output[32]);

View File

@@ -138,7 +138,6 @@ static const uint8_t algorithm_attr_ecdsa[] __attribute__ ((aligned (1))) = {
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 /* OID of NIST curve P-256 */
};
#define PW_LEN_MAX 127
/*
* Representation of PW1_LIFETIME:
* 0: PW1_LIEFTIME_P == NULL : PW1 is valid for single PSO:CDS command
@@ -578,6 +577,7 @@ proc_resetting_code (const uint8_t *data, int len)
else if (r == 0)
{
DEBUG_INFO ("done (no prvkey).\r\n");
new_ks0[0] |= PW_LEN_KEYSTRING_BIT;
gpg_do_write_simple (NR_DO_KEYSTRING_RC, new_ks0, KEYSTRING_SIZE);
}
else
@@ -888,11 +888,17 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
if (++num_prv_keys == NUM_ALL_PRV_KEYS) /* All keys are registered. */
{
/* Remove contents of keystrings from DO, but length */
if (ks_pw1_len)
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, &ks_pw1_len, 1);
if ((ks_pw1_len & PW_LEN_KEYSTRING_BIT))
{
ks_pw1_len &= PW_LEN_MASK;
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, &ks_pw1_len, 1);
}
if (ks_rc_len)
gpg_do_write_simple (NR_DO_KEYSTRING_RC, &ks_rc_len, 1);
if ((ks_rc_len & PW_LEN_KEYSTRING_BIT))
{
ks_rc_len &= PW_LEN_MASK;
gpg_do_write_simple (NR_DO_KEYSTRING_RC, &ks_rc_len, 1);
}
}
return 0;

View File

@@ -353,6 +353,7 @@ cmd_change_password (void)
}
else if (r == 0 && who == BY_USER) /* no prvkey */
{
new_ks0[0] |= PW_LEN_KEYSTRING_BIT;
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE);
ac_reset_pso_cds ();
ac_reset_other ();
@@ -384,7 +385,10 @@ cmd_change_password (void)
else /* r == 0 && who == BY_ADMIN */ /* no prvkey */
{
if (!pw3_null)
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, KEYSTRING_SIZE);
{
new_ks0[0] |= PW_LEN_KEYSTRING_BIT;
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 ();
@@ -451,7 +455,7 @@ cmd_reset_user_password (void)
return;
}
pw_len = ks_rc[0];
pw_len = ks_rc[0] & PW_LEN_MASK;
newpw = pw + pw_len;
newpw_len = len - pw_len;
s2k (BY_RESETCODE, pw, pw_len, old_ks);
@@ -475,6 +479,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");
new_ks0[0] |= PW_LEN_KEYSTRING_BIT;
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE);
ac_reset_pso_cds ();
ac_reset_other ();
@@ -526,6 +531,7 @@ cmd_reset_user_password (void)
else if (r == 0)
{
DEBUG_INFO ("done (no privkey).\r\n");
new_ks0[0] |= PW_LEN_KEYSTRING_BIT;
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE);
ac_reset_pso_cds ();
ac_reset_other ();