From: Klas Lindfors Date: Tue, 4 Dec 2012 14:21:07 +0000 (+0100) Subject: add -S flag for setting scanmap to the YubiKey NEO X-Git-Tag: v1.10.0~15 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d24ff95018478067dd9305f95430098644293ce;p=yubikey-personalization add -S flag for setting scanmap to the YubiKey NEO --- diff --git a/libykpers-1.map b/libykpers-1.map index 627d722..9ee32ec 100644 --- a/libykpers-1.map +++ b/libykpers-1.map @@ -174,5 +174,6 @@ LIBYKPERS_1.10 { ykp_set_device_mode; ykp_set_device_chalresp_timeout; ykp_set_device_autoeject_time; + yk_write_scan_map; # Variables: } LIBYKPERS_1.9; diff --git a/tests/test_args_to_config.c b/tests/test_args_to_config.c index 02ba388..fe0a9df 100644 --- a/tests/test_args_to_config.c +++ b/tests/test_args_to_config.c @@ -118,6 +118,8 @@ int _test_config (YKP_CONFIG *cfg, YK_STATUS *st, int argc, char **argv) unsigned char usb_mode = -1; bool zap = false; + unsigned char scan_map[strlen(SCAN_MAP)]; + int rc; ykp_errno = 0; @@ -133,7 +135,7 @@ int _test_config (YKP_CONFIG *cfg, YK_STATUS *st, int argc, char **argv) st, &verbose, access_code, &use_access_code, &aesviahash, &ndef_type, ndef, &usb_mode, &zap, - &exit_code); + scan_map, &exit_code); return rc; } @@ -297,6 +299,8 @@ int _test_non_config_args(void) unsigned char usb_mode = -1; bool zap = false; + unsigned char scan_map[strlen(SCAN_MAP)]; + char *argv[] = { "unittest", "-1", "-sout", "-iin", "-c313233343536", "-y", "-v", NULL @@ -317,7 +321,7 @@ int _test_non_config_args(void) st, &verbose, access_code, &use_access_code, &aesviahash, &ndef_type, ndef, &usb_mode, &zap, - &exit_code); + scan_map, &exit_code); assert(rc == 1); i = strcmp(infname, "in"); assert(i == 0); i = strcmp(outfname, "out"); assert(i == 0); diff --git a/ykcore/ykcore.c b/ykcore/ykcore.c index 5d8255f..2ad4a72 100644 --- a/ykcore/ykcore.c +++ b/ykcore/ykcore.c @@ -302,6 +302,11 @@ int yk_write_device_config(YK_KEY *yk, YK_DEVICE_CONFIG *device_config) return _yk_write(yk, SLOT_DEVICE_CONFIG, buf, sizeof(YK_DEVICE_CONFIG)); } +int yk_write_scan_map(YK_KEY *yk, unsigned char *scan_map) +{ + return _yk_write(yk, SLOT_SCAN_MAP, scan_map, strlen(SCAN_MAP)); +} + /* * This function is for doing HMAC-SHA1 or Yubico challenge-response with a key. */ diff --git a/ykcore/ykcore.h b/ykcore/ykcore.h index ea2fccb..40c6f02 100644 --- a/ykcore/ykcore.h +++ b/ykcore/ykcore.h @@ -123,6 +123,8 @@ extern int yk_write_ndef(YK_KEY *yk, YK_NDEF *ndef); extern int yk_write_ndef2(YK_KEY *yk, YK_NDEF *ndef, int confnum); /* writes a device config block to the key. */ extern int yk_write_device_config(YK_KEY *yk, YK_DEVICE_CONFIG *device_config); +/* writes a scanmap to the key. */ +extern int yk_write_scan_map(YK_KEY *yk, unsigned char *scan_map); /* Write something to the YubiKey (a command that is). */ extern int yk_write_to_key(YK_KEY *yk, uint8_t slot, const void *buf, int bufcount); /* Do a challenge-response round with the key. */ diff --git a/ykpers-args.c b/ykpers-args.c index 852cf8d..70e9f3e 100644 --- a/ykpers-args.c +++ b/ykpers-args.c @@ -77,6 +77,8 @@ const char *usage = " 1 CCID device only.\n" " 2 HID/CCID composite device.\n" " Add 80 to set MODE_FLAG_EJECT, for example: 81\n" +"-S0605.. Set the scanmap to use with the YubiKey NEO. Must be 44 unique bytes,\n" +" in hex. Use with no argument to reset to the default.\n" "-oOPTION change configuration option. Possible OPTION arguments are:\n" " salt=ssssssss Salt to be used when deriving key from a\n" " password. If none is given, a unique random\n" @@ -151,7 +153,7 @@ const char *usage = "-v verbose\n" "-h help (this text)\n" ; -const char *optstring = "u12xza:c:n:t:hi:o:s:vym:"; +const char *optstring = "u12xza:c:n:t:hi:o:s:vym:S::"; static int _set_fixed(char *opt, YKP_CONFIG *cfg); static int _format_decimal_as_hex(uint8_t *dst, size_t dst_len, uint8_t *src); @@ -225,8 +227,9 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, bool *autocommit, char *salt, YK_STATUS *st, bool *verbose, unsigned char *access_code, bool *use_access_code, - bool *aesviahash, char *ndef_type, char *ndef, unsigned char *usb_mode, bool *zap, - int *exit_code) + bool *aesviahash, char *ndef_type, char *ndef, + unsigned char *usb_mode, bool *zap, + unsigned char *scan_bin, int *exit_code) { int c; const char *aeshash = NULL; @@ -238,6 +241,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, bool update_seen = false; bool ndef_seen = false; bool usb_mode_seen = false; + bool scan_map_seen = false; struct config_st *ycfg; ykp_configure_version(cfg, st); @@ -463,6 +467,32 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, return 0; break; + case 'S': + { + size_t scanlength = strlen(SCAN_MAP); + if(optarg) { + size_t scanbinlen; + size_t scanlen = strlen (optarg); + int rc = hex_modhex_decode(scan_bin, &scanbinlen, + optarg, scanlen, + scanlength * 2, scanlength * 2, + false); + + if (rc <= 0) { + fprintf(stderr, + "Invalid scanmap string %s\n", + optarg); + *exit_code = 1; + return 0; + } + } else { + memset(scan_bin, 0, scanlength); + } + scan_map_seen = true; + } + if (!ykp_configure_command(cfg, SLOT_SCAN_MAP)) + return 0; + break; case 'o': if (*zap) { fprintf(stderr, "No options can be given with zap (-z).\n"); @@ -652,7 +682,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, } } - if (!slot_chosen && !ndef_seen && !usb_mode_seen) { + if (!slot_chosen && !ndef_seen && !usb_mode_seen && !scan_map_seen) { fprintf(stderr, "A slot must be chosen with -1 or -2.\n"); *exit_code = 1; return 0; diff --git a/ykpers-args.h b/ykpers-args.h index 3f563b8..8ee82eb 100644 --- a/ykpers-args.h +++ b/ykpers-args.h @@ -39,7 +39,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, YK_STATUS *st, bool *verbose, unsigned char *access_code, bool *use_access_code, bool *aesviahash, char *ndef_type, char *ndef, unsigned char *usb_mode, - bool *zap, int *exit_code); + bool *zap, unsigned char *scan_bin, int *exit_code); void report_yk_error(void); diff --git a/ykpers.c b/ykpers.c index f800d48..00bb048 100644 --- a/ykpers.c +++ b/ykpers.c @@ -184,19 +184,14 @@ int ykp_configure_command(YKP_CONFIG *cfg, uint8_t command) return 0; } break; - /* TODO: Make sure this is correct */ case SLOT_DEVICE_CONFIG: - /* For testing only */ + case SLOT_SCAN_MAP: + case SLOT_NDEF2: if(!(cfg->yk_major_version >= 3)) { ykp_errno = YKP_EYUBIKEYVER; return 0; } break; - case SLOT_NDEF2: - if (!(cfg->yk_major_version == 3)) { - ykp_errno = YKP_EYUBIKEYVER; - return 0; - } case SLOT_NDEF: /* NDEF is available for neo, thus within 2.1 from build 4 */ if (!((cfg->yk_major_version == 2 && cfg->yk_minor_version == 1 && diff --git a/ykpersonalize.c b/ykpersonalize.c index 6c4e171..a130b67 100644 --- a/ykpersonalize.c +++ b/ykpersonalize.c @@ -58,6 +58,7 @@ int main(int argc, char **argv) bool aesviahash = false; bool use_access_code = false; unsigned char access_code[256]; + unsigned char scan_codes[strlen(SCAN_MAP)]; YK_KEY *yk = 0; YKP_CONFIG *cfg = ykp_alloc(); YK_STATUS *st = ykds_alloc(); @@ -128,8 +129,8 @@ int main(int argc, char **argv) &autocommit, salt, st, &verbose, access_code, &use_access_code, - &aesviahash, &ndef_type, ndef_string, - &usb_mode, &zap, &exit_code)) { + &aesviahash, &ndef_type, ndef_string, + &usb_mode, &zap, scan_codes, &exit_code)) { goto err; } @@ -207,6 +208,8 @@ int main(int argc, char **argv) fprintf(stderr, "New NDEF will be written as:\n%s\n", ndef_string); } else if(ykp_command(cfg) == SLOT_DEVICE_CONFIG) { fprintf(stderr, "The USB mode will be set to: 0x%x\n", usb_mode); + } else if(ykp_command(cfg) == SLOT_SCAN_MAP) { + fprintf(stderr, "A new scanmap will be written.\n"); } else if(zap) { fprintf(stderr, "Configuration in slot %d will be deleted\n", ykp_config_num(cfg)); } else { @@ -262,6 +265,14 @@ int main(int argc, char **argv) goto err; } ykp_free_device_config(device_config); + + + } else if(ykp_command(cfg) == SLOT_SCAN_MAP) { + if(!yk_write_scan_map(yk, scan_codes)) { + if(verbose) + printf(" failure\n"); + goto err; + } } else { YK_CONFIG *ycfg = NULL; /* if we're deleting a slot we send the configuration as NULL */