File: | lib/auth/rsa.c |
Location: | line 117, column 7 |
Description: | Value stored to 'ret' is never read |
1 | /* |
2 | * Copyright (C) 2000-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 RSA key exchange part of the certificate |
24 | * authentication. |
25 | */ |
26 | |
27 | #include "gnutls_int.h" |
28 | #include "gnutls_auth.h" |
29 | #include "gnutls_errors.h" |
30 | #include "gnutls_dh.h" |
31 | #include "gnutls_num.h" |
32 | #include "gnutls_datum.h" |
33 | #include <auth/cert.h> |
34 | #include <gnutls_pk.h> |
35 | #include <algorithms.h> |
36 | #include <gnutls_global.h> |
37 | #include "debug.h" |
38 | #include <gnutls_sig.h> |
39 | #include <gnutls_x509.h> |
40 | #include <random.h> |
41 | #include <gnutls_mpi.h> |
42 | #include <abstract_int.h> |
43 | |
44 | int _gnutls_gen_rsa_client_kx (gnutls_session_t, gnutls_buffer_st*); |
45 | static int proc_rsa_client_kx (gnutls_session_t, opaque *, size_t); |
46 | |
47 | const mod_auth_st rsa_auth_struct = { |
48 | "RSA", |
49 | _gnutls_gen_cert_server_certificate, |
50 | _gnutls_gen_cert_client_certificate, |
51 | NULL((void*)0), /* gen server kx */ |
52 | _gnutls_gen_rsa_client_kx, |
53 | _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */ |
54 | _gnutls_gen_cert_server_cert_req, /* server cert request */ |
55 | |
56 | _gnutls_proc_certificate, |
57 | _gnutls_proc_certificate, |
58 | NULL((void*)0), /* proc server kx */ |
59 | proc_rsa_client_kx, /* proc client kx */ |
60 | _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */ |
61 | _gnutls_proc_cert_cert_req /* proc server cert request */ |
62 | }; |
63 | |
64 | /* This function reads the RSA parameters from peer's certificate; |
65 | */ |
66 | static int |
67 | _gnutls_get_public_rsa_params (gnutls_session_t session, |
68 | gnutls_pk_params_st * params) |
69 | { |
70 | int ret; |
71 | cert_auth_info_t info; |
72 | gnutls_pcert_st peer_cert; |
73 | int i; |
74 | |
75 | /* normal non export case */ |
76 | |
77 | info = _gnutls_get_auth_info (session); |
78 | |
79 | if (info == NULL((void*)0) || info->ncerts == 0) |
80 | { |
81 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",81); } while(0);; |
82 | return GNUTLS_E_INTERNAL_ERROR-59; |
83 | } |
84 | |
85 | ret = |
86 | _gnutls_get_auth_info_pcert (&peer_cert, |
87 | session->security_parameters.cert_type, |
88 | info); |
89 | |
90 | if (ret < 0) |
91 | { |
92 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",92); } while(0);; |
93 | return ret; |
94 | } |
95 | |
96 | gnutls_pk_params_init(params); |
97 | params->params_nr = RSA_PUBLIC_PARAMS2; |
98 | |
99 | /* EXPORT case: */ |
100 | if (_gnutls_cipher_suite_get_kx_algo |
101 | (session->security_parameters.cipher_suite) == |
102 | GNUTLS_KX_RSA_EXPORT && |
103 | _gnutls_pubkey_is_over_rsa_512(peer_cert.pubkey) == 0) |
104 | { |
105 | if (session->key->rsa[0] == NULL((void*)0) || session->key->rsa[1] == NULL((void*)0)) |
106 | { |
107 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",107); } while(0);; |
108 | ret = GNUTLS_E_INTERNAL_ERROR-59; |
109 | goto cleanup; |
110 | } |
111 | |
112 | for (i = 0; i < params->params_nr; i++) |
113 | { |
114 | params->params[i] = _gnutls_mpi_copy (session->key->rsa[i])_gnutls_mpi_ops.bigint_set(((void*)0),session->key->rsa [i]); |
115 | } |
116 | |
117 | ret = 0; |
Value stored to 'ret' is never read | |
118 | goto cleanup; |
119 | } |
120 | |
121 | ret = _gnutls_pubkey_get_mpis(peer_cert.pubkey, params); |
122 | if (ret < 0) |
123 | { |
124 | ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "rsa.c", 124); |
125 | goto cleanup; |
126 | } |
127 | |
128 | ret = 0; |
129 | |
130 | cleanup: |
131 | gnutls_pcert_deinit (&peer_cert); |
132 | |
133 | return 0; |
134 | } |
135 | |
136 | static int |
137 | proc_rsa_client_kx (gnutls_session_t session, opaque * data, |
138 | size_t _data_size) |
139 | { |
140 | gnutls_datum_t plaintext; |
141 | gnutls_datum_t ciphertext; |
142 | int ret, dsize; |
143 | int randomize_key = 0; |
144 | ssize_t data_size = _data_size; |
145 | |
146 | if (gnutls_protocol_get_version_gnutls_protocol_get_version (session) == GNUTLS_SSL3) |
147 | { |
148 | /* SSL 3.0 |
149 | */ |
150 | ciphertext.data = data; |
151 | ciphertext.size = data_size; |
152 | } |
153 | else |
154 | { |
155 | /* TLS 1.0 |
156 | */ |
157 | 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" , "rsa.c",157); } while(0);; return -9;} } while (0); |
158 | ciphertext.data = &data[2]; |
159 | dsize = _gnutls_read_uint16 (data); |
160 | |
161 | if (dsize != data_size) |
162 | { |
163 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",163); } while(0);; |
164 | return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9; |
165 | } |
166 | ciphertext.size = dsize; |
167 | } |
168 | |
169 | ret = |
170 | gnutls_privkey_decrypt_data (session->internals.selected_key, 0, |
171 | &ciphertext, &plaintext); |
172 | |
173 | if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE48) |
174 | { |
175 | /* In case decryption fails then don't inform |
176 | * the peer. Just use a random key. (in order to avoid |
177 | * attack against pkcs-1 formating). |
178 | */ |
179 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",179); } while(0);; |
180 | _gnutls_audit_log (session, "auth_rsa: Possible PKCS #1 format attack\n"); |
181 | randomize_key = 1; |
182 | } |
183 | else |
184 | { |
185 | /* If the secret was properly formatted, then |
186 | * check the version number. |
187 | */ |
188 | if (_gnutls_get_adv_version_major (session)session->internals.adv_version_major != plaintext.data[0] |
189 | || _gnutls_get_adv_version_minor (session)session->internals.adv_version_minor != plaintext.data[1]) |
190 | { |
191 | /* No error is returned here, if the version number check |
192 | * fails. We proceed normally. |
193 | * That is to defend against the attack described in the paper |
194 | * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima, |
195 | * Ondej Pokorny and Tomas Rosa. |
196 | */ |
197 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",197); } while(0);; |
198 | _gnutls_audit_log |
199 | (session, "auth_rsa: Possible PKCS #1 version check format attack\n"); |
200 | } |
201 | } |
202 | |
203 | if (randomize_key != 0) |
204 | { |
205 | session->key->key.size = GNUTLS_MASTER_SIZE48; |
206 | session->key->key.data = gnutls_malloc (session->key->key.size); |
207 | if (session->key->key.data == NULL((void*)0)) |
208 | { |
209 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",209); } while(0);; |
210 | return GNUTLS_E_MEMORY_ERROR-25; |
211 | } |
212 | |
213 | /* we do not need strong random numbers here. |
214 | */ |
215 | ret = _gnutls_rnd (GNUTLS_RND_NONCE, session->key->key.data, |
216 | session->key->key.size); |
217 | if (ret < 0) |
218 | { |
219 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",219); } while(0);; |
220 | return ret; |
221 | } |
222 | |
223 | } |
224 | else |
225 | { |
226 | session->key->key.data = plaintext.data; |
227 | session->key->key.size = plaintext.size; |
228 | } |
229 | |
230 | /* This is here to avoid the version check attack |
231 | * discussed above. |
232 | */ |
233 | session->key->key.data[0] = _gnutls_get_adv_version_major (session)session->internals.adv_version_major; |
234 | session->key->key.data[1] = _gnutls_get_adv_version_minor (session)session->internals.adv_version_minor; |
235 | |
236 | return 0; |
237 | } |
238 | |
239 | |
240 | |
241 | /* return RSA(random) using the peers public key |
242 | */ |
243 | int |
244 | _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) |
245 | { |
246 | cert_auth_info_t auth = session->key->auth_info; |
247 | gnutls_datum_t sdata; /* data to send */ |
248 | gnutls_pk_params_st params; |
249 | int ret; |
250 | gnutls_protocol_t ver; |
251 | |
252 | if (auth == NULL((void*)0)) |
253 | { |
254 | /* this shouldn't have happened. The proc_certificate |
255 | * function should have detected that. |
256 | */ |
257 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",257); } while(0);; |
258 | return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32; |
259 | } |
260 | |
261 | session->key->key.size = GNUTLS_MASTER_SIZE48; |
262 | session->key->key.data = gnutls_malloc (session->key->key.size); |
263 | |
264 | if (session->key->key.data == NULL((void*)0)) |
265 | { |
266 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",266); } while(0);; |
267 | return GNUTLS_E_MEMORY_ERROR-25; |
268 | } |
269 | |
270 | ret = _gnutls_rnd (GNUTLS_RND_RANDOM, session->key->key.data, |
271 | session->key->key.size); |
272 | if (ret < 0) |
273 | { |
274 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",274); } while(0);; |
275 | return ret; |
276 | } |
277 | |
278 | ver = _gnutls_get_adv_version (session); |
279 | |
280 | if (session->internals.rsa_pms_version[0] == 0) |
281 | { |
282 | session->key->key.data[0] = _gnutls_version_get_major (ver); |
283 | session->key->key.data[1] = _gnutls_version_get_minor (ver); |
284 | } |
285 | else |
286 | { /* use the version provided */ |
287 | session->key->key.data[0] = session->internals.rsa_pms_version[0]; |
288 | session->key->key.data[1] = session->internals.rsa_pms_version[1]; |
289 | } |
290 | |
291 | /* move RSA parameters to key (session). |
292 | */ |
293 | if ((ret = |
294 | _gnutls_get_public_rsa_params (session, ¶ms)) < 0) |
295 | { |
296 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "rsa.c",296); } while(0);; |
297 | return ret; |
298 | } |
299 | |
300 | ret = |
301 | _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key, |
302 | ¶ms, 2); |
303 | |
304 | gnutls_pk_params_release(¶ms); |
305 | |
306 | if (ret < 0) |
307 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "rsa.c", 307); |
308 | |
309 | |
310 | if (gnutls_protocol_get_version_gnutls_protocol_get_version (session) == GNUTLS_SSL3) |
311 | { |
312 | /* SSL 3.0 */ |
313 | _gnutls_buffer_replace_data( data, &sdata); |
314 | |
315 | return data->length; |
316 | } |
317 | else |
318 | { /* TLS 1 */ |
319 | ret = _gnutls_buffer_append_data_prefix( data, 16, sdata.data, sdata.size); |
320 | |
321 | _gnutls_free_datum (&sdata)_gnutls_free_datum_m(&sdata, gnutls_free); |
322 | return ret; |
323 | } |
324 | |
325 | } |