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' |
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 | |
39 | static int _gnutls_supported_ecc_recv_params (gnutls_session_t session, |
40 | const opaque * data, |
41 | size_t data_size); |
42 | static int _gnutls_supported_ecc_send_params (gnutls_session_t session, |
43 | gnutls_buffer_st * extdata); |
44 | |
45 | static int _gnutls_supported_ecc_pf_recv_params (gnutls_session_t session, |
46 | const opaque * data, |
47 | size_t data_size); |
48 | static int _gnutls_supported_ecc_pf_send_params (gnutls_session_t session, |
49 | gnutls_buffer_st * extdata); |
50 | |
51 | extension_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 | |
63 | extension_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 | */ |
83 | static 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 | */ |
152 | static 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 | */ |
199 | static int |
200 | _gnutls_supported_ecc_pf_recv_params (gnutls_session_t session, |
201 | const opaque * data, size_t _data_size) |
202 | { |
203 | int len, i; |
204 | int uncompressed = 0; |
205 | int 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 | */ |
236 | static 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 | */ |
256 | int |
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 | } |