aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls/auth_dh_common.c
diff options
context:
space:
mode:
authorlv-426 <oxcafebaby@yahoo.com>2008-06-22 18:20:35 +0000
committerlv-426 <oxcafebaby@yahoo.com>2008-06-22 18:20:35 +0000
commita0339d2458867dbe9485499265641ff205063445 (patch)
tree055b38828b3696520408a32edf81df5bb37400f0 /src/daemon/https/tls/auth_dh_common.c
parent97c026da05495b83f1511906c2ca027e12ef6cf7 (diff)
downloadlibmicrohttpd-a0339d2458867dbe9485499265641ff205063445.tar.gz
libmicrohttpd-a0339d2458867dbe9485499265641ff205063445.zip
initial GNU TLS import - this should reduce in size considerable
Diffstat (limited to 'src/daemon/https/tls/auth_dh_common.c')
-rw-r--r--src/daemon/https/tls/auth_dh_common.c369
1 files changed, 369 insertions, 0 deletions
diff --git a/src/daemon/https/tls/auth_dh_common.c b/src/daemon/https/tls/auth_dh_common.c
new file mode 100644
index 00000000..f1b82bf9
--- /dev/null
+++ b/src/daemon/https/tls/auth_dh_common.c
@@ -0,0 +1,369 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains common stuff in Ephemeral Diffie Hellman (DHE) and
26 * Anonymous DH key exchange(DHA). These are used in the handshake procedure
27 * of the certificate and anoymous authentication.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_errors.h"
33#include "gnutls_dh.h"
34#include "gnutls_num.h"
35#include "gnutls_sig.h"
36#include <gnutls_datum.h>
37#include <gnutls_x509.h>
38#include <gnutls_state.h>
39#include <auth_dh_common.h>
40#include <gnutls_algorithms.h>
41
42/* Frees the dh_info_st structure.
43 */
44void
45_gnutls_free_dh_info (dh_info_st * dh)
46{
47 dh->secret_bits = 0;
48 _gnutls_free_datum (&dh->prime);
49 _gnutls_free_datum (&dh->generator);
50 _gnutls_free_datum (&dh->public_key);
51}
52
53int
54_gnutls_proc_dh_common_client_kx (gnutls_session_t session,
55 opaque * data, size_t _data_size,
56 mpi_t g, mpi_t p)
57{
58 uint16_t n_Y;
59 size_t _n_Y;
60 int ret;
61 ssize_t data_size = _data_size;
62
63
64 DECR_LEN (data_size, 2);
65 n_Y = _gnutls_read_uint16 (&data[0]);
66 _n_Y = n_Y;
67
68 DECR_LEN (data_size, n_Y);
69 if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], &_n_Y))
70 {
71 gnutls_assert ();
72 return GNUTLS_E_MPI_SCAN_FAILED;
73 }
74
75 _gnutls_dh_set_peer_public (session, session->key->client_Y);
76
77 session->key->KEY =
78 gnutls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
79
80 if (session->key->KEY == NULL)
81 {
82 gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
84 }
85
86 _gnutls_mpi_release (&session->key->client_Y);
87 _gnutls_mpi_release (&session->key->dh_secret);
88
89
90 if (_gnutls_cipher_suite_get_kx_algo
91 (&session->security_parameters.current_cipher_suite)
92 != GNUTLS_KX_DHE_PSK)
93 {
94 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
95 }
96 /* In DHE_PSK the key is set differently
97 else
98 {
99 gnutls_datum_t tmp_dh_key;
100 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
101 if (ret < 0)
102 {
103 gnutls_assert ();
104 return ret;
105 }
106
107 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
108 _gnutls_free_datum (&tmp_dh_key);
109
110 }
111 */
112
113 _gnutls_mpi_release (&session->key->KEY);
114
115 if (ret < 0)
116 {
117 return ret;
118 }
119
120 return 0;
121}
122
123int
124_gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data)
125{
126 mpi_t x = NULL, X = NULL;
127 size_t n_X;
128 int ret;
129
130 *data = NULL;
131
132 X = gnutls_calc_dh_secret (&x, session->key->client_g,
133 session->key->client_p);
134 if (X == NULL || x == NULL)
135 {
136 gnutls_assert ();
137 ret = GNUTLS_E_MEMORY_ERROR;
138 goto error;
139 }
140
141 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
142
143 _gnutls_mpi_print (NULL, &n_X, X);
144 (*data) = gnutls_malloc (n_X + 2);
145 if (*data == NULL)
146 {
147 ret = GNUTLS_E_MEMORY_ERROR;
148 goto error;
149 }
150
151 _gnutls_mpi_print (&(*data)[2], &n_X, X);
152 _gnutls_mpi_release (&X);
153
154 _gnutls_write_uint16 (n_X, &(*data)[0]);
155
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);
159
160 _gnutls_mpi_release (&x);
161 if (session->key->KEY == NULL)
162 {
163 gnutls_assert ();
164 ret = GNUTLS_E_MEMORY_ERROR;
165 goto error;
166 }
167
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);
172
173 if (_gnutls_cipher_suite_get_kx_algo
174 (&session->security_parameters.current_cipher_suite)
175 != GNUTLS_KX_DHE_PSK)
176 {
177 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
178 }
179 /* In DHE_PSK the key is set differently
180 else
181 {
182 gnutls_datum_t tmp_dh_key;
183 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
184 if (ret < 0)
185 {
186 gnutls_assert ();
187 goto error;
188 }
189
190 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
191 _gnutls_free_datum (&tmp_dh_key);
192
193 }*/
194
195 _gnutls_mpi_release (&session->key->KEY);
196
197 if (ret < 0)
198 {
199 gnutls_assert ();
200 goto error;
201 }
202
203 return n_X + 2;
204
205error:
206 _gnutls_mpi_release (&x);
207 _gnutls_mpi_release (&X);
208 gnutls_free (*data);
209 *data = NULL;
210 return ret;
211}
212
213int
214_gnutls_proc_dh_common_server_kx (gnutls_session_t session,
215 opaque * data, size_t _data_size, int psk)
216{
217 uint16_t n_Y, n_g, n_p;
218 size_t _n_Y, _n_g, _n_p;
219 uint8_t *data_p;
220 uint8_t *data_g;
221 uint8_t *data_Y;
222 int i, bits, psk_size, ret;
223 ssize_t data_size = _data_size;
224
225 i = 0;
226
227 if (psk != 0)
228 {
229 DECR_LEN (data_size, 2);
230 psk_size = _gnutls_read_uint16 (&data[i]);
231 DECR_LEN (data_size, psk_size);
232 i += 2 + psk_size;
233 }
234
235 DECR_LEN (data_size, 2);
236 n_p = _gnutls_read_uint16 (&data[i]);
237 i += 2;
238
239 DECR_LEN (data_size, n_p);
240 data_p = &data[i];
241 i += n_p;
242
243 DECR_LEN (data_size, 2);
244 n_g = _gnutls_read_uint16 (&data[i]);
245 i += 2;
246
247 DECR_LEN (data_size, n_g);
248 data_g = &data[i];
249 i += n_g;
250
251 DECR_LEN (data_size, 2);
252 n_Y = _gnutls_read_uint16 (&data[i]);
253 i += 2;
254
255 DECR_LEN (data_size, n_Y);
256 data_Y = &data[i];
257 i += n_Y;
258
259 _n_Y = n_Y;
260 _n_g = n_g;
261 _n_p = n_p;
262
263 if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, &_n_Y) != 0)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_MPI_SCAN_FAILED;
267 }
268
269 if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, &_n_g) != 0)
270 {
271 gnutls_assert ();
272 return GNUTLS_E_MPI_SCAN_FAILED;
273 }
274 if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, &_n_p) != 0)
275 {
276 gnutls_assert ();
277 return GNUTLS_E_MPI_SCAN_FAILED;
278 }
279
280 bits = _gnutls_dh_get_allowed_prime_bits (session);
281 if (bits < 0)
282 {
283 gnutls_assert ();
284 return bits;
285 }
286
287 if (_gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
288 {
289 /* the prime used by the peer is not acceptable
290 */
291 gnutls_assert ();
292 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
293 }
294
295 _gnutls_dh_set_group (session, session->key->client_g,
296 session->key->client_p);
297 _gnutls_dh_set_peer_public (session, session->key->client_Y);
298
299 ret = n_Y + n_p + n_g + 6;
300 if (psk != 0)
301 ret += 2;
302
303 return ret;
304}
305
306/* If the psk flag is set, then an empty psk_identity_hint will
307 * be inserted */
308int
309_gnutls_dh_common_print_server_kx (gnutls_session_t session,
310 mpi_t g, mpi_t p, opaque ** data, int psk)
311{
312 mpi_t x, X;
313 size_t n_X, n_g, n_p;
314 int ret, data_size, pos;
315 uint8_t *pdata;
316
317 X = gnutls_calc_dh_secret (&x, g, p);
318 if (X == NULL || x == NULL)
319 {
320 gnutls_assert ();
321 return GNUTLS_E_MEMORY_ERROR;
322 }
323
324 session->key->dh_secret = x;
325 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
326
327 _gnutls_mpi_print (NULL, &n_g, g);
328 _gnutls_mpi_print (NULL, &n_p, p);
329 _gnutls_mpi_print (NULL, &n_X, X);
330
331 data_size = n_g + n_p + n_X + 6;
332 if (psk != 0)
333 data_size += 2;
334
335 (*data) = gnutls_malloc (data_size);
336 if (*data == NULL)
337 {
338 _gnutls_mpi_release (&X);
339 return GNUTLS_E_MEMORY_ERROR;
340 }
341
342 pos = 0;
343 pdata = *data;
344
345 if (psk != 0)
346 {
347 _gnutls_write_uint16 (0, &pdata[pos]);
348 pos += 2;
349 }
350
351 _gnutls_mpi_print (&pdata[pos + 2], &n_p, p);
352 _gnutls_write_uint16 (n_p, &pdata[pos]);
353
354 pos += n_p + 2;
355
356 _gnutls_mpi_print (&pdata[pos + 2], &n_g, g);
357 _gnutls_write_uint16 (n_g, &pdata[pos]);
358
359 pos += n_g + 2;
360
361 _gnutls_mpi_print (&pdata[pos + 2], &n_X, X);
362 _gnutls_mpi_release (&X);
363
364 _gnutls_write_uint16 (n_X, &pdata[pos]);
365
366 ret = data_size;
367
368 return ret;
369}