From: Dain Nilsson Date: Fri, 23 Nov 2012 16:25:15 +0000 (+0100) Subject: Added the USB mode option to ykpersonalize, though the actual implementation is still... X-Git-Tag: v1.10.0~20^2~9 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02823f033e4bef37f49c417c2f0fd7e9ff1d9603;p=yubikey-personalization Added the USB mode option to ykpersonalize, though the actual implementation is still missing. --- diff --git a/tests/test_args_to_config.c b/tests/test_args_to_config.c index 8c8786a..9f319f5 100644 --- a/tests/test_args_to_config.c +++ b/tests/test_args_to_config.c @@ -115,6 +115,7 @@ int _test_config (YKP_CONFIG *cfg, YK_STATUS *st, int argc, char **argv) char *salt = NULL; char ndef[128]; char ndef_type = 0; + int usb_mode = -1; bool zap = false; int rc; @@ -131,7 +132,7 @@ int _test_config (YKP_CONFIG *cfg, YK_STATUS *st, int argc, char **argv) &autocommit, salt, st, &verbose, access_code, &use_access_code, - &aesviahash, &ndef_type, ndef, &zap, + &aesviahash, &ndef_type, ndef, &usb_mode, &zap, &exit_code); return rc; @@ -293,6 +294,7 @@ int _test_non_config_args(void) char *salt = NULL; char ndef[128]; char ndef_type = NULL; + int usb_mode = -1; bool zap = false; char *argv[] = { @@ -314,7 +316,7 @@ int _test_non_config_args(void) &autocommit, salt, st, &verbose, access_code, &use_access_code, - &aesviahash, &ndef_type, ndef, &zap, + &aesviahash, &ndef_type, ndef, &usb_mode, &zap, &exit_code); assert(rc == 1); i = strcmp(infname, "in"); assert(i == 0); diff --git a/ykcore/ykcore.c b/ykcore/ykcore.c index f3985d2..4dbd2fc 100644 --- a/ykcore/ykcore.c +++ b/ykcore/ykcore.c @@ -315,6 +315,47 @@ int yk_write_ndef2(YK_KEY *yk, YK_NDEF *ndef, int confnum) return stat.pgmSeq != seq; } +int yk_set_usb_mode(YK_KEY *yk, int usb_mode) +{ + if(!(usb_mode >= 0 && usb_mode < 4)) { + yk_errno = YK_EINVALIDCMD; + return 1; + } + + unsigned char buf[sizeof(YK_NDEF)]; + YK_STATUS stat; + int seq; + + /* Get current sequence # from status block */ + if (!yk_get_status(yk, &stat)) + return 0; + + seq = stat.pgmSeq; + + fprintf(stderr, "Pretending to set the USB mode to: %d\n", usb_mode); + + /* Write to Yubikey */ + if(/*TODO: !yk_write_to_key(yk, SLOT_USB_MODE, buf, sizeof(buf)) */ 1 == 2) + return 0; + + /* When the Yubikey clears the SLOT_WRITE_FLAG, it has processed the last write. + * This wait can't be done in yk_write_to_key since some users of that function + * want to get the bytes in the status message, but when writing configuration + * we don't expect any data back. + */ + yk_wait_for_key_status(yk, SLOT_USB_MODE, 0, WAIT_FOR_WRITE_FLAG, false, SLOT_WRITE_FLAG, NULL); + + /* Verify update */ + + if (!yk_get_status(yk, &stat /*, 0*/)) + return 0; + + yk_errno = YK_EWRITEERR; + return stat.pgmSeq != seq; + + return 1; +} + /* * This function is for doing HMAC-SHA1 or Yubico challenge-response with a key. */ diff --git a/ykcore/ykdef.h b/ykcore/ykdef.h index 5e0cbb6..08de9d6 100644 --- a/ykcore/ykdef.h +++ b/ykcore/ykdef.h @@ -40,6 +40,8 @@ #define SLOT_NDEF 8 /* Write NDEF record */ #define SLOT_NDEF2 9 /* Write NDEF record for slot 2 */ +#define SLOT_USB_MODE 0x0b /* USB mode of operation (NEO) */ + #define SLOT_DEVICE_SERIAL 0x10 /* Device serial number */ #define SLOT_CHAL_OTP1 0x20 /* Write 6 byte challenge to slot 1, get Yubico OTP response */ diff --git a/ykpers-args.c b/ykpers-args.c index a8b4c4a..1aeb239 100644 --- a/ykpers-args.c +++ b/ykpers-args.c @@ -71,6 +71,12 @@ const char *usage = " (this does NOT SET the access code, that's done with -oaccess=)\n" "-nXXX.. Write NDEF type 2 URI to YubiKey NEO, must be used with -1 or -2\n" "-tXXX.. Write NDEF type 2 text to YubiKey NEO, must be used with -1 or -2\n" +"-mMODE Set the USB operation mode of the YubiKey NEO.\n" +" Possible MODE arguments are:\n" +" 0 HID device only.\n" +" 1 CCID device only, permanently attached.\n" +" 2 CCID device only, with insert/removal.\n" +" 3 HID/CCID composite device.\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" @@ -145,7 +151,7 @@ const char *usage = "-v verbose\n" "-h help (this text)\n" ; -const char *optstring = "u12xza:c:n:t:hi:o:s:vy"; +const char *optstring = "u12xza:c:n:t:hi:o:s:vym:"; 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); @@ -219,7 +225,7 @@ 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, bool *zap, + bool *aesviahash, char *ndef_type, char *ndef, int *usb_mode, bool *zap, int *exit_code) { int c; @@ -231,6 +237,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, bool swap_seen = false; bool update_seen = false; bool ndef_seen = false; + bool usb_mode_seen = false; struct config_st *ycfg; ykp_configure_version(cfg, st); @@ -429,6 +436,29 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, ndef_seen = true; break; } + case 'm': + if(slot_chosen || swap_seen || update_seen || option_seen || *zap) { + fprintf(stderr, "USB mode (-m) can not be combined with other options.\n"); + *exit_code = 1; + return 0; + } + if(optarg[1] == '\0') { + int mode = optarg[0] - '0'; + if(mode >= 0 && mode < 4) { + *usb_mode = mode; + usb_mode_seen = true; + } + } + /* Only true if we've parsed a valid USB mode number */ + if(!usb_mode_seen) { + fprintf(stderr, "Invalid USB operation mode.\n"); + *exit_code = 1; + return 0; + } + if (!ykp_configure_command(cfg, SLOT_USB_MODE)) + return 0; + + break; case 'o': if (*zap) { fprintf(stderr, "No options can be given with zap (-z).\n"); @@ -618,7 +648,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, YK_KEY *yk, } } - if (!slot_chosen && !ndef_seen) { + if (!slot_chosen && !ndef_seen && !usb_mode_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 6611a9a..d42ad38 100644 --- a/ykpers-args.h +++ b/ykpers-args.h @@ -38,8 +38,8 @@ 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, bool *zap, - int *exit_code); + bool *aesviahash, char *ndef_type, char *ndef, int *usb_mode, + bool *zap, int *exit_code); void report_yk_error(void); diff --git a/ykpers.c b/ykpers.c index 12ead7d..f2dd875 100644 --- a/ykpers.c +++ b/ykpers.c @@ -184,6 +184,14 @@ int ykp_configure_command(YKP_CONFIG *cfg, uint8_t command) return 0; } break; + /* TODO: Make sure this is correct */ + case SLOT_USB_MODE: + /* For testing only */ + if(!(cfg->yk_major_version == 2 && cfg->yk_minor_version == 3 && cfg->yk_build_version == 1)) { + ykp_errno = YKP_EYUBIKEYVER; + return 0; + } + break; case SLOT_NDEF2: if (!(cfg->yk_major_version == 3)) { ykp_errno = YKP_EYUBIKEYVER; diff --git a/ykpersonalize.c b/ykpersonalize.c index 1b39839..f868101 100644 --- a/ykpersonalize.c +++ b/ykpersonalize.c @@ -67,6 +67,7 @@ int main(int argc, char **argv) char *salt = NULL; char ndef_string[128] = {0}; char ndef_type = 0; + int usb_mode = -1; bool zap = false; bool error = false; @@ -127,8 +128,8 @@ int main(int argc, char **argv) &autocommit, salt, st, &verbose, access_code, &use_access_code, - &aesviahash, &ndef_type, ndef_string, &zap, - &exit_code)) { + &aesviahash, &ndef_type, ndef_string, + &usb_mode, &zap, &exit_code)) { goto err; } @@ -204,6 +205,8 @@ int main(int argc, char **argv) fprintf(stderr, "Configuration in slot 1 and 2 will be swapped\n"); } else if(ykp_command(cfg) == SLOT_NDEF || ykp_command(cfg) == SLOT_NDEF2) { fprintf(stderr, "New NDEF will be written as:\n%s\n", ndef_string); + } else if(ykp_command(cfg) == SLOT_USB_MODE) { + fprintf(stderr, "The USB mode will be set to: %d\n", usb_mode); } else if(zap) { fprintf(stderr, "Configuration in slot %d will be deleted\n", ykp_config_num(cfg)); } else { @@ -250,6 +253,12 @@ int main(int argc, char **argv) goto err; } ykp_free_ndef(ndef); + } else if(ykp_command(cfg) == SLOT_USB_MODE) { + if(!yk_set_usb_mode(yk, usb_mode)) { + if(verbose) + printf(" failure\n"); + goto err; + } } else { YK_CONFIG *ycfg = NULL; /* if we're deleting a slot we send the configuration as NULL */