From: Frank Cusack Date: Wed, 20 Jul 2011 10:12:11 +0000 (+0200) Subject: Add flag and API for OATH initial moving factor. X-Git-Tag: v1.6.0~3 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f326e8ec16506bb883428332731f842c6281d75;p=yubikey-personalization.old Add flag and API for OATH initial moving factor. Signed-off-by: Simon Josefsson --- diff --git a/libykpers-1.map b/libykpers-1.map index 3fb110c..582da7d 100644 --- a/libykpers-1.map +++ b/libykpers-1.map @@ -116,5 +116,7 @@ LIBYKPERS_1.5 { yk_wait_for_key_status; yk_read_response_from_key; yk_get_serial; + ykp_set_oath_imf; + ykp_get_oath_imf; # Variables: } LIBYKPERS_1.4; diff --git a/ykpers-args.c b/ykpers-args.c index a25d6a8..6d8620c 100644 --- a/ykpers-args.c +++ b/ykpers-args.c @@ -113,6 +113,7 @@ const char *usage = " [-]chal-hmac set/clear CHAL_HMAC\n" " [-]hmac-lt64 set/clear HMAC_LT64\n" " [-]chal-btn-trig set/clear CHAL_BTN_TRIG\n" +" oath-imf=IMF set OATH Initial Moving Factor\n" "\n" " Extended flags for firmware version 2.2 and above:\n" " [-]serial-btn-visible set/clear SERIAL_BTN_VISIBLE\n" @@ -416,6 +417,31 @@ 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 + else if (strncmp(optarg, "oath-imf=", 9) == 0) { + unsigned long imf; + + if (!(ycfg->tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP) { + fprintf(stderr, + "Option oath-imf= only valid with -ooath-hotp or -ooath-hotp8.\n" + ); + *exit_code = 1; + return 0; + } + + if (sscanf(optarg+9, "%lu", &imf) != 1 || + /* yubikey limitations */ + imf > 65535*16 || imf % 16 != 0) { + fprintf(stderr, + "Invalid value %s for oath-imf=.\n", optarg+9 + ); + *exit_code = 1; + return 0; + } + if (! ykp_set_oath_imf(cfg, imf)) { + *exit_code = 1; + return 0; + } + } #define EXTFLAG(o, f) \ else if (strcmp(optarg, o) == 0) { \ diff --git a/ykpers.c b/ykpers.c index 6f0b954..c833653 100644 --- a/ykpers.c +++ b/ykpers.c @@ -309,6 +309,36 @@ static bool vcheck_v22_or_greater(const YKP_CONFIG *cfg) cfg->yk_major_version > 2; } +int ykp_set_oath_imf(YKP_CONFIG *cfg, unsigned long imf) +{ + if (!vcheck_v22_or_greater(cfg)) { + ykp_errno = YKP_EYUBIKEYVER; + return 0; + } + if (imf > 65535*16) { + ykp_errno = YKP_EINVAL; + return 0; + } + if (imf % 16 != 0) { + ykp_errno = YKP_EINVAL; + return 0; + } + /* IMF/16 is 16 bits stored big-endian in uid[4] */ + imf /= 16; + cfg->ykcore_config.uid[4] = imf >> 8; + cfg->ykcore_config.uid[5] = imf; + return 1; +} + +unsigned long ykp_get_oath_imf(YKP_CONFIG *cfg) +{ + if (!vcheck_v22_or_greater(cfg)) + return 0; + + /* we can't do a simple cast due to alignment issues */ + return ((cfg->ykcore_config.uid[4] << 8) | cfg->ykcore_config.uid[5]) << 4; +} + #define def_set_charfield(fnname,fieldname,size,extra,vcheck) \ int ykp_set_ ## fnname(YKP_CONFIG *cfg, unsigned char *input, size_t len) \ { \ @@ -431,6 +461,7 @@ const char str_fixed[] = "fixed"; const char str_uid[] = "uid"; const char str_key[] = "key"; const char str_acc_code[] = "acc_code"; +const char str_oath_imf[] = "OATH IMF"; const char str_flags_separator[] = "|"; @@ -569,6 +600,21 @@ int ykp_write_config(const YKP_CONFIG *cfg, writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); + /* OATH IMF: */ + if ((cfg->ykcore_config.tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP && + vcheck_v22_or_greater(cfg)) { + writer(str_oath_imf, strlen(str_oath_imf), userdata); + writer(str_key_value_separator, + strlen(str_key_value_separator), + userdata); + writer(str_hex_prefix, + strlen(str_hex_prefix), + userdata); + sprintf(buffer, "%lx", ykp_get_oath_imf(cfg)); + writer(buffer, strlen(buffer), userdata); + writer("\n", 1, userdata); + } + /* ticket_flags: */ buffer[0] = '\0'; for (p = ticket_flags_map; p->flag; p++) { @@ -693,6 +739,7 @@ static const char *errtext[] = { "option not available for this Yubikey version", "too old yubikey for this operation", "invalid configuration number (this is a programming error)", + "invalid option/argument value", }; const char *ykp_strerror(int errnum) { diff --git a/ykpers.h b/ykpers.h index cf0ef18..614cdb3 100644 --- a/ykpers.h +++ b/ykpers.h @@ -54,6 +54,8 @@ int ykp_HMAC_key_from_hex(YKP_CONFIG *cfg, const char *hexkey); int ykp_set_access_code(YKP_CONFIG *cfg, unsigned char *access_code, size_t len); int ykp_set_fixed(YKP_CONFIG *cfg, unsigned char *fixed, size_t len); int ykp_set_uid(YKP_CONFIG *cfg, unsigned char *uid, size_t len); +int ykp_set_oath_imf(YKP_CONFIG *cfg, unsigned long imf); +unsigned long ykp_get_oath_imf(YKP_CONFIG *cfg); int ykp_set_tktflag_TAB_FIRST(YKP_CONFIG *cfg, bool state); int ykp_set_tktflag_APPEND_TAB1(YKP_CONFIG *cfg, bool state); @@ -109,5 +111,6 @@ const char *ykp_strerror(int errnum); #define YKP_EYUBIKEYVER 0x03 #define YKP_EOLDYUBIKEY 0x04 #define YKP_EINVCONFNUM 0x05 +#define YKP_EINVAL 0x06 #endif // __YKPERS_H_INCLUDED__