From 10e0073f117ae56834493d99a394a3cedaea8ef2 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 17 Jan 2011 10:42:28 +0100 Subject: [PATCH] Add support for the extended flags in Yubikey 2.2. --- libykpers-1.map | 3 ++ tests/test_args_to_config.c | 60 ++++++++++++++++++++++++++++++++++++- ykpers.c | 54 +++++++++++++++++++++++++++++++-- ykpersonalize.c | 22 ++++++++++++++ 4 files changed, 136 insertions(+), 3 deletions(-) diff --git a/libykpers-1.map b/libykpers-1.map index a67e4e0..61a3960 100644 --- a/libykpers-1.map +++ b/libykpers-1.map @@ -92,6 +92,9 @@ LIBYKPERS_1.0 { ykp_set_uid; ykp_strerror; ykp_write_config; + ykp_set_extflag_SERIAL_BTN_VISIBLE; + ykp_set_extflag_SERIAL_USB_VISIBLE; + ykp_set_extflag_SERIAL_API_VISIBLE; # Variables: _yk_errno_location; diff --git a/tests/test_args_to_config.c b/tests/test_args_to_config.c index 88a8c08..d1fb06d 100644 --- a/tests/test_args_to_config.c +++ b/tests/test_args_to_config.c @@ -68,6 +68,28 @@ void _yktest_hexdump(char *prefix, void *buffer, int size, int break_on) fflush(stderr); } +void _check_success(int rc, YKP_CONFIG *cfg, unsigned char *expected) +{ + struct config_st *ycfg; + bool config_matches_expected = false; + + if (rc != 1) + printf ("Error returned : %i/%i (%s)\n", rc, ykp_errno, ykp_strerror(ykp_errno)); + assert(rc == 1); + + ycfg = (struct config_st *) ykp_core_config(cfg); + /* insert CRC */ + ycfg->crc = ~yubikey_crc16 ((unsigned char *) ycfg, + offsetof(struct config_st, crc)); + + config_matches_expected = ! memcmp(expected, ycfg, sizeof(*ycfg)); + if (! config_matches_expected) { + _yktest_hexdump ("BAD MATCH :\n", ycfg, sizeof(*ycfg), 8); + _yktest_hexdump ("EXPECTED :\n", expected, sizeof(*ycfg), 8); + } + assert(config_matches_expected == true); +} + int _test_config (YKP_CONFIG *cfg, YK_STATUS *st, int argc, char **argv) { const char *infname = NULL; @@ -124,7 +146,7 @@ int _test_config_slot1() YK_STATUS *st = _test_init_st(1, 3, 0); int rc = 0; struct config_st *ycfg; - + char *argv[] = { "unittest", "-1", NULL @@ -322,6 +344,41 @@ int _test_oath_hotp_nist_160_bits() free(st); } +int _test_extended_flags1() +{ + YKP_CONFIG *cfg = ykp_create_config(); + YK_STATUS *st = _test_init_st(2, 2, 0); + int rc = 0; + + /* this matches the python-yubico test case test_challenge_response_hmac_nist */ + unsigned char expected[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x00, + 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x40, 0x26, 0x00, + 0x00, 0x98, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x95, 0x56, 0x00, 0x00, 0x00, + }; + + char *argv[] = { + "unittest", "-2", "-a303132333435363738393a3b3c3d3e3f40414243", + "-o-append-cr", "-o-static-ticket", "-o-strong-pw1", "-o-strong-pw2", "-o-man-update", + "-ochal-resp", "-ochal-hmac", "-ohmac-lt64", "-oserial-api-visible", + NULL + }; + int argc = sizeof argv/sizeof argv[0] - 1; + + rc = _test_config(cfg, st, argc, argv); + _check_success(rc, cfg, &expected); + + ykp_free_config(cfg); + free(st); +} + int main (int argc, char **argv) { _test_config_slot1(); @@ -330,6 +387,7 @@ int main (int argc, char **argv) _test_too_new_key(); _test_non_config_args(); _test_oath_hotp_nist_160_bits(); + _test_extended_flags1(); return 0; } diff --git a/ykpers.c b/ykpers.c index 4e9c923..e6b4bdb 100644 --- a/ykpers.c +++ b/ykpers.c @@ -55,7 +55,7 @@ static const YK_CONFIG default_config1 = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* key */ { 0, 0, 0, 0, 0, 0 }, /* accCode */ 0, /* fixedSize */ - 0, /* pgmSeq */ + 0, /* extFlags */ TKTFLAG_APPEND_CR, /* tktFlags */ 0, /* cfgFlags */ 0, /* ctrOffs */ @@ -68,7 +68,7 @@ static const YK_CONFIG default_config2 = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* key */ { 0, 0, 0, 0, 0, 0 }, /* accCode */ 0, /* fixedSize */ - 0, /* pgmSeq */ + 0, /* extFlags */ TKTFLAG_APPEND_CR, /* tktFlags */ /* cfgFlags */ CFGFLAG_STATIC_TICKET | CFGFLAG_STRONG_PW1 | CFGFLAG_STRONG_PW2 | CFGFLAG_MAN_UPDATE, @@ -343,6 +343,24 @@ int ykp_set_cfgflag_ ## type(YKP_CONFIG *cfg, bool state) \ return 0; \ } +#define def_set_extflag(type,vcheck) \ +int ykp_set_extflag_ ## type(YKP_CONFIG *cfg, bool state) \ +{ \ + if (cfg) { \ + if (!vcheck(cfg)) { \ + ykp_errno = YKP_EYUBIKEYVER; \ + return 0; \ + } \ + if (state) \ + cfg->ykcore_config.extFlags |= EXTFLAG_ ## type; \ + else \ + cfg->ykcore_config.extFlags &= ~EXTFLAG_ ## type; \ + return 1; \ + } \ + ykp_errno = YKP_ENOCFG; \ + return 0; \ +} + def_set_tktflag(TAB_FIRST,vcheck_all) def_set_tktflag(APPEND_TAB1,vcheck_all) def_set_tktflag(APPEND_TAB2,vcheck_all) @@ -372,6 +390,10 @@ def_set_cfgflag(CHAL_HMAC,vcheck_v22_or_greater) def_set_cfgflag(HMAC_LT64,vcheck_v22_or_greater) def_set_cfgflag(CHAL_BTN_TRIG,vcheck_v22_or_greater) +def_set_extflag(SERIAL_BTN_VISIBLE,vcheck_v22_or_greater) +def_set_extflag(SERIAL_USB_VISIBLE,vcheck_v22_or_greater) +def_set_extflag(SERIAL_API_VISIBLE,vcheck_v22_or_greater) + const char str_key_value_separator[] = ": "; const char str_hex_prefix[] = "h:"; const char str_modhex_prefix[] = "m:"; @@ -437,6 +459,14 @@ struct map_st config_flags_map[] = { { 0, "" } }; +const char str_extended_flags[] = "extended_flags"; +struct map_st extended_flags_map[] = { + { EXTFLAG_SERIAL_BTN_VISIBLE, "SERIAL_BTN_VISIBLE", vcheck_v22_or_greater, 0 }, + { EXTFLAG_SERIAL_USB_VISIBLE, "SERIAL_USB_VISIBLE", vcheck_v22_or_greater, 0 }, + { EXTFLAG_SERIAL_API_VISIBLE, "SERIAL_API_VISIBLE", vcheck_v22_or_greater, 0 }, + { 0, "", 0 } +}; + int ykp_write_config(const YKP_CONFIG *cfg, int (*writer)(const char *buf, size_t count, void *userdata), @@ -541,6 +571,26 @@ int ykp_write_config(const YKP_CONFIG *cfg, writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); + /* extended_flags: */ + buffer[0] = '\0'; + for (p = extended_flags_map; p->flag; p++) { + if ((cfg->ykcore_config.extFlags & p->flag) == p->flag + && p->vcheck(cfg)) { + if (*buffer) { + strcat(buffer, str_flags_separator); + strcat(buffer, p->flag_text); + } else { + strcpy(buffer, p->flag_text); + } + } + } + writer(str_extended_flags, strlen(str_extended_flags), userdata); + writer(str_key_value_separator, + strlen(str_key_value_separator), + userdata); + writer(buffer, strlen(buffer), userdata); + writer("\n", 1, userdata); + return 1; } return 0; diff --git a/ykpersonalize.c b/ykpersonalize.c index 9d62855..9aeef4f 100644 --- a/ykpersonalize.c +++ b/ykpersonalize.c @@ -114,6 +114,11 @@ const char *usage = " [-]hmac-lt64 set/clear HMAC_LT64\n" " [-]chal-btn-trig set/clear CHAL_BTN_TRIG\n" "\n" +" Extended flags for firmware version 2.2 and above:\n" +" [-]serial-btn-visible set/clear SERIAL_BTN_VISIBLE\n" +" [-]serial-usb-visible set/clear SERIAL_USB_VISIBLE\n" +" [-]serial-api-visible set/clear SERIAL_API_VISIBLE\n" +"\n" "-y always commit (do not prompt)\n" "\n" "-v verbose\n" @@ -352,6 +357,23 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, CFGFLAG("hmac-lt64", HMAC_LT64) CFGFLAG("chal-btn-trig", CHAL_BTN_TRIG) #undef CFGFLAG + +#define EXTFLAG(o, f) \ + else if (strcmp(optarg, o) == 0) { \ + if (! ykp_set_extflag_##f(cfg, true)) { \ + *exit_code = 1; \ + return 0; \ + } \ + } else if (strcmp(optarg, "-" o) == 0) { \ + if (! ykp_set_extflag_##f(cfg, false)) { \ + *exit_code = 1; \ + return 0; \ + } \ + } + EXTFLAG("serial-btn-visible", SERIAL_BTN_VISIBLE) + EXTFLAG("serial-usb-visible", SERIAL_USB_VISIBLE) + EXTFLAG("serial-api-visible", SERIAL_API_VISIBLE) +#undef EXTFLAG else { fprintf(stderr, "Unknown option '%s'\n", optarg); -- 2.39.5