From 12f35b88847203e8dff56eb211017a30ddc7f58d Mon Sep 17 00:00:00 2001 From: Trevor Bentley Date: Tue, 12 Sep 2017 15:20:56 +0200 Subject: [PATCH] yubico-piv-tool: use util function for key generation --- tool/yubico-piv-tool.c | 142 +++++++++++++---------------------------- 1 file changed, 45 insertions(+), 97 deletions(-) diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index 757e1c4..700eaa1 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -119,20 +119,20 @@ static bool generate_key(ykpiv_state *state, const char *slot, enum enum_algorithm algorithm, const char *output_file_name, enum enum_key_format key_format, enum enum_pin_policy pin_policy, enum enum_touch_policy touch_policy) { - unsigned char in_data[11]; - unsigned char *in_ptr = in_data; - unsigned char data[1024]; - unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMETRIC, 0, 0}; - unsigned long recv_len = sizeof(data); - int sw; int key = 0; - FILE *output_file = NULL; bool ret = false; + ykpiv_rc res; + FILE *output_file = NULL; EVP_PKEY *public_key = NULL; RSA *rsa = NULL; - BIGNUM *bignum_n = NULL; - BIGNUM *bignum_e = NULL; EC_KEY *eckey = NULL; + EC_POINT *ecpoint = NULL; + uint8_t *mod = NULL; + uint8_t *exp = NULL; + uint8_t *point = NULL; + size_t mod_len = 0; + size_t exp_len = 0; + size_t point_len = 0; EC_POINT *point = NULL; char version[7]; @@ -152,130 +152,69 @@ static bool generate_key(ykpiv_state *state, const char *slot, } sscanf(slot, "%2x", &key); - templ[3] = key; output_file = open_file(output_file_name, OUTPUT); if(!output_file) { return false; } - *in_ptr++ = 0xac; - *in_ptr++ = 3; - *in_ptr++ = YKPIV_ALGO_TAG; - *in_ptr++ = 1; - *in_ptr++ = get_piv_algorithm(algorithm); - if(in_data[4] == 0) { - fprintf(stderr, "Unexpected algorithm.\n"); - goto generate_out; - } - if(pin_policy != pin_policy__NULL) { - in_data[1] += 3; - *in_ptr++ = YKPIV_PINPOLICY_TAG; - *in_ptr++ = 1; - *in_ptr++ = get_pin_policy(pin_policy); - } - if(touch_policy != touch_policy__NULL) { - in_data[1] += 3; - *in_ptr++ = YKPIV_TOUCHPOLICY_TAG; - *in_ptr++ = 1; - *in_ptr++ = get_touch_policy(touch_policy); - } - if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data, - &recv_len, &sw) != YKPIV_OK) { - fprintf(stderr, "Failed to communicate.\n"); - goto generate_out; - } else if(sw != SW_SUCCESS) { - fprintf(stderr, "Failed to generate new key ("); - if(sw == SW_ERR_INCORRECT_SLOT) { - fprintf(stderr, "slot not supported?)\n"); - } else if(sw == SW_ERR_INCORRECT_PARAM) { - if(pin_policy != pin_policy__NULL) { - fprintf(stderr, "pin policy not supported?)\n"); - } else if(touch_policy != touch_policy__NULL) { - fprintf(stderr, "touch policy not supported?)\n"); - } else { - fprintf(stderr, "algorithm not supported?)\n"); - } - } else { - fprintf(stderr, "error %x)\n", sw); - } + res = ykpiv_util_generate_key(state, + (uint8_t)(key & 0xFF), + get_piv_algorithm(algorithm), + get_pin_policy(pin_policy), + get_touch_policy(touch_policy), + &mod, + &mod_len, + &exp, + &exp_len, + &point, + &point_len); + if (res != YKPIV_OK) { + fprintf(stderr, "Key generation failed.\n"); goto generate_out; } if(key_format == key_format_arg_PEM) { public_key = EVP_PKEY_new(); if(algorithm == algorithm_arg_RSA1024 || algorithm == algorithm_arg_RSA2048) { - unsigned char *data_ptr = data + 5; - int len = 0; rsa = RSA_new(); - - if(*data_ptr != 0x81) { - fprintf(stderr, "Failed to parse public key structure.\n"); - goto generate_out; - } - data_ptr++; - data_ptr += get_length(data_ptr, &len); - bignum_n = BN_bin2bn(data_ptr, len, NULL); - if(bignum_n == NULL) { + rsa->n = BN_bin2bn(mod, mod_len, NULL); + if (rsa->n == NULL) { fprintf(stderr, "Failed to parse public key modulus.\n"); goto generate_out; } - data_ptr += len; - - if(*data_ptr != 0x82) { - fprintf(stderr, "Failed to parse public key structure (2).\n"); - goto generate_out; - } - data_ptr++; - data_ptr += get_length(data_ptr, &len); - bignum_e = BN_bin2bn(data_ptr, len, NULL); - if(bignum_e == NULL) { + rsa->e = BN_bin2bn(exp, exp_len, NULL); + if(rsa->e == NULL) { fprintf(stderr, "Failed to parse public key exponent.\n"); goto generate_out; } - - rsa->n = bignum_n; - rsa->e = bignum_e; EVP_PKEY_set1_RSA(public_key, rsa); } else if(algorithm == algorithm_arg_ECCP256 || algorithm == algorithm_arg_ECCP384) { EC_GROUP *group; - unsigned char *data_ptr = data + 3; int nid; - size_t len; if(algorithm == algorithm_arg_ECCP256) { nid = NID_X9_62_prime256v1; - len = 65; } else { nid = NID_secp384r1; - len = 97; } - eckey = EC_KEY_new(); group = EC_GROUP_new_by_curve_name(nid); EC_GROUP_set_asn1_flag(group, nid); EC_KEY_set_group(eckey, group); - point = EC_POINT_new(group); - if(*data_ptr++ != 0x86) { - fprintf(stderr, "Failed to parse public key structure.\n"); - goto generate_out; - } - if(*data_ptr++ != len) { /* the curve point should always be 65 bytes */ - fprintf(stderr, "Unexpected length.\n"); - goto generate_out; - } - if(!EC_POINT_oct2point(group, point, data_ptr, len, NULL)) { + ecpoint = EC_POINT_new(group); + + if(!EC_POINT_oct2point(group, ecpoint, point, point_len, NULL)) { fprintf(stderr, "Failed to load public point.\n"); goto generate_out; } - if(!EC_KEY_set_public_key(eckey, point)) { + if(!EC_KEY_set_public_key(eckey, ecpoint)) { fprintf(stderr, "Failed to set the public key.\n"); goto generate_out; } EVP_PKEY_set1_EC_KEY(public_key, eckey); } else { fprintf(stderr, "Wrong algorithm.\n"); - goto generate_out; } PEM_write_PUBKEY(output_file, public_key); ret = true; @@ -285,21 +224,30 @@ static bool generate_key(ykpiv_state *state, const char *slot, } generate_out: - if(output_file != stdout) { + if (output_file != stdout) { fclose(output_file); } - if(point) { - EC_POINT_free(point); + if (ecpoint) { + EC_POINT_free(ecpoint); } - if(eckey) { + if (eckey) { EC_KEY_free(eckey); } - if(rsa) { + if (rsa) { RSA_free(rsa); } - if(public_key) { + if (public_key) { EVP_PKEY_free(public_key); } + if (point) { + ykpiv_util_free(state, point); + } + if (mod) { + ykpiv_util_free(state, mod); + } + if (exp) { + ykpiv_util_free(state, exp); + } return ret; }