diff options
author | Martin Willi <martin@revosec.ch> | 2010-09-06 15:31:32 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-09-06 15:37:51 +0200 |
commit | e6cce7ff0d1b38ba720dcdda6bbc0308839f85f4 (patch) | |
tree | 452ad834a05f7a3ed942f55f42d254e2cca3f143 /src | |
parent | e4fd2bb4289b37be47ba9d6b072b28b06fef6db9 (diff) | |
download | strongswan-e6cce7ff0d1b38ba720dcdda6bbc0308839f85f4.tar.bz2 strongswan-e6cce7ff0d1b38ba720dcdda6bbc0308839f85f4.tar.xz |
Prepend point format to ECDH public key
Diffstat (limited to 'src')
-rw-r--r-- | src/libtls/tls_crypto.c | 8 | ||||
-rw-r--r-- | src/libtls/tls_crypto.h | 16 | ||||
-rw-r--r-- | src/libtls/tls_peer.c | 18 | ||||
-rw-r--r-- | src/libtls/tls_server.c | 18 |
4 files changed, 52 insertions, 8 deletions
diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 49ee88def..12d543ec1 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -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; diff --git a/src/libtls/tls_crypto.h b/src/libtls/tls_crypto.h index cc83df300..b41ae5f13 100644 --- a/src/libtls/tls_crypto.h +++ b/src/libtls/tls_crypto.h @@ -359,6 +359,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. */ struct tls_crypto_t { diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index d6d697644..ac22bd1c5 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -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); diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index 409fe83c9..e48e6c5b7 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -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); |