Prepend point format to ECDH public key

This commit is contained in:
Martin Willi 2010-09-06 15:31:32 +02:00
parent e4fd2bb428
commit e6cce7ff0d
4 changed files with 52 additions and 8 deletions

View File

@ -306,6 +306,14 @@ ENUM(tls_named_curve_names, TLS_SECT163K1, TLS_SECP521R1,
"SECP521R1",
);
ENUM(tls_ecp_format_names, TLS_ECP_COMPRESSED, TLS_ECP_HYBRID_Y,
"compressed",
"compressed y",
"uncompressed",
"uncompressed y",
"hybrid",
"hybrid y",
);
typedef struct private_tls_crypto_t private_tls_crypto_t;

View File

@ -358,6 +358,22 @@ enum tls_named_curve_t {
*/
extern enum_name_t *tls_named_curve_names;
/**
* EC Point format, ANSI X9.62.
*/
enum tls_ecp_format_t {
TLS_ECP_COMPRESSED = 2,
TLS_ECP_COMPRESSED_Y = 3,
TLS_ECP_UNCOMPRESSED = 4,
TLS_ECP_HYBRID = 6,
TLS_ECP_HYBRID_Y = 7,
};
/**
* Enum names for tls_ecp_format_t.
*/
extern enum_name_t *tls_ecp_format_names;
/**
* TLS crypto helper functions.
*/

View File

@ -402,7 +402,7 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this,
return NEED_MORE;
}
if (!reader->read_uint16(reader, &curve) ||
!reader->read_data8(reader, &pub))
!reader->read_data8(reader, &pub) || pub.len == 0)
{
DBG1(DBG_TLS, "received invalid Server Key Exchange");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
@ -448,7 +448,15 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
this->dh->set_other_public_value(this->dh, pub);
if (pub.ptr[0] != TLS_ECP_UNCOMPRESSED)
{
DBG1(DBG_TLS, "DH point format '%N' not supported",
tls_ecp_format_names, pub.ptr[0]);
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1));
this->state = STATE_KEY_EXCHANGE_RECEIVED;
return NEED_MORE;
@ -908,8 +916,10 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
writer->write_data16(writer, pub);
}
else
{ /* ECP uses 8bit length header only */
writer->write_data8(writer, pub);
{ /* ECP uses 8bit length header only, but a point format */
writer->write_uint8(writer, pub.len + 1);
writer->write_uint8(writer, TLS_ECP_UNCOMPRESSED);
writer->write_data(writer, pub);
}
free(pub.ptr);

View File

@ -412,13 +412,21 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
ec = diffie_hellman_group_is_ec(this->dh->get_dh_group(this->dh));
if ((ec && !reader->read_data8(reader, &pub)) ||
(!ec && !reader->read_data16(reader, &pub)))
(!ec && (!reader->read_data16(reader, &pub) || pub.len == 0)))
{
DBG1(DBG_TLS, "received invalid Client Key Exchange");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
return NEED_MORE;
}
this->dh->set_other_public_value(this->dh, pub);
if (pub.ptr[0] != TLS_ECP_UNCOMPRESSED)
{
DBG1(DBG_TLS, "DH point format '%N' not supported",
tls_ecp_format_names, pub.ptr[0]);
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1));
if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS)
{
DBG1(DBG_TLS, "calculating premaster from DH failed");
@ -847,8 +855,10 @@ static status_t send_server_key_exchange(private_tls_server_t *this,
writer->write_data16(writer, chunk);
}
else
{ /* 8bit header for EC groups */
writer->write_data8(writer, chunk);
{ /* ECP uses 8bit length header only, but a point format */
writer->write_uint8(writer, chunk.len + 1);
writer->write_uint8(writer, TLS_ECP_UNCOMPRESSED);
writer->write_data(writer, chunk);
}
free(chunk.ptr);