]> err.no Git - yubikey-personalization/commitdiff
Add ability to read serial number.
authorFredrik Thulin <fredrik@yubico.com>
Mon, 7 Mar 2011 15:28:08 +0000 (16:28 +0100)
committerFredrik Thulin <fredrik@yubico.com>
Mon, 7 Mar 2011 15:28:08 +0000 (16:28 +0100)
ykcore/ykcore.c
ykpersonalize.c

index e74e0fed977eed845ff134d4c5fb39aa6569cb45..ed2afd4c7555aef32a2d1862f236ec9db9b721cb 100644 (file)
@@ -52,6 +52,10 @@ int yk_wait_for_key_status(YK_KEY *yk, uint8_t slot, unsigned int flags,
                           bool logic_and, unsigned char mask,
                           unsigned char *last_data);
 
+int yk_read_response_from_key(YK_KEY *yk, uint8_t slot, unsigned int flags,
+                             void *buf, unsigned int bufsize, unsigned int expect_bytes,
+                             unsigned int *bytes_read);
+
 int yk_init(void)
 {
        return _ykusb_start();
@@ -126,6 +130,50 @@ int yk_get_status(YK_KEY *k, YK_STATUS *status)
        return 1;
 }
 
+/* Read the factory programmed serial number from a YubiKey.
+ * The possibility to retreive the serial number might be disabled
+ * using configuration, so it should not be considered a fatal error
+ * to not be able to read the serial number using this function.
+ *
+ * Serial number reading might also be configured to require user
+ * interaction (YubiKey button press) on startup, in which case flags
+ * might have to have YK_FLAG_MAYBLOCK set - haven't tried that.
+ *
+ * The slot parameter is here for future purposes only.
+ */
+int yk_get_serial(YK_KEY *yk, uint8_t slot, unsigned int flags, unsigned int *serial)
+{
+       unsigned char buf[FEATURE_RPT_SIZE * 2];
+       int yk_cmd;
+       unsigned int response_len = 0;
+       unsigned int expect_bytes = 0;
+
+       memset(buf, 0, sizeof(buf));
+
+       if (!yk_write_to_key(yk, SLOT_DEVICE_SERIAL, &buf, 0))
+               return 0;
+
+       expect_bytes = 4;
+
+       if (! yk_read_response_from_key(yk, slot, flags,
+                                       &buf, sizeof(buf),
+                                       expect_bytes,
+                                       &response_len))
+               return 0;
+
+       /* Serial number is stored in big endian byte order, despite
+        * everything else in the YubiKey being little endian - for
+        * some good reason I don't remember.
+        */
+       *serial =
+               (buf[0] << 24) +
+               (buf[1] << 16) +
+               (buf[2] << 8) +
+               (buf[3]);
+
+       return 1;
+}
+
 int yk_write_config(YK_KEY *yk, YK_CONFIG *cfg, int confnum,
                    unsigned char *acc_code)
 {
index 387e650563d395dbfbe3f57258f1373b9f5fae03..cb480f1aebc8c10c29586dd2f38d213a79375dfe 100644 (file)
@@ -246,7 +246,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg,
 
                        option_seen = true;
                }
-                   
+
                switch (c) {
                case '1':
                        if (slot_chosen) {
@@ -464,7 +464,7 @@ int args_to_config(int argc, char **argv, YKP_CONFIG *cfg,
                } else {
                        res = ykp_AES_key_from_hex(cfg, aeshash);
                }
-                       
+
                if (res) {
                        fprintf(stderr, "Bad %s key: %s\n", long_key_valid ? "HMAC":"AES", aeshash);
                        fflush(stderr);
@@ -557,6 +557,18 @@ int main(int argc, char **argv)
                goto err;
        }
 
+       if (verbose && ykds_version_major(st) >= 2) {
+               unsigned int serial;
+               if (! yk_get_serial(yk, 0, 0, &serial)) {
+                       printf ("Failed to read serial number (serial-api-visible disabled?).\n");
+
+               } else {
+                       printf ("Serial number : %i\n", serial);
+               }
+       }
+
+       printf ("\n");
+
        if (infname) {
                if (strcmp(infname, "-") == 0)
                        inf = stdin;