From 5e784ec3c255516a4045f7a667356fb29a53b2aa Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 31 May 2016 15:18:06 +0200 Subject: [PATCH] Fix key generation error handling - Check allowed RSA/DSA key lengths - Translate known openssl errors - Fix SIZE_MAX checks - Update doxygen Change-Id: If230518bb4a4d490cffde61fb2930ee7200fa083 --- api/yaca/yaca_key.h | 4 ++++ src/debug.c | 4 ++++ src/key.c | 24 +++++++++--------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index 94c46ef..f79115f 100644 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -174,6 +174,10 @@ int yaca_key_export(const yaca_key_h key, * * @remarks This function is used to generate symmetric and private asymmetric keys. * + * Supported key lengths: + * - RSA: length >= 256bits + * - DSA: length >= 512bits, multiple of 64 + * * @param[in] key_type Type of the key to be generated * @param[in] key_bits Length of the key (in bits) to be generated * @param[out] key Newly generated key (must be freed with yaca_key_free()) diff --git a/src/debug.c b/src/debug.c index 595626c..39c15de 100644 --- a/src/debug.c +++ b/src/debug.c @@ -135,6 +135,10 @@ int error_handle(const char *file, int line, const char *function) /* known errors */ } else { switch (err) { + case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED): + ret = YACA_ERROR_INVALID_ARGUMENT; + break; case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT): case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT): ret = YACA_ERROR_PASSWORD_INVALID; diff --git a/src/key.c b/src/key.c index ea0098e..f9ed709 100644 --- a/src/key.c +++ b/src/key.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -203,7 +202,8 @@ int import_simple(yaca_key_h *key, return ret; } - if (key_data_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) { + /* key_bits has to fit in size_t */ + if (key_data_len > SIZE_MAX / 8) { ret = YACA_ERROR_INVALID_ARGUMENT; goto out; } @@ -718,9 +718,6 @@ int gen_simple(struct yaca_key_simple_s **out, size_t key_bits) struct yaca_key_simple_s *nk; size_t key_byte_len = key_bits / 8; - if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) - return YACA_ERROR_INVALID_ARGUMENT; - nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); if (nk == NULL) return YACA_ERROR_OUT_OF_MEMORY; @@ -748,9 +745,6 @@ int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits) struct yaca_key_simple_s *nk; size_t key_byte_len = key_bits / 8; - if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) - return YACA_ERROR_INVALID_ARGUMENT; - nk = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len); if (nk == NULL) return YACA_ERROR_OUT_OF_MEMORY; @@ -815,8 +809,7 @@ int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits) ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits); if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); + ret = ERROR_HANDLE(); goto free_ctx; } @@ -847,6 +840,11 @@ int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits) assert(key_bits > 0); assert(key_bits % 8 == 0); + /* Openssl generates 512-bit key for key lengths smaller than 512. It also + * rounds key size to multiplication of 64. */ + if(key_bits < 512 || key_bits % 64 != 0) + return YACA_ERROR_INVALID_ARGUMENT; + int ret; struct yaca_key_evp_s *nk; EVP_PKEY_CTX *pctx; @@ -874,8 +872,7 @@ int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits) ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bits); if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); + ret = ERROR_HANDLE(); goto free_pctx; } @@ -1236,9 +1233,6 @@ API int yaca_key_derive_pbkdf2(const char *password, if (key_bits % 8) /* Key length must be multiple of 8-bits */ return YACA_ERROR_INVALID_ARGUMENT; - if (key_byte_len > SIZE_MAX - sizeof(struct yaca_key_simple_s)) - return YACA_ERROR_INVALID_ARGUMENT; - ret = digest_get_algorithm(algo, &md); if (ret != YACA_ERROR_NONE) return ret; -- 2.7.4