diff --git a/lib/error.c b/lib/error.c index 4f5aa9a..af3454f 100644 --- a/lib/error.c +++ b/lib/error.c @@ -49,6 +49,7 @@ static const err_t errors[] = { ERR (YKPIV_AUTHENTICATION_ERROR, "Error during authentication"), ERR (YKPIV_RANDOMNESS_ERROR, "Error getting randomness"), ERR (YKPIV_GENERIC_ERROR, "Something went wrong."), + ERR (YKPIV_KEY_ERROR, "Error in key"), }; /** diff --git a/lib/ykpiv.c b/lib/ykpiv.c index 62851aa..ac8a357 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -383,3 +383,33 @@ ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key) { } return YKPIV_GENERIC_ERROR; } + +ykpiv_rc ykpiv_parse_key(ykpiv_state *state, + const char *key_in, unsigned char *key_out) { + unsigned int i; + char key_part[4] = {0}; + int key_len = strlen(key_in); + + if(key_len != DES_KEY_SZ * 3 * 2) { + if(state->verbose) { + fprintf(stderr, "Wrong key size, should be %lu characters (was %d).\n", DES_KEY_SZ * 3 * 2, key_len); + } + return YKPIV_SIZE_ERROR; + } + for(i = 0; i < DES_KEY_SZ * 3; i++) { + key_part[0] = *key_in++; + key_part[1] = *key_in++; + if(sscanf(key_part, "%hhx", &key_out[i]) != 1) { + if(state->verbose) { + fprintf(stderr, "Failed parsing key at position %d.\n", i); + } + return YKPIV_KEY_ERROR; + } + } + if(state->verbose > 1) { + fprintf(stderr, "parsed key: "); + dump_hex(key_out, DES_KEY_SZ * 3); + fprintf(stderr, "\n"); + } + return YKPIV_OK; +} diff --git a/lib/ykpiv.h b/lib/ykpiv.h index 7d8924a..847667c 100644 --- a/lib/ykpiv.h +++ b/lib/ykpiv.h @@ -48,6 +48,7 @@ extern "C" YKPIV_AUTHENTICATION_ERROR = -5, YKPIV_RANDOMNESS_ERROR = -6, YKPIV_GENERIC_ERROR = -7, + YKPIV_KEY_ERROR = -8, } ykpiv_rc; const char *ykpiv_strerror(ykpiv_rc err); @@ -63,6 +64,8 @@ extern "C" unsigned char *data, unsigned long *recv_len, int *sw); ykpiv_rc ykpiv_authenticate(ykpiv_state *state, const unsigned char *key); ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key); + ykpiv_rc ykpiv_parse_key(ykpiv_state *state, + const char *key_in, unsigned char *key_out); #define YKPIV_ALGO_3DES 0x03; #define YKPIV_ALGO_RSA1024 0x06; diff --git a/lib/ykpiv.map b/lib/ykpiv.map index 20e07d9..34ab3fd 100644 --- a/lib/ykpiv.map +++ b/lib/ykpiv.map @@ -37,6 +37,7 @@ global: ykpiv_transfer_data; ykpiv_authenticate; ykpiv_set_mgmkey; + ykpiv_parse_key; local: *; diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index 86f4d0c..051a765 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -1063,31 +1063,6 @@ static void dump_hex(const unsigned char *buf, unsigned int len) { } } -static bool parse_key(char *key_arg, unsigned char *key, int verbose) { - int i; - char key_part[4] = {0}; - int key_len = strlen(key_arg); - - if(key_len != KEY_LEN * 2) { - fprintf(stderr, "Wrong key size, should be %d characters (was %d).\n", KEY_LEN * 2, key_len); - return false; - } - for(i = 0; i < KEY_LEN; i++) { - key_part[0] = *key_arg++; - key_part[1] = *key_arg++; - if(sscanf(key_part, "%hhx", &key[i]) != 1) { - fprintf(stderr, "Failed parsing key at position %d.\n", i); - return false; - } - } - if(verbose > 1) { - fprintf(stderr, "parsed key: "); - dump_hex(key, KEY_LEN); - fprintf(stderr, "\n"); - } - return true; -} - static int get_length(unsigned char *buffer, int *len) { if(buffer[0] < 0x81) { *len = buffer[0]; @@ -1156,10 +1131,6 @@ int main(int argc, char *argv[]) { verbosity = args_info.verbose_arg + (int)args_info.verbose_given; - if(parse_key(args_info.key_arg, key, verbosity) == false) { - return EXIT_FAILURE; - } - if(ykpiv_init(&state, verbosity) != YKPIV_OK) { fprintf(stderr, "Failed initializing library.\n"); return EXIT_FAILURE; @@ -1170,6 +1141,10 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + if(ykpiv_parse_key(state, args_info.key_arg, key) != YKPIV_OK) { + return EXIT_FAILURE; + } + if(ykpiv_authenticate(state, key) != YKPIV_OK) { fprintf(stderr, "Failed authentication with the applet.\n"); return EXIT_FAILURE; @@ -1203,7 +1178,7 @@ int main(int argc, char *argv[]) { case action_arg_setMINUS_mgmMINUS_key: if(args_info.new_key_arg) { unsigned char new_key[KEY_LEN]; - if(parse_key(args_info.new_key_arg, new_key, verbosity) == false) { + if(ykpiv_parse_key(state, args_info.new_key_arg, new_key) != YKPIV_OK) { ret = EXIT_FAILURE; } else if(ykpiv_set_mgmkey(state, new_key) != YKPIV_OK) { ret = EXIT_FAILURE;