LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/tls13 - post_handshake.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.7 Code Coverage Lines: 83 96 86.5 %
Date: 2019-04-24 03:13:53 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 38 213 17.8 %

           Branch data     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                 :            : /* 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 "tls13/certificate_request.h"
      50                 :            : #include "tls13/certificate_verify.h"
      51                 :            : #include "tls13/certificate.h"
      52                 :            : #include "tls13/finished.h"
      53                 :            : 
      54                 :            : #undef AGAIN
      55                 :            : #define AGAIN(x) ((x)==(REAUTH_STATE))
      56                 :            : 
      57                 :            : /*
      58                 :            :  * _gnutls13_reauth_client
      59                 :            :  * This function performs the client side of the post-handshake authentication
      60                 :            :  */
      61                 :            : static
      62                 :          1 : int _gnutls13_reauth_client(gnutls_session_t session)
      63                 :            : {
      64                 :          1 :         int ret = 0;
      65                 :          1 :         size_t tmp;
      66                 :            : 
      67         [ -  + ]:          1 :         if (!session->internals.initial_negotiation_completed)
      68         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE);
      69                 :            : 
      70         [ -  + ]:          1 :         if (!(session->internals.flags & GNUTLS_POST_HANDSHAKE_AUTH))
      71         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
      72                 :            : 
      73         [ -  + ]:          1 :         if (session->internals.reauth_buffer.length == 0)
      74         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
      75                 :            : 
      76   [ +  -  -  -  :          1 :         switch (REAUTH_STATE) {
                   -  - ]
      77                 :          1 :         case REAUTH_STATE0:
      78                 :            : 
      79                 :            :                 /* restore handshake transcript */
      80                 :          1 :                 _gnutls_buffer_reset(&session->internals.handshake_hash_buffer);
      81                 :          3 :                 ret = gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
      82                 :          1 :                                                 session->internals.post_handshake_hash_buffer.data,
      83                 :            :                                                 session->internals.post_handshake_hash_buffer.length);
      84         [ -  + ]:          1 :                 if (ret < 0)
      85         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
      86                 :            : 
      87                 :            :                 /* append the previously received certificate request message, to the
      88                 :            :                  * transcript. */
      89                 :          3 :                 ret = gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
      90                 :          1 :                                                 session->internals.reauth_buffer.data,
      91                 :            :                                                 session->internals.reauth_buffer.length);
      92         [ -  + ]:          1 :                 if (ret < 0)
      93         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
      94                 :            : 
      95                 :          1 :                 session->internals.handshake_hash_buffer_prev_len = session->internals.handshake_hash_buffer.length;
      96                 :            : 
      97                 :            :                 /* skip the reauth buffer handshake message headers */
      98                 :          1 :                 ret = _gnutls_buffer_pop_prefix32(&session->internals.reauth_buffer, &tmp, 0);
      99         [ -  + ]:          1 :                 if (ret < 0)
     100         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
     101                 :            : 
     102                 :          1 :                 FALLTHROUGH;
     103                 :            :         case REAUTH_STATE1:
     104                 :          1 :                 ret = _gnutls13_recv_certificate_request_int(session,
     105                 :            :                                                              &session->internals.reauth_buffer);
     106                 :          1 :                 REAUTH_STATE = REAUTH_STATE1;
     107   [ -  +  #  #  :          1 :                 IMED_RET("recv certificate request", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     108                 :          1 :                 FALLTHROUGH;
     109                 :            :         case REAUTH_STATE2:
     110                 :          1 :                 ret = _gnutls13_send_certificate(session, AGAIN(REAUTH_STATE2));
     111                 :          1 :                 REAUTH_STATE = REAUTH_STATE2;
     112   [ -  +  #  #  :          1 :                 IMED_RET("send certificate", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     113                 :          1 :                 FALLTHROUGH;
     114                 :            :         case REAUTH_STATE3:
     115                 :          1 :                 ret = _gnutls13_send_certificate_verify(session, AGAIN(REAUTH_STATE3));
     116                 :          1 :                 REAUTH_STATE = REAUTH_STATE3;
     117   [ -  +  #  #  :          1 :                 IMED_RET("send certificate verify", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     118                 :          1 :                 FALLTHROUGH;
     119                 :            :         case REAUTH_STATE4:
     120                 :          1 :                 ret = _gnutls13_send_finished(session, AGAIN(REAUTH_STATE4));
     121                 :          1 :                 REAUTH_STATE = REAUTH_STATE4;
     122   [ -  +  #  #  :          1 :                 IMED_RET("send finished", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     123                 :          1 :                 break;
     124                 :            :         default:
     125         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     126                 :            :         }
     127                 :            : 
     128                 :          1 :         _gnutls_handshake_hash_buffers_clear(session);
     129                 :          1 :         _gnutls_buffer_reset(&session->internals.reauth_buffer);
     130                 :          1 :         REAUTH_STATE = REAUTH_STATE0;
     131                 :            : 
     132                 :          1 :         return 0;
     133                 :            : }
     134                 :            : 
     135                 :            : /*
     136                 :            :  * _gnutls13_reauth_server
     137                 :            :  * This function does the server stuff of the post-handshake authentication.
     138                 :            :  */
     139                 :            : static
     140                 :      14847 : int _gnutls13_reauth_server(gnutls_session_t session)
     141                 :            : {
     142                 :      14847 :         int ret = 0;
     143                 :            : 
     144         [ +  + ]:      14847 :         if (session->security_parameters.post_handshake_auth == 0 ||
     145         [ -  + ]:      14846 :             (!(session->internals.flags & GNUTLS_POST_HANDSHAKE_AUTH)))
     146         [ -  + ]:          1 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     147                 :            : 
     148         [ -  + ]:      14846 :         if (session->internals.send_cert_req == 0) {
     149         [ #  # ]:          0 :                 _gnutls_debug_log("You need to call gnutls_certificate_server_set_request to enable post handshake auth\n");
     150         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     151                 :            :         }
     152                 :            : 
     153   [ +  -  +  -  :      14846 :         switch (REAUTH_STATE) {
                -  -  - ]
     154                 :         27 :         case REAUTH_STATE0:
     155                 :            :                 /* restore handshake transcript */
     156                 :         27 :                 _gnutls_buffer_reset(&session->internals.handshake_hash_buffer);
     157                 :         81 :                 ret = gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
     158                 :         27 :                                                 session->internals.post_handshake_hash_buffer.data,
     159                 :            :                                                 session->internals.post_handshake_hash_buffer.length);
     160         [ -  + ]:         27 :                 if (ret < 0)
     161         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
     162                 :            : 
     163                 :         27 :                 session->internals.handshake_hash_buffer_prev_len = session->internals.handshake_hash_buffer.length;
     164                 :            : 
     165                 :         27 :                 FALLTHROUGH;
     166                 :         27 :         case REAUTH_STATE1:
     167                 :         27 :                 ret = _gnutls13_send_certificate_request(session, AGAIN(REAUTH_STATE1));
     168                 :         27 :                 REAUTH_STATE = REAUTH_STATE1;
     169   [ -  +  #  #  :         27 :                 IMED_RET("send certificate request", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     170                 :      14846 :                 FALLTHROUGH;
     171                 :            :         case REAUTH_STATE2:
     172                 :            :                 /* here we should tolerate application data */
     173                 :      14846 :                 ret = _gnutls13_recv_certificate(session);
     174                 :      14846 :                 REAUTH_STATE = REAUTH_STATE2;
     175 [ +  + ][ +  + ]:      14846 :                 IMED_RET("recv certificate", ret, 0);
         [ +  + ][ -  + ]
         [ +  - ][ -  + ]
                 [ -  + ]
           [ -  +  #  # ]
     176                 :         23 :                 FALLTHROUGH;
     177                 :            :         case REAUTH_STATE3:
     178                 :         23 :                 ret = _gnutls13_recv_certificate_verify(session);
     179                 :         23 :                 REAUTH_STATE = REAUTH_STATE3;
     180   [ -  +  #  #  :         23 :                 IMED_RET("recv certificate verify", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     181                 :         23 :                 FALLTHROUGH;
     182                 :            :         case REAUTH_STATE4:
     183                 :         23 :                 ret = _gnutls_run_verify_callback(session, GNUTLS_CLIENT);
     184                 :         23 :                 REAUTH_STATE = REAUTH_STATE4;
     185         [ -  + ]:         23 :                 if (ret < 0)
     186         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
     187                 :         23 :                 FALLTHROUGH;
     188                 :            :         case REAUTH_STATE5:
     189                 :         23 :                 ret = _gnutls13_recv_finished(session);
     190                 :         23 :                 REAUTH_STATE = REAUTH_STATE5;
     191   [ -  +  #  #  :         23 :                 IMED_RET("recv finished", ret, 0);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     192                 :         23 :                 break;
     193                 :            :         default:
     194         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     195                 :            :         }
     196                 :            : 
     197                 :         23 :         _gnutls_handshake_hash_buffers_clear(session);
     198                 :         23 :         REAUTH_STATE = REAUTH_STATE0;
     199                 :            : 
     200                 :         23 :         return 0;
     201                 :            : }
     202                 :            : 
     203                 :            : /**
     204                 :            :  * gnutls_reauth:
     205                 :            :  * @session: is a #gnutls_session_t type.
     206                 :            :  * @flags: must be zero
     207                 :            :  *
     208                 :            :  * This function performs the post-handshake authentication
     209                 :            :  * for TLS 1.3. The post-handshake authentication is initiated by the server
     210                 :            :  * by calling this function. Clients respond when %GNUTLS_E_REAUTH_REQUEST
     211                 :            :  * has been seen while receiving data.
     212                 :            :  *
     213                 :            :  * The non-fatal errors expected by this function are:
     214                 :            :  * %GNUTLS_E_INTERRUPTED, %GNUTLS_E_AGAIN, as well as
     215                 :            :  * %GNUTLS_E_GOT_APPLICATION_DATA when called on server side.
     216                 :            :  *
     217                 :            :  * The former two interrupt the authentication procedure due to the transport
     218                 :            :  * layer being interrupted, and the latter because there were pending data prior
     219                 :            :  * to peer initiating the re-authentication. The server should read/process that
     220                 :            :  * data as unauthenticated and retry calling gnutls_reauth().
     221                 :            :  *
     222                 :            :  * When this function is called under TLS1.2 or earlier or the peer didn't
     223                 :            :  * advertise post-handshake auth, it always fails with
     224                 :            :  * %GNUTLS_E_INVALID_REQUEST. The verification of the received peers certificate
     225                 :            :  * is delegated to the session or credentials verification callbacks. A
     226                 :            :  * server can check whether post handshake authentication is supported
     227                 :            :  * by the client by checking the session flags with gnutls_session_get_flags().
     228                 :            :  *
     229                 :            :  * Prior to calling this function in server side, the function
     230                 :            :  * gnutls_certificate_server_set_request() must be called setting expectations
     231                 :            :  * for the received certificate (request or require). If none are set
     232                 :            :  * this function will return with %GNUTLS_E_INVALID_REQUEST.
     233                 :            :  *
     234                 :            :  * Note that post handshake authentication is available irrespective
     235                 :            :  * of the initial negotiation type (PSK or certificate). In all cases
     236                 :            :  * however, certificate credentials must be set to the session prior
     237                 :            :  * to calling this function.
     238                 :            :  *
     239                 :            :  * Returns: %GNUTLS_E_SUCCESS on a successful authentication, otherwise a negative error code.
     240                 :            :  **/
     241                 :      14848 : int gnutls_reauth(gnutls_session_t session, unsigned int flags)
     242                 :            : {
     243         [ -  + ]:      14848 :         const version_entry_st *vers = get_version(session);
     244                 :            : 
     245         [ -  + ]:      14848 :         if (unlikely(!vers->tls13_sem))
     246         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     247                 :            : 
     248         [ +  + ]:      14848 :         if (session->security_parameters.entity == GNUTLS_SERVER)
     249                 :      14847 :                 return _gnutls13_reauth_server(session);
     250                 :            :         else
     251                 :          1 :                 return _gnutls13_reauth_client(session);
     252                 :            : }

Generated by: LCOV version 1.13