LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - handshake-tls13.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 374 429 87.2 %
Date: 2020-10-30 04:50:48 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2017-2018 Red Hat, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : /* Functions that relate to the TLS handshake procedure.
      24             :  */
      25             : 
      26             : #include "gnutls_int.h"
      27             : #include "errors.h"
      28             : #include "dh.h"
      29             : #include "debug.h"
      30             : #include "algorithms.h"
      31             : #include "cipher.h"
      32             : #include "buffers.h"
      33             : #include "mbuffers.h"
      34             : #include "kx.h"
      35             : #include "handshake.h"
      36             : #include "num.h"
      37             : #include "hash_int.h"
      38             : #include "db.h"
      39             : #include "hello_ext.h"
      40             : #include "supplemental.h"
      41             : #include "auth.h"
      42             : #include "sslv2_compat.h"
      43             : #include <auth/cert.h>
      44             : #include "constate.h"
      45             : #include <record.h>
      46             : #include <state.h>
      47             : #include <random.h>
      48             : #include <dtls.h>
      49             : #include "secrets.h"
      50             : #include "tls13/hello_retry.h"
      51             : #include "tls13/encrypted_extensions.h"
      52             : #include "tls13/certificate_request.h"
      53             : #include "tls13/certificate_verify.h"
      54             : #include "tls13/certificate.h"
      55             : #include "tls13/early_data.h"
      56             : #include "tls13/finished.h"
      57             : #include "tls13/key_update.h"
      58             : #include "ext/pre_shared_key.h"
      59             : #include "locks.h"
      60             : 
      61             : static int generate_rms_keys(gnutls_session_t session);
      62             : static int generate_hs_traffic_keys(gnutls_session_t session);
      63             : static int generate_ap_traffic_keys(gnutls_session_t session);
      64             : 
      65             : #define SAVE_TRANSCRIPT \
      66             :         if (session->internals.flags & GNUTLS_POST_HANDSHAKE_AUTH) { \
      67             :                 /* If post-handshake auth is in use we need a copy of the original \
      68             :                  * handshake transcript */ \
      69             :                 memcpy( &session->internals.post_handshake_hash_buffer, \
      70             :                         &session->internals.handshake_hash_buffer, \
      71             :                         sizeof(session->internals.handshake_hash_buffer)); \
      72             :                 _gnutls_buffer_init(&session->internals.handshake_hash_buffer); \
      73             :         }
      74             : 
      75             : /*
      76             :  * _gnutls13_handshake_client
      77             :  * This function performs the client side of the handshake of the TLS/SSL protocol.
      78             :  */
      79         750 : int _gnutls13_handshake_client(gnutls_session_t session)
      80             : {
      81         750 :         int ret = 0;
      82             : 
      83         750 :         switch (STATE) {
      84         602 :         case STATE99:
      85             :         case STATE100:
      86             : #ifdef TLS13_APPENDIX_D4
      87             :                 /* We send it before keys are generated. That works because CCS
      88             :                  * is always being cached and queued and not being sent directly */
      89         602 :                 ret = _gnutls_send_change_cipher_spec(session, AGAIN(STATE100));
      90         602 :                 STATE = STATE100;
      91         602 :                 IMED_RET("send change cipher spec", ret, 0);
      92             : #endif
      93         598 :                 FALLTHROUGH;
      94             :         case STATE101:
      95             :                 /* Note that we check IN_FLIGHT, not ACCEPTED
      96             :                  * here. This is because the client sends early data
      97             :                  * speculatively. */
      98         598 :                 if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
      99           3 :                         ret = _tls13_write_connection_state_init(session, STAGE_EARLY);
     100           3 :                         if (ret == 0) {
     101           3 :                                 _gnutls_epoch_bump(session);
     102           3 :                                 ret = _gnutls_epoch_dup(session, EPOCH_WRITE_CURRENT);
     103             :                         }
     104           3 :                         STATE = STATE101;
     105           3 :                         IMED_RET_FATAL("set early traffic keys", ret, 0);
     106             :                 }
     107         598 :                 FALLTHROUGH;
     108             :         case STATE102:
     109         598 :                 ret = _gnutls13_send_early_data(session);
     110         598 :                 STATE = STATE102;
     111         598 :                 IMED_RET("send early data", ret, 0);
     112         598 :                 FALLTHROUGH;
     113             :         case STATE103:
     114         598 :                 STATE = STATE103;
     115         598 :                 ret = generate_hs_traffic_keys(session);
     116             :                 /* Note that we check IN_FLIGHT, not ACCEPTED
     117             :                  * here. This is because the client sends early data
     118             :                  * speculatively. */
     119         598 :                 IMED_RET_FATAL("generate hs traffic keys", ret, 0);
     120         598 :                 if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)
     121           3 :                         ret = _tls13_read_connection_state_init(session, STAGE_HS);
     122             :                 else
     123         595 :                         ret = _tls13_connection_state_init(session, STAGE_HS);
     124         598 :                 IMED_RET_FATAL("set hs traffic keys", ret, 0);
     125         635 :                 FALLTHROUGH;
     126             :         case STATE104:
     127         635 :                 ret = _gnutls13_recv_encrypted_extensions(session);
     128         635 :                 STATE = STATE104;
     129         635 :                 IMED_RET("recv encrypted extensions", ret, 0);
     130         628 :                 FALLTHROUGH;
     131             :         case STATE105:
     132         628 :                 ret = _gnutls13_recv_certificate_request(session);
     133         628 :                 STATE = STATE105;
     134         628 :                 IMED_RET("recv certificate request", ret, 0);
     135         602 :                 FALLTHROUGH;
     136             :         case STATE106:
     137         602 :                 ret = _gnutls13_recv_certificate(session);
     138         602 :                 STATE = STATE106;
     139         602 :                 IMED_RET("recv certificate", ret, 0);
     140         595 :                 FALLTHROUGH;
     141             :         case STATE107:
     142         595 :                 ret = _gnutls13_recv_certificate_verify(session);
     143         595 :                 STATE = STATE107;
     144         595 :                 IMED_RET("recv server certificate verify", ret, 0);
     145         590 :                 FALLTHROUGH;
     146             :         case STATE108:
     147         590 :                 ret = _gnutls_run_verify_callback(session, GNUTLS_CLIENT);
     148         590 :                 STATE = STATE108;
     149         590 :                 if (ret < 0)
     150          22 :                         return gnutls_assert_val(ret);
     151         594 :                 FALLTHROUGH;
     152             :         case STATE109:
     153         594 :                 ret = _gnutls13_recv_finished(session);
     154         594 :                 STATE = STATE109;
     155         594 :                 IMED_RET("recv finished", ret, 0);
     156         569 :                 FALLTHROUGH;
     157             :         case STATE110:
     158         569 :                 ret = _gnutls13_send_end_of_early_data(session, AGAIN(STATE110));
     159         569 :                 STATE = STATE110;
     160         569 :                 IMED_RET("send end of early data", ret, 0);
     161             : 
     162             :                 /* Note that we check IN_FLIGHT, not ACCEPTED
     163             :                  * here. This is because the client sends early data
     164             :                  * speculatively. */
     165         569 :                 if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
     166           3 :                         session->internals.hsk_flags &= ~HSK_EARLY_DATA_IN_FLIGHT;
     167           3 :                         ret = _tls13_write_connection_state_init(session, STAGE_HS);
     168           3 :                         IMED_RET_FATAL("set hs traffic key after sending early data", ret, 0);
     169             :                 }
     170         569 :                 FALLTHROUGH;
     171             :         case STATE111:
     172         569 :                 ret = _gnutls13_send_certificate(session, AGAIN(STATE111));
     173         569 :                 STATE = STATE111;
     174         569 :                 IMED_RET("send certificate", ret, 0);
     175         569 :                 FALLTHROUGH;
     176             :         case STATE112:
     177         569 :                 ret = _gnutls13_send_certificate_verify(session, AGAIN(STATE112));
     178         569 :                 STATE = STATE112;
     179         569 :                 IMED_RET("send certificate verify", ret, 0);
     180         603 :                 FALLTHROUGH;
     181             :         case STATE113:
     182         603 :                 ret = _gnutls13_send_finished(session, AGAIN(STATE113));
     183         603 :                 STATE = STATE113;
     184         603 :                 IMED_RET("send finished", ret, 0);
     185         569 :                 FALLTHROUGH;
     186             :         case STATE114:
     187         569 :                 STATE = STATE114;
     188             : 
     189         569 :                 ret =
     190         569 :                     generate_ap_traffic_keys(session);
     191         569 :                 IMED_RET_FATAL("generate app keys", ret, 0);
     192             : 
     193         569 :                 ret = generate_rms_keys(session);
     194         569 :                 IMED_RET_FATAL("generate rms keys", ret, 0);
     195             : 
     196             :                 /* set traffic keys */
     197         569 :                 ret = _tls13_connection_state_init(session, STAGE_APP);
     198         569 :                 IMED_RET_FATAL("set app keys", ret, 0);
     199             : 
     200         569 :                 STATE = STATE0;
     201         569 :                 break;
     202             :         default:
     203           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     204             :         }
     205             : 
     206             :         /* no lock of post_negotiation_lock is required here as this is not run
     207             :          * after handshake */
     208         569 :         session->internals.recv_state = RECV_STATE_0;
     209         569 :         session->internals.initial_negotiation_completed = 1;
     210             : 
     211         569 :         SAVE_TRANSCRIPT;
     212             : 
     213         569 :         if (session->internals.resumed != RESUME_FALSE)
     214          52 :                 _gnutls_set_resumed_parameters(session);
     215             : 
     216             :         return 0;
     217             : }
     218             : 
     219        3413 : static int generate_non_auth_rms_keys(gnutls_session_t session)
     220             : {
     221        3413 :         int ret;
     222             :         /* we simulate client finished */
     223        3413 :         uint8_t finished[MAX_HASH_SIZE+TLS_HANDSHAKE_HEADER_SIZE];
     224        3413 :         unsigned spos;
     225             : 
     226        6826 :         ret = _gnutls13_compute_finished(session->security_parameters.prf,
     227        3413 :                                          session->key.proto.tls13.hs_ckey,
     228             :                                          &session->internals.handshake_hash_buffer,
     229             :                                          finished+TLS_HANDSHAKE_HEADER_SIZE);
     230        3413 :         if (ret < 0)
     231           0 :                 return gnutls_assert_val(ret);
     232             : 
     233        3413 :         spos = session->internals.handshake_hash_buffer.length;
     234             : 
     235        3413 :         finished[0] = GNUTLS_HANDSHAKE_FINISHED;
     236        3413 :         _gnutls_write_uint24(session->security_parameters.prf->output_size, finished+1);
     237             : 
     238        6826 :         ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer, finished,
     239        3413 :                                          TLS_HANDSHAKE_HEADER_SIZE+session->security_parameters.prf->output_size);
     240        3413 :         if (ret < 0)
     241           0 :                 return gnutls_assert_val(ret);
     242             : 
     243        6826 :         ret = _tls13_derive_secret(session, RMS_MASTER_LABEL, sizeof(RMS_MASTER_LABEL)-1,
     244        3413 :                                    session->internals.handshake_hash_buffer.data,
     245             :                                    session->internals.handshake_hash_buffer.length,
     246        3413 :                                    session->key.proto.tls13.temp_secret,
     247        3413 :                                    session->key.proto.tls13.ap_rms);
     248        3413 :         if (ret < 0)
     249           0 :                 return gnutls_assert_val(ret);
     250             : 
     251        3413 :         session->internals.handshake_hash_buffer.length = spos;
     252             : 
     253        3413 :         return 0;
     254             : }
     255             : 
     256        2176 : static int generate_rms_keys(gnutls_session_t session)
     257             : {
     258        2176 :         int ret;
     259             : 
     260        4352 :         ret = _tls13_derive_secret(session, RMS_MASTER_LABEL, sizeof(RMS_MASTER_LABEL)-1,
     261        2176 :                                    session->internals.handshake_hash_buffer.data,
     262        2176 :                                    session->internals.handshake_hash_buffer_client_finished_len,
     263        2176 :                                    session->key.proto.tls13.temp_secret,
     264        2176 :                                    session->key.proto.tls13.ap_rms);
     265        2176 :         if (ret < 0)
     266           0 :                 return gnutls_assert_val(ret);
     267             : 
     268             :         return 0;
     269             : }
     270             : 
     271        5658 : static int generate_ap_traffic_keys(gnutls_session_t session)
     272             : {
     273        5658 :         int ret;
     274        5658 :         uint8_t zero[MAX_HASH_SIZE];
     275             : 
     276       11316 :         ret = _tls13_derive_secret(session, DERIVED_LABEL, sizeof(DERIVED_LABEL)-1,
     277             :                                    NULL, 0, session->key.proto.tls13.temp_secret,
     278        5658 :                                    session->key.proto.tls13.temp_secret);
     279        5658 :         if (ret < 0)
     280           0 :                 return gnutls_assert_val(ret);
     281             : 
     282        5658 :         memset(zero, 0, session->security_parameters.prf->output_size);
     283        5658 :         ret = _tls13_update_secret(session, zero, session->security_parameters.prf->output_size);
     284        5658 :         if (ret < 0)
     285           0 :                 return gnutls_assert_val(ret);
     286             : 
     287       11316 :         ret = _tls13_derive_secret(session, EXPORTER_MASTER_LABEL, sizeof(EXPORTER_MASTER_LABEL)-1,
     288        5658 :                                    session->internals.handshake_hash_buffer.data,
     289        5658 :                                    session->internals.handshake_hash_buffer_server_finished_len,
     290             :                                    session->key.proto.tls13.temp_secret,
     291        5658 :                                    session->key.proto.tls13.ap_expkey);
     292        5658 :         if (ret < 0)
     293           0 :                 return gnutls_assert_val(ret);
     294             : 
     295       11316 :         ret = _gnutls_call_keylog_func(session, "EXPORTER_SECRET",
     296             :                                        session->key.proto.tls13.ap_expkey,
     297        5658 :                                        session->security_parameters.prf->output_size);
     298        5658 :         if (ret < 0)
     299           0 :                 return gnutls_assert_val(ret);
     300             : 
     301        5658 :         _gnutls_epoch_bump(session);
     302        5658 :         ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
     303        5658 :         if (ret < 0)
     304           0 :                 return gnutls_assert_val(ret);
     305             : 
     306             :         return 0;
     307             : }
     308             : 
     309        5699 : static int generate_hs_traffic_keys(gnutls_session_t session)
     310             : {
     311        5699 :         int ret;
     312        5699 :         unsigned null_key = 0;
     313             : 
     314        5699 :         if (unlikely(session->key.proto.tls13.temp_secret_size == 0))
     315           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     316             : 
     317       11398 :         ret = _tls13_derive_secret(session, DERIVED_LABEL, sizeof(DERIVED_LABEL)-1,
     318             :                                    NULL, 0, session->key.proto.tls13.temp_secret,
     319        5699 :                                    session->key.proto.tls13.temp_secret);
     320        5699 :         if (ret < 0) {
     321           0 :                 gnutls_assert();
     322           0 :                 return ret;
     323             :         }
     324             : 
     325        5699 :         if ((session->security_parameters.entity == GNUTLS_CLIENT &&
     326         598 :               (!(session->internals.hsk_flags & HSK_KEY_SHARE_RECEIVED) ||
     327         547 :                 (!(session->internals.hsk_flags & HSK_PSK_KE_MODE_DHE_PSK) &&
     328        5648 :                    session->internals.resumed != RESUME_FALSE))) ||
     329        5101 :             (session->security_parameters.entity == GNUTLS_SERVER &&
     330        5101 :               !(session->internals.hsk_flags & HSK_KEY_SHARE_SENT))) {
     331             : 
     332         976 :                 if ((session->internals.hsk_flags & HSK_PSK_SELECTED) &&
     333             :                     (session->internals.hsk_flags & HSK_PSK_KE_MODE_PSK)) {
     334         976 :                         null_key = 1;
     335             :                 }
     336             :         }
     337             : 
     338         976 :         if (null_key) {
     339         976 :                 uint8_t digest[MAX_HASH_SIZE];
     340         976 :                 unsigned digest_size;
     341             : 
     342         976 :                 if (unlikely(session->security_parameters.prf == NULL))
     343           0 :                         return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     344             : 
     345         976 :                 digest_size = session->security_parameters.prf->output_size;
     346         976 :                 memset(digest, 0, digest_size);
     347             : 
     348         976 :                 ret = _tls13_update_secret(session, digest, digest_size);
     349         976 :                 if (ret < 0) {
     350           0 :                         gnutls_assert();
     351           0 :                         return ret;
     352             :                 }
     353             :         } else {
     354        4723 :                 if (unlikely(session->key.key.size == 0))
     355           0 :                         return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     356             : 
     357        4723 :                 ret = _tls13_update_secret(session, session->key.key.data, session->key.key.size);
     358        4723 :                 if (ret < 0) {
     359           0 :                         gnutls_assert();
     360           0 :                         return ret;
     361             :                 }
     362             :         }
     363             : 
     364             :         return 0;
     365             : }
     366             : 
     367             : /*
     368             :  * _gnutls13_handshake_server
     369             :  * This function does the server stuff of the handshake protocol.
     370             :  */
     371        5549 : int _gnutls13_handshake_server(gnutls_session_t session)
     372             : {
     373        5549 :         int ret = 0;
     374             : 
     375        5549 :         switch (STATE) {
     376         219 :         case STATE90:
     377         219 :                 ret = _gnutls13_handshake_hash_buffers_synth(session, session->security_parameters.prf, 0);
     378         219 :                 STATE = STATE90;
     379         219 :                 IMED_RET_FATAL("reset handshake buffers", ret, 0);
     380         219 :                 FALLTHROUGH;
     381             :         case STATE91:
     382         219 :                 ret = _gnutls13_send_hello_retry_request(session, AGAIN(STATE91));
     383         219 :                 STATE = STATE91;
     384         219 :                 IMED_RET("send hello retry request", ret, 0);
     385          63 :                 FALLTHROUGH;
     386             :         case STATE92:
     387             : #ifdef TLS13_APPENDIX_D4
     388          63 :                 ret = _gnutls_send_change_cipher_spec(session, AGAIN(STATE92));
     389          63 :                 STATE = STATE92;
     390          63 :                 IMED_RET("send change cipher spec", ret, 0);
     391             : #endif
     392          79 :                 FALLTHROUGH;
     393             :         case STATE93:
     394          79 :                 ret =
     395          79 :                     _gnutls_recv_handshake(session,
     396             :                                            GNUTLS_HANDSHAKE_CLIENT_HELLO,
     397             :                                            0, NULL);
     398          79 :                 if (ret == GNUTLS_E_INT_RET_0) {
     399             :                         /* this is triggered by post_client_hello, and instructs the
     400             :                          * handshake to proceed but be put on hold */
     401           0 :                         ret = GNUTLS_E_INTERRUPTED;
     402           0 :                         STATE = STATE94; /* hello already parsed -> move to next state */
     403             :                 } else {
     404          79 :                         STATE = STATE93;
     405             :                 }
     406             : 
     407          79 :                 IMED_RET("recv client hello", ret, 0);
     408          63 :                 FALLTHROUGH;
     409             :         case STATE94:
     410          63 :                 ret = _gnutls_send_server_hello(session, AGAIN(STATE94));
     411          63 :                 STATE = STATE94;
     412          63 :                 IMED_RET("send hello", ret, 0);
     413        5101 :                 FALLTHROUGH;
     414             :         case STATE99:
     415             :         case STATE100:
     416             : #ifdef TLS13_APPENDIX_D4
     417             :                 /* don't send CCS twice: when HRR has already been
     418             :                  * sent, CCS should have followed it (see above) */
     419        5101 :                 if (!(session->internals.hsk_flags & HSK_HRR_SENT)) {
     420        5038 :                         ret = _gnutls_send_change_cipher_spec(session, AGAIN(STATE100));
     421        5038 :                         STATE = STATE100;
     422        5038 :                         IMED_RET("send change cipher spec", ret, 0);
     423             :                 }
     424             : #endif
     425        5101 :                 FALLTHROUGH;
     426             :         case STATE101:
     427        5101 :                 STATE = STATE101;
     428        5101 :                 if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) {
     429           5 :                         ret = _tls13_read_connection_state_init(session, STAGE_EARLY);
     430           5 :                         if (ret == 0) {
     431           5 :                                 _gnutls_epoch_bump(session);
     432           5 :                                 ret = _gnutls_epoch_dup(session, EPOCH_READ_CURRENT);
     433             :                         }
     434           5 :                         IMED_RET_FATAL("set early traffic keys", ret, 0);
     435             : 
     436           5 :                         ret = generate_hs_traffic_keys(session);
     437           5 :                         IMED_RET_FATAL("generate hs traffic keys", ret, 0);
     438             : 
     439           5 :                         ret = _tls13_write_connection_state_init(session, STAGE_HS);
     440             :                 } else {
     441        5096 :                         ret = generate_hs_traffic_keys(session);
     442        5096 :                         IMED_RET_FATAL("generate hs traffic keys", ret, 0);
     443             : 
     444        5096 :                         ret = _tls13_connection_state_init(session, STAGE_HS);
     445             :                 }
     446        5101 :                 IMED_RET_FATAL("set hs traffic keys", ret, 0);
     447        5101 :                 FALLTHROUGH;
     448             :         case STATE102:
     449        5101 :                 ret = _gnutls13_send_encrypted_extensions(session, AGAIN(STATE102));
     450        5101 :                 STATE = STATE102;
     451        5101 :                 IMED_RET("send encrypted extensions", ret, 0);
     452        5101 :                 FALLTHROUGH;
     453             :         case STATE103:
     454        5101 :                 ret = _gnutls13_send_certificate_request(session, AGAIN(STATE103));
     455        5101 :                 STATE = STATE103;
     456        5101 :                 IMED_RET("send certificate request", ret, 0);
     457        5101 :                 FALLTHROUGH;
     458             :         case STATE104:
     459        5101 :                 ret = _gnutls13_send_certificate(session, AGAIN(STATE104));
     460        5101 :                 STATE = STATE104;
     461        5101 :                 IMED_RET("send certificate", ret, 0);
     462        5090 :                 FALLTHROUGH;
     463             :         case STATE105:
     464        5090 :                 ret = _gnutls13_send_certificate_verify(session, AGAIN(STATE105));
     465        5090 :                 STATE = STATE105;
     466        5090 :                 IMED_RET("send certificate verify", ret, 0);
     467        5090 :                 FALLTHROUGH;
     468             :         case STATE106:
     469        5090 :                 ret = _gnutls13_send_finished(session, AGAIN(STATE106));
     470        5090 :                 STATE = STATE106;
     471        5090 :                 IMED_RET("send finished", ret, 0);
     472        5094 :                 FALLTHROUGH;
     473             :         case STATE107:
     474        5094 :                 ret = _gnutls13_recv_end_of_early_data(session);
     475        5094 :                 STATE = STATE107;
     476        5094 :                 IMED_RET("recv end of early data", ret, 0);
     477             : 
     478        5089 :                 if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) {
     479           4 :                         ret = _tls13_read_connection_state_init(session, STAGE_HS);
     480           4 :                         IMED_RET_FATAL("set hs traffic key after receiving early data", ret, 0);
     481             :                 }
     482        5089 :                 FALLTHROUGH;
     483             :         case STATE108:
     484             :                 /* At this point our sending keys should be the app keys
     485             :                  * see 4.4.4 at draft-ietf-tls-tls13-28 */
     486        5089 :                 ret =
     487        5089 :                     generate_ap_traffic_keys(session);
     488        5089 :                 IMED_RET_FATAL("generate app keys", ret, 0);
     489             : 
     490             :                 /* If the session is unauthenticated, try to optimize the handshake by
     491             :                  * sending the session ticket early. */
     492        5089 :                 if (!(session->internals.hsk_flags & (HSK_CRT_REQ_SENT|HSK_PSK_SELECTED))) {
     493        3413 :                         STATE = STATE108;
     494             : 
     495        3413 :                         ret = generate_non_auth_rms_keys(session);
     496        3413 :                         IMED_RET_FATAL("generate rms keys", ret, 0);
     497             : 
     498        3413 :                         session->internals.hsk_flags |= HSK_EARLY_START_USED;
     499        3413 :                         _gnutls_handshake_log("HSK[%p]: unauthenticated session eligible for early start\n", session);
     500             :                 }
     501             : 
     502        5089 :                 ret = _tls13_write_connection_state_init(session, STAGE_APP);
     503        5089 :                 IMED_RET_FATAL("set write app keys", ret, 0);
     504             : 
     505        5089 :                 _gnutls_handshake_log("HSK[%p]: switching early to application traffic keys\n", session);
     506             : 
     507        5089 :                 FALLTHROUGH;
     508             :         case STATE109:
     509        5089 :                 if (session->internals.resumed != RESUME_FALSE)
     510         172 :                         _gnutls_set_resumed_parameters(session);
     511             : 
     512        5089 :                 if (session->internals.hsk_flags & HSK_EARLY_START_USED) {
     513        3413 :                         if (!(session->internals.flags & GNUTLS_NO_AUTO_SEND_TICKET))
     514        3411 :                                 ret = _gnutls13_send_session_ticket(session, TLS13_TICKETS_TO_SEND,
     515        3411 :                                                                     AGAIN(STATE109));
     516             : 
     517        3413 :                         STATE = STATE109;
     518        3413 :                         IMED_RET("send session ticket", ret, 0);
     519             : 
     520             :                         /* complete this phase of the handshake. We
     521             :                          * should be called again by gnutls_record_recv()
     522             :                          */
     523             : 
     524        3413 :                         if (session->internals.flags & GNUTLS_ENABLE_EARLY_START) {
     525          12 :                                 STATE = STATE113; /* finished */
     526          12 :                                 gnutls_assert();
     527             : 
     528          12 :                                 session->internals.recv_state = RECV_STATE_EARLY_START;
     529          12 :                                 return 0;
     530             :                         }
     531             :                 }
     532        5139 :                 FALLTHROUGH;
     533             :         case STATE110:
     534        5139 :                 ret = _gnutls13_recv_certificate(session);
     535        5139 :                 STATE = STATE110;
     536        5139 :                 IMED_RET("recv certificate", ret, 0);
     537        5012 :                 FALLTHROUGH;
     538             :         case STATE111:
     539        5012 :                 ret = _gnutls13_recv_certificate_verify(session);
     540        5012 :                 STATE = STATE111;
     541        5012 :                 IMED_RET("recv certificate verify", ret, 0);
     542        5011 :                 FALLTHROUGH;
     543             :         case STATE112:
     544        5011 :                 ret = _gnutls_run_verify_callback(session, GNUTLS_CLIENT);
     545        5011 :                 STATE = STATE112;
     546        5011 :                 if (ret < 0)
     547           2 :                         return gnutls_assert_val(ret);
     548        5219 :                 FALLTHROUGH;
     549             :         case STATE113: /* can enter from STATE109 */
     550        5219 :                 ret = _gnutls13_recv_finished(session);
     551        5219 :                 STATE = STATE113;
     552        5219 :                 IMED_RET("recv finished", ret, 0);
     553        4990 :                 FALLTHROUGH;
     554             :         case STATE114:
     555             :                 /* If we did request a client certificate, then we can
     556             :                  * only send the tickets here */
     557        4990 :                 STATE = STATE114;
     558             : 
     559        4990 :                 if (!(session->internals.hsk_flags & HSK_EARLY_START_USED)) {
     560        1607 :                         ret = generate_rms_keys(session);
     561        1607 :                         IMED_RET_FATAL("generate rms keys", ret, 0);
     562             :                 }
     563             : 
     564        4990 :                 ret = _tls13_read_connection_state_init(session, STAGE_APP);
     565        4990 :                 IMED_RET_FATAL("set read app keys", ret, 0);
     566             : 
     567        4990 :                 FALLTHROUGH;
     568             :         case STATE115:
     569        4990 :                 if (!(session->internals.hsk_flags & (HSK_TLS13_TICKET_SENT|HSK_EARLY_START_USED)) &&
     570        1607 :                     !(session->internals.flags & GNUTLS_NO_AUTO_SEND_TICKET)) {
     571        3212 :                         ret = _gnutls13_send_session_ticket(session, TLS13_TICKETS_TO_SEND,
     572        1606 :                                                             AGAIN(STATE115));
     573        1606 :                         STATE = STATE115;
     574        1606 :                         IMED_RET("send session ticket", ret, 0);
     575             :                 }
     576             : 
     577        4990 :                 STATE = STATE0;
     578        4990 :                 break;
     579             :         default:
     580           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     581             :         }
     582             : 
     583             :         /* explicitly reset any early start flags */
     584        4990 :         gnutls_mutex_lock(&session->internals.post_negotiation_lock);
     585        4990 :         session->internals.recv_state = RECV_STATE_0;
     586        4990 :         session->internals.initial_negotiation_completed = 1;
     587        4990 :         gnutls_mutex_unlock(&session->internals.post_negotiation_lock);
     588             : 
     589        4990 :         SAVE_TRANSCRIPT;
     590             : 
     591             : 
     592             :         return 0;
     593             : }
     594             : 
     595             : /* Processes handshake messages received asynchronously after initial handshake.
     596             :  *
     597             :  * It is called once per message and should return success, or a fatal error code.
     598             :  */
     599             : int
     600         381 : _gnutls13_recv_async_handshake(gnutls_session_t session)
     601             : {
     602         381 :         int ret;
     603         381 :         handshake_buffer_st hsk;
     604         381 :         recv_state_t next_state = RECV_STATE_0;
     605             : 
     606             :         /* The following messages are expected asynchronously after
     607             :          * the handshake process is complete */
     608         381 :         if (unlikely(session->internals.handshake_in_progress))
     609           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
     610             : 
     611         383 :         do {
     612         383 :                 _gnutls_handshake_buffer_init(&hsk);
     613             : 
     614             :                 /* the received handshake message has already been pushed into
     615             :                  * handshake buffers. As we do not need to use the handshake hash
     616             :                  * buffers we call the lower level receive functions */
     617         383 :                 ret = _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE_ANY, &hsk, 0);
     618         383 :                 if (ret < 0) {
     619           0 :                         gnutls_assert();
     620           0 :                         goto cleanup;
     621             :                 }
     622         383 :                 session->internals.last_handshake_in = hsk.htype;
     623             : 
     624         766 :                 ret = _gnutls_call_hook_func(session, hsk.htype, GNUTLS_HOOK_PRE, 1,
     625         383 :                                              hsk.data.data, hsk.data.length);
     626         383 :                 if (ret < 0) {
     627           0 :                         gnutls_assert();
     628           0 :                         goto cleanup;
     629             :                 }
     630             : 
     631         383 :                 switch(hsk.htype) {
     632           1 :                         case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
     633           1 :                                 if (!(session->security_parameters.entity == GNUTLS_CLIENT) ||
     634           1 :                                     !(session->internals.flags & GNUTLS_POST_HANDSHAKE_AUTH)) {
     635           0 :                                         ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
     636           0 :                                         goto cleanup;
     637             :                                 }
     638             : 
     639           1 :                                 _gnutls_buffer_reset(&session->internals.reauth_buffer);
     640             : 
     641             :                                 /* include the handshake headers in reauth buffer */
     642           2 :                                 ret = _gnutls_buffer_append_data(&session->internals.reauth_buffer,
     643           1 :                                                                  hsk.header, hsk.header_size);
     644           1 :                                 if (ret < 0) {
     645           0 :                                         gnutls_assert();
     646           0 :                                         goto cleanup;
     647             :                                 }
     648             : 
     649           2 :                                 ret = _gnutls_buffer_append_data(&session->internals.reauth_buffer,
     650           1 :                                                                  hsk.data.data, hsk.data.length);
     651           1 :                                 if (ret < 0) {
     652           0 :                                         gnutls_assert();
     653           0 :                                         goto cleanup;
     654             :                                 }
     655             : 
     656           1 :                                 if (session->internals.flags & GNUTLS_AUTO_REAUTH) {
     657           1 :                                         ret = gnutls_reauth(session, 0);
     658           1 :                                         if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) {
     659             :                                                 next_state = RECV_STATE_REAUTH;
     660           1 :                                         } else if (ret < 0) {
     661           0 :                                                 gnutls_assert();
     662           0 :                                                 goto cleanup;
     663             :                                         }
     664             :                                 } else {
     665             :                                         /* Application is expected to handle re-authentication
     666             :                                          * explicitly.  */
     667             :                                         ret = GNUTLS_E_REAUTH_REQUEST;
     668             :                                 }
     669             : 
     670           1 :                                 goto cleanup;
     671             : 
     672          51 :                         case GNUTLS_HANDSHAKE_KEY_UPDATE:
     673          51 :                                 ret = _gnutls13_recv_key_update(session, &hsk.data);
     674          51 :                                 if (ret < 0) {
     675           5 :                                         gnutls_assert();
     676           5 :                                         goto cleanup;
     677             :                                 }
     678             : 
     679             :                                 /* Handshake messages MUST NOT span key changes, i.e., we
     680             :                                  * should not have any other pending handshake messages from
     681             :                                  * the same record. */
     682          46 :                                 if (session->internals.handshake_recv_buffer_size != 0) {
     683           0 :                                         ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
     684           0 :                                         goto cleanup;
     685             :                                 }
     686             :                                 break;
     687         331 :                         case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
     688         331 :                                 if (session->security_parameters.entity != GNUTLS_CLIENT) {
     689           0 :                                         ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
     690           0 :                                         goto cleanup;
     691             :                                 }
     692             : 
     693         331 :                                 ret = _gnutls13_recv_session_ticket(session, &hsk.data);
     694         331 :                                 if (ret < 0) {
     695           0 :                                         gnutls_assert();
     696           0 :                                         goto cleanup;
     697             :                                 }
     698             : 
     699         331 :                                 memcpy(session->internals.tls13_ticket.resumption_master_secret,
     700         331 :                                        session->key.proto.tls13.ap_rms,
     701         331 :                                        session->key.proto.tls13.temp_secret_size);
     702             : 
     703         331 :                                 session->internals.tls13_ticket.prf = session->security_parameters.prf;
     704         331 :                                 session->internals.hsk_flags |= HSK_TICKET_RECEIVED;
     705         331 :                                 break;
     706           0 :                         default:
     707           0 :                                 gnutls_assert();
     708           0 :                                 ret = GNUTLS_E_UNEXPECTED_PACKET;
     709           0 :                                 goto cleanup;
     710             :                 }
     711             : 
     712         377 :                 ret = _gnutls_call_hook_func(session, hsk.htype, GNUTLS_HOOK_POST, 1, hsk.data.data, hsk.data.length);
     713         377 :                 if (ret < 0) {
     714           0 :                         gnutls_assert();
     715           0 :                         goto cleanup;
     716             :                 }
     717         377 :                 _gnutls_handshake_buffer_clear(&hsk);
     718             : 
     719         377 :         } while (_gnutls_record_buffer_get_size(session) > 0);
     720             : 
     721         375 :         session->internals.recv_state = next_state;
     722             : 
     723         375 :         return 0;
     724             : 
     725           6 :  cleanup:
     726             :         /* if we have pending/partial handshake data in buffers, ensure that
     727             :          * next read will read handshake data */
     728           6 :         if (_gnutls_record_buffer_get_size(session) > 0)
     729           0 :                 session->internals.recv_state = RECV_STATE_ASYNC_HANDSHAKE;
     730             :         else
     731           6 :                 session->internals.recv_state = next_state;
     732             : 
     733           6 :         _gnutls_handshake_buffer_clear(&hsk);
     734           6 :         return ret;
     735             : }
     736             : 
     737             : /**
     738             :  * gnutls_session_ticket_send:
     739             :  * @session: is a #gnutls_session_t type.
     740             :  * @nr: the number of tickets to send
     741             :  * @flags: must be zero
     742             :  *
     743             :  * Sends a fresh session ticket to the peer. This is relevant only
     744             :  * in server side under TLS1.3. This function may also return %GNUTLS_E_AGAIN
     745             :  * or %GNUTLS_E_INTERRUPTED and in that case it must be called again.
     746             :  *
     747             :  * Returns: %GNUTLS_E_SUCCESS on success, or a negative error code.
     748             :  **/
     749           6 : int gnutls_session_ticket_send(gnutls_session_t session, unsigned nr, unsigned flags)
     750             : {
     751           6 :         int ret = 0;
     752           6 :         const version_entry_st *vers = get_version(session);
     753             : 
     754           6 :         if (!vers->tls13_sem || session->security_parameters.entity == GNUTLS_CLIENT)
     755           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     756             : 
     757           6 :         if (nr == 0)
     758           1 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     759             : 
     760           5 :         switch (TICKET_STATE) {
     761           5 :         case TICKET_STATE0:
     762           5 :                 ret = _gnutls_io_write_flush(session);
     763           5 :                 TICKET_STATE = TICKET_STATE0;
     764           5 :                 if (ret < 0) {
     765           0 :                         gnutls_assert();
     766           0 :                         return ret;
     767             :                 }
     768           5 :                 FALLTHROUGH;
     769             :         case TICKET_STATE1:
     770           5 :                 ret =
     771           5 :                     _gnutls13_send_session_ticket(session, nr, TICKET_STATE==TICKET_STATE1?1:0);
     772           5 :                 TICKET_STATE = TICKET_STATE1;
     773           5 :                 if (ret < 0) {
     774           0 :                         gnutls_assert();
     775           0 :                         return ret;
     776             :                 }
     777           5 :                 break;
     778           0 :         default:
     779           0 :                 gnutls_assert();
     780             :                 return GNUTLS_E_INTERNAL_ERROR;
     781             :         }
     782             : 
     783           5 :         TICKET_STATE = TICKET_STATE0;
     784             : 
     785           5 :         return 0;
     786             : }

Generated by: LCOV version 1.14