From: Tobias Brunner Date: Fri, 28 Aug 2020 08:23:43 +0000 (+0200) Subject: tls-peer: Support answering KeyUpdate requests X-Git-Tag: 5.9.2rc1~23^2~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e02f19e3c6a6463f5d799e54e23788e76be63a58;p=thirdparty%2Fstrongswan.git tls-peer: Support answering KeyUpdate requests --- diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c index 483613fff1..f2aa1b59db 100644 --- a/src/libtls/tls_fragmentation.c +++ b/src/libtls/tls_fragmentation.c @@ -358,6 +358,7 @@ static status_t build_handshake(private_tls_fragmentation_t *this) DBG2(DBG_TLS, "sending TLS %N handshake (%u bytes)", tls_handshake_type_names, type, hs->get_buf(hs).len); if (type != TLS_FINISHED && + type != TLS_KEY_UPDATE && !this->handshake->cipherspec_changed(this->handshake, FALSE)) { hs->destroy(hs); diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index a63b9fc5b4..04c0072897 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -47,6 +47,8 @@ typedef enum { STATE_ENCRYPTED_EXTENSIONS_RECEIVED, STATE_CERT_VERIFY_RECEIVED, STATE_FINISHED_SENT_KEY_SWITCHED, + STATE_KEY_UPDATE_REQUESTED, + STATE_KEY_UPDATE_SENT, } peer_state_t; @@ -1054,7 +1056,8 @@ static status_t process_key_update(private_tls_peer_t *this, if (update_requested) { - DBG1(DBG_TLS, "server requested KeyUpdate, currently not supported"); + DBG1(DBG_TLS, "server requested KeyUpdate"); + this->state = STATE_KEY_UPDATE_REQUESTED; } return NEED_MORE; } @@ -1657,6 +1660,21 @@ static status_t send_finished(private_tls_peer_t *this, return NEED_MORE; } +/** + * Send KeyUpdate message + */ +static status_t send_key_update(private_tls_peer_t *this, + tls_handshake_type_t *type, bio_writer_t *writer) +{ + *type = TLS_KEY_UPDATE; + + /* we currently only send this as reply, so we never request an update */ + writer->write_uint8(writer, 0); + + this->state = STATE_KEY_UPDATE_SENT; + return NEED_MORE; +} + METHOD(tls_handshake_t, build, status_t, private_tls_peer_t *this, tls_handshake_type_t *type, bio_writer_t *writer) { @@ -1709,6 +1727,17 @@ METHOD(tls_handshake_t, build, status_t, this->crypto->change_cipher(this->crypto, FALSE); this->state = STATE_FINISHED_SENT_KEY_SWITCHED; return SUCCESS; + case STATE_KEY_UPDATE_REQUESTED: + return send_key_update(this, type, writer); + case STATE_KEY_UPDATE_SENT: + if (!this->crypto->update_app_keys(this->crypto, FALSE)) + { + this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); + return NEED_MORE; + } + this->crypto->change_cipher(this->crypto, FALSE); + this->state = STATE_FINISHED_SENT_KEY_SWITCHED; + return SUCCESS; case STATE_FINISHED_SENT_KEY_SWITCHED: return SUCCESS; default: