Bug Summary

File:lib/ext/ecc.c
Location:line 116, column 16
Description:Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'

Annotated Source Code

1/*
2 * Copyright (C) 2011-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 3 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 <http://www.gnu.org/licenses/>
20 *
21 */
22
23/* This file contains the code the Certificate Type TLS extension.
24 * This extension is currently gnutls specific.
25 */
26
27#include "gnutls_int.h"
28#include "gnutls_errors.h"
29#include "gnutls_num.h"
30#include <ext/ecc.h>
31#include <gnutls_state.h>
32#include <gnutls_num.h>
33#include <algorithms.h>
34
35/* Maps record size to numbers according to the
36 * extensions draft.
37 */
38
39static int _gnutls_supported_ecc_recv_params (gnutls_session_t session,
40 const opaque * data,
41 size_t data_size);
42static int _gnutls_supported_ecc_send_params (gnutls_session_t session,
43 gnutls_buffer_st * extdata);
44
45static int _gnutls_supported_ecc_pf_recv_params (gnutls_session_t session,
46 const opaque * data,
47 size_t data_size);
48static int _gnutls_supported_ecc_pf_send_params (gnutls_session_t session,
49 gnutls_buffer_st * extdata);
50
51extension_entry_st ext_mod_supported_ecc = {
52 .name = "SUPPORTED ECC",
53 .type = GNUTLS_EXTENSION_SUPPORTED_ECC,
54 .parse_type = GNUTLS_EXT_TLS,
55
56 .recv_func = _gnutls_supported_ecc_recv_params,
57 .send_func = _gnutls_supported_ecc_send_params,
58 .pack_func = NULL((void*)0),
59 .unpack_func = NULL((void*)0),
60 .deinit_func = NULL((void*)0)
61};
62
63extension_entry_st ext_mod_supported_ecc_pf = {
64 .name = "SUPPORTED ECC POINT FORMATS",
65 .type = GNUTLS_EXTENSION_SUPPORTED_ECC_PF,
66 .parse_type = GNUTLS_EXT_TLS,
67
68 .recv_func = _gnutls_supported_ecc_pf_recv_params,
69 .send_func = _gnutls_supported_ecc_pf_send_params,
70 .pack_func = NULL((void*)0),
71 .unpack_func = NULL((void*)0),
72 .deinit_func = NULL((void*)0)
73};
74
75/*
76 * In case of a server: if a SUPPORTED_ECC extension type is received then it stores
77 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
78 * to access it.
79 *
80 * In case of a client: If a supported_eccs have been specified then we send the extension.
81 *
82 */
83static int
84_gnutls_supported_ecc_recv_params (gnutls_session_t session,
85 const opaque * data, size_t _data_size)
86{
87 int new_type = -1, ret, i;
88 ssize_t data_size = _data_size;
89 uint16_t len;
90 const opaque* p = data;
91
92 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
93 {
94 /* A client shouldn't receive this extension */
95 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)gnutls_assert_val_int(-58, "ecc.c", 95);
96 }
97 else
98 { /* SERVER SIDE - we must check if the sent supported ecc type is the right one
99 */
100 if (data_size < 2)
101 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)gnutls_assert_val_int(-58, "ecc.c", 101);
102
103 DECR_LEN (data_size, 2)do { data_size-=2; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "ecc.c",103); } while(0);; return -9;} } while (0)
;
104 len = _gnutls_read_uint16(p);
105 p += 2;
106
107 DECR_LEN (data_size, len)do { data_size-=len; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "ecc.c",107); } while(0);; return -9;} } while (0)
;
108
109 for (i = 0; i < len; i+=2)
110 {
111 new_type = _gnutls_tls_id_to_ecc_curve (_gnutls_read_uint16(&p[i]));
112 if (new_type < 0)
113 continue;
114
115 /* Check if we support this supported_ecc */
116 if ((ret =
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'
117 _gnutls_session_supports_ecc_curve (session, new_type)) < 0)
118 {
119 continue;
120 }
121 else
122 break;
123 /* new_type is ok */
124 }
125
126 if (new_type < 0)
127 {
128 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "ecc.c",128); } while(0);
;
129 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER-55;
130 }
131
132 if ((ret =
133 _gnutls_session_supports_ecc_curve (session, new_type)) < 0)
134 {
135 /* The peer has requested unsupported ecc
136 * types. Instead of failing, procceed normally.
137 * (the ciphersuite selection would fail, or a
138 * non certificate ciphersuite will be selected).
139 */
140 return gnutls_assert_val(0)gnutls_assert_val_int(0, "ecc.c", 140);
141 }
142
143 _gnutls_session_ecc_curve_set (session, new_type);
144 }
145
146 return 0;
147}
148
149
150/* returns data_size or a negative number on failure
151 */
152static int
153_gnutls_supported_ecc_send_params (gnutls_session_t session, gnutls_buffer_st* extdata)
154{
155 unsigned len, i;
156 int ret;
157 uint16_t p;
158
159 /* this extension is only being sent on client side */
160 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
161 {
162
163 if (session->internals.priorities.supported_ecc.algorithms > 0)
164 {
165
166 len = session->internals.priorities.supported_ecc.algorithms;
167
168 /* this is a vector!
169 */
170 ret = _gnutls_buffer_append_prefix(extdata, 16, len*2);
171 if (ret < 0)
172 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "ecc.c", 172);
173
174 for (i = 0; i < len; i++)
175 {
176 p =
177 _gnutls_ecc_curve_get_tls_id (session->internals.priorities.
178 supported_ecc.priority[i]);
179 ret = _gnutls_buffer_append_prefix(extdata, 16, p);
180 if (ret < 0)
181 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "ecc.c", 181);
182 }
183 return (len + 1)*2;
184 }
185
186 }
187
188 return 0;
189}
190
191/*
192 * In case of a server: if a SUPPORTED_ECC extension type is received then it stores
193 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
194 * to access it.
195 *
196 * In case of a client: If a supported_eccs have been specified then we send the extension.
197 *
198 */
199static int
200_gnutls_supported_ecc_pf_recv_params (gnutls_session_t session,
201 const opaque * data, size_t _data_size)
202{
203int len, i;
204int uncompressed = 0;
205int data_size = _data_size;
206
207 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
208 {
209 if (data_size < 1)
210 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)gnutls_assert_val_int(-58, "ecc.c", 210);
211
212 len = data[0];
213 DECR_LEN (data_size, len+1)do { data_size-=len+1; if (data_size<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "ecc.c",213); } while(0);; return -9;} } while (0)
;
214
215 for (i=1;i<=len;i++)
216 if (data[i] == 0) /* uncompressed */
217 uncompressed = 1;
218
219 if (uncompressed == 0)
220 return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM)gnutls_assert_val_int(-80, "ecc.c", 220);
221 }
222 else
223 {
224 /* only sanity check here. We only support uncompressed points
225 * and a client must support it thus nothing to check.
226 */
227 if (_data_size < 1)
228 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)gnutls_assert_val_int(-58, "ecc.c", 228);
229 }
230
231 return 0;
232}
233
234/* returns data_size or a negative number on failure
235 */
236static int
237_gnutls_supported_ecc_pf_send_params (gnutls_session_t session, gnutls_buffer_st* extdata)
238{
239 const opaque p[2] = {0x01, 0x00}; /* only support uncompressed point format */
240
241 if (session->security_parameters.entity == GNUTLS_SERVER1 && !_gnutls_session_is_ecc(session))
242 return 0;
243
244 if (session->internals.priorities.supported_ecc.algorithms > 0)
245 {
246 _gnutls_buffer_append_data(extdata, p, 2);
247 return 2;
248 }
249 return 0;
250}
251
252
253/* Returns 0 if the given ECC curve is allowed in the current
254 * session. A negative error value is returned otherwise.
255 */
256int
257_gnutls_session_supports_ecc_curve (gnutls_session_t session, int ecc_type)
258{
259 unsigned i;
260
261 if (session->internals.priorities.supported_ecc.algorithms > 0)
262 {
263 for (i = 0; i < session->internals.priorities.supported_ecc.algorithms; i++)
264 {
265 if (session->internals.priorities.supported_ecc.priority[i] == ecc_type)
266 return 0;
267 }
268 }
269
270 return GNUTLS_E_ECC_UNSUPPORTED_CURVE-322;
271}