LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/tls13 - session_ticket.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.7 Code Coverage Lines: 239 282 84.8 %
Date: 2019-04-24 03:13:53 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81 224 36.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2017-2018 Red Hat, Inc.
       3                 :            :  *
       4                 :            :  * Author: Nikos Mavrogiannopoulos, Ander Juaristi
       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 "extv.h"
      26                 :            : #include "handshake.h"
      27                 :            : #include "mbuffers.h"
      28                 :            : #include "ext/pre_shared_key.h"
      29                 :            : #include "ext/session_ticket.h"
      30                 :            : #include "ext/early_data.h"
      31                 :            : #include "auth/cert.h"
      32                 :            : #include "tls13/session_ticket.h"
      33                 :            : #include "session_pack.h"
      34                 :            : #include "db.h"
      35                 :            : 
      36                 :            : static int
      37                 :       3063 : pack_ticket(gnutls_session_t session, tls13_ticket_st *ticket, gnutls_datum_t *packed)
      38                 :            : {
      39                 :       3063 :         uint8_t *p;
      40                 :       3063 :         gnutls_datum_t state;
      41                 :       3063 :         int ret;
      42                 :            : 
      43                 :       3063 :         ret = _gnutls_session_pack(session, &state);
      44         [ -  + ]:       3063 :         if (ret < 0)
      45         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
      46                 :            : 
      47                 :       6126 :         packed->size = 2 + 4 + 4 +
      48                 :       3063 :                 1 + ticket->prf->output_size +
      49                 :       3063 :                 1 + ticket->nonce_size + 2 + state.size + 12;
      50                 :            : 
      51                 :       3063 :         packed->data = gnutls_malloc(packed->size);
      52         [ -  + ]:       3063 :         if (!packed->data) {
      53         [ #  # ]:          0 :                 gnutls_assert();
      54                 :          0 :                 ret = GNUTLS_E_MEMORY_ERROR;
      55                 :          0 :                 goto cleanup;
      56                 :            :         }
      57                 :            : 
      58                 :       3063 :         p = packed->data;
      59                 :            : 
      60                 :       3063 :         _gnutls_write_uint16(ticket->prf->id, p);
      61                 :       3063 :         p += 2;
      62                 :       3063 :         _gnutls_write_uint32(ticket->age_add, p);
      63                 :       3063 :         p += 4;
      64                 :       3063 :         _gnutls_write_uint32(ticket->lifetime, p);
      65                 :       3063 :         p += 4;
      66                 :       3063 :         *p = ticket->prf->output_size;
      67                 :       3063 :         p += 1;
      68                 :       3063 :         memcpy(p, ticket->resumption_master_secret, ticket->prf->output_size);
      69                 :       3063 :         p += ticket->prf->output_size;
      70                 :       3063 :         *p = ticket->nonce_size;
      71                 :            : 
      72                 :       3063 :         p += 1;
      73                 :       3063 :         memcpy(p, ticket->nonce, ticket->nonce_size);
      74                 :       3063 :         p += ticket->nonce_size;
      75                 :            : 
      76                 :       3063 :         _gnutls_write_uint16(state.size, p);
      77                 :       3063 :         p += 2;
      78                 :            : 
      79                 :       3063 :         memcpy(p, state.data, state.size);
      80                 :       3063 :         p += state.size;
      81                 :            : 
      82                 :       3063 :         _gnutls_write_uint32((uint64_t) ticket->creation_time.tv_sec >> 32, p);
      83                 :       3063 :         p += 4;
      84                 :       3063 :         _gnutls_write_uint32(ticket->creation_time.tv_sec & 0xFFFFFFFF, p);
      85                 :       3063 :         p += 4;
      86                 :       3063 :         _gnutls_write_uint32(ticket->creation_time.tv_nsec, p);
      87                 :            : 
      88                 :       3063 :         ret = 0;
      89                 :            : 
      90                 :       3063 :  cleanup:
      91                 :       3063 :         gnutls_free(state.data);
      92                 :       3063 :         return ret;
      93                 :            : }
      94                 :            : 
      95                 :            : static int
      96                 :        182 : unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st *data)
      97                 :            : {
      98                 :        182 :         uint32_t age_add, lifetime;
      99                 :        182 :         struct timespec creation_time;
     100                 :        182 :         uint8_t resumption_master_secret[MAX_HASH_SIZE];
     101                 :        182 :         size_t resumption_master_secret_size;
     102                 :        182 :         uint8_t nonce[UINT8_MAX];
     103                 :        182 :         size_t nonce_size;
     104                 :        182 :         gnutls_datum_t state;
     105                 :        182 :         gnutls_mac_algorithm_t kdf;
     106                 :        182 :         const mac_entry_st *prf;
     107                 :        182 :         uint8_t *p;
     108                 :        182 :         ssize_t len;
     109                 :        182 :         uint64_t v;
     110                 :        182 :         int ret;
     111                 :            : 
     112         [ -  + ]:        182 :         if (unlikely(packed == NULL || data == NULL))
     113         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     114                 :            : 
     115                 :        182 :         memset(data, 0, sizeof(*data));
     116                 :            : 
     117                 :        182 :         p = packed->data;
     118                 :        182 :         len = packed->size;
     119                 :            : 
     120   [ -  +  #  # ]:        182 :         DECR_LEN(len, 2);
     121                 :        182 :         kdf = _gnutls_read_uint16(p);
     122                 :        182 :         p += 2;
     123                 :            : 
     124                 :            :         /* Check if the MAC ID we got is valid */
     125                 :        182 :         prf = _gnutls_mac_to_entry(kdf);
     126         [ -  + ]:        182 :         if (prf == NULL)
     127         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
     128                 :            : 
     129                 :            :         /* Read the ticket age add and the ticket lifetime */
     130   [ -  +  #  # ]:        182 :         DECR_LEN(len, 4);
     131         [ -  + ]:        182 :         age_add = _gnutls_read_uint32(p);
     132                 :        182 :         p += 4;
     133                 :            : 
     134   [ -  +  #  # ]:        182 :         DECR_LEN(len, 4);
     135         [ -  + ]:        182 :         lifetime = _gnutls_read_uint32(p);
     136                 :        182 :         p += 4;
     137                 :            : 
     138                 :            :         /*
     139                 :            :          * Check if the whole ticket is large enough,
     140                 :            :          * and read the resumption master secret
     141                 :            :          */
     142   [ -  +  #  # ]:        182 :         DECR_LEN(len, 1);
     143                 :        182 :         resumption_master_secret_size = *p;
     144                 :        182 :         p += 1;
     145                 :            : 
     146                 :            :         /* Check if the size of resumption_master_secret matches the PRF */
     147         [ -  + ]:        182 :         if (resumption_master_secret_size != prf->output_size)
     148         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
     149                 :            : 
     150   [ -  +  #  # ]:        182 :         DECR_LEN(len, resumption_master_secret_size);
     151                 :        182 :         memcpy(resumption_master_secret, p, resumption_master_secret_size);
     152                 :        182 :         p += resumption_master_secret_size;
     153                 :            : 
     154                 :            :         /* Read the ticket nonce */
     155   [ -  +  #  # ]:        182 :         DECR_LEN(len, 1);
     156                 :        182 :         nonce_size = *p;
     157                 :        182 :         p += 1;
     158                 :            : 
     159   [ -  +  #  # ]:        182 :         DECR_LEN(len, nonce_size);
     160                 :        182 :         memcpy(nonce, p, nonce_size);
     161                 :        182 :         p += nonce_size;
     162                 :            : 
     163   [ -  +  #  # ]:        182 :         DECR_LEN(len, 2);
     164         [ -  + ]:        182 :         state.size = _gnutls_read_uint16(p);
     165                 :        182 :         p += 2;
     166                 :            : 
     167   [ -  +  #  # ]:        182 :         DECR_LEN(len, state.size);
     168                 :        182 :         state.data = p;
     169                 :        182 :         p += state.size;
     170                 :            : 
     171   [ -  +  #  # ]:        182 :         DECR_LEN(len, 12);
     172                 :        182 :         v = _gnutls_read_uint32(p);
     173                 :        182 :         p += 4;
     174                 :        182 :         creation_time.tv_sec = (v << 32) | _gnutls_read_uint32(p);
     175                 :        182 :         p += 4;
     176                 :        182 :         creation_time.tv_nsec = _gnutls_read_uint32(p);
     177                 :            : 
     178                 :        182 :         ret = _gnutls_session_unpack(session, &state);
     179         [ -  + ]:        182 :         if (ret < 0)
     180         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     181                 :            : 
     182                 :            :         /* No errors - Now return all the data to the caller */
     183                 :        182 :         data->prf = prf;
     184                 :        182 :         memcpy(data->resumption_master_secret, resumption_master_secret,
     185                 :            :                resumption_master_secret_size);
     186                 :        182 :         memcpy(data->nonce, nonce, nonce_size);
     187                 :        182 :         data->nonce_size = nonce_size;
     188                 :        182 :         data->age_add = age_add;
     189                 :        182 :         data->lifetime = lifetime;
     190                 :        182 :         memcpy(&data->creation_time, &creation_time, sizeof(struct timespec));
     191                 :            : 
     192                 :        182 :         return 0;
     193                 :            : }
     194                 :            : 
     195                 :            : static int
     196                 :       3065 : generate_session_ticket(gnutls_session_t session, tls13_ticket_st *ticket)
     197                 :            : {
     198                 :       3065 :         int ret;
     199                 :       3065 :         gnutls_datum_t packed = { NULL, 0 };
     200                 :       3065 :         struct timespec now;
     201                 :       3065 :         tls13_ticket_st ticket_data;
     202                 :            : 
     203                 :       3065 :         gnutls_gettime(&now);
     204         [ +  + ]:       3065 :         if (session->internals.resumed != RESUME_FALSE) {
     205                 :            :                 /* If we are resuming ensure that we don't extend the lifetime
     206                 :            :                  * of the ticket past the original session expiration time */
     207         [ +  + ]:        330 :                 if (now.tv_sec >= session->security_parameters.timestamp + session->internals.expire_time)
     208                 :            :                         return GNUTLS_E_INT_RET_0; /* don't send ticket */
     209                 :            :                 else
     210                 :        656 :                         ticket->lifetime = session->security_parameters.timestamp +
     211                 :        328 :                                            session->internals.expire_time - now.tv_sec;
     212                 :            :         } else {
     213                 :            :                 /* Set ticket lifetime to the default expiration time */
     214                 :       2735 :                 ticket->lifetime = session->internals.expire_time;
     215                 :            :         }
     216                 :            : 
     217                 :            :         /* Generate a random 32-bit ticket nonce */
     218                 :       3063 :         ticket->nonce_size = 4;
     219                 :            : 
     220         [ -  + ]:       3063 :         if ((ret = gnutls_rnd(GNUTLS_RND_NONCE,
     221                 :       3063 :                         ticket->nonce, ticket->nonce_size)) < 0)
     222         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     223                 :            : 
     224         [ -  + ]:       3063 :         if ((ret = gnutls_rnd(GNUTLS_RND_NONCE, &ticket->age_add, sizeof(uint32_t))) < 0)
     225         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     226                 :            :         /* This is merely to produce the same binder value on
     227                 :            :          * different endian architectures. */
     228                 :            : #ifdef WORDS_BIGENDIAN
     229                 :            :         ticket->age_add = bswap_32(ticket->age_add);
     230                 :            : #endif
     231                 :            : 
     232                 :       3063 :         ticket->prf = session->security_parameters.prf;
     233                 :            : 
     234                 :            :         /* Encrypt the ticket and place the result in ticket->ticket */
     235                 :       3063 :         ticket_data.lifetime = ticket->lifetime;
     236                 :       3063 :         ticket_data.age_add = ticket->age_add;
     237                 :       3063 :         memcpy(&ticket_data.creation_time, &now, sizeof(struct timespec));
     238                 :       3063 :         memcpy(ticket_data.nonce, ticket->nonce, ticket->nonce_size);
     239                 :       3063 :         ticket_data.nonce_size = ticket->nonce_size;
     240                 :       3063 :         ticket_data.prf = ticket->prf;
     241                 :       9189 :         memcpy(&ticket_data.resumption_master_secret,
     242                 :       3063 :                session->key.proto.tls13.ap_rms,
     243                 :       3063 :                ticket->prf->output_size);
     244                 :            : 
     245                 :       3063 :         ret = pack_ticket(session, &ticket_data, &packed);
     246         [ -  + ]:       3063 :         if (ret < 0)
     247         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     248                 :            : 
     249                 :       3063 :         ret = _gnutls_encrypt_session_ticket(session, &packed, &ticket->ticket);
     250         [ +  - ]:       3063 :         _gnutls_free_datum(&packed);
     251         [ -  + ]:       3063 :         if (ret < 0)
     252         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     253                 :            : 
     254                 :            :         return 0;
     255                 :            : }
     256                 :            : 
     257                 :       3063 : static int append_nst_extension(void *ctx, gnutls_buffer_st *buf)
     258                 :            : {
     259                 :       3063 :         gnutls_session_t session = ctx;
     260                 :       3063 :         int ret;
     261                 :            : 
     262         [ +  + ]:       3063 :         if (!(session->internals.flags & GNUTLS_ENABLE_EARLY_DATA))
     263                 :            :                 return 0;
     264                 :            : 
     265                 :         66 :         ret = _gnutls_buffer_append_prefix(buf, 32,
     266                 :         22 :                                            session->security_parameters.
     267                 :            :                                            max_early_data_size);
     268         [ -  + ]:         22 :         if (ret < 0)
     269         [ #  # ]:          0 :                 gnutls_assert();
     270                 :            : 
     271                 :            :         return ret;
     272                 :            : }
     273                 :            : 
     274                 :       1993 : int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned nr, unsigned again)
     275                 :            : {
     276                 :       1993 :         int ret = 0;
     277                 :       1993 :         mbuffer_st *bufel = NULL;
     278                 :       1993 :         gnutls_buffer_st buf;
     279                 :       1993 :         tls13_ticket_st ticket;
     280                 :       1993 :         unsigned i;
     281                 :            : 
     282                 :            :         /* Client does not send a NewSessionTicket */
     283         [ -  + ]:       1993 :         if (unlikely(session->security_parameters.entity == GNUTLS_CLIENT))
     284         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     285                 :            : 
     286                 :            :         /* Session resumption has not been enabled */
     287         [ +  + ]:       1993 :         if (session->internals.flags & GNUTLS_NO_TICKETS)
     288         [ +  + ]:        469 :                 return gnutls_assert_val(0);
     289                 :            : 
     290                 :            :         /* If we received the psk_key_exchange_modes extension which
     291                 :            :          * does not have overlap with the server configuration, don't
     292                 :            :          * send a session ticket */
     293         [ +  + ]:       1526 :         if (session->internals.hsk_flags & HSK_PSK_KE_MODE_INVALID)
     294         [ -  + ]:          2 :                 return gnutls_assert_val(0);
     295                 :            : 
     296         [ +  - ]:       1524 :         if (again == 0) {
     297         [ +  + ]:       4587 :                 for (i=0;i<nr;i++) {
     298                 :       3065 :                         unsigned init_pos;
     299                 :            : 
     300                 :       3065 :                         memset(&ticket, 0, sizeof(tls13_ticket_st));
     301                 :       3065 :                         bufel = NULL;
     302                 :            : 
     303         [ +  - ]:       6130 :                         ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     304         [ -  + ]:       3065 :                         if (ret < 0)
     305         [ #  # ]:          0 :                                 return gnutls_assert_val(ret);
     306                 :            : 
     307                 :       3065 :                         ret = generate_session_ticket(session, &ticket);
     308         [ +  + ]:       3065 :                         if (ret < 0) {
     309         [ +  - ]:          2 :                                 if (ret == GNUTLS_E_INT_RET_0) {
     310         [ -  + ]:          2 :                                         ret = gnutls_assert_val(0);
     311                 :          2 :                                         goto cleanup;
     312                 :            :                                 }
     313         [ #  # ]:          0 :                                 gnutls_assert();
     314                 :          0 :                                 goto cleanup;
     315                 :            :                         }
     316                 :            : 
     317                 :       3063 :                         ret = _gnutls_buffer_append_prefix(&buf, 32, ticket.lifetime);
     318         [ -  + ]:       3063 :                         if (ret < 0) {
     319         [ #  # ]:          0 :                                 gnutls_assert();
     320                 :          0 :                                 goto cleanup;
     321                 :            :                         }
     322                 :            : 
     323                 :       3063 :                         ret = _gnutls_buffer_append_prefix(&buf, 32, ticket.age_add);
     324         [ -  + ]:       3063 :                         if (ret < 0) {
     325         [ #  # ]:          0 :                                 gnutls_assert();
     326                 :          0 :                                 goto cleanup;
     327                 :            :                         }
     328                 :            : 
     329                 :            :                         /* append ticket_nonce */
     330                 :       3063 :                         ret = _gnutls_buffer_append_data_prefix(&buf, 8, ticket.nonce, ticket.nonce_size);
     331         [ -  + ]:       3063 :                         if (ret < 0) {
     332         [ #  # ]:          0 :                                 gnutls_assert();
     333                 :          0 :                                 goto cleanup;
     334                 :            :                         }
     335                 :            : 
     336                 :            :                         /* append ticket */
     337                 :       3063 :                         ret = _gnutls_buffer_append_data_prefix(&buf, 16, ticket.ticket.data, ticket.ticket.size);
     338         [ -  + ]:       3063 :                         if (ret < 0) {
     339         [ #  # ]:          0 :                                 gnutls_assert();
     340                 :          0 :                                 goto cleanup;
     341                 :            :                         }
     342                 :            : 
     343         [ +  - ]:       3063 :                         _gnutls_free_datum(&ticket.ticket);
     344                 :            : 
     345                 :            :                         /* append extensions */
     346                 :       3063 :                         ret = _gnutls_extv_append_init(&buf);
     347         [ -  + ]:       3063 :                         if (ret < 0) {
     348         [ #  # ]:          0 :                                 gnutls_assert();
     349                 :          0 :                                 goto cleanup;
     350                 :            :                         }
     351                 :       3063 :                         init_pos = ret;
     352                 :            : 
     353                 :       3063 :                         ret = _gnutls_extv_append(&buf, ext_mod_early_data.tls_id, session,
     354                 :            :                                                   (extv_append_func)append_nst_extension);
     355         [ -  + ]:       3063 :                         if (ret < 0) {
     356         [ #  # ]:          0 :                                 gnutls_assert();
     357                 :          0 :                                 goto cleanup;
     358                 :            :                         }
     359                 :            : 
     360                 :       3063 :                         ret = _gnutls_extv_append_final(&buf, init_pos, 0);
     361         [ -  + ]:       3063 :                         if (ret < 0) {
     362         [ #  # ]:          0 :                                 gnutls_assert();
     363                 :          0 :                                 goto cleanup;
     364                 :            :                         }
     365                 :            : 
     366                 :       3063 :                         bufel = _gnutls_buffer_to_mbuffer(&buf);
     367                 :            : 
     368                 :       3063 :                         ret = _gnutls_send_handshake2(session, bufel,
     369                 :            :                                                       GNUTLS_HANDSHAKE_NEW_SESSION_TICKET, 1);
     370         [ -  + ]:       3063 :                         if (ret < 0) {
     371         [ #  # ]:          0 :                                 gnutls_assert();
     372                 :          0 :                                 goto cleanup;
     373                 :            :                         }
     374                 :            : 
     375                 :       3063 :                         session->internals.hsk_flags |= HSK_TLS13_TICKET_SENT;
     376                 :            :                 }
     377                 :            :         }
     378                 :            : 
     379                 :       1522 :         ret = _gnutls_handshake_io_write_flush(session);
     380                 :            : 
     381                 :       1522 :         return ret;
     382                 :            : 
     383                 :          2 : cleanup:
     384         [ -  + ]:          2 :         _gnutls_free_datum(&ticket.ticket);
     385         [ -  + ]:          2 :         _mbuffer_xfree(&bufel);
     386                 :          2 :         _gnutls_buffer_clear(&buf);
     387                 :            : 
     388                 :          2 :         return ret;
     389                 :            : }
     390                 :            : 
     391                 :          7 : static int parse_nst_extension(void *ctx, unsigned tls_id, const unsigned char *data, unsigned data_size)
     392                 :            : {
     393                 :          7 :         gnutls_session_t session = ctx;
     394         [ +  - ]:          7 :         if (tls_id == ext_mod_early_data.tls_id) {
     395         [ -  + ]:          7 :                 if (data_size < 4)
     396         [ #  # ]:          0 :                         return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR);
     397                 :         14 :                 session->security_parameters.max_early_data_size =
     398                 :         14 :                         _gnutls_read_uint32(data);
     399                 :            :         }
     400                 :            :         return 0;
     401                 :            : }
     402                 :            : 
     403                 :       1751 : int _gnutls13_recv_session_ticket(gnutls_session_t session, gnutls_buffer_st *buf)
     404                 :            : {
     405                 :       1751 :         int ret;
     406                 :       1751 :         uint8_t value;
     407                 :       1751 :         tls13_ticket_st *ticket = &session->internals.tls13_ticket;
     408                 :       1751 :         gnutls_datum_t t;
     409                 :       1751 :         size_t val;
     410                 :            : 
     411         [ -  + ]:       1751 :         if (unlikely(buf == NULL))
     412         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     413                 :            : 
     414         [ +  - ]:       1751 :         _gnutls_free_datum(&ticket->ticket);
     415                 :       1751 :         memset(ticket, 0, sizeof(tls13_ticket_st));
     416                 :            : 
     417         [ -  + ]:       1751 :         _gnutls_handshake_log("HSK[%p]: parsing session ticket message\n", session);
     418                 :            : 
     419                 :            :         /* ticket_lifetime */
     420                 :       1751 :         ret = _gnutls_buffer_pop_prefix32(buf, &val, 0);
     421         [ -  + ]:       1751 :         if (ret < 0)
     422         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     423                 :       1751 :         ticket->lifetime = val;
     424                 :            : 
     425                 :            :         /* ticket_age_add */
     426                 :       1751 :         ret = _gnutls_buffer_pop_prefix32(buf, &val, 0);
     427         [ -  + ]:       1751 :         if (ret < 0)
     428         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     429                 :       1751 :         ticket->age_add = val;
     430                 :            : 
     431                 :            :         /* ticket_nonce */
     432                 :       1751 :         ret = _gnutls_buffer_pop_prefix8(buf, &value, 0);
     433         [ -  + ]:       1751 :         if (ret < 0)
     434         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     435                 :            : 
     436                 :       1751 :         ticket->nonce_size = value;
     437                 :       1751 :         ret = _gnutls_buffer_pop_data(buf, ticket->nonce, ticket->nonce_size);
     438         [ -  + ]:       1751 :         if (ret < 0)
     439         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     440                 :            : 
     441                 :            :         /* ticket */
     442                 :       1751 :         ret = _gnutls_buffer_pop_datum_prefix16(buf, &t);
     443         [ -  + ]:       1751 :         if (ret < 0)
     444         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     445                 :            : 
     446                 :       1751 :         gnutls_free(ticket->ticket.data);
     447                 :       1751 :         ret = _gnutls_set_datum(&ticket->ticket, t.data, t.size);
     448         [ -  + ]:       1751 :         if (ret < 0)
     449         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     450                 :            : 
     451                 :            :         /* Extensions */
     452                 :       1751 :         ret = _gnutls_extv_parse(session, parse_nst_extension, buf->data, buf->length);
     453         [ -  + ]:       1751 :         if (ret < 0)
     454         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     455                 :            : 
     456                 :            :         /* Record the ticket arrival time */
     457                 :       1751 :         gnutls_gettime(&ticket->arrival_time);
     458                 :            : 
     459                 :       1751 :         return 0;
     460                 :            : }
     461                 :            : 
     462                 :            : /*
     463                 :            :  * Parse the ticket in 'data' and return the resumption master secret
     464                 :            :  * and the KDF ID associated to it.
     465                 :            :  */
     466                 :        244 : int _gnutls13_unpack_session_ticket(gnutls_session_t session,
     467                 :            :                 gnutls_datum_t *data,
     468                 :            :                 tls13_ticket_st *ticket_data)
     469                 :            : {
     470                 :        244 :         int ret;
     471                 :        244 :         gnutls_datum_t decrypted = { NULL, 0 };
     472                 :            : 
     473         [ -  + ]:        244 :         if (unlikely(data == NULL || ticket_data == NULL))
     474         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     475                 :            : 
     476                 :            :         /* Check MAC and decrypt ticket */
     477                 :        244 :         ret = _gnutls_decrypt_session_ticket(session, data, &decrypted);
     478         [ +  + ]:        244 :         if (ret < 0)
     479         [ +  + ]:         78 :                 return gnutls_assert_val(ret);
     480                 :            : 
     481                 :            :         /* Return ticket parameters */
     482                 :        182 :         ret = unpack_ticket(session, &decrypted, ticket_data);
     483         [ +  - ]:        182 :         _gnutls_free_datum(&decrypted);
     484         [ +  - ]:        182 :         if (ret < 0)
     485                 :            :                 return ret;
     486                 :            : 
     487                 :        182 :         ret = _gnutls_check_resumed_params(session);
     488         [ +  + ]:        182 :         if (ret < 0)
     489         [ -  + ]:         13 :                 return gnutls_assert_val(ret);
     490                 :            : 
     491                 :            :         return 0;
     492                 :            : }

Generated by: LCOV version 1.13