Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wipe output on failure: key generation #586

Merged
merged 3 commits into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/soter/openssl/soter_rsa_key_pair_gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#include "soter/openssl/soter_engine.h"

static unsigned rsa_key_length(const int size)
static int rsa_key_length(unsigned size)
{
switch (size) {
case RSA_KEY_LENGTH_1024:
Expand Down Expand Up @@ -72,7 +72,7 @@ static soter_status_t soter_set_default_rsa_pub_exp(EVP_PKEY_CTX* pkey_ctx)
return SOTER_SUCCESS;
}

static soter_status_t soter_set_rsa_key_length(EVP_PKEY_CTX* pkey_ctx, unsigned length)
static soter_status_t soter_set_rsa_key_length(EVP_PKEY_CTX* pkey_ctx, int length)
{
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, length, NULL) != 1) {
return SOTER_FAIL;
Expand Down
96 changes: 64 additions & 32 deletions src/themis/secure_keygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "soter/soter_rsa_key.h"
#include "soter/soter_rsa_key_pair_gen.h"
#include "soter/soter_t.h"
#include "soter/soter_wipe.h"

#include "themis/themis_portable_endian.h"

Expand All @@ -39,61 +40,92 @@
*/
#define THEMIS_SYM_KEY_LENGTH 32

static themis_status_t combine_key_generation_results(uint8_t* private_key,
const size_t* private_key_length,
themis_status_t private_result,
uint8_t* public_key,
const size_t* public_key_length,
themis_status_t public_result)
{
if (private_result == THEMIS_SUCCESS && public_result == THEMIS_SUCCESS) {
return THEMIS_SUCCESS;
}

if (private_result != THEMIS_BUFFER_TOO_SMALL) {
soter_wipe(private_key, *private_key_length);
}
if (public_result != THEMIS_BUFFER_TOO_SMALL) {
soter_wipe(public_key, *public_key_length);
}

if (private_result == THEMIS_BUFFER_TOO_SMALL || public_result == THEMIS_BUFFER_TOO_SMALL) {
return THEMIS_BUFFER_TOO_SMALL;
}

return (private_result != THEMIS_SUCCESS) ? private_result : public_result;
}

themis_status_t themis_gen_key_pair(soter_sign_alg_t alg,
uint8_t* private_key,
size_t* private_key_length,
uint8_t* public_key,
size_t* public_key_length)
{
soter_sign_ctx_t* ctx = soter_sign_create(alg, NULL, 0, NULL, 0);
THEMIS_CHECK(ctx != NULL);
themis_status_t private_result = THEMIS_FAIL;
themis_status_t public_result = THEMIS_FAIL;
soter_sign_ctx_t* ctx = NULL;

soter_status_t res_private = soter_sign_export_key(ctx, private_key, private_key_length, true);
if (res_private != THEMIS_SUCCESS && res_private != THEMIS_BUFFER_TOO_SMALL) {
soter_sign_destroy(ctx);
return res_private;
if (!private_key_length || !public_key_length) {
return THEMIS_INVALID_PARAMETER;
}

soter_status_t res_public = soter_sign_export_key(ctx, public_key, public_key_length, false);
if (res_public != THEMIS_SUCCESS && res_public != THEMIS_BUFFER_TOO_SMALL) {
soter_sign_destroy(ctx);
return res_public;
ctx = soter_sign_create(alg, NULL, 0, NULL, 0);
if (!ctx) {
return THEMIS_FAIL;
}

private_result = soter_sign_export_key(ctx, private_key, private_key_length, true);
public_result = soter_sign_export_key(ctx, public_key, public_key_length, false);

soter_sign_destroy(ctx);
if (res_private == THEMIS_BUFFER_TOO_SMALL || res_public == THEMIS_BUFFER_TOO_SMALL) {
return THEMIS_BUFFER_TOO_SMALL;
}
return THEMIS_SUCCESS;

return combine_key_generation_results(private_key,
private_key_length,
private_result,
public_key,
public_key_length,
public_result);
}

themis_status_t themis_gen_rsa_key_pair(uint8_t* private_key,
size_t* private_key_length,
uint8_t* public_key,
size_t* public_key_length)
{
soter_rsa_key_pair_gen_t* key_pair_ctx = soter_rsa_key_pair_gen_create(THEMIS_RSA_KEY_LENGTH);
THEMIS_CHECK(key_pair_ctx != NULL);
themis_status_t private_result = THEMIS_FAIL;
themis_status_t public_result = THEMIS_FAIL;
soter_rsa_key_pair_gen_t* ctx = NULL;

soter_status_t res_private =
soter_rsa_key_pair_gen_export_key(key_pair_ctx, private_key, private_key_length, true);
if (res_private != THEMIS_SUCCESS && res_private != THEMIS_BUFFER_TOO_SMALL) {
soter_rsa_key_pair_gen_destroy(key_pair_ctx);
return res_private;
if (!private_key_length || !public_key_length) {
return THEMIS_INVALID_PARAMETER;
}

soter_status_t res_public =
soter_rsa_key_pair_gen_export_key(key_pair_ctx, public_key, public_key_length, false);
if (res_public != THEMIS_SUCCESS && res_public != THEMIS_BUFFER_TOO_SMALL) {
soter_rsa_key_pair_gen_destroy(key_pair_ctx);
return res_public;
ctx = soter_rsa_key_pair_gen_create(THEMIS_RSA_KEY_LENGTH);
if (!ctx) {
return THEMIS_FAIL;
}

soter_rsa_key_pair_gen_destroy(key_pair_ctx);
if (res_private == THEMIS_BUFFER_TOO_SMALL || res_public == THEMIS_BUFFER_TOO_SMALL) {
return THEMIS_BUFFER_TOO_SMALL;
}
return THEMIS_SUCCESS;
private_result = soter_rsa_key_pair_gen_export_key(ctx, private_key, private_key_length, true);
public_result = soter_rsa_key_pair_gen_export_key(ctx, public_key, public_key_length, false);

soter_rsa_key_pair_gen_destroy(ctx);

return combine_key_generation_results(private_key,
private_key_length,
private_result,
public_key,
public_key_length,
public_result);
}

themis_status_t themis_gen_ec_key_pair(uint8_t* private_key,
Expand Down Expand Up @@ -179,6 +211,6 @@ themis_status_t themis_gen_sym_key(uint8_t* key, size_t* key_length)
return THEMIS_BUFFER_TOO_SMALL;
}

/* Soter error codes have the same value as Themis ones */
/* soter_rand() wipes the key on failure, soter_wipe() not needed */
return soter_rand(key, *key_length);
}