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", "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; 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; 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. * 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; return NEED_MORE;
} }
if (!reader->read_uint16(reader, &curve) || 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"); DBG1(DBG_TLS, "received invalid Server Key Exchange");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); 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); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE; 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; this->state = STATE_KEY_EXCHANGE_RECEIVED;
return NEED_MORE; return NEED_MORE;
@ -908,8 +916,10 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
writer->write_data16(writer, pub); writer->write_data16(writer, pub);
} }
else else
{ /* ECP uses 8bit length header only */ { /* ECP uses 8bit length header only, but a point format */
writer->write_data8(writer, pub); writer->write_uint8(writer, pub.len + 1);
writer->write_uint8(writer, TLS_ECP_UNCOMPRESSED);
writer->write_data(writer, pub);
} }
free(pub.ptr); 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)); ec = diffie_hellman_group_is_ec(this->dh->get_dh_group(this->dh));
if ((ec && !reader->read_data8(reader, &pub)) || 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"); DBG1(DBG_TLS, "received invalid Client Key Exchange");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
return NEED_MORE; 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) if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS)
{ {
DBG1(DBG_TLS, "calculating premaster from DH failed"); 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); writer->write_data16(writer, chunk);
} }
else else
{ /* 8bit header for EC groups */ { /* ECP uses 8bit length header only, but a point format */
writer->write_data8(writer, chunk); writer->write_uint8(writer, chunk.len + 1);
writer->write_uint8(writer, TLS_ECP_UNCOMPRESSED);
writer->write_data(writer, chunk);
} }
free(chunk.ptr); free(chunk.ptr);