From: Lukasz Pawelczyk Date: Mon, 2 May 2016 11:50:46 +0000 (+0200) Subject: yaca_key_extract_public() public function X-Git-Tag: accepted/tizen/common/20160810.161523~176 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2758c7949bf6208e94e180565fabde70d795eb01;p=platform%2Fcore%2Fsecurity%2Fyaca.git yaca_key_extract_public() public function The idea is to remove yaca_key_gen_pair() and always generate using yaca_key_gen(). The latter will always generate private keys for asymmetric types. Public key will be extracted (if needed) using the function implemented here. This approach has an advantage that we can extract public keys for private keys imported from external sources. Previously this was impossible. Change-Id: I081c81eb37ed3267518aac21a9bf36063ef0e901 --- diff --git a/api/yaca/key.h b/api/yaca/key.h index 3a829d5..c7e3727 100644 --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -127,6 +127,17 @@ int yaca_key_gen(yaca_key_h *sym_key, size_t key_bits); /** + * @brief yaca_key_extract_public Extracts public key from a private one. + * + * @param[in] prv_key Private key to extract the public one from. + * @param[out] pub_key Extracted public key (must be freed with yaca_key_free()). + * + * @return 0 on success, negative on error. + * @see yaca_key_gen(), yaca_key_import(), yaca_key_free() + */ +int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); + +/** * @brief yaca_key_gen_pair Generates a new key pair. * * @param[out] prv_key Newly generated private key (must be freed with yaca_key_free()). diff --git a/src/key.c b/src/key.c index a8fb8ff..5c0d43c 100644 --- a/src/key.c +++ b/src/key.c @@ -704,6 +704,73 @@ err: return ret; } +API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) +{ + int ret; + struct yaca_key_evp_s *evp_key = key_get_evp(prv_key); + struct yaca_key_evp_s *nk = NULL; + RSA *rsa_pub = NULL; + + if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + + nk = yaca_zalloc(sizeof(struct yaca_key_evp_s)); + if (nk == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + nk->evp = EVP_PKEY_new(); + if (nk->evp == NULL) { + ret = YACA_ERROR_OUT_OF_MEMORY; + ERROR_DUMP(ret); + goto free_key; + } + + switch(prv_key->type) + { + case YACA_KEY_TYPE_RSA_PRIV: + assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_RSA); + + rsa_pub = RSAPublicKey_dup(EVP_PKEY_get0(evp_key->evp)); + if (rsa_pub == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_evp; + } + + ret = EVP_PKEY_assign_RSA(nk->evp, rsa_pub); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto free_rsa; + } + + *pub_key = (yaca_key_h)nk; + (*pub_key)->type = YACA_KEY_TYPE_RSA_PUB; + + return 0; + + case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_ECDSA_PRIV: + ret = YACA_ERROR_NOT_IMPLEMENTED; + goto free_evp; + + default: + ret = YACA_ERROR_INVALID_ARGUMENT; + goto free_evp; + } + + return YACA_ERROR_INVALID_ARGUMENT; + +free_rsa: + RSA_free(rsa_pub); +free_evp: + EVP_PKEY_free(nk->evp); +free_key: + yaca_free(nk); + + return ret; +} + API int yaca_key_gen_pair(yaca_key_h *prv_key, yaca_key_h *pub_key, yaca_key_type_e key_type,