Export new ABIs. Doc fixes for new APIs.
[gnutls.git] / lib / gnutls_psk.c
blob67cef93890e13f34bcbb7a562ab14e2fd9bedb95
1 /*
2 * Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation,
3 * 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 /* Functions for manipulating the PSK credentials. */
28 #include <gnutls_int.h>
29 #include <gnutls_errors.h>
30 #include <auth_psk.h>
31 #include <gnutls_state.h>
33 #ifdef ENABLE_PSK
35 #include <auth_psk_passwd.h>
36 #include <gnutls_num.h>
37 #include <gnutls_helper.h>
38 #include <gnutls_datum.h>
39 #include "debug.h"
41 /**
42 * gnutls_psk_free_client_credentials:
43 * @sc: is a #gnutls_psk_client_credentials_t structure.
45 * This structure is complex enough to manipulate directly thus this
46 * helper function is provided in order to free (deallocate) it.
47 **/
48 void
49 gnutls_psk_free_client_credentials (gnutls_psk_client_credentials_t sc)
51 _gnutls_free_datum (&sc->username);
52 _gnutls_free_datum (&sc->key);
53 gnutls_free (sc);
56 /**
57 * gnutls_psk_allocate_client_credentials:
58 * @sc: is a pointer to a #gnutls_psk_server_credentials_t structure.
60 * This structure is complex enough to manipulate directly thus this
61 * helper function is provided in order to allocate it.
63 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
64 **/
65 int
66 gnutls_psk_allocate_client_credentials (gnutls_psk_client_credentials_t * sc)
68 *sc = gnutls_calloc (1, sizeof (psk_client_credentials_st));
70 if (*sc == NULL)
71 return GNUTLS_E_MEMORY_ERROR;
73 return 0;
76 /**
77 * gnutls_psk_set_client_credentials:
78 * @res: is a #gnutls_psk_client_credentials_t structure.
79 * @username: is the user's zero-terminated userid
80 * @key: is the user's key
81 * @format: indicate the format of the key, either
82 * %GNUTLS_PSK_KEY_RAW or %GNUTLS_PSK_KEY_HEX.
84 * This function sets the username and password, in a
85 * gnutls_psk_client_credentials_t structure. Those will be used in
86 * PSK authentication. @username should be an ASCII string or UTF-8
87 * strings prepared using the "SASLprep" profile of "stringprep". The
88 * key can be either in raw byte format or in Hex format (without the
89 * 0x prefix).
91 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
92 **/
93 int
94 gnutls_psk_set_client_credentials (gnutls_psk_client_credentials_t res,
95 const char *username,
96 const gnutls_datum_t * key,
97 gnutls_psk_key_flags flags)
99 int ret;
101 if (username == NULL || key == NULL || key->data == NULL)
103 gnutls_assert ();
104 return GNUTLS_E_INVALID_REQUEST;
107 ret = _gnutls_set_datum (&res->username, username, strlen (username));
108 if (ret < 0)
109 return ret;
111 if (flags == GNUTLS_PSK_KEY_RAW)
113 if (_gnutls_set_datum (&res->key, key->data, key->size) < 0)
115 gnutls_assert ();
116 ret = GNUTLS_E_MEMORY_ERROR;
117 goto error;
120 else
121 { /* HEX key */
122 size_t size;
123 size = res->key.size = key->size / 2;
124 res->key.data = gnutls_malloc (size);
125 if (res->key.data == NULL)
127 gnutls_assert ();
128 ret = GNUTLS_E_MEMORY_ERROR;
129 goto error;
132 ret = gnutls_hex_decode (key, (char *) res->key.data, &size);
133 res->key.size = (unsigned int) size;
134 if (ret < 0)
136 gnutls_assert ();
137 goto error;
142 return 0;
144 error:
145 _gnutls_free_datum (&res->username);
147 return ret;
151 * gnutls_psk_free_server_credentials:
152 * @sc: is a #gnutls_psk_server_credentials_t structure.
154 * This structure is complex enough to manipulate directly thus this
155 * helper function is provided in order to free (deallocate) it.
157 void
158 gnutls_psk_free_server_credentials (gnutls_psk_server_credentials_t sc)
160 gnutls_free (sc->password_file);
161 gnutls_free (sc);
165 * gnutls_psk_allocate_server_credentials:
166 * @sc: is a pointer to a #gnutls_psk_server_credentials_t structure.
168 * This structure is complex enough to manipulate directly thus this
169 * helper function is provided in order to allocate it.
171 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
174 gnutls_psk_allocate_server_credentials (gnutls_psk_server_credentials_t * sc)
176 *sc = gnutls_calloc (1, sizeof (psk_server_cred_st));
178 if (*sc == NULL)
179 return GNUTLS_E_MEMORY_ERROR;
181 return 0;
186 * gnutls_psk_set_server_credentials_file:
187 * @res: is a #gnutls_psk_server_credentials_t structure.
188 * @password_file: is the PSK password file (passwd.psk)
190 * This function sets the password file, in a
191 * %gnutls_psk_server_credentials_t structure. This password file
192 * holds usernames and keys and will be used for PSK authentication.
194 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
197 gnutls_psk_set_server_credentials_file (gnutls_psk_server_credentials_t
198 res, const char *password_file)
201 if (password_file == NULL)
203 gnutls_assert ();
204 return GNUTLS_E_INVALID_REQUEST;
207 /* Check if the files can be opened */
208 if (_gnutls_file_exists (password_file) != 0)
210 gnutls_assert ();
211 return GNUTLS_E_FILE_ERROR;
214 res->password_file = gnutls_strdup (password_file);
215 if (res->password_file == NULL)
217 gnutls_assert ();
218 return GNUTLS_E_MEMORY_ERROR;
221 return 0;
225 * gnutls_psk_set_server_credentials_hint:
226 * @res: is a #gnutls_psk_server_credentials_t structure.
227 * @hint: is the PSK identity hint string
229 * This function sets the identity hint, in a
230 * %gnutls_psk_server_credentials_t structure. This hint is sent to
231 * the client to help it chose a good PSK credential (i.e., username
232 * and password).
234 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
236 * Since: 2.4.0
239 gnutls_psk_set_server_credentials_hint (gnutls_psk_server_credentials_t res,
240 const char *hint)
242 res->hint = gnutls_strdup (hint);
243 if (res->hint == NULL)
245 gnutls_assert ();
246 return GNUTLS_E_MEMORY_ERROR;
249 return 0;
253 * gnutls_psk_set_server_credentials_function:
254 * @cred: is a #gnutls_psk_server_credentials_t structure.
255 * @func: is the callback function
257 * This function can be used to set a callback to retrieve the user's PSK credentials.
258 * The callback's function form is:
259 * int (*callback)(gnutls_session_t, const char* username,
260 * gnutls_datum_t* key);
262 * @username contains the actual username.
263 * The @key must be filled in using the gnutls_malloc().
265 * In case the callback returned a negative number then gnutls will
266 * assume that the username does not exist.
268 * The callback function will only be called once per handshake. The
269 * callback function should return 0 on success, while -1 indicates
270 * an error.
272 void
273 gnutls_psk_set_server_credentials_function (gnutls_psk_server_credentials_t
274 cred,
275 gnutls_psk_server_credentials_function
276 * func)
278 cred->pwd_callback = func;
282 * gnutls_psk_set_client_credentials_function:
283 * @cred: is a #gnutls_psk_server_credentials_t structure.
284 * @func: is the callback function
286 * This function can be used to set a callback to retrieve the username and
287 * password for client PSK authentication.
288 * The callback's function form is:
289 * int (*callback)(gnutls_session_t, char** username,
290 * gnutls_datum_t* key);
292 * The @username and @key->data must be allocated using gnutls_malloc().
293 * @username should be ASCII strings or UTF-8 strings prepared using
294 * the "SASLprep" profile of "stringprep".
296 * The callback function will be called once per handshake.
298 * The callback function should return 0 on success.
299 * -1 indicates an error.
301 void
302 gnutls_psk_set_client_credentials_function (gnutls_psk_client_credentials_t
303 cred,
304 gnutls_psk_client_credentials_function
305 * func)
307 cred->get_function = func;
312 * gnutls_psk_server_get_username:
313 * @session: is a gnutls session
315 * This should only be called in case of PSK authentication and in
316 * case of a server.
318 * Returns: the username of the peer, or %NULL in case of an error.
320 const char *
321 gnutls_psk_server_get_username (gnutls_session_t session)
323 psk_auth_info_t info;
325 CHECK_AUTH (GNUTLS_CRD_PSK, NULL);
327 info = _gnutls_get_auth_info (session);
328 if (info == NULL)
329 return NULL;
331 if (info->username[0] != 0)
332 return info->username;
334 return NULL;
338 * gnutls_psk_client_get_hint:
339 * @session: is a gnutls session
341 * The PSK identity hint may give the client help in deciding which
342 * username to use. This should only be called in case of PSK
343 * authentication and in case of a client.
345 * Returns: the identity hint of the peer, or %NULL in case of an error.
347 * Since: 2.4.0
349 const char *
350 gnutls_psk_client_get_hint (gnutls_session_t session)
352 psk_auth_info_t info;
354 CHECK_AUTH (GNUTLS_CRD_PSK, NULL);
356 info = _gnutls_get_auth_info (session);
357 if (info == NULL)
358 return NULL;
360 if (info->hint[0] != 0)
361 return info->hint;
363 return NULL;
367 * gnutls_hex_decode:
368 * @hex_data: contain the encoded data
369 * @result: the place where decoded data will be copied
370 * @result_size: holds the size of the result
372 * This function will decode the given encoded data, using the hex
373 * encoding used by PSK password files.
375 * Note that hex_data should be null terminated.
377 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
378 * long enough, or 0 on success.
381 gnutls_hex_decode (const gnutls_datum_t * hex_data, char *result,
382 size_t * result_size)
384 int ret;
386 ret =
387 _gnutls_hex2bin (hex_data->data, hex_data->size, (opaque *) result,
388 result_size);
389 if (ret < 0)
390 return ret;
392 return 0;
396 * gnutls_hex_encode:
397 * @data: contain the raw data
398 * @result: the place where hex data will be copied
399 * @result_size: holds the size of the result
401 * This function will convert the given data to printable data, using
402 * the hex encoding, as used in the PSK password files.
404 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
405 * long enough, or 0 on success.
408 gnutls_hex_encode (const gnutls_datum_t * data, char *result,
409 size_t * result_size)
411 size_t res = data->size + data->size + 1;
413 if (*result_size < res)
415 gnutls_assert ();
416 return GNUTLS_E_SHORT_MEMORY_BUFFER;
419 _gnutls_bin2hex (data->data, data->size, result, *result_size);
420 *result_size = res;
422 return 0;
426 * gnutls_psk_set_server_dh_params:
427 * @res: is a gnutls_psk_server_credentials_t structure
428 * @dh_params: is a structure that holds Diffie-Hellman parameters.
430 * This function will set the Diffie-Hellman parameters for an
431 * anonymous server to use. These parameters will be used in
432 * Diffie-Hellman exchange with PSK cipher suites.
434 void
435 gnutls_psk_set_server_dh_params (gnutls_psk_server_credentials_t res,
436 gnutls_dh_params_t dh_params)
438 res->dh_params = dh_params;
442 * gnutls_psk_set_server_params_function:
443 * @res: is a #gnutls_certificate_credentials_t structure
444 * @func: is the function to be called
446 * This function will set a callback in order for the server to get
447 * the Diffie-Hellman parameters for PSK authentication. The callback
448 * should return zero on success.
450 void
451 gnutls_psk_set_server_params_function (gnutls_psk_server_credentials_t res,
452 gnutls_params_function * func)
454 res->params_func = func;
457 #endif /* ENABLE_PSK */