openssl: Extract helper function to derive a shared DH secret
This commit is contained in:
@@ -29,6 +29,49 @@
|
|||||||
#define ASN1_STRING_get0_data(a) ASN1_STRING_data((ASN1_STRING*)a)
|
#define ASN1_STRING_get0_data(a) ASN1_STRING_data((ASN1_STRING*)a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header
|
||||||
|
*/
|
||||||
|
bool openssl_compute_shared_key(EVP_PKEY *priv, EVP_PKEY *pub, chunk_t *shared)
|
||||||
|
{
|
||||||
|
EVP_PKEY_CTX *ctx;
|
||||||
|
bool success = FALSE;
|
||||||
|
|
||||||
|
ctx = EVP_PKEY_CTX_new(priv, NULL);
|
||||||
|
if (!ctx)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_PKEY_derive_init(ctx) <= 0)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_PKEY_derive_set_peer(ctx, pub) <= 0)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_PKEY_derive(ctx, NULL, &shared->len) <= 0)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*shared = chunk_alloc(shared->len);
|
||||||
|
|
||||||
|
if (EVP_PKEY_derive(ctx, shared->ptr, &shared->len) <= 0)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -36,6 +36,16 @@
|
|||||||
*/
|
*/
|
||||||
#define EC_FIELD_ELEMENT_LEN(group) ((EC_GROUP_get_degree(group) + 7) / 8)
|
#define EC_FIELD_ELEMENT_LEN(group) ((EC_GROUP_get_degree(group) + 7) / 8)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derives a shared DH secret from the given keys.
|
||||||
|
*
|
||||||
|
* @param priv private key
|
||||||
|
* @param pub public key
|
||||||
|
* @param shared shared secret
|
||||||
|
* @return TRUE on success, FALSE otherwise
|
||||||
|
*/
|
||||||
|
bool openssl_compute_shared_key(EVP_PKEY *priv, EVP_PKEY *pub, chunk_t *shared);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a hash of a given type of a chunk of data.
|
* Creates a hash of a given type of a chunk of data.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_ECDH)
|
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_ECDH)
|
||||||
|
|
||||||
#include "openssl_x_diffie_hellman.h"
|
#include "openssl_x_diffie_hellman.h"
|
||||||
|
#include "openssl_util.h"
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
@@ -71,50 +72,6 @@ static int map_key_type(diffie_hellman_group_t group)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the shared secret
|
|
||||||
*/
|
|
||||||
static bool compute_shared_key(private_diffie_hellman_t *this, EVP_PKEY *pub,
|
|
||||||
chunk_t *shared_secret)
|
|
||||||
{
|
|
||||||
EVP_PKEY_CTX *ctx;
|
|
||||||
bool success = FALSE;
|
|
||||||
|
|
||||||
ctx = EVP_PKEY_CTX_new(this->key, NULL);
|
|
||||||
if (!ctx)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EVP_PKEY_derive_init(ctx) <= 0)
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EVP_PKEY_derive_set_peer(ctx, pub) <= 0)
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EVP_PKEY_derive(ctx, NULL, &shared_secret->len) <= 0)
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*shared_secret = chunk_alloc(shared_secret->len);
|
|
||||||
|
|
||||||
if (EVP_PKEY_derive(ctx, shared_secret->ptr, &shared_secret->len) <= 0)
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
success = TRUE;
|
|
||||||
|
|
||||||
error:
|
|
||||||
EVP_PKEY_CTX_free(ctx);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||||
private_diffie_hellman_t *this, chunk_t value)
|
private_diffie_hellman_t *this, chunk_t value)
|
||||||
{
|
{
|
||||||
@@ -136,7 +93,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
|
|||||||
|
|
||||||
chunk_clear(&this->shared_secret);
|
chunk_clear(&this->shared_secret);
|
||||||
|
|
||||||
if (!compute_shared_key(this, pub, &this->shared_secret))
|
if (!openssl_compute_shared_key(this->key, pub, &this->shared_secret))
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "%N shared secret computation failed",
|
DBG1(DBG_LIB, "%N shared secret computation failed",
|
||||||
diffie_hellman_group_names, this->group);
|
diffie_hellman_group_names, this->group);
|
||||||
|
|||||||
Reference in New Issue
Block a user