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

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2017 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             : #include "gnutls_int.h"
      24             : #include "errors.h"
      25             : #include "hello_ext.h"
      26             : #include "handshake.h"
      27             : #include "tls13/hello_retry.h"
      28             : #include "auth/cert.h"
      29             : #include "mbuffers.h"
      30             : #include "state.h"
      31             : 
      32         219 : int _gnutls13_send_hello_retry_request(gnutls_session_t session, unsigned again)
      33             : {
      34         219 :         int ret;
      35         219 :         mbuffer_st *bufel = NULL;
      36         219 :         gnutls_buffer_st buf;
      37         219 :         const version_entry_st *ver;
      38         219 :         const uint8_t vbuf[2] = {0x03, 0x03};
      39             : 
      40         219 :         if (again == 0) {
      41         219 :                 ver = get_version(session);
      42         219 :                 if (unlikely(ver == NULL || session->security_parameters.cs == NULL))
      43           0 :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
      44             : 
      45         438 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
      46         219 :                 if (ret < 0)
      47           0 :                         return gnutls_assert_val(ret);
      48             : 
      49         219 :                 ret = _gnutls_buffer_append_data(&buf, vbuf, 2);
      50         219 :                 if (ret < 0)
      51           0 :                         return gnutls_assert_val(ret);
      52             : 
      53         219 :                 ret = _gnutls_buffer_append_data(&buf,
      54             :                                                  HRR_RANDOM,
      55             :                                                  GNUTLS_RANDOM_SIZE);
      56         219 :                 if (ret < 0) {
      57           0 :                         gnutls_assert();
      58           0 :                         goto cleanup;
      59             :                 }
      60             : 
      61         438 :                 ret = _gnutls_buffer_append_data_prefix(&buf, 8,
      62         219 :                                                         session->security_parameters.session_id,
      63         219 :                                                         session->security_parameters.session_id_size);
      64         219 :                 if (ret < 0) {
      65           0 :                         gnutls_assert();
      66           0 :                         goto cleanup;
      67             :                 }
      68             : 
      69         219 :                 ret = _gnutls_buffer_append_data(&buf, session->security_parameters.cs->id, 2);
      70         219 :                 if (ret < 0) {
      71           0 :                         gnutls_assert();
      72           0 :                         goto cleanup;
      73             :                 }
      74             : 
      75             :                 /* compression */
      76         219 :                 ret = _gnutls_buffer_append_prefix(&buf, 8, 0);
      77         219 :                 if (ret < 0) {
      78           0 :                         gnutls_assert();
      79           0 :                         goto cleanup;
      80             :                 }
      81             : 
      82         219 :                 ret = _gnutls_gen_hello_extensions(session, &buf,
      83             :                                                    GNUTLS_EXT_FLAG_HRR,
      84             :                                                    GNUTLS_EXT_ANY);
      85         219 :                 if (ret < 0) {
      86         156 :                         gnutls_assert();
      87         156 :                         goto cleanup;
      88             :                 }
      89             : 
      90             :                 /* reset extensions sent by this session to allow re-sending them */
      91          63 :                 session->internals.used_exts = 0;
      92             : 
      93          63 :                 reset_binders(session);
      94             : 
      95          63 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
      96             :         }
      97             : 
      98          63 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_HELLO_RETRY_REQUEST);
      99             : 
     100         156 :  cleanup:
     101         156 :         _gnutls_buffer_clear(&buf);
     102         156 :         return ret;
     103             : }
     104             : 
     105             : int
     106          24 : _gnutls13_recv_hello_retry_request(gnutls_session_t session,
     107             :                                    gnutls_buffer_st *buf)
     108             : {
     109          24 :         int ret;
     110          24 :         uint8_t tmp[2];
     111          24 :         const gnutls_cipher_suite_entry_st *cs;
     112          24 :         const mac_entry_st *prf;
     113          24 :         gnutls_datum_t session_id;
     114          24 :         uint8_t random[GNUTLS_RANDOM_SIZE];
     115             : 
     116             :         /* only under TLS 1.3 */
     117          24 :         if (IS_DTLS(session))
     118           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
     119             : 
     120          24 :         if (session->internals.hsk_flags & HSK_HRR_RECEIVED)
     121           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
     122             : 
     123          24 :         session->internals.hsk_flags |= HSK_HRR_RECEIVED;
     124             : 
     125             :         /* version */
     126          24 :         ret = _gnutls_buffer_pop_data(buf, tmp, 2);
     127          24 :         if (ret < 0)
     128           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     129             : 
     130          24 :         if (unlikely(tmp[0] != 0x03 || tmp[1] != 0x03))
     131           0 :                 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
     132             : 
     133          24 :         ret = _gnutls_buffer_pop_data(buf, random, GNUTLS_RANDOM_SIZE);
     134          24 :         if (ret < 0)
     135           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     136             : 
     137          24 :         if (memcmp(random, HRR_RANDOM, GNUTLS_RANDOM_SIZE) != 0) {
     138           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     139             :         }
     140             : 
     141          24 :         ret = _gnutls_buffer_pop_datum_prefix8(buf, &session_id);
     142          24 :         if (ret < 0)
     143           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     144             : 
     145             :         /* read ciphersuites */
     146          24 :         ret = _gnutls_buffer_pop_data(buf, tmp, 2);
     147          24 :         if (ret < 0)
     148           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     149             : 
     150          24 :         cs = ciphersuite_to_entry(tmp);
     151          24 :         if (unlikely(cs == NULL))
     152           0 :                 return gnutls_assert_val(GNUTLS_E_UNKNOWN_CIPHER_SUITE);
     153             : 
     154          24 :         _gnutls_handshake_log("EXT[%p]: Hello Retry Request with %s\n", session, cs->name);
     155          24 :         memcpy(session->internals.hrr_cs, cs->id, 2);
     156             : 
     157          24 :         prf = mac_to_entry(cs->prf);
     158          24 :         if (unlikely(prf == NULL))
     159           0 :                 return gnutls_assert_val(GNUTLS_E_UNKNOWN_CIPHER_SUITE);
     160             : 
     161             :         /* compression */
     162          24 :         ret = _gnutls_buffer_pop_data(buf, tmp, 1);
     163          24 :         if (ret < 0)
     164           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     165             : 
     166          24 :         if (unlikely(tmp[0] != 0))
     167           0 :                 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     168             : 
     169          24 :         ret = _gnutls13_handshake_hash_buffers_synth(session, prf, 1);
     170          24 :         if (ret < 0)
     171           0 :                 return gnutls_assert_val(ret);
     172             : 
     173          24 :         if (buf->length <= 2) {
     174             :                 /* no extensions present */
     175           0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
     176             :         }
     177             : 
     178             :         /* figure version first */
     179          24 :         ret =
     180          48 :             _gnutls_parse_hello_extensions(session, GNUTLS_EXT_FLAG_HRR,
     181             :                                            GNUTLS_EXT_VERSION_NEG,
     182          24 :                                            buf->data, buf->length);
     183          24 :         if (ret < 0)
     184           0 :                 return gnutls_assert_val(ret);
     185             : 
     186             :         /* parse the rest of extensions */
     187          48 :         ret = _gnutls_parse_hello_extensions(session, GNUTLS_EXT_FLAG_HRR, GNUTLS_EXT_ANY,
     188          24 :                                              buf->data, buf->length);
     189          24 :         if (ret < 0)
     190           0 :                 return gnutls_assert_val(ret);
     191             : 
     192          24 :         session->internals.used_exts = 0;
     193             : 
     194          24 :         return 0;
     195             : }

Generated by: LCOV version 1.14