]> err.no Git - yubikey-personalization/commitdiff
Added the USB mode option to ykpersonalize, though the actual implementation is still...
authorDain Nilsson <dain@yubico.com>
Fri, 23 Nov 2012 16:25:15 +0000 (17:25 +0100)
committerDain Nilsson <dain@yubico.com>
Mon, 26 Nov 2012 11:30:21 +0000 (12:30 +0100)
tests/test_args_to_config.c
ykcore/ykcore.c
ykcore/ykdef.h
ykpers-args.c
ykpers-args.h
ykpers.c
ykpersonalize.c

index 8c8786a2e1aebe28f0cd950a3202e78cce0d8d7e..9f319f5cef8bfd2b7e0eab7e045129ef36ef1abe 100644 (file)
@@ -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);
index f3985d228d7db580d0127e094aa3b010220b9aef..4dbd2fcbe3b7c8a66bc0fd240b36888a2938e152 100644 (file)
@@ -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.
  */
index 5e0cbb66a25ca96e8263257fd6532cbe1edcf96d..08de9d62ee144d284aa9361dd9a678d8074b213f 100644 (file)
@@ -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 */
index a8b4c4a954bf015e3a978713640d9421fc636e7b..1aeb2398465a7701cae2e5f25754a0c65042f258 100644 (file)
@@ -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;
index 6611a9a26188e66cc769ff1e71028095511ce39e..d42ad3823a2c47aee2f96e14125ba6a32c8d1bf0 100644 (file)
@@ -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);
 
index 12ead7d69958c3164c30fb5c0e35da2bd6b3d606..f2dd87545b5572ef37fe415ff1205a43e29ba0bb 100644 (file)
--- 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;
index 1b39839f70a82e7aa8f6bb597af5b8f5fc15484d..f8681010e4df7bebdacd5434d7235f7566676f2b 100644 (file)
@@ -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 */