+int tls_construct_key_update(SSL *s, WPACKET *pkt)
+{
+ if (!WPACKET_put_bytes_u8(pkt, s->key_update)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_KEY_UPDATE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ s->key_update = SSL_KEY_UPDATE_NONE;
+ return 1;
+
+ err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return 0;
+}
+
+MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt)
+{
+ int al;
+ unsigned int updatetype;
+
+ s->key_update_count++;
+ if (s->key_update_count > MAX_KEY_UPDATE_MESSAGES) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_TOO_MANY_KEY_UPDATES);
+ goto err;
+ }
+
+ if (!PACKET_get_1(pkt, &updatetype)
+ || PACKET_remaining(pkt) != 0
+ || (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
+ && updatetype != SSL_KEY_UPDATE_REQUESTED)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_BAD_KEY_UPDATE);
+ goto err;
+ }
+
+ /*
+ * If we get a request for us to update our sending keys too then, we need
+ * to additionally send a KeyUpdate message. However that message should
+ * not also request an update (otherwise we get into an infinite loop).
+ */
+ if (updatetype == SSL_KEY_UPDATE_REQUESTED)
+ s->key_update = SSL_KEY_UPDATE_NOT_REQUESTED;
+
+ if (!tls13_update_key(s, 0)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ return MSG_PROCESS_FINISHED_READING;
+ err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ossl_statem_set_error(s);
+ return MSG_PROCESS_ERROR;
+}
+