We reverted the ABI bump.
[gnutls.git] / lib / gnutls_psk.c
blob1c3209aeb960a45a72e5107796daf10848b2ee67
1 /*
2 * Copyright (C) 2005, 2007, 2008 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
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 /* Functions for manipulating the PSK credentials. */
27 #include <gnutls_int.h>
28 #include <gnutls_errors.h>
29 #include <auth_psk.h>
30 #include <gnutls_state.h>
32 #ifdef ENABLE_PSK
34 #include <auth_psk_passwd.h>
35 #include <gnutls_num.h>
36 #include <gnutls_helper.h>
37 #include <gnutls_datum.h>
38 #include "debug.h"
40 /**
41 * gnutls_psk_free_client_credentials - Used to free an allocated gnutls_psk_client_credentials_t structure
42 * @sc: is an #gnutls_psk_client_credentials_t structure.
44 * This structure is complex enough to manipulate directly thus this
45 * helper function is provided in order to free (deallocate) it.
46 **/
47 void
48 gnutls_psk_free_client_credentials (gnutls_psk_client_credentials_t sc)
50 _gnutls_free_datum (&sc->username);
51 _gnutls_free_datum (&sc->key);
52 gnutls_free (sc);
55 /**
56 * gnutls_psk_allocate_client_credentials - Used to allocate an gnutls_psk_server_credentials_t structure
57 * @sc: is a pointer to an #gnutls_psk_server_credentials_t structure.
59 * This structure is complex enough to manipulate directly thus this
60 * helper function is provided in order to allocate it.
62 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
63 **/
64 int
65 gnutls_psk_allocate_client_credentials (gnutls_psk_client_credentials_t * sc)
67 *sc = gnutls_calloc (1, sizeof (psk_client_credentials_st));
69 if (*sc == NULL)
70 return GNUTLS_E_MEMORY_ERROR;
72 return 0;
75 /**
76 * gnutls_psk_set_client_credentials - Used to set the username/password, in a gnutls_psk_client_credentials_t structure
77 * @res: is an #gnutls_psk_client_credentials_t structure.
78 * @username: is the user's zero-terminated userid
79 * @key: is the user's key
80 * @format: indicate the format of the key, either
81 * %GNUTLS_PSK_KEY_RAW or %GNUTLS_PSK_KEY_HEX.
83 * This function sets the username and password, in a
84 * gnutls_psk_client_credentials_t structure. Those will be used in
85 * PSK authentication. @username should be an ASCII string or UTF-8
86 * strings prepared using the "SASLprep" profile of "stringprep".
87 * The key can be either in raw byte format or in Hex (not with the
88 * '0x' prefix).
90 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
91 **/
92 int
93 gnutls_psk_set_client_credentials (gnutls_psk_client_credentials_t res,
94 const char *username,
95 const gnutls_datum_t * key,
96 gnutls_psk_key_flags flags)
98 int ret;
100 if (username == NULL || key == NULL || key->data == NULL)
102 gnutls_assert ();
103 return GNUTLS_E_INVALID_REQUEST;
106 ret = _gnutls_set_datum (&res->username, username, strlen (username));
107 if (ret < 0)
108 return ret;
110 if (flags == GNUTLS_PSK_KEY_RAW)
112 if (_gnutls_set_datum (&res->key, key->data, key->size) < 0)
114 gnutls_assert ();
115 ret = GNUTLS_E_MEMORY_ERROR;
116 goto error;
119 else
120 { /* HEX key */
121 size_t size;
122 size = res->key.size = key->size / 2;
123 res->key.data = gnutls_malloc (size);
124 if (res->key.data == NULL)
126 gnutls_assert ();
127 ret = GNUTLS_E_MEMORY_ERROR;
128 goto error;
131 ret = gnutls_hex_decode (key, (char *) res->key.data, &size);
132 res->key.size = (unsigned int)size;
133 if (ret < 0)
135 gnutls_assert ();
136 goto error;
141 return 0;
143 error:
144 _gnutls_free_datum (&res->username);
146 return ret;
150 * gnutls_psk_free_server_credentials - Used to free an allocated gnutls_psk_server_credentials_t structure
151 * @sc: is an #gnutls_psk_server_credentials_t structure.
153 * This structure is complex enough to manipulate directly thus this
154 * helper function is provided in order to free (deallocate) it.
156 void
157 gnutls_psk_free_server_credentials (gnutls_psk_server_credentials_t sc)
159 gnutls_free (sc->password_file);
160 gnutls_free (sc);
164 * gnutls_psk_allocate_server_credentials - Used to allocate an gnutls_psk_server_credentials_t structure
165 * @sc: is a pointer to an #gnutls_psk_server_credentials_t structure.
167 * This structure is complex enough to manipulate directly thus this
168 * helper function is provided in order to allocate it.
170 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
173 gnutls_psk_allocate_server_credentials (gnutls_psk_server_credentials_t * sc)
175 *sc = gnutls_calloc (1, sizeof (psk_server_cred_st));
177 if (*sc == NULL)
178 return GNUTLS_E_MEMORY_ERROR;
180 return 0;
185 * gnutls_psk_set_server_credentials_file - Used to set the password files, in a gnutls_psk_server_credentials_t structure
186 * @res: is an #gnutls_psk_server_credentials_t structure.
187 * @password_file: is the PSK password file (passwd.psk)
189 * This function sets the password file, in a
190 * %gnutls_psk_server_credentials_t structure. This password file
191 * holds usernames and keys and will be used for PSK authentication.
193 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
196 gnutls_psk_set_server_credentials_file (gnutls_psk_server_credentials_t
197 res, const char *password_file)
200 if (password_file == NULL)
202 gnutls_assert ();
203 return GNUTLS_E_INVALID_REQUEST;
206 /* Check if the files can be opened */
207 if (_gnutls_file_exists (password_file) != 0)
209 gnutls_assert ();
210 return GNUTLS_E_FILE_ERROR;
213 res->password_file = gnutls_strdup (password_file);
214 if (res->password_file == NULL)
216 gnutls_assert ();
217 return GNUTLS_E_MEMORY_ERROR;
220 return 0;
224 * gnutls_psk_set_server_credentials_hint - Set a identity hint, in a %gnutls_psk_server_credentials_t structure
225 * @res: is an #gnutls_psk_server_credentials_t structure.
226 * @hint: is the PSK identity hint string
228 * This function sets the identity hint, in a
229 * %gnutls_psk_server_credentials_t structure. This hint is sent to
230 * the client to help it chose a good PSK credential (i.e., username
231 * and password).
233 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
235 * Since: 2.4.0
238 gnutls_psk_set_server_credentials_hint (gnutls_psk_server_credentials_t res,
239 const char *hint)
241 res->hint = gnutls_strdup (hint);
242 if (res->hint == NULL)
244 gnutls_assert ();
245 return GNUTLS_E_MEMORY_ERROR;
248 return 0;
252 * gnutls_psk_set_server_credentials_function - Used to set a callback to retrieve the user's PSK credentials
253 * @cred: is a #gnutls_psk_server_credentials_t structure.
254 * @func: is the callback function
256 * This function can be used to set a callback to retrieve the user's PSK credentials.
257 * The callback's function form is:
258 * int (*callback)(gnutls_session_t, const char* username,
259 * gnutls_datum_t* key);
261 * @username contains the actual username.
262 * The @key must be filled in using the gnutls_malloc().
264 * In case the callback returned a negative number then gnutls will
265 * assume that the username does not exist.
267 * The callback function will only be called once per handshake. The
268 * callback function should return 0 on success, while -1 indicates
269 * an error.
271 void
272 gnutls_psk_set_server_credentials_function (gnutls_psk_server_credentials_t
273 cred,
274 gnutls_psk_server_credentials_function
275 * func)
277 cred->pwd_callback = func;
281 * gnutls_psk_set_client_credentials_function - Used to set a callback to retrieve the username and key
282 * @cred: is a #gnutls_psk_server_credentials_t structure.
283 * @func: is the callback function
285 * This function can be used to set a callback to retrieve the username and
286 * password for client PSK authentication.
287 * The callback's function form is:
288 * int (*callback)(gnutls_session_t, char** username,
289 * gnutls_datum_t* key);
291 * The @username and @key->data must be allocated using gnutls_malloc().
292 * @username should be ASCII strings or UTF-8 strings prepared using
293 * the "SASLprep" profile of "stringprep".
295 * The callback function will be called once per handshake.
297 * The callback function should return 0 on success.
298 * -1 indicates an error.
300 void
301 gnutls_psk_set_client_credentials_function (gnutls_psk_client_credentials_t
302 cred,
303 gnutls_psk_client_credentials_function
304 * func)
306 cred->get_function = func;
311 * gnutls_psk_server_get_username - return the username of the peer
312 * @session: is a gnutls session
314 * This should only be called in case of PSK authentication and in
315 * case of a server.
317 * Returns: the username of the peer, or %NULL in case of an error.
319 const char *
320 gnutls_psk_server_get_username (gnutls_session_t session)
322 psk_auth_info_t info;
324 CHECK_AUTH (GNUTLS_CRD_PSK, NULL);
326 info = _gnutls_get_auth_info (session);
327 if (info == NULL)
328 return NULL;
330 if (info->username[0] != 0)
331 return info->username;
333 return NULL;
337 * gnutls_psk_client_get_hint - return the PSK identity hint of the peer
338 * @session: is a gnutls session
340 * The PSK identity hint may give the client help in deciding which
341 * username to use. This should only be called in case of PSK
342 * authentication and in case of a client.
344 * Returns: the identity hint of the peer, or %NULL in case of an error.
346 * Since: 2.4.0
348 const char *
349 gnutls_psk_client_get_hint (gnutls_session_t session)
351 psk_auth_info_t info;
353 CHECK_AUTH (GNUTLS_CRD_PSK, NULL);
355 info = _gnutls_get_auth_info (session);
356 if (info == NULL)
357 return NULL;
359 if (info->hint[0] != 0)
360 return info->hint;
362 return NULL;
366 * gnutls_hex_decode - decode hex encoded data
367 * @hex_data: contain the encoded data
368 * @result: the place where decoded data will be copied
369 * @result_size: holds the size of the result
371 * This function will decode the given encoded data, using the hex encoding
372 * used by PSK password files.
374 * Note that hex_data should be null terminated.
376 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
377 * long enough, or 0 on success.
380 gnutls_hex_decode (const gnutls_datum_t * hex_data, char *result,
381 size_t * result_size)
383 int ret;
385 ret =
386 _gnutls_hex2bin (hex_data->data, hex_data->size, (opaque *) result,
387 result_size);
388 if (ret < 0)
389 return ret;
391 return 0;
395 * gnutls_hex_encode - convert raw data to hex encoded
396 * @data: contain the raw data
397 * @result: the place where hex data will be copied
398 * @result_size: holds the size of the result
400 * This function will convert the given data to printable data, using
401 * the hex encoding, as used in the PSK password files.
403 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
404 * long enough, or 0 on success.
407 gnutls_hex_encode (const gnutls_datum_t * data, char *result,
408 size_t * result_size)
410 if (*result_size < data->size + data->size + 1)
412 gnutls_assert ();
413 return GNUTLS_E_SHORT_MEMORY_BUFFER;
416 _gnutls_bin2hex (data->data, data->size, result, *result_size);
418 return 0;
422 * gnutls_psk_set_server_dh_params - set the DH parameters for a server to use
423 * @res: is a gnutls_psk_server_credentials_t structure
424 * @dh_params: is a structure that holds diffie hellman parameters.
426 * This function will set the diffie hellman parameters for an
427 * anonymous server to use. These parameters will be used in Diffie
428 * Hellman with PSK cipher suites.
430 void
431 gnutls_psk_set_server_dh_params (gnutls_psk_server_credentials_t res,
432 gnutls_dh_params_t dh_params)
434 res->dh_params = dh_params;
438 * gnutls_psk_set_server_params_function - set the DH parameters callback
439 * @res: is a gnutls_certificate_credentials_t structure
440 * @func: is the function to be called
442 * This function will set a callback in order for the server to get
443 * the diffie hellman parameters for PSK authentication. The callback
444 * should return zero on success.
446 void
447 gnutls_psk_set_server_params_function (gnutls_psk_server_credentials_t res,
448 gnutls_params_function * func)
450 res->params_func = func;
453 #endif /* ENABLE_PSK */