LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - kx.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 275 308 89.3 %
Date: 2020-10-30 04:50:48 Functions: 20 20 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2000-2012 Free Software Foundation, 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             : /* This file contains functions which are wrappers for the key exchange
      24             :  * part of TLS. They are called by the handshake functions (gnutls_handshake)
      25             :  */
      26             : 
      27             : #include "gnutls_int.h"
      28             : #include "handshake.h"
      29             : #include "kx.h"
      30             : #include "dh.h"
      31             : #include "errors.h"
      32             : #include "algorithms.h"
      33             : #include "debug.h"
      34             : #include "locks.h"
      35             : #include "mpi.h"
      36             : #include <state.h>
      37             : #include <datum.h>
      38             : #include <mbuffers.h>
      39             : 
      40             : /* This file contains important thing for the TLS handshake procedure.
      41             :  */
      42             : 
      43             : #define MASTER_SECRET "master secret"
      44             : #define MASTER_SECRET_SIZE (sizeof(MASTER_SECRET)-1)
      45             : 
      46             : #define EXT_MASTER_SECRET "extended master secret"
      47             : #define EXT_MASTER_SECRET_SIZE (sizeof(EXT_MASTER_SECRET)-1)
      48             : 
      49             : GNUTLS_STATIC_MUTEX(keylog_mutex);
      50             : static FILE *keylog;
      51             : 
      52             : static int generate_normal_master(gnutls_session_t session,
      53             :                                   gnutls_datum_t *, int);
      54             : 
      55        9411 : int _gnutls_generate_master(gnutls_session_t session, int keep_premaster)
      56             : {
      57        9411 :         if (session->internals.resumed == RESUME_FALSE)
      58        8515 :                 return generate_normal_master(session, &session->key.key,
      59             :                                               keep_premaster);
      60         896 :         else if (session->internals.premaster_set) {
      61          21 :                 gnutls_datum_t premaster;
      62          21 :                 premaster.size =
      63             :                     sizeof(session->internals.resumed_security_parameters.
      64             :                            master_secret);
      65          21 :                 premaster.data =
      66          21 :                     session->internals.resumed_security_parameters.
      67             :                     master_secret;
      68          21 :                 return generate_normal_master(session, &premaster, 1);
      69             :         }
      70             :         return 0;
      71             : }
      72             : 
      73             : /**
      74             :  * gnutls_session_get_keylog_function:
      75             :  * @session: is #gnutls_session_t type
      76             :  *
      77             :  * This function will return the callback function set using
      78             :  * gnutls_session_set_keylog_function().
      79             :  *
      80             :  * Returns: The function set or %NULL otherwise.
      81             :  *
      82             :  * Since: 3.6.13
      83             :  */
      84             : gnutls_keylog_func
      85           1 : gnutls_session_get_keylog_function(const gnutls_session_t session)
      86             : {
      87           1 :         return session->internals.keylog_func;
      88             : }
      89             : 
      90             : /**
      91             :  * gnutls_session_set_keylog_function:
      92             :  * @session: is #gnutls_session_t type
      93             :  * @func: is the function to be called
      94             :  *
      95             :  * This function will set a callback to be called when a new secret is
      96             :  * derived and installed during handshake.
      97             :  *
      98             :  * Since: 3.6.13
      99             :  */
     100             : void
     101       23100 : gnutls_session_set_keylog_function(gnutls_session_t session,
     102             :                                    gnutls_keylog_func func)
     103             : {
     104       23100 :         session->internals.keylog_func = func;
     105       23100 : }
     106             : 
     107             : int
     108       41428 : _gnutls_call_keylog_func(gnutls_session_t session,
     109             :                          const char *label,
     110             :                          const uint8_t *data,
     111             :                          unsigned size)
     112             : {
     113       41428 :         if (session->internals.keylog_func) {
     114       41428 :                 gnutls_datum_t secret = {(void*)data, size};
     115       41428 :                 return session->internals.keylog_func(session, label, &secret);
     116             :         }
     117             :         return 0;
     118             : }
     119             : 
     120             : int
     121       41418 : _gnutls_nss_keylog_func(gnutls_session_t session,
     122             :                         const char *label,
     123             :                         const gnutls_datum_t *secret)
     124             : {
     125             :         /* ignore subsequent traffic secrets that are calculated from
     126             :          * the previous traffic secret
     127             :          */
     128       41418 :         if (!session->internals.handshake_in_progress)
     129             :                 return 0;
     130             : 
     131       41418 :         _gnutls_nss_keylog_write(session, label, secret->data, secret->size);
     132       41418 :         return 0;
     133             : }
     134             : 
     135       41418 : void _gnutls_nss_keylog_write(gnutls_session_t session,
     136             :                               const char *label,
     137             :                               const uint8_t *secret, size_t secret_size)
     138             : {
     139       41418 :         static const char *keylogfile = NULL;
     140       41418 :         static unsigned checked_env = 0;
     141             : 
     142       41418 :         if (!checked_env) {
     143        1236 :                 checked_env = 1;
     144        1236 :                 keylogfile = secure_getenv("SSLKEYLOGFILE");
     145        1236 :                 if (keylogfile != NULL)
     146           1 :                         keylog = fopen(keylogfile, "ae");
     147             :         }
     148             : 
     149       41418 :         if (keylog) {
     150          12 :                 char client_random_hex[2*GNUTLS_RANDOM_SIZE+1];
     151          12 :                 char secret_hex[2*MAX_HASH_SIZE+1];
     152             : 
     153          12 :                 GNUTLS_STATIC_MUTEX_LOCK(keylog_mutex);
     154          24 :                 fprintf(keylog, "%s %s %s\n",
     155             :                         label,
     156          12 :                         _gnutls_bin2hex(session->security_parameters.
     157             :                                         client_random, GNUTLS_RANDOM_SIZE,
     158             :                                         client_random_hex,
     159             :                                         sizeof(client_random_hex), NULL),
     160             :                         _gnutls_bin2hex(secret, secret_size,
     161             :                                         secret_hex, sizeof(secret_hex), NULL));
     162          12 :                 fflush(keylog);
     163          12 :                 GNUTLS_STATIC_MUTEX_UNLOCK(keylog_mutex);
     164             :         }
     165       41418 : }
     166             : 
     167        2185 : void _gnutls_nss_keylog_deinit(void)
     168             : {
     169        2185 :         if (keylog) {
     170           1 :                 fclose(keylog);
     171           1 :                 keylog = NULL;
     172             :         }
     173        2185 : }
     174             : 
     175             : /* here we generate the TLS Master secret.
     176             :  */
     177             : static int
     178        8536 : generate_normal_master(gnutls_session_t session,
     179             :                        gnutls_datum_t * premaster, int keep_premaster)
     180             : {
     181        8536 :         int ret = 0;
     182        8536 :         char buf[512];
     183             : 
     184        8536 :         _gnutls_hard_log("INT: PREMASTER SECRET[%d]: %s\n",
     185             :                          premaster->size, _gnutls_bin2hex(premaster->data,
     186             :                                                           premaster->size,
     187             :                                                           buf, sizeof(buf),
     188             :                                                           NULL));
     189        8536 :         _gnutls_hard_log("INT: CLIENT RANDOM[%d]: %s\n", 32,
     190             :                          _gnutls_bin2hex(session->security_parameters.
     191             :                                          client_random, 32, buf,
     192             :                                          sizeof(buf), NULL));
     193        8536 :         _gnutls_hard_log("INT: SERVER RANDOM[%d]: %s\n", 32,
     194             :                          _gnutls_bin2hex(session->security_parameters.
     195             :                                          server_random, 32, buf,
     196             :                                          sizeof(buf), NULL));
     197             : 
     198        8536 :         if (session->security_parameters.ext_master_secret == 0) {
     199        3386 :                 uint8_t rnd[2 * GNUTLS_RANDOM_SIZE + 1];
     200        3386 :                 memcpy(rnd, session->security_parameters.client_random,
     201             :                        GNUTLS_RANDOM_SIZE);
     202        3386 :                 memcpy(&rnd[GNUTLS_RANDOM_SIZE],
     203        3386 :                        session->security_parameters.server_random,
     204             :                        GNUTLS_RANDOM_SIZE);
     205             : 
     206             : #ifdef ENABLE_SSL3
     207             :                 if (get_num_version(session) == GNUTLS_SSL3) {
     208             :                         ret =
     209             :                             _gnutls_ssl3_generate_random(premaster->data,
     210             :                                                          premaster->size, rnd,
     211             :                                                          2 * GNUTLS_RANDOM_SIZE,
     212             :                                                          GNUTLS_MASTER_SIZE,
     213             :                                                          session->security_parameters.
     214             :                                                          master_secret);
     215             :                 } else
     216             : #endif
     217        3386 :                         ret =
     218        3386 :                             _gnutls_PRF(session, premaster->data, premaster->size,
     219             :                                         MASTER_SECRET, MASTER_SECRET_SIZE,
     220             :                                         rnd, 2 * GNUTLS_RANDOM_SIZE,
     221             :                                         GNUTLS_MASTER_SIZE,
     222        3386 :                                         session->security_parameters.
     223             :                                         master_secret);
     224             :         } else {
     225        5150 :                 gnutls_datum_t shash = {NULL, 0};
     226             : 
     227             :                 /* draft-ietf-tls-session-hash-02 */
     228        5150 :                 ret = _gnutls_handshake_get_session_hash(session, &shash);
     229        5150 :                 if (ret < 0)
     230           0 :                         return gnutls_assert_val(ret);
     231             : #ifdef ENABLE_SSL3
     232             :                 if (get_num_version(session) == GNUTLS_SSL3)
     233             :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     234             : #endif
     235             : 
     236        5150 :                 ret =
     237       10300 :                     _gnutls_PRF(session, premaster->data, premaster->size,
     238             :                                 EXT_MASTER_SECRET, EXT_MASTER_SECRET_SIZE,
     239        5150 :                                 shash.data, shash.size,
     240             :                                 GNUTLS_MASTER_SIZE,
     241        5150 :                                 session->security_parameters.
     242             :                                 master_secret);
     243             : 
     244        5150 :                 gnutls_free(shash.data);
     245             :         }
     246             : 
     247        8536 :         if (!keep_premaster)
     248        8515 :                 _gnutls_free_temp_key_datum(premaster);
     249             : 
     250        8536 :         if (ret < 0)
     251             :                 return ret;
     252             : 
     253       17072 :         ret = _gnutls_call_keylog_func(session, "CLIENT_RANDOM",
     254        8536 :                                        session->security_parameters.master_secret,
     255             :                                        GNUTLS_MASTER_SIZE);
     256        8536 :         if (ret < 0)
     257           0 :                 return gnutls_assert_val(ret);
     258             : 
     259        8536 :         _gnutls_hard_log("INT: MASTER SECRET[%d]: %s\n",
     260             :                          GNUTLS_MASTER_SIZE,
     261             :                          _gnutls_bin2hex(session->security_parameters.
     262             :                                          master_secret, GNUTLS_MASTER_SIZE,
     263             :                                          buf, sizeof(buf), NULL));
     264             : 
     265             :         return ret;
     266             : }
     267             : 
     268             : /* This is called when we want to receive the key exchange message of the
     269             :  * server. It does nothing if this type of message is not required
     270             :  * by the selected ciphersuite. 
     271             :  */
     272       10019 : int _gnutls_send_server_kx_message(gnutls_session_t session, int again)
     273             : {
     274       10019 :         gnutls_buffer_st buf;
     275       10019 :         int ret = 0;
     276       10019 :         mbuffer_st *bufel = NULL;
     277             : 
     278       10019 :         if (session->internals.auth_struct->gnutls_generate_server_kx ==
     279             :             NULL)
     280             :                 return 0;
     281             : 
     282             : 
     283        6381 :         if (again == 0) {
     284       12527 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     285        6381 :                 if (ret < 0)
     286           0 :                         return gnutls_assert_val(ret);
     287             : 
     288        6381 :                 ret =
     289        6381 :                     session->internals.auth_struct->
     290             :                     gnutls_generate_server_kx(session, &buf);
     291             : 
     292        6381 :                 if (ret == GNUTLS_E_INT_RET_0) {
     293         470 :                         gnutls_assert();
     294         470 :                         ret = 0;
     295         470 :                         goto cleanup;
     296             :                 }
     297             : 
     298        5911 :                 if (ret < 0) {
     299          45 :                         gnutls_assert();
     300          45 :                         goto cleanup;
     301             :                 }
     302             : 
     303        5866 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     304             :         }
     305             : 
     306        5866 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
     307             : 
     308         515 :  cleanup:
     309         515 :         _gnutls_buffer_clear(&buf);
     310         515 :         return ret;
     311             : }
     312             : 
     313             : /* This function sends a certificate request message to the
     314             :  * client.
     315             :  */
     316        9974 : int _gnutls_send_server_crt_request(gnutls_session_t session, int again)
     317             : {
     318        9974 :         gnutls_buffer_st buf;
     319        9974 :         int ret = 0;
     320        9974 :         mbuffer_st *bufel = NULL;
     321             : 
     322        9974 :         if (session->internals.auth_struct->
     323             :             gnutls_generate_server_crt_request == NULL)
     324             :                 return 0;
     325             : 
     326        7127 :         if (session->internals.send_cert_req <= 0)
     327             :                 return 0;
     328             : 
     329             : 
     330        2708 :         if (again == 0) {
     331        5348 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     332        2708 :                 if (ret < 0)
     333           0 :                         return gnutls_assert_val(ret);
     334             : 
     335        2708 :                 ret =
     336        2708 :                     session->internals.auth_struct->
     337             :                     gnutls_generate_server_crt_request(session, &buf);
     338             : 
     339        2708 :                 if (ret < 0) {
     340           0 :                         gnutls_assert();
     341           0 :                         goto cleanup;
     342             :                 }
     343             : 
     344        2708 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     345             :         }
     346             : 
     347        2708 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
     348             : 
     349           0 :  cleanup:
     350           0 :         _gnutls_buffer_clear(&buf);
     351           0 :         return ret;
     352             : }
     353             : 
     354             : 
     355             : /* This is the function for the client to send the key
     356             :  * exchange message 
     357             :  */
     358        1480 : int _gnutls_send_client_kx_message(gnutls_session_t session, int again)
     359             : {
     360        1480 :         gnutls_buffer_st buf;
     361        1480 :         int ret = 0;
     362        1480 :         mbuffer_st *bufel = NULL;
     363             : 
     364        1480 :         if (session->internals.auth_struct->gnutls_generate_client_kx ==
     365             :             NULL)
     366             :                 return 0;
     367             : 
     368        1480 :         if (again == 0) {
     369        2693 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     370        1480 :                 if (ret < 0)
     371           0 :                         return gnutls_assert_val(ret);
     372             : 
     373        1480 :                 ret =
     374        1480 :                     session->internals.auth_struct->
     375             :                     gnutls_generate_client_kx(session, &buf);
     376        1480 :                 if (ret < 0) {
     377           7 :                         gnutls_assert();
     378           7 :                         goto cleanup;
     379             :                 }
     380             : 
     381        1473 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     382             :         }
     383             : 
     384        1473 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
     385             : 
     386           7 :  cleanup:
     387           7 :         _gnutls_buffer_clear(&buf);
     388           7 :         return ret;
     389             : }
     390             : 
     391             : 
     392             : /* This is the function for the client to send the certificate
     393             :  * verify message
     394             :  */
     395             : int
     396        1473 : _gnutls_send_client_certificate_verify(gnutls_session_t session, int again)
     397             : {
     398        1473 :         gnutls_buffer_st buf;
     399        1473 :         int ret = 0;
     400        1473 :         mbuffer_st *bufel = NULL;
     401             : 
     402             :         /* This is a packet that is only sent by the client
     403             :          */
     404        1473 :         if (session->security_parameters.entity == GNUTLS_SERVER)
     405             :                 return 0;
     406             : 
     407             :         /* if certificate verify is not needed just exit 
     408             :          */
     409        1473 :         if (!(session->internals.hsk_flags & HSK_CRT_ASKED))
     410             :                 return 0;
     411             : 
     412             : 
     413         396 :         if (session->internals.auth_struct->
     414             :             gnutls_generate_client_crt_vrfy == NULL) {
     415           0 :                 gnutls_assert();
     416           0 :                 return 0;       /* this algorithm does not support cli_crt_vrfy 
     417             :                                  */
     418             :         }
     419             : 
     420         396 :         if (again == 0) {
     421         748 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     422         396 :                 if (ret < 0)
     423           0 :                         return gnutls_assert_val(ret);
     424             : 
     425         396 :                 ret =
     426         396 :                     session->internals.auth_struct->
     427             :                     gnutls_generate_client_crt_vrfy(session, &buf);
     428         396 :                 if (ret < 0) {
     429           3 :                         gnutls_assert();
     430           3 :                         goto cleanup;
     431             :                 }
     432             : 
     433         393 :                 if (ret == 0)
     434         265 :                         goto cleanup;
     435             : 
     436             : 
     437         128 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     438             :         }
     439             : 
     440         128 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
     441             : 
     442         268 :  cleanup:
     443         268 :         _gnutls_buffer_clear(&buf);
     444         268 :         return ret;
     445             : }
     446             : 
     447             : /* This is called when we want send our certificate
     448             :  */
     449        1480 : int _gnutls_send_client_certificate(gnutls_session_t session, int again)
     450             : {
     451        1480 :         gnutls_buffer_st buf;
     452        1480 :         int ret = 0;
     453        1480 :         mbuffer_st *bufel = NULL;
     454             : 
     455        1480 :         if (!(session->internals.hsk_flags & HSK_CRT_ASKED))
     456             :                 return 0;
     457             : 
     458         396 :         if (session->internals.auth_struct->
     459             :             gnutls_generate_client_certificate == NULL)
     460             :                 return 0;
     461             : 
     462         396 :         if (again == 0) {
     463         748 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     464         396 :                 if (ret < 0)
     465           0 :                         return gnutls_assert_val(ret);
     466             : 
     467             : #ifdef ENABLE_SSL3
     468             :                 if (get_num_version(session) != GNUTLS_SSL3 ||
     469             :                     session->internals.selected_cert_list_length > 0)
     470             : #endif
     471             :                 {
     472             :                         /* TLS 1.x or SSL 3.0 with a valid certificate 
     473             :                          */
     474         396 :                         ret =
     475         396 :                             session->internals.auth_struct->
     476             :                             gnutls_generate_client_certificate(session,
     477             :                                                                &buf);
     478             : 
     479         396 :                         if (ret < 0) {
     480           0 :                                 gnutls_assert();
     481           0 :                                 goto cleanup;
     482             :                         }
     483             :                 }
     484             : 
     485         396 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     486             :         }
     487             : 
     488             : #ifdef ENABLE_SSL3
     489             :         /* In the SSL 3.0 protocol we need to send a
     490             :          * no certificate alert instead of an
     491             :          * empty certificate.
     492             :          */
     493             :         if (get_num_version(session) == GNUTLS_SSL3 &&
     494             :             session->internals.selected_cert_list_length == 0) {
     495             :                 _mbuffer_xfree(&bufel);
     496             :                 return
     497             :                     gnutls_alert_send(session, GNUTLS_AL_WARNING,
     498             :                                       GNUTLS_A_SSL3_NO_CERTIFICATE);
     499             : 
     500             :         } else          /* TLS 1.0 or SSL 3.0 with a valid certificate 
     501             :                          */
     502             : #endif
     503         396 :                 return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
     504             : 
     505           0 :  cleanup:
     506           0 :         _gnutls_buffer_clear(&buf);
     507           0 :         return ret;
     508             : }
     509             : 
     510             : 
     511             : /* This is called when we want send our certificate
     512             :  */
     513       10019 : int _gnutls_send_server_certificate(gnutls_session_t session, int again)
     514             : {
     515       10019 :         gnutls_buffer_st buf;
     516       10019 :         int ret = 0;
     517       10019 :         mbuffer_st *bufel = NULL;
     518             : 
     519       10019 :         if (session->internals.auth_struct->
     520             :             gnutls_generate_server_certificate == NULL)
     521             :                 return 0;
     522             : 
     523        7309 :         if (again == 0) {
     524       14415 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     525        7309 :                 if (ret < 0)
     526           0 :                         return gnutls_assert_val(ret);
     527             : 
     528        7309 :                 ret =
     529        7309 :                     session->internals.auth_struct->
     530             :                     gnutls_generate_server_certificate(session, &buf);
     531             : 
     532        7309 :                 if (ret < 0) {
     533           0 :                         gnutls_assert();
     534           0 :                         goto cleanup;
     535             :                 }
     536             : 
     537        7309 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     538             :         }
     539             : 
     540        7309 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
     541             : 
     542           0 :  cleanup:
     543           0 :         _gnutls_buffer_clear(&buf);
     544           0 :         return ret;
     545             : }
     546             : 
     547             : 
     548     6981440 : int _gnutls_recv_server_kx_message(gnutls_session_t session)
     549             : {
     550     6981440 :         gnutls_buffer_st buf;
     551     6981440 :         int ret = 0;
     552     6981440 :         unsigned int optflag = 0;
     553             : 
     554     6981440 :         if (session->internals.auth_struct->gnutls_process_server_kx !=
     555             :             NULL) {
     556             :                 /* Server key exchange packet is optional for PSK. */
     557     6981150 :                 if (_gnutls_session_is_psk(session))
     558         150 :                         optflag = 1;
     559             : 
     560     6981150 :                 ret =
     561     6981150 :                     _gnutls_recv_handshake(session,
     562             :                                            GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
     563             :                                            optflag, &buf);
     564     6981150 :                 if (ret < 0) {
     565     6979800 :                         gnutls_assert();
     566     6979800 :                         return ret;
     567             :                 }
     568             : 
     569        1346 :                 ret =
     570        1346 :                     session->internals.auth_struct->
     571             :                     gnutls_process_server_kx(session, buf.data,
     572             :                                              buf.length);
     573        1346 :                 _gnutls_buffer_clear(&buf);
     574             : 
     575        1346 :                 if (ret < 0) {
     576          88 :                         gnutls_assert();
     577          88 :                         return ret;
     578             :                 }
     579             : 
     580             :         }
     581             :         return ret;
     582             : }
     583             : 
     584        1821 : int _gnutls_recv_server_crt_request(gnutls_session_t session)
     585             : {
     586        1821 :         gnutls_buffer_st buf;
     587        1821 :         int ret = 0;
     588             : 
     589        1821 :         if (session->internals.auth_struct->
     590             :             gnutls_process_server_crt_request != NULL) {
     591             : 
     592        1357 :                 ret =
     593        1357 :                     _gnutls_recv_handshake(session,
     594             :                                            GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
     595             :                                            1, &buf);
     596        1357 :                 if (ret < 0)
     597             :                         return ret;
     598             : 
     599        1079 :                 if (ret == 0 && buf.length == 0) {
     600         655 :                         _gnutls_buffer_clear(&buf);
     601         655 :                         return 0;       /* ignored */
     602             :                 }
     603             : 
     604         424 :                 ret =
     605         424 :                     session->internals.auth_struct->
     606             :                     gnutls_process_server_crt_request(session, buf.data,
     607             :                                                       buf.length);
     608         424 :                 _gnutls_buffer_clear(&buf);
     609         424 :                 if (ret < 0)
     610             :                         return ret;
     611             : 
     612             :         }
     613             :         return ret;
     614             : }
     615             : 
     616       11119 : int _gnutls_recv_client_kx_message(gnutls_session_t session)
     617             : {
     618       11119 :         gnutls_buffer_st buf;
     619       11119 :         int ret = 0;
     620             : 
     621             : 
     622             :         /* Do key exchange only if the algorithm permits it */
     623       11119 :         if (session->internals.auth_struct->gnutls_process_client_kx !=
     624             :             NULL) {
     625             : 
     626       11119 :                 ret =
     627       11119 :                     _gnutls_recv_handshake(session,
     628             :                                            GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
     629             :                                            0, &buf);
     630       11119 :                 if (ret < 0)
     631             :                         return ret;
     632             : 
     633        7762 :                 ret =
     634        7762 :                     session->internals.auth_struct->
     635             :                     gnutls_process_client_kx(session, buf.data,
     636             :                                              buf.length);
     637        7762 :                 _gnutls_buffer_clear(&buf);
     638        7762 :                 if (ret < 0)
     639             :                         return ret;
     640             : 
     641             :         }
     642             : 
     643             :         return ret;
     644             : }
     645             : 
     646             : 
     647       10045 : int _gnutls_recv_client_certificate(gnutls_session_t session)
     648             : {
     649       10045 :         gnutls_buffer_st buf;
     650       10045 :         int ret = 0;
     651       10045 :         int optional;
     652             : 
     653       10045 :         if (session->internals.auth_struct->
     654             :             gnutls_process_client_certificate == NULL)
     655             :                 return 0;
     656             : 
     657             :         /* if we have not requested a certificate then just return
     658             :          */
     659        7199 :         if (session->internals.send_cert_req == 0) {
     660             :                 return 0;
     661             :         }
     662             : 
     663        2780 :         if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
     664             :                 optional = 0;
     665             :         else
     666        2679 :                 optional = 1;
     667             : 
     668        2780 :         ret =
     669        2780 :             _gnutls_recv_handshake(session,
     670             :                                    GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
     671             :                                    optional, &buf);
     672             : 
     673        2780 :         if (ret < 0) {
     674             :                 /* Handle the case of old SSL3 clients who send
     675             :                  * a warning alert instead of an empty certificate to indicate
     676             :                  * no certificate.
     677             :                  */
     678             : #ifdef ENABLE_SSL3
     679             :                 if (optional != 0 &&
     680             :                     ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
     681             :                     get_num_version(session) == GNUTLS_SSL3 &&
     682             :                     gnutls_alert_get(session) ==
     683             :                     GNUTLS_A_SSL3_NO_CERTIFICATE) {
     684             : 
     685             :                         /* SSL3 does not send an empty certificate,
     686             :                          * but this alert. So we just ignore it.
     687             :                          */
     688             :                         gnutls_assert();
     689             :                         return 0;
     690             :                 }
     691             : #endif
     692             : 
     693             :                 /* certificate was required 
     694             :                  */
     695          83 :                 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
     696          83 :                      || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
     697           5 :                     && optional == 0) {
     698           0 :                         gnutls_assert();
     699           0 :                         return GNUTLS_E_NO_CERTIFICATE_FOUND;
     700             :                 }
     701             : 
     702             :                 return ret;
     703             :         }
     704             : 
     705        2697 :         if (ret == 0 && buf.length == 0 && optional != 0) {
     706             :                 /* Client has not sent the certificate message.
     707             :                  * well I'm not sure we should accept this
     708             :                  * behaviour.
     709             :                  */
     710           0 :                 gnutls_assert();
     711           0 :                 ret = 0;
     712           0 :                 goto cleanup;
     713             :         }
     714        2697 :         ret =
     715        2697 :             session->internals.auth_struct->
     716             :             gnutls_process_client_certificate(session, buf.data,
     717             :                                               buf.length);
     718             : 
     719        2697 :         if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND) {
     720        1643 :                 gnutls_assert();
     721        1643 :                 goto cleanup;
     722             :         }
     723             : 
     724             :         /* ok we should expect a certificate verify message now 
     725             :          */
     726        1054 :         if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional != 0)
     727             :                 ret = 0;
     728             :         else
     729         768 :                 session->internals.hsk_flags |= HSK_CRT_VRFY_EXPECTED;
     730             : 
     731        2697 :       cleanup:
     732        2697 :         _gnutls_buffer_clear(&buf);
     733        2697 :         return ret;
     734             : }
     735             : 
     736        3107 : int _gnutls_recv_server_certificate(gnutls_session_t session)
     737             : {
     738        3107 :         gnutls_buffer_st buf;
     739        3107 :         int ret = 0;
     740             : 
     741        3107 :         if (session->internals.auth_struct->
     742             :             gnutls_process_server_certificate != NULL) {
     743             : 
     744        2597 :                 ret =
     745        2597 :                     _gnutls_recv_handshake(session,
     746             :                                            GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
     747             :                                            0, &buf);
     748        2597 :                 if (ret < 0) {
     749        1121 :                         gnutls_assert();
     750        1121 :                         return ret;
     751             :                 }
     752             : 
     753        1476 :                 ret =
     754        1476 :                     session->internals.auth_struct->
     755             :                     gnutls_process_server_certificate(session, buf.data,
     756             :                                                       buf.length);
     757        1476 :                 _gnutls_buffer_clear(&buf);
     758        1476 :                 if (ret < 0) {
     759         269 :                         gnutls_assert();
     760         269 :                         return ret;
     761             :                 }
     762             :         }
     763             : 
     764             :         return ret;
     765             : }
     766             : 
     767             : 
     768             : /* Recv the client certificate verify. This packet may not
     769             :  * arrive if the peer did not send us a certificate.
     770             :  */
     771             : int
     772        7602 : _gnutls_recv_client_certificate_verify_message(gnutls_session_t session)
     773             : {
     774        7602 :         gnutls_buffer_st buf;
     775        7602 :         int ret = 0;
     776             : 
     777             : 
     778        7602 :         if (session->internals.auth_struct->
     779             :             gnutls_process_client_crt_vrfy == NULL)
     780             :                 return 0;
     781             : 
     782        5135 :         if (session->internals.send_cert_req == 0 ||
     783        1035 :             (!(session->internals.hsk_flags & HSK_CRT_VRFY_EXPECTED))) {
     784             :                 return 0;
     785             :         }
     786             : 
     787         750 :         ret =
     788         750 :             _gnutls_recv_handshake(session,
     789             :                                    GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
     790             :                                    1, &buf);
     791         750 :         if (ret < 0)
     792             :                 return ret;
     793             : 
     794         750 :         if (ret == 0 && buf.length == 0
     795           1 :             && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE) {
     796             :                 /* certificate was required */
     797           0 :                 gnutls_assert();
     798           0 :                 ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
     799           0 :                 goto cleanup;
     800             :         }
     801             : 
     802         750 :         ret =
     803         750 :             session->internals.auth_struct->
     804             :             gnutls_process_client_crt_vrfy(session, buf.data, buf.length);
     805             : 
     806         750 :       cleanup:
     807         750 :         _gnutls_buffer_clear(&buf);
     808         750 :         return ret;
     809             : }

Generated by: LCOV version 1.14