Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/ext/etm.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2014 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
/* This file contains the code for the Max Record Size TLS extension.
24
 */
25
26
#include "gnutls_int.h"
27
#include "errors.h"
28
#include "num.h"
29
#include <hello_ext.h>
30
#include <ext/etm.h>
31
32
static int _gnutls_ext_etm_recv_params(gnutls_session_t session,
33
               const uint8_t * data, size_t data_size);
34
static int _gnutls_ext_etm_send_params(gnutls_session_t session,
35
               gnutls_buffer_st * extdata);
36
37
const hello_ext_entry_st ext_mod_etm = {
38
  .name = "Encrypt-then-MAC",
39
  .tls_id = 22,
40
  .gid = GNUTLS_EXTENSION_ETM,
41
  .client_parse_point = GNUTLS_EXT_MANDATORY,
42
  .server_parse_point = GNUTLS_EXT_MANDATORY,
43
  .validity =
44
      GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_DTLS |
45
      GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO,
46
  .recv_func = _gnutls_ext_etm_recv_params,
47
  .send_func = _gnutls_ext_etm_send_params,
48
  .pack_func = NULL,
49
  .unpack_func = NULL,
50
  .deinit_func = NULL,
51
  .cannot_be_overriden = 1
52
};
53
54
/* 
55
 * In case of a server: if an EXT_MASTER_SECRET extension type is received then it
56
 * sets a flag into the session security parameters.
57
 *
58
 */
59
static int
60
_gnutls_ext_etm_recv_params(gnutls_session_t session,
61
          const uint8_t * data, size_t _data_size)
62
0
{
63
0
  ssize_t data_size = _data_size;
64
65
0
  if (data_size != 0) {
66
0
    return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
67
0
  }
68
69
0
  if (session->security_parameters.entity == GNUTLS_SERVER) {
70
0
    gnutls_ext_priv_data_t epriv;
71
72
0
    if (session->internals.no_etm != 0)
73
0
      return 0;
74
75
0
    epriv = (void *)(intptr_t) 1;
76
0
    _gnutls_hello_ext_set_priv(session,
77
0
             GNUTLS_EXTENSION_ETM, epriv);
78
79
    /* don't decide now, decide on send */
80
0
    return 0;
81
0
  } else {   /* client */
82
0
    const gnutls_cipher_suite_entry_st *e =
83
0
        session->security_parameters.cs;
84
0
    if (e != NULL) {
85
0
      const cipher_entry_st *c;
86
0
      c = cipher_to_entry(e->block_algorithm);
87
0
      if (c == NULL
88
0
          || (c->type == CIPHER_AEAD
89
0
        || c->type == CIPHER_STREAM))
90
0
        return 0;
91
92
0
      session->security_parameters.etm = 1;
93
0
    }
94
0
  }
95
96
0
  return 0;
97
0
}
98
99
/* returns data_size or a negative number on failure
100
 */
101
static int
102
_gnutls_ext_etm_send_params(gnutls_session_t session,
103
          gnutls_buffer_st * extdata)
104
0
{
105
0
  if (session->internals.no_etm != 0)
106
0
    return 0;
107
108
  /* this function sends the client extension data */
109
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
110
0
    if (session->internals.priorities->have_cbc != 0)
111
0
      return GNUTLS_E_INT_RET_0;
112
0
    else
113
0
      return 0;
114
0
  } else {   /* server side */
115
0
    const gnutls_cipher_suite_entry_st *e;
116
0
    const cipher_entry_st *c;
117
0
    int ret;
118
0
    gnutls_ext_priv_data_t epriv;
119
120
0
    e = session->security_parameters.cs;
121
0
    if (e != NULL) {
122
0
      c = cipher_to_entry(e->block_algorithm);
123
0
      if (c == NULL
124
0
          || (c->type == CIPHER_AEAD
125
0
        || c->type == CIPHER_STREAM))
126
0
        return 0;
127
128
0
      ret = _gnutls_hello_ext_get_priv(session,
129
0
               GNUTLS_EXTENSION_ETM,
130
0
               &epriv);
131
0
      if (ret < 0 || ((intptr_t) epriv) == 0)
132
0
        return 0;
133
134
0
      session->security_parameters.etm = 1;
135
0
      return GNUTLS_E_INT_RET_0;
136
0
    }
137
0
  }
138
139
0
  return 0;
140
0
}
141
142
/**
143
 * gnutls_session_etm_status:
144
 * @session: is a #gnutls_session_t type.
145
 *
146
 * Get the status of the encrypt-then-mac extension negotiation.
147
 * This is in accordance to rfc7366
148
 *
149
 * Returns: Non-zero if the negotiation was successful or zero otherwise.
150
 **/
151
unsigned gnutls_session_etm_status(gnutls_session_t session)
152
0
{
153
0
  return session->security_parameters.etm;
154
0
}