diff --git a/lib/util.c b/lib/util.c index 022363a0..cb5ef528 100644 --- a/lib/util.c +++ b/lib/util.c @@ -34,6 +34,10 @@ #ifdef USE_CERT_COMPRESS #include +#include +#include +#include + #endif #include "internal.h" @@ -1860,3 +1864,55 @@ static ykpiv_rc _write_metadata(ykpiv_state *state, uint8_t tag, uint8_t *data, return res; } + +ykpiv_rc get_ec_pubkey_from_bytes(int curve_name, uint8_t *point, size_t point_len, EVP_PKEY **pkey) { + ykpiv_rc rc = YKPIV_OK; + EC_POINT *ecpoint = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = EC_GROUP_new_by_curve_name(curve_name); + if(group == NULL) + return YKPIV_MEMORY_ERROR; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + eckey = EC_KEY_new(); + if(eckey == NULL) { + rc = YKPIV_MEMORY_ERROR; + goto create_ec_cleanup; + } + if(EC_KEY_set_group(eckey, group) <= 0) { + rc = YKPIV_GENERIC_ERROR; + goto create_ec_cleanup; + } + ecpoint = EC_POINT_new(group); + if(ecpoint == NULL) { + rc = YKPIV_MEMORY_ERROR; + goto create_ec_cleanup; + } + if(EC_POINT_oct2point(group, ecpoint, point, point_len, NULL) <= 0) { + rc = YKPIV_ARGUMENT_ERROR; + goto create_ec_cleanup; + } + if(EC_KEY_set_public_key(eckey, ecpoint) <= 0) { + rc = YKPIV_GENERIC_ERROR; + goto create_ec_cleanup; + } + EVP_PKEY_free(*pkey); + *pkey = EVP_PKEY_new(); + if(*pkey == NULL) { + rc = YKPIV_MEMORY_ERROR; + goto create_ec_cleanup; + } + if(EVP_PKEY_assign_EC_KEY(*pkey, eckey) <= 0) { + rc = YKPIV_GENERIC_ERROR; + goto create_ec_cleanup; + } + +create_ec_cleanup: + EC_GROUP_clear_free(group); + if(ecpoint != NULL) { + EC_POINT_clear_free(ecpoint); + } + if(rc != YKPIV_OK && eckey != NULL) { + EC_KEY_free(eckey); + } + return rc; +} \ No newline at end of file diff --git a/lib/ykpiv.c b/lib/ykpiv.c index 47231a5c..9b352e2e 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -390,58 +390,7 @@ ykpiv_rc ykpiv_disconnect(ykpiv_state *state) { return YKPIV_OK; } -static EVP_PKEY *get_ec_pubkey_from_bytes(uint8_t *pubkey, uint8_t pubkey_len) { - EVP_PKEY *evp_pkey = NULL; - EC_GROUP *ecg = NULL; - EC_POINT *ecp = NULL; - EC_KEY *eckey = NULL; - - ecg = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); - if(!ecg) { - DBG("Failed to create EC_GROUP"); - return NULL; - } - - ecp = EC_POINT_new(ecg); - if(!ecp) { - DBG("Failed to create EC_POINT"); - goto ec_pubkey_cleanup; - } - - if (EC_POINT_oct2point(ecg, ecp, pubkey, pubkey_len, NULL) == 0) { - DBG("Failed to parse public key as ec_point"); - goto ec_pubkey_cleanup; - } - - eckey = EC_KEY_new(); - EC_KEY_set_group(eckey, ecg); - if (EC_KEY_set_public_key(eckey, ecp) == 0) { - DBG("Failed to convert sd pubkey point to eckey"); - goto ec_pubkey_cleanup; - } - - evp_pkey = EVP_PKEY_new(); - if (!EVP_PKEY_assign_EC_KEY(evp_pkey, eckey)) { - DBG("Failed to convert sd pubkey eckey to evp_pkey"); - goto ec_pubkey_cleanup; - } - - return evp_pkey; - -ec_pubkey_cleanup: - if(ecg) { - EC_GROUP_free(ecg); - } - if(ecp) { - EC_POINT_free(ecp); - } - if(eckey) { - EC_KEY_free(eckey); - } - - return NULL; - } - +#if (OPENSSL_VERSION_NUMBER > 0x10100000L) static ykpiv_rc derive_ecdh(EVP_PKEY *private_key, EVP_PKEY *peer_key, uint8_t *ecdh_key, size_t ecdh_len) { /* Create the context for the shared secret derivation */ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(private_key, NULL); @@ -487,7 +436,7 @@ static ykpiv_rc derive_ecdh(EVP_PKEY *private_key, EVP_PKEY *peer_key, uint8_t * return rc; } -#if (OPENSSL_VERSION_NUMBER > 0x10100000L) + static EVP_PKEY* scp11_get_sd_pubkey(ykpiv_state *state) { ykpiv_rc res; @@ -527,10 +476,12 @@ static EVP_PKEY* scp11_get_sd_pubkey(ykpiv_state *state) { static ykpiv_rc scp11_derive_session_keys(EC_KEY *ekeypair_oce, uint8_t *epubkey_sd_bytes, size_t epubkey_sd_len, EVP_PKEY *pubkey_sd, uint8_t *session_keys) { - EVP_PKEY *epubkey_sd = get_ec_pubkey_from_bytes(epubkey_sd_bytes, epubkey_sd_len); - if (!epubkey_sd) { + ykpiv_rc rc = YKPIV_OK; + EVP_PKEY *epubkey_sd = NULL; + rc = get_ec_pubkey_from_bytes(NID_X9_62_prime256v1, epubkey_sd_bytes, epubkey_sd_len, &epubkey_sd); + if (rc != YKPIV_OK) { DBG("Failed to convert sd pubkey bytes to evp_pkey"); - return YKPIV_MEMORY_ERROR; + return rc; } EVP_PKEY *eprivkey_oce = EVP_PKEY_new(); @@ -539,7 +490,6 @@ static ykpiv_rc scp11_derive_session_keys(EC_KEY *ekeypair_oce, uint8_t *epubkey return YKPIV_MEMORY_ERROR; } - ykpiv_rc rc = YKPIV_OK; if (!EVP_PKEY_assign_EC_KEY(eprivkey_oce, ekeypair_oce)) { DBG("Failed to parse OCE ephemeral private key (eSK.OCE.ECKA)"); rc = YKPIV_AUTHENTICATION_ERROR; diff --git a/lib/ykpiv.h b/lib/ykpiv.h index 2da4e3d3..0d330945 100644 --- a/lib/ykpiv.h +++ b/lib/ykpiv.h @@ -42,6 +42,7 @@ #include #include #include +#include #include "ykpiv-config.h" @@ -221,6 +222,7 @@ extern "C" */ ykpiv_rc ykpiv_get_serial(ykpiv_state *state, uint32_t* p_serial); + ykpiv_rc get_ec_pubkey_from_bytes(int curve_name, uint8_t *point, size_t point_len, EVP_PKEY **pkey); //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index d2cd27ea..8f52b2be 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -360,24 +360,8 @@ static bool generate_key(ykpiv_state *state, enum enum_slot slot, } else { nid = NID_secp384r1; } - eckey = EC_KEY_new(); - group = EC_GROUP_new_by_curve_name(nid); - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(eckey, group) != 1) { - fprintf(stderr, "Failed to set EC group.\n"); - goto generate_out; - } - 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, ecpoint)) { - fprintf(stderr, "Failed to set the public key.\n"); - goto generate_out; - } - if (EVP_PKEY_set1_EC_KEY(public_key, eckey) != 1) { + res = get_ec_pubkey_from_bytes(nid, point, point_len, &public_key); + if(res != YKPIV_OK) { fprintf(stderr, "Failed to set EC public key.\n"); goto generate_out; } diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index 50c1a531..5298444e 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -164,58 +164,6 @@ CK_RV do_generate_ec_key(int curve_name, ykcs11_pkey_t **pkey) { return rv; } -CK_RV do_create_ec_key(CK_BYTE_PTR point, CK_ULONG point_len, int curve_name, ykcs11_pkey_t **pkey) { - CK_RV rv; - EC_POINT *ecpoint = NULL; - EC_KEY *eckey = NULL; - EC_GROUP *group = EC_GROUP_new_by_curve_name(curve_name); - if(group == NULL) - return CKR_HOST_MEMORY; - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - eckey = EC_KEY_new(); - if(eckey == NULL) { - rv = CKR_HOST_MEMORY; - goto create_ec_cleanup; - } - if(EC_KEY_set_group(eckey, group) <= 0) { - rv = CKR_GENERAL_ERROR; - goto create_ec_cleanup; - } - ecpoint = EC_POINT_new(group); - if(ecpoint == NULL) { - rv = CKR_HOST_MEMORY; - goto create_ec_cleanup; - } - if(EC_POINT_oct2point(group, ecpoint, point, point_len, NULL) <= 0) { - rv = CKR_ARGUMENTS_BAD; - goto create_ec_cleanup; - } - if(EC_KEY_set_public_key(eckey, ecpoint) <= 0) { - rv = CKR_GENERAL_ERROR; - goto create_ec_cleanup; - } - EVP_PKEY_free(*pkey); - *pkey = EVP_PKEY_new(); - if(*pkey == NULL) { - rv = CKR_HOST_MEMORY; - goto create_ec_cleanup; - } - if(EVP_PKEY_assign_EC_KEY(*pkey, eckey) <= 0) { - rv = CKR_GENERAL_ERROR; - goto create_ec_cleanup; - } - rv = CKR_OK; -create_ec_cleanup: - EC_GROUP_clear_free(group); - if(ecpoint != NULL) { - EC_POINT_clear_free(ecpoint); - } - if(rv != CKR_OK && eckey != NULL) { - EC_KEY_free(eckey); - } - return rv; -} - CK_RV do_create_rsa_key(CK_BYTE_PTR mod, CK_ULONG mod_len, CK_BYTE_PTR exp, CK_ULONG exp_len, ykcs11_pkey_t **pkey) { CK_RV rv; RSA *rsa = NULL; @@ -306,7 +254,7 @@ CK_RV do_create_public_key(CK_BYTE_PTR in, CK_ULONG in_len, CK_ULONG algorithm, if (YKPIV_IS_EC(algorithm)) { int curve_name = get_curve_name(algorithm); - return do_create_ec_key(in, len, curve_name, pkey); + return get_ec_pubkey_from_bytes(curve_name, in, len, pkey); #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) } else if (YKPIV_IS_25519(algorithm)) { if (algorithm == YKPIV_ALGO_ED25519) { diff --git a/ykcs11/openssl_utils.h b/ykcs11/openssl_utils.h index b3230766..02fd6166 100644 --- a/ykcs11/openssl_utils.h +++ b/ykcs11/openssl_utils.h @@ -41,7 +41,6 @@ CK_RV do_rsa_encrypt(ykcs11_pkey_t *key, int padding, const ykcs11_md_t* oaep_md CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR enc, CK_ULONG_PTR enc_len); CK_RV do_store_cert(CK_BYTE_PTR data, CK_ULONG len, ykcs11_x509_t **cert); CK_RV do_generate_ec_key(int curve_name, ykcs11_pkey_t **pkey); -CK_RV do_create_ec_key(CK_BYTE_PTR point, CK_ULONG point_len, int curve_name, ykcs11_pkey_t **pkey); CK_RV do_create_rsa_key(CK_BYTE_PTR mod, CK_ULONG mod_len, CK_BYTE_PTR exp, CK_ULONG exp_len, ykcs11_pkey_t **pkey); CK_RV do_create_public_key(CK_BYTE_PTR in, CK_ULONG in_len, CK_ULONG algorithm, ykcs11_pkey_t **pkey); CK_RV do_sign_empty_cert(const char *cn, ykcs11_pkey_t *pubkey, ykcs11_pkey_t *pvtkey, ykcs11_x509_t **cert);