combined more tests with eagain-common.h.
[gnutls.git] / lib / auth_dh_common.c
blobea9062c5cf012b020f3e2977434b86b3bf4d586c
1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009, 2010 Free Software
3 * Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* This file contains common stuff in Ephemeral Diffie-Hellman (DHE)
27 * and Anonymous DH key exchange(DHA). These are used in the handshake
28 * procedure of the certificate and anoymous authentication.
31 #include "gnutls_int.h"
32 #include "gnutls_auth.h"
33 #include "gnutls_errors.h"
34 #include "gnutls_dh.h"
35 #include "gnutls_num.h"
36 #include "gnutls_sig.h"
37 #include <gnutls_datum.h>
38 #include <gnutls_x509.h>
39 #include <gnutls_state.h>
40 #include <auth_dh_common.h>
41 #include <gnutls_algorithms.h>
42 #include <auth_psk.h>
44 /* Frees the dh_info_st structure.
46 void
47 _gnutls_free_dh_info (dh_info_st * dh)
49 dh->secret_bits = 0;
50 _gnutls_free_datum (&dh->prime);
51 _gnutls_free_datum (&dh->generator);
52 _gnutls_free_datum (&dh->public_key);
55 int
56 _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
57 opaque * data, size_t _data_size,
58 bigint_t g, bigint_t p)
60 uint16_t n_Y;
61 size_t _n_Y;
62 int ret;
63 ssize_t data_size = _data_size;
66 DECR_LEN (data_size, 2);
67 n_Y = _gnutls_read_uint16 (&data[0]);
68 _n_Y = n_Y;
70 DECR_LEN (data_size, n_Y);
71 if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], _n_Y))
73 gnutls_assert ();
74 return GNUTLS_E_MPI_SCAN_FAILED;
77 _gnutls_dh_set_peer_public (session, session->key->client_Y);
79 session->key->KEY =
80 gnutls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
82 if (session->key->KEY == NULL)
84 gnutls_assert ();
85 return GNUTLS_E_MEMORY_ERROR;
88 _gnutls_mpi_release (&session->key->client_Y);
89 _gnutls_mpi_release (&session->key->dh_secret);
92 if (_gnutls_cipher_suite_get_kx_algo
93 (&session->security_parameters.current_cipher_suite)
94 != GNUTLS_KX_DHE_PSK)
96 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
98 else /* In DHE_PSK the key is set differently */
100 gnutls_datum_t tmp_dh_key;
101 ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key);
102 if (ret < 0)
104 gnutls_assert ();
105 return ret;
108 ret = _gnutls_set_psk_session_key (session, NULL, &tmp_dh_key);
109 _gnutls_free_datum (&tmp_dh_key);
113 _gnutls_mpi_release (&session->key->KEY);
115 if (ret < 0)
117 return ret;
120 return 0;
123 int _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque** data)
125 return _gnutls_gen_dh_common_client_kx_int(session, data, NULL);
129 _gnutls_gen_dh_common_client_kx_int (gnutls_session_t session, opaque ** data, gnutls_datum_t* pskkey)
131 bigint_t x = NULL, X = NULL;
132 size_t n_X;
133 int ret;
135 *data = NULL;
137 X = gnutls_calc_dh_secret (&x, session->key->client_g,
138 session->key->client_p);
139 if (X == NULL || x == NULL)
141 gnutls_assert ();
142 ret = GNUTLS_E_MEMORY_ERROR;
143 goto error;
146 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
148 _gnutls_mpi_print (X, NULL, &n_X);
149 (*data) = gnutls_malloc (n_X + 2);
150 if (*data == NULL)
152 ret = GNUTLS_E_MEMORY_ERROR;
153 goto error;
156 _gnutls_mpi_print (X, &(*data)[2], &n_X);
157 _gnutls_mpi_release (&X);
159 _gnutls_write_uint16 (n_X, &(*data)[0]);
161 /* calculate the key after calculating the message */
162 session->key->KEY =
163 gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
165 if (session->key->KEY == NULL)
167 gnutls_assert ();
168 ret = GNUTLS_E_MEMORY_ERROR;
169 goto error;
172 /* THESE SHOULD BE DISCARDED */
173 _gnutls_mpi_release (&session->key->client_Y);
174 _gnutls_mpi_release (&session->key->client_p);
175 _gnutls_mpi_release (&session->key->client_g);
177 if (_gnutls_cipher_suite_get_kx_algo
178 (&session->security_parameters.current_cipher_suite)
179 != GNUTLS_KX_DHE_PSK)
181 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
183 else /* In DHE_PSK the key is set differently */
185 gnutls_datum_t tmp_dh_key;
187 ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key);
188 if (ret < 0)
190 gnutls_assert ();
191 goto error;
194 ret = _gnutls_set_psk_session_key (session, pskkey, &tmp_dh_key);
195 _gnutls_free_datum (&tmp_dh_key);
198 _gnutls_mpi_release (&session->key->KEY);
200 if (ret < 0)
202 gnutls_assert ();
203 goto error;
206 ret = n_X + 2;
208 error:
209 _gnutls_mpi_release (&x);
210 _gnutls_mpi_release (&X);
211 gnutls_free (*data);
212 *data = NULL;
213 return ret;
217 _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
218 opaque * data, size_t _data_size, int psk)
220 uint16_t n_Y, n_g, n_p;
221 size_t _n_Y, _n_g, _n_p;
222 uint8_t *data_p;
223 uint8_t *data_g;
224 uint8_t *data_Y;
225 int i, bits, psk_size, ret;
226 ssize_t data_size = _data_size;
228 i = 0;
230 if (psk != 0)
232 DECR_LEN (data_size, 2);
233 psk_size = _gnutls_read_uint16 (&data[i]);
234 DECR_LEN (data_size, psk_size);
235 i += 2 + psk_size;
238 DECR_LEN (data_size, 2);
239 n_p = _gnutls_read_uint16 (&data[i]);
240 i += 2;
242 DECR_LEN (data_size, n_p);
243 data_p = &data[i];
244 i += n_p;
246 DECR_LEN (data_size, 2);
247 n_g = _gnutls_read_uint16 (&data[i]);
248 i += 2;
250 DECR_LEN (data_size, n_g);
251 data_g = &data[i];
252 i += n_g;
254 DECR_LEN (data_size, 2);
255 n_Y = _gnutls_read_uint16 (&data[i]);
256 i += 2;
258 DECR_LEN (data_size, n_Y);
259 data_Y = &data[i];
260 i += n_Y;
262 _n_Y = n_Y;
263 _n_g = n_g;
264 _n_p = n_p;
266 if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, _n_Y) != 0)
268 gnutls_assert ();
269 return GNUTLS_E_MPI_SCAN_FAILED;
272 if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, _n_g) != 0)
274 gnutls_assert ();
275 return GNUTLS_E_MPI_SCAN_FAILED;
277 if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, _n_p) != 0)
279 gnutls_assert ();
280 return GNUTLS_E_MPI_SCAN_FAILED;
283 bits = _gnutls_dh_get_allowed_prime_bits (session);
284 if (bits < 0)
286 gnutls_assert ();
287 return bits;
290 if (_gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
292 /* the prime used by the peer is not acceptable
294 gnutls_assert ();
295 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
298 _gnutls_dh_set_group (session, session->key->client_g,
299 session->key->client_p);
300 _gnutls_dh_set_peer_public (session, session->key->client_Y);
302 ret = n_Y + n_p + n_g + 6;
303 if (psk != 0)
304 ret += 2;
306 return ret;
309 /* If the psk flag is set, then an empty psk_identity_hint will
310 * be inserted */
312 _gnutls_dh_common_print_server_kx (gnutls_session_t session,
313 bigint_t g, bigint_t p, opaque ** data,
314 int psk)
316 bigint_t x, X;
317 size_t n_X, n_g, n_p;
318 int ret, data_size, pos;
319 uint8_t *pdata;
321 X = gnutls_calc_dh_secret (&x, g, p);
322 if (X == NULL || x == NULL)
324 gnutls_assert ();
325 return GNUTLS_E_MEMORY_ERROR;
328 session->key->dh_secret = x;
329 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
331 _gnutls_mpi_print (g, NULL, &n_g);
332 _gnutls_mpi_print (p, NULL, &n_p);
333 _gnutls_mpi_print (X, NULL, &n_X);
335 data_size = n_g + n_p + n_X + 6;
336 if (psk != 0)
337 data_size += 2;
339 (*data) = gnutls_malloc (data_size);
340 if (*data == NULL)
342 _gnutls_mpi_release (&X);
343 return GNUTLS_E_MEMORY_ERROR;
346 pos = 0;
347 pdata = *data;
349 if (psk != 0)
351 _gnutls_write_uint16 (0, &pdata[pos]);
352 pos += 2;
355 _gnutls_mpi_print (p, &pdata[pos + 2], &n_p);
356 _gnutls_write_uint16 (n_p, &pdata[pos]);
358 pos += n_p + 2;
360 _gnutls_mpi_print (g, &pdata[pos + 2], &n_g);
361 _gnutls_write_uint16 (n_g, &pdata[pos]);
363 pos += n_g + 2;
365 _gnutls_mpi_print (X, &pdata[pos + 2], &n_X);
366 _gnutls_mpi_release (&X);
368 _gnutls_write_uint16 (n_X, &pdata[pos]);
370 /* do not use data_size. _gnutls_mpi_print() might
371 * have been pessimist and might have returned initially
372 * more data */
373 ret = n_g + n_p + n_X + 6;
374 if (psk != 0)
375 ret += 2;
377 return ret;