Remove.
[gnutls.git] / lib / auth_dh_common.c
blob17052bfb687d1d35b2a47ff400687ca417fba91d
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 library 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, &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;
124 _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data)
126 bigint_t x = NULL, X = NULL;
127 size_t n_X;
128 int ret;
130 *data = NULL;
132 X = gnutls_calc_dh_secret (&x, session->key->client_g,
133 session->key->client_p);
134 if (X == NULL || x == NULL)
136 gnutls_assert ();
137 ret = GNUTLS_E_MEMORY_ERROR;
138 goto error;
141 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
143 _gnutls_mpi_print (X, NULL, &n_X);
144 (*data) = gnutls_malloc (n_X + 2);
145 if (*data == NULL)
147 ret = GNUTLS_E_MEMORY_ERROR;
148 goto error;
151 _gnutls_mpi_print (X, &(*data)[2], &n_X);
152 _gnutls_mpi_release (&X);
154 _gnutls_write_uint16 (n_X, &(*data)[0]);
156 /* calculate the key after calculating the message */
157 session->key->KEY =
158 gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
160 _gnutls_mpi_release (&x);
161 if (session->key->KEY == NULL)
163 gnutls_assert ();
164 ret = GNUTLS_E_MEMORY_ERROR;
165 goto error;
168 /* THESE SHOULD BE DISCARDED */
169 _gnutls_mpi_release (&session->key->client_Y);
170 _gnutls_mpi_release (&session->key->client_p);
171 _gnutls_mpi_release (&session->key->client_g);
173 if (_gnutls_cipher_suite_get_kx_algo
174 (&session->security_parameters.current_cipher_suite)
175 != GNUTLS_KX_DHE_PSK)
177 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
179 else /* In DHE_PSK the key is set differently */
181 gnutls_datum_t tmp_dh_key;
182 ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key);
183 if (ret < 0)
185 gnutls_assert ();
186 goto error;
189 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
190 _gnutls_free_datum (&tmp_dh_key);
194 _gnutls_mpi_release (&session->key->KEY);
196 if (ret < 0)
198 gnutls_assert ();
199 goto error;
202 return n_X + 2;
204 error:
205 _gnutls_mpi_release (&x);
206 _gnutls_mpi_release (&X);
207 gnutls_free (*data);
208 *data = NULL;
209 return ret;
213 _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
214 opaque * data, size_t _data_size, int psk)
216 uint16_t n_Y, n_g, n_p;
217 size_t _n_Y, _n_g, _n_p;
218 uint8_t *data_p;
219 uint8_t *data_g;
220 uint8_t *data_Y;
221 int i, bits, psk_size, ret;
222 ssize_t data_size = _data_size;
224 i = 0;
226 if (psk != 0)
228 DECR_LEN (data_size, 2);
229 psk_size = _gnutls_read_uint16 (&data[i]);
230 DECR_LEN (data_size, psk_size);
231 i += 2 + psk_size;
234 DECR_LEN (data_size, 2);
235 n_p = _gnutls_read_uint16 (&data[i]);
236 i += 2;
238 DECR_LEN (data_size, n_p);
239 data_p = &data[i];
240 i += n_p;
242 DECR_LEN (data_size, 2);
243 n_g = _gnutls_read_uint16 (&data[i]);
244 i += 2;
246 DECR_LEN (data_size, n_g);
247 data_g = &data[i];
248 i += n_g;
250 DECR_LEN (data_size, 2);
251 n_Y = _gnutls_read_uint16 (&data[i]);
252 i += 2;
254 DECR_LEN (data_size, n_Y);
255 data_Y = &data[i];
256 i += n_Y;
258 _n_Y = n_Y;
259 _n_g = n_g;
260 _n_p = n_p;
262 if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, _n_Y) != 0)
264 gnutls_assert ();
265 return GNUTLS_E_MPI_SCAN_FAILED;
268 if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, _n_g) != 0)
270 gnutls_assert ();
271 return GNUTLS_E_MPI_SCAN_FAILED;
273 if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, _n_p) != 0)
275 gnutls_assert ();
276 return GNUTLS_E_MPI_SCAN_FAILED;
279 bits = _gnutls_dh_get_allowed_prime_bits (session);
280 if (bits < 0)
282 gnutls_assert ();
283 return bits;
286 if (_gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
288 /* the prime used by the peer is not acceptable
290 gnutls_assert ();
291 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
294 _gnutls_dh_set_group (session, session->key->client_g,
295 session->key->client_p);
296 _gnutls_dh_set_peer_public (session, session->key->client_Y);
298 ret = n_Y + n_p + n_g + 6;
299 if (psk != 0)
300 ret += 2;
302 return ret;
305 /* If the psk flag is set, then an empty psk_identity_hint will
306 * be inserted */
308 _gnutls_dh_common_print_server_kx (gnutls_session_t session,
309 bigint_t g, bigint_t p, opaque ** data,
310 int psk)
312 bigint_t x, X;
313 size_t n_X, n_g, n_p;
314 int ret, data_size, pos;
315 uint8_t *pdata;
317 X = gnutls_calc_dh_secret (&x, g, p);
318 if (X == NULL || x == NULL)
320 gnutls_assert ();
321 return GNUTLS_E_MEMORY_ERROR;
324 session->key->dh_secret = x;
325 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
327 _gnutls_mpi_print (g, NULL, &n_g);
328 _gnutls_mpi_print (p, NULL, &n_p);
329 _gnutls_mpi_print (X, NULL, &n_X);
331 data_size = n_g + n_p + n_X + 6;
332 if (psk != 0)
333 data_size += 2;
335 (*data) = gnutls_malloc (data_size);
336 if (*data == NULL)
338 _gnutls_mpi_release (&X);
339 return GNUTLS_E_MEMORY_ERROR;
342 pos = 0;
343 pdata = *data;
345 if (psk != 0)
347 _gnutls_write_uint16 (0, &pdata[pos]);
348 pos += 2;
351 _gnutls_mpi_print (p, &pdata[pos + 2], &n_p);
352 _gnutls_write_uint16 (n_p, &pdata[pos]);
354 pos += n_p + 2;
356 _gnutls_mpi_print (g, &pdata[pos + 2], &n_g);
357 _gnutls_write_uint16 (n_g, &pdata[pos]);
359 pos += n_g + 2;
361 _gnutls_mpi_print (X, &pdata[pos + 2], &n_X);
362 _gnutls_mpi_release (&X);
364 _gnutls_write_uint16 (n_X, &pdata[pos]);
366 ret = data_size;
368 return ret;