corrected copyright notices
[gnutls.git] / lib / ext / srp.c
blobc9fad8dbdf172e1942d168fbdabfa55b9796b9f7
1 /*
2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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.
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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <ext/srp.h>
26 #ifdef ENABLE_SRP
28 #include "gnutls_auth.h"
29 #include <auth/srp.h>
30 #include "gnutls_errors.h"
31 #include "algorithms.h"
32 #include <gnutls_num.h>
33 #include <gnutls_extensions.h>
35 static int _gnutls_srp_unpack (gnutls_buffer_st * ps,
36 extension_priv_data_t * _priv);
37 static int _gnutls_srp_pack (extension_priv_data_t epriv,
38 gnutls_buffer_st * ps);
39 static void _gnutls_srp_deinit_data (extension_priv_data_t epriv);
40 static int _gnutls_srp_recv_params (gnutls_session_t state,
41 const uint8_t * data, size_t data_size);
42 static int _gnutls_srp_send_params (gnutls_session_t state, gnutls_buffer_st * extdata);
44 extension_entry_st ext_mod_srp = {
45 .name = "SRP",
46 .type = GNUTLS_EXTENSION_SRP,
47 .parse_type = GNUTLS_EXT_TLS,
49 .recv_func = _gnutls_srp_recv_params,
50 .send_func = _gnutls_srp_send_params,
51 .pack_func = _gnutls_srp_pack,
52 .unpack_func = _gnutls_srp_unpack,
53 .deinit_func = _gnutls_srp_deinit_data
57 static int
58 _gnutls_srp_recv_params (gnutls_session_t session, const uint8_t * data,
59 size_t _data_size)
61 uint8_t len;
62 ssize_t data_size = _data_size;
63 extension_priv_data_t epriv;
64 srp_ext_st *priv;
66 if (session->security_parameters.entity == GNUTLS_SERVER)
68 if (data_size > 0)
70 len = data[0];
71 DECR_LEN (data_size, len);
73 if (MAX_USERNAME_SIZE < len)
75 gnutls_assert ();
76 return GNUTLS_E_ILLEGAL_SRP_USERNAME;
79 priv = gnutls_calloc (1, sizeof (*priv));
80 if (priv == NULL)
82 gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
86 priv->username = gnutls_malloc (len + 1);
87 if (priv->username)
89 memcpy (priv->username, &data[1], len);
90 /* null terminated */
91 priv->username[len] = 0;
94 epriv.ptr = priv;
95 _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SRP, epriv);
98 return 0;
101 /* returns data_size or a negative number on failure
102 * data is allocated locally
104 static int
105 _gnutls_srp_send_params (gnutls_session_t session,
106 gnutls_buffer_st * extdata)
108 unsigned len;
109 int ret;
110 extension_priv_data_t epriv;
111 srp_ext_st *priv = NULL;
112 char *username = NULL, *password = NULL;
114 if (_gnutls_kx_priority (session, GNUTLS_KX_SRP) < 0 &&
115 _gnutls_kx_priority (session, GNUTLS_KX_SRP_DSS) < 0 &&
116 _gnutls_kx_priority (session, GNUTLS_KX_SRP_RSA) < 0)
118 /* algorithm was not allowed in this session
120 return 0;
123 /* this function sends the client extension data (username) */
124 if (session->security_parameters.entity == GNUTLS_CLIENT)
126 gnutls_srp_client_credentials_t cred = (gnutls_srp_client_credentials_t)
127 _gnutls_get_cred (session, GNUTLS_CRD_SRP, NULL);
129 if (cred == NULL)
130 return 0;
132 priv = gnutls_malloc (sizeof (*priv));
133 if (priv == NULL)
134 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
136 if (cred->username != NULL)
137 { /* send username */
138 len = MIN (strlen (cred->username), 255);
140 ret = _gnutls_buffer_append_data_prefix(extdata, 8, cred->username, len);
141 if (ret < 0)
143 gnutls_assert();
144 goto cleanup;
147 priv->username = strdup(cred->username);
148 if (priv->username == NULL)
150 gnutls_assert();
151 goto cleanup;
154 priv->password = strdup(cred->password);
155 if (priv->password == NULL)
157 gnutls_assert();
158 goto cleanup;
161 epriv.ptr = priv;
162 _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SRP, epriv);
164 return len + 1;
166 else if (cred->get_function != NULL)
168 /* Try the callback
171 if (cred->get_function (session, &username, &password) < 0
172 || username == NULL || password == NULL)
174 gnutls_assert ();
175 return GNUTLS_E_ILLEGAL_SRP_USERNAME;
178 len = MIN (strlen (username), 255);
180 priv->username = username;
181 priv->password = password;
183 ret = _gnutls_buffer_append_data_prefix(extdata, 8, username, len);
184 if (ret < 0)
186 ret = gnutls_assert_val(ret);
187 goto cleanup;
190 epriv.ptr = priv;
191 _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SRP, epriv);
193 return len + 1;
196 return 0;
198 cleanup:
199 gnutls_free (username);
200 gnutls_free (password);
201 gnutls_free (priv);
203 return ret;
206 static void
207 _gnutls_srp_deinit_data (extension_priv_data_t epriv)
209 srp_ext_st *priv = epriv.ptr;
211 gnutls_free (priv->username);
212 gnutls_free (priv->password);
213 gnutls_free (priv);
216 static int
217 _gnutls_srp_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
219 srp_ext_st *priv = epriv.ptr;
220 int ret;
221 int password_len = 0, username_len = 0;
223 if (priv->username)
224 username_len = strlen (priv->username);
226 if (priv->password)
227 password_len = strlen (priv->password);
229 BUFFER_APPEND_PFX4 (ps, priv->username, username_len);
230 BUFFER_APPEND_PFX4 (ps, priv->password, password_len);
232 return 0;
235 static int
236 _gnutls_srp_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv)
238 srp_ext_st *priv;
239 int ret;
240 extension_priv_data_t epriv;
241 gnutls_datum_t username = { NULL, 0 };
242 gnutls_datum_t password = { NULL, 0 };
244 priv = gnutls_calloc (1, sizeof (*priv));
245 if (priv == NULL)
247 gnutls_assert ();
248 return GNUTLS_E_MEMORY_ERROR;
251 BUFFER_POP_DATUM (ps, &username);
252 BUFFER_POP_DATUM (ps, &password);
254 priv->username = (char*)username.data;
255 priv->password = (char*)password.data;
257 epriv.ptr = priv;
258 *_priv = epriv;
260 return 0;
262 error:
263 _gnutls_free_datum (&username);
264 _gnutls_free_datum (&password);
265 return ret;
269 #endif /* ENABLE_SRP */