Version 1.7.10.
[gnutls.git] / lib / auth_dhe_psk.c
blob2586604ecae6d3422fdde42435cfc2a16dceddbd
1 /*
2 * Copyright (C) 2005 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
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.
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.
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
25 /* This file contains the PSK Diffie Hellman key exchange part of
26 * the PSK authentication. The functions here are used in the
27 * handshake.
30 #include <gnutls_int.h>
32 #ifdef ENABLE_PSK
34 #include "gnutls_auth_int.h"
35 #include "gnutls_errors.h"
36 #include "gnutls_dh.h"
37 #include "auth_psk.h"
38 #include "gnutls_num.h"
39 #include "gnutls_mpi.h"
40 #include <gnutls_state.h>
41 #include <auth_dh_common.h>
42 #include <gnutls_datum.h>
44 static int gen_psk_server_kx (gnutls_session_t, opaque **);
45 static int gen_psk_client_kx (gnutls_session_t, opaque **);
46 static int proc_psk_client_kx (gnutls_session_t, opaque *, size_t);
47 static int proc_psk_server_kx (gnutls_session_t, opaque *, size_t);
49 const mod_auth_st dhe_psk_auth_struct = {
50 "DHE PSK",
51 NULL,
52 NULL,
53 gen_psk_server_kx,
54 gen_psk_client_kx,
55 NULL,
56 NULL,
58 NULL,
59 NULL, /* certificate */
60 proc_psk_server_kx,
61 proc_psk_client_kx,
62 NULL,
63 NULL
66 static int
67 gen_psk_client_kx (gnutls_session_t session, opaque ** data)
69 int ret;
70 opaque *tmp_data = NULL;
71 int data_size, tmp_data_size;
72 gnutls_psk_client_credentials_t cred;
74 cred = (gnutls_psk_client_credentials_t)
75 _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL);
77 if (cred == NULL)
79 gnutls_assert ();
80 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
83 if (cred->username.data == NULL || cred->key.data == NULL)
85 gnutls_assert ();
86 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
89 /* The PSK key is set in there */
90 ret = _gnutls_gen_dh_common_client_kx (session, &tmp_data);
91 if (ret < 0)
93 gnutls_assert ();
94 return ret;
97 tmp_data_size = ret;
98 data_size = tmp_data_size + cred->username.size + 2;
100 (*data) = gnutls_malloc (data_size);
101 if ((*data) == NULL)
103 gnutls_assert ();
104 ret = GNUTLS_E_MEMORY_ERROR;
105 goto error;
108 _gnutls_write_datum16 (*data, cred->username);
109 memcpy (&(*data)[cred->username.size + 2], tmp_data, tmp_data_size);
111 ret = data_size;
113 error:
114 gnutls_free (tmp_data);
115 return ret;
119 static int
120 gen_psk_server_kx (gnutls_session_t session, opaque ** data)
122 mpi_t g, p;
123 const mpi_t *mpis;
124 int ret;
125 gnutls_dh_params_t dh_params;
126 gnutls_psk_server_credentials_t cred;
128 cred = (gnutls_psk_server_credentials_t)
129 _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL);
130 if (cred == NULL)
132 gnutls_assert ();
133 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
136 dh_params =
137 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
138 mpis = _gnutls_dh_params_to_mpi (dh_params);
139 if (mpis == NULL)
141 gnutls_assert ();
142 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
145 p = mpis[0];
146 g = mpis[1];
148 if ((ret =
149 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
150 sizeof (psk_auth_info_st), 1)) < 0)
152 gnutls_assert ();
153 return ret;
156 _gnutls_dh_set_group (session, g, p);
158 ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 1);
159 if (ret < 0)
161 gnutls_assert ();
164 return ret;
168 static int
169 proc_psk_client_kx (gnutls_session_t session, opaque * data,
170 size_t _data_size)
172 int bits;
173 int ret;
174 mpi_t p, g;
175 gnutls_dh_params_t dh_params;
176 const mpi_t *mpis;
177 gnutls_psk_server_credentials_t cred;
178 psk_auth_info_t info;
179 gnutls_datum username;
180 ssize_t data_size = _data_size;
182 cred = (gnutls_psk_server_credentials_t)
183 _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL);
185 if (cred == NULL)
187 gnutls_assert ();
188 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
191 bits = _gnutls_dh_get_allowed_prime_bits (session);
193 if ((ret =
194 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
195 sizeof (psk_auth_info_st), 1)) < 0)
197 gnutls_assert ();
198 return ret;
201 dh_params =
202 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
203 mpis = _gnutls_dh_params_to_mpi (dh_params);
204 if (mpis == NULL)
206 gnutls_assert ();
207 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
210 p = mpis[0];
211 g = mpis[1];
213 DECR_LEN (data_size, 2);
214 username.size = _gnutls_read_uint16 (&data[0]);
216 DECR_LEN (data_size, username.size);
218 username.data = &data[2];
220 /* copy the username to the auth info structures
222 info = _gnutls_get_auth_info (session);
224 if (username.size > MAX_SRP_USERNAME)
226 gnutls_assert ();
227 return GNUTLS_E_ILLEGAL_SRP_USERNAME;
230 memcpy (info->username, username.data, username.size);
231 info->username[username.size] = 0;
233 /* Adjust the data */
234 data += username.size + 2;
236 ret = _gnutls_proc_dh_common_client_kx (session, data, data_size, g, p);
238 return ret;
243 proc_psk_server_kx (gnutls_session_t session, opaque * data,
244 size_t _data_size)
247 int ret;
249 /* set auth_info */
250 if ((ret =
251 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
252 sizeof (psk_auth_info_st), 1)) < 0)
254 gnutls_assert ();
255 return ret;
258 ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 1);
259 if (ret < 0)
261 gnutls_assert ();
262 return ret;
265 return 0;
268 #endif /* ENABLE_PSK */