ecp_x_coordinate only option allows ECP interoperability with MS Windows

This commit is contained in:
Andreas Steffen
2009-07-06 08:47:18 +02:00
parent 887ed734d0
commit 21863d6361
2 changed files with 24 additions and 9 deletions
@@ -108,7 +108,8 @@ error:
* Convert an EC_POINT to a chunk by concatenating the x and y coordinates of * Convert an EC_POINT to a chunk by concatenating the x and y coordinates of
* the point. This function allocates memory for the chunk. * the point. This function allocates memory for the chunk.
*/ */
static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, chunk_t *chunk) static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point,
chunk_t *chunk, bool x_coordinate_only)
{ {
BN_CTX *ctx; BN_CTX *ctx;
BIGNUM *x, *y; BIGNUM *x, *y;
@@ -133,6 +134,10 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, chunk_t *chu
goto error; goto error;
} }
if (x_coordinate_only)
{
y = NULL;
}
if (!openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), x, y, chunk)) if (!openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), x, y, chunk))
{ {
goto error; goto error;
@@ -160,7 +165,7 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_
{ {
const BIGNUM *priv_key; const BIGNUM *priv_key;
EC_POINT *secret = NULL; EC_POINT *secret = NULL;
bool ret = FALSE; bool x_coordinate_only, ret = FALSE;
priv_key = EC_KEY_get0_private_key(this->key); priv_key = EC_KEY_get0_private_key(this->key);
if (!priv_key) if (!priv_key)
@@ -179,7 +184,12 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_
goto error; goto error;
} }
if (!ecp2chunk(this->ec_group, secret, shared_secret)) /*
* x_coordinate_only = TRUE applies errata for RFC 4753
*/
x_coordinate_only = lib->settings->get_bool(lib->settings,
"libstrongswan.ecp_x_coordinate_only", FALSE);
if (!ecp2chunk(this->ec_group, secret, shared_secret, x_coordinate_only))
{ {
goto error; goto error;
} }
@@ -219,7 +229,7 @@ static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, ch
*/ */
static void get_my_public_value(private_openssl_ec_diffie_hellman_t *this,chunk_t *value) static void get_my_public_value(private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
{ {
ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value); ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value, FALSE);
} }
/** /**
@@ -71,21 +71,26 @@ bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk)
{ {
int offset; int offset;
chunk->len = len * 2; chunk->len = len + (b ? len : 0);
chunk->ptr = malloc(chunk->len); chunk->ptr = malloc(chunk->len);
memset(chunk->ptr, 0, chunk->len); memset(chunk->ptr, 0, chunk->len);
/* convert a */
offset = len - BN_num_bytes(a); offset = len - BN_num_bytes(a);
if (!BN_bn2bin(a, chunk->ptr + offset)) if (!BN_bn2bin(a, chunk->ptr + offset))
{ {
goto error; goto error;
} }
offset = len - BN_num_bytes(b); /* optionally convert and concatenate b */
if (!BN_bn2bin(b, chunk->ptr + len + offset)) if (b)
{ {
goto error; offset = len - BN_num_bytes(b);
} if (!BN_bn2bin(b, chunk->ptr + len + offset))
{
goto error;
}
}
return TRUE; return TRUE;
error: error: