From 5d805255525c869cc4eb66b446b9a10122d664a4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 9 Oct 2013 11:47:06 +0900 Subject: [PATCH] auth and keystring handling improvement (2) --- ChangeLog | 8 ++++++++ src/ac.c | 4 ++-- src/gnuk.h | 8 ++++++++ src/openpgp-do.c | 16 +++++++++++----- src/openpgp.c | 10 ++++++++-- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b5bd12..738e018 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-10-09 Niibe Yutaka + + * 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 * src/ac.c (verify_admin_00): New. Add authentication by loading diff --git a/src/ac.c b/src/ac.c index 8aaea8c..f47e63c 100644 --- a/src/ac.c +++ b/src/ac.c @@ -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; diff --git a/src/gnuk.h b/src/gnuk.h index 544fe47..b29a613 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -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]); diff --git a/src/openpgp-do.c b/src/openpgp-do.c index e6f0a4a..75e8cea 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -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; diff --git a/src/openpgp.c b/src/openpgp.c index 5f5f938..f3d3933 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -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 ();