tls-server: Refactor writing of key share extensions

Client and server now share the same code to write this extension.
This commit is contained in:
Pascal Knecht
2021-02-12 14:35:23 +01:00
committed by Tobias Brunner
parent 7fbe2e27ec
commit 5c4cb40e47
2 changed files with 53 additions and 51 deletions
+8 -18
View File
@@ -157,6 +157,10 @@ struct private_tls_peer_t {
chunk_t cert_types;
};
/* Implemented in tls_server.c */
bool tls_write_key_share(bio_writer_t **key_share, tls_named_group_t group,
diffie_hellman_t *dh);
/**
* Verify the DH group/key type requested by the server is valid.
*/
@@ -1202,7 +1206,6 @@ static status_t send_client_hello(private_tls_peer_t *this,
enumerator_t *enumerator;
int count, i, v;
rng_t *rng;
chunk_t pub;
htoun32(&this->client_random, time(NULL));
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
@@ -1352,34 +1355,21 @@ static status_t send_client_hello(private_tls_peer_t *this,
extensions->write_data16(extensions, signatures->get_buf(signatures));
signatures->destroy(signatures);
if (this->dh)
if (this->tls->get_version_max(this->tls) >= TLS_1_3 &&
this->dh)
{
DBG2(DBG_TLS, "sending extension: %N",
tls_extension_names, TLS_EXT_KEY_SHARE);
if (!this->dh->get_my_public_value(this->dh, &pub))
extensions->write_uint16(extensions, TLS_EXT_KEY_SHARE);
if (!tls_write_key_share(&key_share, selected_curve, this->dh))
{
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
extensions->destroy(extensions);
return NEED_MORE;
}
extensions->write_uint16(extensions, TLS_EXT_KEY_SHARE);
key_share = bio_writer_create(pub.len + 6);
key_share->write_uint16(key_share, selected_curve);
if (selected_curve == TLS_CURVE25519 ||
selected_curve == TLS_CURVE448)
{
key_share->write_data16(key_share, pub);
}
else
{ /* classic format (see RFC 8446, section 4.2.8.2) */
key_share->write_uint16(key_share, pub.len + 1);
key_share->write_uint8(key_share, TLS_ANSI_UNCOMPRESSED);
key_share->write_data(key_share, pub);
}
key_share->wrap16(key_share);
extensions->write_data16(extensions, key_share->get_buf(key_share));
key_share->destroy(key_share);
free(pub.ptr);
}
writer->write_data16(writer, extensions->get_buf(extensions));
+45 -33
View File
@@ -340,8 +340,7 @@ static status_t process_client_hello(private_tls_server_t *this,
{
DBG1(DBG_TLS, "invalid %N extension",
tls_extension_names, extension_type);
this->alert->add(this->alert, TLS_FATAL,
TLS_DECODE_ERROR);
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
extensions->destroy(extensions);
extension->destroy(extension);
return NEED_MORE;
@@ -915,15 +914,46 @@ METHOD(tls_handshake_t, process, status_t,
return NEED_MORE;
}
/**
* Write public key into key share extension
*/
bool tls_write_key_share(bio_writer_t **key_share, tls_named_group_t group,
diffie_hellman_t *dh)
{
bio_writer_t *writer;
chunk_t pub;
if (!dh || !dh->get_my_public_value(dh, &pub))
{
return FALSE;
}
*key_share = writer = bio_writer_create(pub.len + 7);
writer->write_uint16(writer, group);
if (group == TLS_CURVE25519 ||
group == TLS_CURVE448)
{
writer->write_data16(writer, pub);
}
else
{ /* classic format (see RFC 8446, section 4.2.8.2) */
writer->write_uint16(writer, pub.len + 1);
writer->write_uint8(writer, TLS_ANSI_UNCOMPRESSED);
writer->write_data(writer, pub);
}
free(pub.ptr);
return TRUE;
}
/**
* Send ServerHello message
*/
static status_t send_server_hello(private_tls_server_t *this,
tls_handshake_type_t *type, bio_writer_t *writer)
{
bio_writer_t *extensions, *key_share;
tls_version_t version = this->tls->get_version_max(this->tls);
chunk_t pub;
bio_writer_t *key_share, *extensions;
tls_version_t version;
version = this->tls->get_version_max(this->tls);
/* cap legacy version at TLS 1.2 for middlebox compatibility */
writer->write_uint16(writer, min(TLS_1_2, version));
@@ -948,36 +978,18 @@ static status_t send_server_hello(private_tls_server_t *this,
extensions->write_uint16(extensions, 2);
extensions->write_uint16(extensions, version);
if (this->dh)
{
tls_named_group_t selected_curve = this->requested_curve;
DBG2(DBG_TLS, "sending extension: %N",
tls_extension_names, TLS_EXT_KEY_SHARE);
extensions->write_uint16(extensions, TLS_EXT_KEY_SHARE);
DBG2(DBG_TLS, "sending extension: %N",
tls_extension_names, TLS_EXT_KEY_SHARE);
if (!this->dh->get_my_public_value(this->dh, &pub))
{
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
extensions->destroy(extensions);
return NEED_MORE;
}
extensions->write_uint16(extensions, TLS_EXT_KEY_SHARE);
key_share = bio_writer_create(pub.len + 6);
key_share->write_uint16(key_share, selected_curve);
if (selected_curve == TLS_CURVE25519 ||
selected_curve == TLS_CURVE448)
{
key_share->write_data16(key_share, pub);
}
else
{ /* classic format (see RFC 8446, section 4.2.8.2) */
key_share->write_uint16(key_share, pub.len + 1);
key_share->write_uint8(key_share, TLS_ANSI_UNCOMPRESSED);
key_share->write_data(key_share, pub);
}
extensions->write_data16(extensions, key_share->get_buf(key_share));
key_share->destroy(key_share);
free(pub.ptr);
if (!tls_write_key_share(&key_share, this->requested_curve, this->dh))
{
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
extensions->destroy(extensions);
return NEED_MORE;
}
extensions->write_data16(extensions, key_share->get_buf(key_share));
key_share->destroy(key_share);
writer->write_data16(writer, extensions->get_buf(extensions));
extensions->destroy(extensions);