If OCSP revocation data are invalid or too old set appropriate verification flags.
[gnutls.git] / lib / gnutls_psk.c
blobce3588ff6471792d6762559a48778aab42445f19
1 /*
2 * Copyright (C) 2005-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 /* Functions for manipulating the PSK credentials. */
25 #include <gnutls_int.h>
26 #include <gnutls_errors.h>
27 #include <auth/psk.h>
28 #include <gnutls_state.h>
30 #ifdef ENABLE_PSK
32 #include <auth/psk_passwd.h>
33 #include <gnutls_num.h>
34 #include <gnutls_helper.h>
35 #include <gnutls_datum.h>
36 #include "debug.h"
38 /**
39 * gnutls_psk_free_client_credentials:
40 * @sc: is a #gnutls_psk_client_credentials_t structure.
42 * This structure is complex enough to manipulate directly thus this
43 * helper function is provided in order to free (deallocate) it.
44 **/
45 void
46 gnutls_psk_free_client_credentials (gnutls_psk_client_credentials_t sc)
48 _gnutls_free_datum (&sc->username);
49 _gnutls_free_datum (&sc->key);
50 gnutls_free (sc);
53 /**
54 * gnutls_psk_allocate_client_credentials:
55 * @sc: is a pointer to a #gnutls_psk_server_credentials_t structure.
57 * This structure is complex enough to manipulate directly thus this
58 * helper function is provided in order to allocate it.
60 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
61 * an error code is returned.
62 **/
63 int
64 gnutls_psk_allocate_client_credentials (gnutls_psk_client_credentials_t * sc)
66 *sc = gnutls_calloc (1, sizeof (psk_client_credentials_st));
68 if (*sc == NULL)
69 return GNUTLS_E_MEMORY_ERROR;
71 return 0;
74 /**
75 * gnutls_psk_set_client_credentials:
76 * @res: is a #gnutls_psk_client_credentials_t structure.
77 * @username: is the user's zero-terminated userid
78 * @key: is the user's key
79 * @flags: indicate the format of the key, either
80 * %GNUTLS_PSK_KEY_RAW or %GNUTLS_PSK_KEY_HEX.
82 * This function sets the username and password, in a
83 * gnutls_psk_client_credentials_t structure. Those will be used in
84 * PSK authentication. @username should be an ASCII string or UTF-8
85 * strings prepared using the "SASLprep" profile of "stringprep". The
86 * key can be either in raw byte format or in Hex format (without the
87 * 0x prefix).
89 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
90 * an error code is returned.
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:
151 * @sc: is a #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:
165 * @sc: is a pointer to a #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: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
171 * an error code is returned.
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: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
195 * an error code is returned.
198 gnutls_psk_set_server_credentials_file (gnutls_psk_server_credentials_t
199 res, const char *password_file)
202 if (password_file == NULL)
204 gnutls_assert ();
205 return GNUTLS_E_INVALID_REQUEST;
208 /* Check if the files can be opened */
209 if (_gnutls_file_exists (password_file) != 0)
211 gnutls_assert ();
212 return GNUTLS_E_FILE_ERROR;
215 res->password_file = gnutls_strdup (password_file);
216 if (res->password_file == NULL)
218 gnutls_assert ();
219 return GNUTLS_E_MEMORY_ERROR;
222 return 0;
226 * gnutls_psk_set_server_credentials_hint:
227 * @res: is a #gnutls_psk_server_credentials_t structure.
228 * @hint: is the PSK identity hint string
230 * This function sets the identity hint, in a
231 * #gnutls_psk_server_credentials_t structure. This hint is sent to
232 * the client to help it chose a good PSK credential (i.e., username
233 * and password).
235 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
236 * an error code is returned.
238 * Since: 2.4.0
241 gnutls_psk_set_server_credentials_hint (gnutls_psk_server_credentials_t res,
242 const char *hint)
244 res->hint = gnutls_strdup (hint);
245 if (res->hint == NULL)
247 gnutls_assert ();
248 return GNUTLS_E_MEMORY_ERROR;
251 return 0;
255 * gnutls_psk_set_server_credentials_function:
256 * @cred: is a #gnutls_psk_server_credentials_t structure.
257 * @func: is the callback function
259 * This function can be used to set a callback to retrieve the user's PSK credentials.
260 * The callback's function form is:
261 * int (*callback)(gnutls_session_t, const char* username,
262 * gnutls_datum_t* key);
264 * @username contains the actual username.
265 * The @key must be filled in using the gnutls_malloc().
267 * In case the callback returned a negative number then gnutls will
268 * assume that the username does not exist.
270 * The callback function will only be called once per handshake. The
271 * callback function should return 0 on success, while -1 indicates
272 * an error.
274 void
275 gnutls_psk_set_server_credentials_function (gnutls_psk_server_credentials_t
276 cred,
277 gnutls_psk_server_credentials_function
278 * func)
280 cred->pwd_callback = func;
284 * gnutls_psk_set_client_credentials_function:
285 * @cred: is a #gnutls_psk_server_credentials_t structure.
286 * @func: is the callback function
288 * This function can be used to set a callback to retrieve the username and
289 * password for client PSK authentication.
290 * The callback's function form is:
291 * int (*callback)(gnutls_session_t, char** username,
292 * gnutls_datum_t* key);
294 * The @username and @key->data must be allocated using gnutls_malloc().
295 * @username should be ASCII strings or UTF-8 strings prepared using
296 * the "SASLprep" profile of "stringprep".
298 * The callback function will be called once per handshake.
300 * The callback function should return 0 on success.
301 * -1 indicates an error.
303 void
304 gnutls_psk_set_client_credentials_function (gnutls_psk_client_credentials_t
305 cred,
306 gnutls_psk_client_credentials_function
307 * func)
309 cred->get_function = func;
314 * gnutls_psk_server_get_username:
315 * @session: is a gnutls session
317 * This should only be called in case of PSK authentication and in
318 * case of a server.
320 * Returns: the username of the peer, or %NULL in case of an error.
322 const char *
323 gnutls_psk_server_get_username (gnutls_session_t session)
325 psk_auth_info_t info;
327 CHECK_AUTH (GNUTLS_CRD_PSK, NULL);
329 info = _gnutls_get_auth_info (session);
330 if (info == NULL)
331 return NULL;
333 if (info->username[0] != 0)
334 return info->username;
336 return NULL;
340 * gnutls_psk_client_get_hint:
341 * @session: is a gnutls session
343 * The PSK identity hint may give the client help in deciding which
344 * username to use. This should only be called in case of PSK
345 * authentication and in case of a client.
347 * Returns: the identity hint of the peer, or %NULL in case of an error.
349 * Since: 2.4.0
351 const char *
352 gnutls_psk_client_get_hint (gnutls_session_t session)
354 psk_auth_info_t info;
356 CHECK_AUTH (GNUTLS_CRD_PSK, NULL);
358 info = _gnutls_get_auth_info (session);
359 if (info == NULL)
360 return NULL;
362 if (info->hint[0] != 0)
363 return info->hint;
365 return NULL;
369 * gnutls_hex_decode:
370 * @hex_data: contain the encoded data
371 * @result: the place where decoded data will be copied
372 * @result_size: holds the size of the result
374 * This function will decode the given encoded data, using the hex
375 * encoding used by PSK password files.
377 * Note that hex_data should be null terminated.
379 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
380 * long enough, or 0 on success.
383 gnutls_hex_decode (const gnutls_datum_t * hex_data, void *result,
384 size_t * result_size)
386 int ret;
388 ret =
389 _gnutls_hex2bin ((char*)hex_data->data, hex_data->size, (uint8_t *) result,
390 result_size);
391 if (ret < 0)
392 return ret;
394 return 0;
398 * gnutls_hex_encode:
399 * @data: contain the raw data
400 * @result: the place where hex data will be copied
401 * @result_size: holds the size of the result
403 * This function will convert the given data to printable data, using
404 * the hex encoding, as used in the PSK password files.
406 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
407 * long enough, or 0 on success.
410 gnutls_hex_encode (const gnutls_datum_t * data, char *result,
411 size_t * result_size)
413 size_t res = data->size + data->size + 1;
415 if (*result_size < res)
417 gnutls_assert ();
418 return GNUTLS_E_SHORT_MEMORY_BUFFER;
421 _gnutls_bin2hex (data->data, data->size, result, *result_size, NULL);
422 *result_size = res;
424 return 0;
428 * gnutls_psk_set_server_dh_params:
429 * @res: is a gnutls_psk_server_credentials_t structure
430 * @dh_params: is a structure that holds Diffie-Hellman parameters.
432 * This function will set the Diffie-Hellman parameters for an
433 * anonymous server to use. These parameters will be used in
434 * Diffie-Hellman exchange with PSK cipher suites.
436 void
437 gnutls_psk_set_server_dh_params (gnutls_psk_server_credentials_t res,
438 gnutls_dh_params_t dh_params)
440 res->dh_params = dh_params;
444 * gnutls_psk_set_server_params_function:
445 * @res: is a #gnutls_certificate_credentials_t structure
446 * @func: is the function to be called
448 * This function will set a callback in order for the server to get
449 * the Diffie-Hellman parameters for PSK authentication. The callback
450 * should return %GNUTLS_E_SUCCESS (0) on success.
452 void
453 gnutls_psk_set_server_params_function (gnutls_psk_server_credentials_t res,
454 gnutls_params_function * func)
456 res->params_func = func;
459 #endif /* ENABLE_PSK */