From: Fredrik Thulin Date: Mon, 7 Mar 2011 15:28:08 +0000 (+0100) Subject: Add ability to read serial number. X-Git-Tag: v1.5.0~5^2~2 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e29dd200d66f37a09be5c74b837b4ed13ef4cd8;p=yubikey-personalization Add ability to read serial number. --- diff --git a/ykcore/ykcore.c b/ykcore/ykcore.c index e74e0fe..ed2afd4 100644 --- a/ykcore/ykcore.c +++ b/ykcore/ykcore.c @@ -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) { diff --git a/ykpersonalize.c b/ykpersonalize.c index 387e650..cb480f1 100644 --- a/ykpersonalize.c +++ b/ykpersonalize.c @@ -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;