LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/tls13 - certificate.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.7 Code Coverage Lines: 213 285 74.7 %
Date: 2019-04-24 03:13:53 Functions: 5 5 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 127 272 46.7 %

           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                 :            : #include "gnutls_int.h"
      24                 :            : #include "errors.h"
      25                 :            : #include "extv.h"
      26                 :            : #include "handshake.h"
      27                 :            : #include "tls13/certificate.h"
      28                 :            : #include "auth/cert.h"
      29                 :            : #include "mbuffers.h"
      30                 :            : #include "ext/status_request.h"
      31                 :            : 
      32                 :            : static int parse_cert_extension(void *ctx, unsigned tls_id, const uint8_t *data, unsigned data_size);
      33                 :            : static int parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size);
      34                 :            : 
      35                 :      17382 : int _gnutls13_recv_certificate(gnutls_session_t session)
      36                 :            : {
      37                 :      17382 :         int ret;
      38                 :      17382 :         gnutls_buffer_st buf;
      39                 :      17382 :         unsigned optional = 0;
      40                 :            : 
      41         [ +  + ]:      17382 :         if (!session->internals.initial_negotiation_completed &&
      42         [ +  + ]:       2536 :             session->internals.hsk_flags & HSK_PSK_SELECTED)
      43                 :            :                 return 0;
      44                 :            : 
      45         [ +  + ]:      16947 :         if (session->security_parameters.entity == GNUTLS_SERVER) {
      46                 :            :                 /* if we didn't request a certificate, there will not be any */
      47         [ +  + ]:      16561 :                 if (session->internals.send_cert_req == 0)
      48                 :            :                         return 0;
      49                 :            : 
      50         [ +  + ]:      15032 :                 if (session->internals.send_cert_req != GNUTLS_CERT_REQUIRE)
      51                 :      14954 :                         optional = 1;
      52                 :            :         }
      53                 :            : 
      54                 :      15418 :         ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_CERTIFICATE_PKT, 0, &buf);
      55         [ +  + ]:      15418 :         if (ret < 0) {
      56   [ -  +  #  # ]:      14884 :                 if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET && session->internals.send_cert_req)
      57         [ #  # ]:          0 :                         return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
      58                 :            : 
      59         [ +  + ]:      14885 :                 return gnutls_assert_val(ret);
      60                 :            :         }
      61                 :            : 
      62         [ -  + ]:        534 :         if (buf.length == 0) {
      63         [ #  # ]:          0 :                 gnutls_assert();
      64                 :          0 :                 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
      65                 :          0 :                 goto cleanup;
      66                 :            :         }
      67                 :            : 
      68         [ +  + ]:        534 :         if (session->internals.initial_negotiation_completed &&
      69         [ +  - ]:         54 :             session->internals.post_handshake_cr_context.size > 0) {
      70                 :         27 :                 gnutls_datum_t context;
      71                 :            : 
      72                 :            :                 /* verify whether the context matches */
      73                 :         27 :                 ret = _gnutls_buffer_pop_datum_prefix8(&buf, &context);
      74         [ -  + ]:         27 :                 if (ret < 0) {
      75         [ #  # ]:          0 :                         gnutls_assert();
      76                 :          0 :                         goto cleanup;
      77                 :            :                 }
      78                 :            : 
      79         [ +  - ]:         27 :                 if (context.size != session->internals.post_handshake_cr_context.size ||
      80         [ -  + ]:         27 :                     memcmp(context.data, session->internals.post_handshake_cr_context.data,
      81                 :            :                            context.size) != 0) {
      82                 :          0 :                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
      83         [ #  # ]:          0 :                         gnutls_assert();
      84                 :          0 :                         goto cleanup;
      85                 :            :                 }
      86                 :            :         } else {
      87         [ -  + ]:        507 :                 if (buf.data[0] != 0) {
      88                 :            :                         /* The context field must be empty during handshake */
      89         [ #  # ]:          0 :                         gnutls_assert();
      90                 :          0 :                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
      91                 :          0 :                         goto cleanup;
      92                 :            :                 }
      93                 :            : 
      94                 :            :                 /* buf.length is positive */
      95                 :        507 :                 buf.data++;
      96                 :        507 :                 buf.length--;
      97                 :            :         }
      98                 :            : 
      99         [ -  + ]:        534 :         _gnutls_handshake_log("HSK[%p]: parsing certificate message\n", session);
     100                 :            : 
     101                 :        534 :         ret = parse_cert_list(session, buf.data, buf.length);
     102         [ +  + ]:        534 :         if (ret < 0) {
     103         [ +  - ]:         83 :                 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND) {
     104         [ +  + ]:         83 :                         if (optional)
     105                 :            :                                 ret = 0;
     106         [ +  - ]:         18 :                         else if (session->security_parameters.entity ==
     107                 :            :                                  GNUTLS_SERVER)
     108                 :         18 :                                 ret = GNUTLS_E_CERTIFICATE_REQUIRED;
     109                 :            :                 }
     110         [ -  + ]:         83 :                 gnutls_assert();
     111                 :         83 :                 goto cleanup;
     112                 :            :         }
     113                 :            : 
     114                 :        451 :         session->internals.hsk_flags |= HSK_CRT_VRFY_EXPECTED;
     115                 :            : 
     116                 :        451 :         ret = 0;
     117                 :        534 : cleanup:
     118                 :            : 
     119                 :        534 :         _gnutls_buffer_clear(&buf);
     120                 :        534 :         return ret;
     121                 :            : }
     122                 :            : 
     123                 :            : struct ocsp_req_ctx_st {
     124                 :            :         gnutls_pcert_st *pcert;
     125                 :            :         unsigned cert_index;
     126                 :            :         gnutls_session_t session;
     127                 :            :         gnutls_certificate_credentials_t cred;
     128                 :            : };
     129                 :            : 
     130                 :            : static
     131                 :         33 : int append_status_request(void *_ctx, gnutls_buffer_st *buf)
     132                 :            : {
     133                 :         33 :         struct ocsp_req_ctx_st *ctx = _ctx;
     134                 :         33 :         gnutls_session_t session = ctx->session;
     135                 :         33 :         int ret;
     136                 :         33 :         gnutls_datum_t resp;
     137                 :         33 :         unsigned free_resp = 0;
     138                 :            : 
     139 [ +  + ][ -  + ]:         33 :         assert(session->internals.selected_ocsp_func != NULL ||
     140                 :            :                session->internals.selected_ocsp_length != 0);
     141                 :            : 
     142                 :            :         /* The global ocsp callback function can only be used to return
     143                 :            :          * a single certificate request */
     144 [ +  + ][ +  + ]:         33 :         if (session->internals.selected_ocsp_length == 1 && ctx->cert_index != 0)
     145                 :            :                 return 0;
     146                 :            : 
     147         [ +  + ]:         29 :         if (session->internals.selected_ocsp_length > 0) {
     148         [ +  - ]:         24 :                 if (ctx->cert_index < session->internals.selected_ocsp_length) {
     149         [ +  + ]:         24 :                         if ((session->internals.selected_ocsp[ctx->cert_index].exptime != 0 &&
     150         [ +  - ]:         12 :                             gnutls_time(0) >= session->internals.selected_ocsp[ctx->cert_index].exptime) ||
     151         [ -  + ]:         24 :                             session->internals.selected_ocsp[ctx->cert_index].response.data == NULL) {
     152                 :          0 :                                 return 0;
     153                 :            :                         }
     154                 :            : 
     155                 :         24 :                         resp.data = session->internals.selected_ocsp[ctx->cert_index].response.data;
     156                 :         24 :                         resp.size = session->internals.selected_ocsp[ctx->cert_index].response.size;
     157                 :         24 :                         ret = 0;
     158                 :            :                 } else {
     159                 :            :                         return 0;
     160                 :            :                 }
     161         [ +  - ]:          5 :         } else if (session->internals.selected_ocsp_func) {
     162         [ +  + ]:          5 :                 if (ctx->cert_index == 0) {
     163                 :          3 :                         ret = session->internals.selected_ocsp_func(session, session->internals.selected_ocsp_func_ptr, &resp);
     164                 :          3 :                         free_resp = 1;
     165                 :            :                 } else {
     166                 :            :                         return 0;
     167                 :            :                 }
     168                 :            :         } else
     169                 :            :                 return 0;
     170                 :            : 
     171 [ +  - ][ -  + ]:         27 :         if (ret == GNUTLS_E_NO_CERTIFICATE_STATUS || resp.data == 0) {
     172                 :          0 :                 return 0;
     173         [ -  + ]:         27 :         } else if (ret < 0) {
     174         [ #  # ]:          0 :                 return gnutls_assert_val(ret);
     175                 :            :         }
     176                 :            : 
     177                 :         27 :         ret = _gnutls_buffer_append_data(buf, "\x01", 1);
     178         [ -  + ]:         27 :         if (ret < 0) {
     179         [ #  # ]:          0 :                 gnutls_assert();
     180                 :          0 :                 goto cleanup;
     181                 :            :         }
     182                 :            : 
     183                 :         27 :         ret = _gnutls_buffer_append_data_prefix(buf, 24, resp.data, resp.size);
     184         [ -  + ]:         27 :         if (ret < 0) {
     185         [ #  # ]:          0 :                 gnutls_assert();
     186                 :          0 :                 goto cleanup;
     187                 :            :         }
     188                 :            : 
     189                 :            :         ret = 0;
     190                 :         27 :  cleanup:
     191         [ +  + ]:         27 :         if (free_resp)
     192                 :          3 :                 gnutls_free(resp.data);
     193                 :            :         return ret;
     194                 :            : }
     195                 :            : 
     196                 :       2479 : int _gnutls13_send_certificate(gnutls_session_t session, unsigned again)
     197                 :            : {
     198                 :       2479 :         int ret;
     199                 :       2479 :         gnutls_pcert_st *apr_cert_list = NULL;
     200                 :       2479 :         gnutls_privkey_t apr_pkey = NULL;
     201                 :       2479 :         int apr_cert_list_length = 0;
     202                 :       2479 :         mbuffer_st *bufel = NULL;
     203                 :       2479 :         gnutls_buffer_st buf;
     204                 :       2479 :         unsigned pos_mark, ext_pos_mark;
     205                 :       2479 :         unsigned i;
     206                 :       2479 :         struct ocsp_req_ctx_st ctx;
     207                 :       2479 :         gnutls_certificate_credentials_t cred;
     208                 :            : 
     209         [ +  - ]:       2479 :         if (again == 0) {
     210         [ +  + ]:       2479 :                 if (!session->internals.initial_negotiation_completed &&
     211         [ +  + ]:       2478 :                     session->internals.hsk_flags & HSK_PSK_SELECTED)
     212                 :            :                         return 0;
     213                 :            : 
     214         [ +  + ]:       2043 :                 if (session->security_parameters.entity == GNUTLS_SERVER &&
     215         [ +  - ]:       1670 :                     session->internals.resumed)
     216                 :            :                         return 0;
     217                 :            : 
     218                 :       2043 :                 cred = (gnutls_certificate_credentials_t)
     219                 :       2043 :                     _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
     220         [ +  + ]:       2043 :                 if (cred == NULL) {
     221         [ -  + ]:          2 :                         gnutls_assert();
     222                 :          2 :                         return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     223                 :            :                 }
     224                 :            : 
     225         [ +  + ]:       2041 :                 if (session->security_parameters.entity == GNUTLS_CLIENT &&
     226         [ +  + ]:        373 :                     !(session->internals.hsk_flags & HSK_CRT_ASKED)) {
     227                 :            :                         return 0;
     228                 :            :                 }
     229                 :            : 
     230                 :       1760 :                 ret = _gnutls_get_selected_cert(session, &apr_cert_list,
     231                 :            :                                                 &apr_cert_list_length, &apr_pkey);
     232         [ -  + ]:       1760 :                 if (ret < 0)
     233         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
     234                 :            : 
     235         [ +  - ]:       3520 :                 ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
     236         [ -  + ]:       1760 :                 if (ret < 0)
     237         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
     238                 :            : 
     239         [ +  + ]:       1760 :                 if (session->security_parameters.entity == GNUTLS_CLIENT) {
     240                 :        368 :                         ret = _gnutls_buffer_append_data_prefix(&buf, 8,
     241                 :         92 :                                                                 session->internals.post_handshake_cr_context.data,
     242                 :         92 :                                                                 session->internals.post_handshake_cr_context.size);
     243         [ -  + ]:         92 :                         if (ret < 0) {
     244         [ #  # ]:          0 :                                 gnutls_assert();
     245                 :          0 :                                 goto cleanup;
     246                 :            :                         }
     247                 :            : 
     248                 :            :                 } else {
     249                 :       1668 :                         ret = _gnutls_buffer_append_prefix(&buf, 8, 0);
     250         [ -  + ]:       1668 :                         if (ret < 0) {
     251         [ #  # ]:          0 :                                 gnutls_assert();
     252                 :          0 :                                 goto cleanup;
     253                 :            :                         }
     254                 :            :                 }
     255                 :            : 
     256                 :            :                 /* mark total size */
     257                 :       1760 :                 pos_mark = buf.length;
     258                 :       1760 :                 ret = _gnutls_buffer_append_prefix(&buf, 24, 0);
     259         [ -  + ]:       1760 :                 if (ret < 0) {
     260         [ #  # ]:          0 :                         gnutls_assert();
     261                 :          0 :                         goto cleanup;
     262                 :            :                 }
     263                 :            : 
     264         [ +  + ]:       3750 :                 for (i=0;i<(unsigned)apr_cert_list_length;i++) {
     265                 :       7960 :                         ret = _gnutls_buffer_append_data_prefix(&buf, 24,
     266                 :       1990 :                                                                 apr_cert_list[i].cert.data,
     267                 :       1990 :                                                                 apr_cert_list[i].cert.size);
     268         [ -  + ]:       1990 :                         if (ret < 0) {
     269         [ #  # ]:          0 :                                 gnutls_assert();
     270                 :          0 :                                 goto cleanup;
     271                 :            :                         }
     272                 :            : 
     273                 :            : #ifdef ENABLE_OCSP
     274         [ +  + ]:       1990 :                         if ((session->internals.selected_ocsp_length > 0 ||
     275         [ +  + ]:       1962 :                              session->internals.selected_ocsp_func) &&
     276         [ +  + ]:         37 :                             _gnutls_hello_ext_is_present(session, GNUTLS_EXTENSION_STATUS_REQUEST)) {
     277                 :            :                                 /* append status response if available */
     278                 :         33 :                                 ret = _gnutls_extv_append_init(&buf);
     279         [ -  + ]:         33 :                                 if (ret < 0) {
     280         [ #  # ]:          0 :                                         gnutls_assert();
     281                 :          0 :                                         goto cleanup;
     282                 :            :                                 }
     283                 :         33 :                                 ext_pos_mark = ret;
     284                 :            : 
     285                 :         33 :                                 ctx.pcert = &apr_cert_list[i];
     286                 :         33 :                                 ctx.cert_index = i;
     287                 :         33 :                                 ctx.session = session;
     288                 :         33 :                                 ctx.cred = cred;
     289                 :         33 :                                 ret = _gnutls_extv_append(&buf, STATUS_REQUEST_TLS_ID,
     290                 :            :                                                           &ctx, append_status_request);
     291         [ -  + ]:         33 :                                 if (ret < 0) {
     292         [ #  # ]:          0 :                                         gnutls_assert();
     293                 :          0 :                                         goto cleanup;
     294                 :            :                                 }
     295                 :            : 
     296                 :         33 :                                 ret = _gnutls_extv_append_final(&buf, ext_pos_mark, 0);
     297         [ -  + ]:         33 :                                 if (ret < 0) {
     298         [ #  # ]:          0 :                                         gnutls_assert();
     299                 :          0 :                                         goto cleanup;
     300                 :            :                                 }
     301                 :            :                         } else
     302                 :            : #endif
     303                 :            :                         {
     304                 :       1957 :                                 ret = _gnutls_buffer_append_prefix(&buf, 16, 0);
     305         [ -  + ]:       1957 :                                 if (ret < 0) {
     306         [ #  # ]:          0 :                                         gnutls_assert();
     307                 :          0 :                                         goto cleanup;
     308                 :            :                                 }
     309                 :            :                         }
     310                 :            :                 }
     311                 :            : 
     312                 :       1760 :                 _gnutls_write_uint24(buf.length-pos_mark-3, &buf.data[pos_mark]);
     313                 :            : 
     314                 :       1760 :                 bufel = _gnutls_buffer_to_mbuffer(&buf);
     315                 :            :         }
     316                 :            : 
     317                 :       1760 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
     318                 :            : 
     319                 :          0 :  cleanup:
     320                 :          0 :         _gnutls_buffer_clear(&buf);
     321                 :          0 :         return ret;
     322                 :            : }
     323                 :            : 
     324                 :            : typedef struct crt_cert_ctx_st {
     325                 :            :         gnutls_session_t session;
     326                 :            :         gnutls_datum_t *ocsp;
     327                 :            :         unsigned idx;
     328                 :            : } crt_cert_ctx_st;
     329                 :            : 
     330                 :         28 : static int parse_cert_extension(void *_ctx, unsigned tls_id, const uint8_t *data, unsigned data_size)
     331                 :            : {
     332                 :         28 :         crt_cert_ctx_st *ctx = _ctx;
     333                 :         28 :         gnutls_session_t session = ctx->session;
     334                 :         28 :         int ret;
     335                 :            : 
     336         [ +  - ]:         28 :         if (tls_id == STATUS_REQUEST_TLS_ID) {
     337                 :            : #ifdef ENABLE_OCSP
     338         [ -  + ]:         28 :                 if (!_gnutls_hello_ext_is_present(session, ext_mod_status_request.gid)) {
     339         [ #  # ]:          0 :                         gnutls_assert();
     340                 :          0 :                         goto unexpected;
     341                 :            :                 }
     342                 :            : 
     343         [ -  + ]:         28 :                 _gnutls_handshake_log("Found OCSP response on cert %d\n", ctx->idx);
     344                 :            : 
     345                 :         28 :                 ret = _gnutls_parse_ocsp_response(session, data, data_size, ctx->ocsp);
     346         [ -  + ]:         28 :                 if (ret < 0)
     347         [ #  # ]:          0 :                         return gnutls_assert_val(ret);
     348                 :            : #endif
     349                 :            :         } else {
     350                 :            :                 goto unexpected;
     351                 :            :         }
     352                 :            : 
     353                 :            :         return 0;
     354                 :            : 
     355                 :          0 :  unexpected:
     356         [ #  # ]:          0 :         _gnutls_debug_log("received unexpected certificate extension (%d)\n", (int)tls_id);
     357         [ #  # ]:          0 :         return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
     358                 :            : }
     359                 :            : 
     360                 :            : static int
     361                 :        534 : parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size)
     362                 :            : {
     363                 :        534 :         int len, ret;
     364                 :        534 :         uint8_t *p = data;
     365                 :        534 :         cert_auth_info_t info;
     366                 :        534 :         gnutls_certificate_credentials_t cred;
     367                 :        534 :         ssize_t dsize = data_size, size;
     368                 :        534 :         int i;
     369                 :        534 :         unsigned npeer_certs, npeer_ocsp, j;
     370                 :        534 :         crt_cert_ctx_st ctx;
     371                 :        534 :         gnutls_datum_t *peer_certs = NULL;
     372                 :        534 :         gnutls_datum_t *peer_ocsp = NULL;
     373                 :        534 :         unsigned nentries = 0;
     374                 :            : 
     375                 :        534 :         cred = (gnutls_certificate_credentials_t)
     376                 :        534 :             _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
     377         [ -  + ]:        534 :         if (cred == NULL) {
     378         [ #  # ]:          0 :                 gnutls_assert();
     379                 :          0 :                 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     380                 :            :         }
     381                 :            : 
     382                 :       1068 :         if ((ret =
     383         [ -  + ]:        534 :              _gnutls_auth_info_init(session, GNUTLS_CRD_CERTIFICATE,
     384                 :            :                                    sizeof(cert_auth_info_st), 1)) < 0) {
     385         [ #  # ]:          0 :                 gnutls_assert();
     386                 :          0 :                 return ret;
     387                 :            :         }
     388                 :            : 
     389         [ -  + ]:        534 :         if (data == NULL || data_size == 0) {
     390                 :            :                 /* no certificate was sent */
     391         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     392                 :            :         }
     393                 :            : 
     394         [ +  - ]:        534 :         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
     395         [ -  + ]:        534 :         if (info == NULL)
     396         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
     397                 :            : 
     398   [ -  +  #  # ]:        534 :         DECR_LEN(dsize, 3);
     399         [ -  + ]:        534 :         size = _gnutls_read_uint24(p);
     400                 :        534 :         p += 3;
     401                 :            : 
     402         [ -  + ]:        534 :         if (size != dsize)
     403         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     404                 :            : 
     405         [ +  + ]:        534 :         if (size == 0)
     406         [ -  + ]:         83 :                 return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
     407                 :            : 
     408                 :        451 :         i = dsize;
     409                 :            : 
     410         [ +  + ]:       1119 :         while (i > 0) {
     411   [ -  +  #  # ]:        668 :                 DECR_LEN(dsize, 3);
     412         [ -  + ]:        668 :                 len = _gnutls_read_uint24(p);
     413         [ -  + ]:        668 :                 if (len == 0)
     414         [ #  # ]:          0 :                         return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     415                 :            : 
     416   [ -  +  #  # ]:        668 :                 DECR_LEN(dsize, len);
     417                 :        668 :                 p += len + 3;
     418                 :        668 :                 i -= len + 3;
     419                 :            : 
     420   [ -  +  #  # ]:        668 :                 DECR_LEN(dsize, 2);
     421         [ -  + ]:        668 :                 len = _gnutls_read_uint16(p);
     422   [ -  +  #  # ]:        668 :                 DECR_LEN(dsize, len);
     423                 :            : 
     424                 :        668 :                 i -= len + 2;
     425                 :        668 :                 p += len + 2;
     426                 :            : 
     427                 :        668 :                 nentries++;
     428                 :            :         }
     429                 :            : 
     430         [ -  + ]:        451 :         if (dsize != 0)
     431         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     432                 :            : 
     433                 :            :         /* this is unnecessary - keeping to avoid a regression due to a re-org
     434                 :            :          * of the loop above */
     435         [ -  + ]:        451 :         if (nentries == 0)
     436         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     437                 :            : 
     438                 :        451 :         npeer_ocsp = 0;
     439                 :        451 :         npeer_certs = 0;
     440                 :            : 
     441                 :            :         /* Ok we now allocate the memory to hold the
     442                 :            :          * certificate list
     443                 :            :          */
     444                 :        451 :         peer_certs = gnutls_calloc(nentries, sizeof(gnutls_datum_t));
     445         [ -  + ]:        451 :         if (peer_certs == NULL)
     446         [ #  # ]:          0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     447                 :            : 
     448                 :        451 :         peer_ocsp = gnutls_calloc(nentries, sizeof(gnutls_datum_t));
     449         [ -  + ]:        451 :         if (peer_ocsp == NULL) {
     450         [ #  # ]:          0 :                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     451                 :          0 :                 goto cleanup;
     452                 :            :         }
     453                 :            : 
     454                 :        451 :         p = data+3;
     455                 :            : 
     456                 :            :         /* Now we start parsing the list (again).
     457                 :            :          * We don't use DECR_LEN since the list has
     458                 :            :          * been parsed before.
     459                 :            :          */
     460                 :            : 
     461                 :        451 :         ctx.session = session;
     462                 :            : 
     463         [ +  + ]:       1119 :         for (j = 0; j < nentries; j++) {
     464                 :        668 :                 len = _gnutls_read_uint24(p);
     465                 :        668 :                 p += 3;
     466                 :            : 
     467                 :        668 :                 ret = _gnutls_set_datum(&peer_certs[j], p, len);
     468         [ -  + ]:        668 :                 if (ret < 0) {
     469         [ #  # ]:          0 :                         gnutls_assert();
     470                 :          0 :                         ret = GNUTLS_E_CERTIFICATE_ERROR;
     471                 :          0 :                         goto cleanup;
     472                 :            :                 }
     473                 :        668 :                 npeer_certs++;
     474                 :            : 
     475                 :        668 :                 p += len;
     476                 :            : 
     477                 :        668 :                 len = _gnutls_read_uint16(p);
     478                 :            : 
     479                 :        668 :                 ctx.ocsp = &peer_ocsp[j];
     480                 :        668 :                 ctx.idx = j;
     481                 :            : 
     482                 :        668 :                 ret = _gnutls_extv_parse(&ctx, parse_cert_extension, p, len+2);
     483         [ -  + ]:        668 :                 if (ret < 0) {
     484         [ #  # ]:          0 :                         gnutls_assert();
     485                 :          0 :                         goto cleanup;
     486                 :            :                 }
     487                 :            : 
     488                 :        668 :                 p += len+2;
     489                 :        668 :                 npeer_ocsp++;
     490                 :            :         }
     491                 :            : 
     492                 :            :         /* The OCSP entries match the certificate entries, although
     493                 :            :          * the contents of each OCSP entry may be NULL.
     494                 :            :          */
     495         [ +  + ]:        472 :         for(j=0;j<info->ncerts;j++)
     496                 :         21 :                 gnutls_free(info->raw_certificate_list[j].data);
     497                 :        451 :         gnutls_free(info->raw_certificate_list);
     498                 :            : 
     499         [ +  + ]:        472 :         for(j=0;j<info->nocsp;j++)
     500                 :         21 :                 gnutls_free(info->raw_ocsp_list[j].data);
     501                 :        451 :         gnutls_free(info->raw_ocsp_list);
     502                 :            : 
     503                 :            : 
     504                 :        451 :         info->raw_certificate_list = peer_certs;
     505                 :        451 :         info->ncerts = npeer_certs;
     506                 :            : 
     507                 :        451 :         info->raw_ocsp_list = peer_ocsp;
     508                 :        451 :         info->nocsp = npeer_ocsp;
     509                 :            : 
     510                 :        451 :         return 0;
     511                 :            : 
     512                 :          0 :  cleanup:
     513         [ #  # ]:          0 :         for(j=0;j<npeer_certs;j++)
     514                 :          0 :                 gnutls_free(peer_certs[j].data);
     515                 :            : 
     516         [ #  # ]:          0 :         for(j=0;j<npeer_ocsp;j++)
     517                 :          0 :                 gnutls_free(peer_ocsp[j].data);
     518                 :          0 :         gnutls_free(peer_certs);
     519                 :          0 :         gnutls_free(peer_ocsp);
     520                 :          0 :         return ret;
     521                 :            : 
     522                 :            : }
     523                 :            : 

Generated by: LCOV version 1.13