Coverage Report

Created: 2025-11-16 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/psk.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2005-2012 Free Software Foundation, Inc.
3
 *
4
 * Author: Nikos Mavrogiannopoulos
5
 *
6
 * This file is part of GnuTLS.
7
 *
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 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
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.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
/* Functions for manipulating the PSK credentials. */
24
25
#include "gnutls_int.h"
26
#include "errors.h"
27
#include "str.h"
28
#include "auth/psk.h"
29
#include "state.h"
30
31
#ifdef ENABLE_PSK
32
33
#include "auth/psk_passwd.h"
34
#include "num.h"
35
#include "file.h"
36
#include "datum.h"
37
#include "debug.h"
38
#include "dh.h"
39
40
/**
41
 * gnutls_psk_free_client_credentials:
42
 * @sc: is a #gnutls_psk_client_credentials_t type.
43
 *
44
 * Free a gnutls_psk_client_credentials_t structure.
45
 **/
46
void gnutls_psk_free_client_credentials(gnutls_psk_client_credentials_t sc)
47
0
{
48
0
  _gnutls_free_datum(&sc->username);
49
0
  _gnutls_free_datum(&sc->key);
50
0
  gnutls_free(sc);
51
0
}
52
53
/**
54
 * gnutls_psk_allocate_client_credentials:
55
 * @sc: is a pointer to a #gnutls_psk_client_credentials_t type.
56
 *
57
 * Allocate a gnutls_psk_client_credentials_t structure.
58
 *
59
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
60
 *   an error code is returned.
61
 **/
62
int gnutls_psk_allocate_client_credentials(gnutls_psk_client_credentials_t *sc)
63
0
{
64
  /* TLS 1.3 - Default binder HMAC algorithm is SHA-256 */
65
0
  return gnutls_psk_allocate_client_credentials2(sc, GNUTLS_MAC_SHA256);
66
0
}
67
68
/**
69
 * gnutls_psk_allocate_client_credentials2:
70
 * @sc: is a pointer to a #gnutls_psk_client_credentials_t type.
71
 * @mac: encryption algorithm to use
72
 *
73
 * Allocate a gnutls_psk_client_credentials_t structure and initializes
74
 * the HMAC binder algorithm to @mac.
75
 *
76
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
77
 *   an error code is returned.
78
 **/
79
int gnutls_psk_allocate_client_credentials2(gnutls_psk_client_credentials_t *sc,
80
              gnutls_mac_algorithm_t mac)
81
0
{
82
  /* TLS 1.3 - Only SHA-256 and SHA-384 are allowed */
83
0
  if (mac != GNUTLS_MAC_SHA256 && mac != GNUTLS_MAC_SHA384)
84
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
85
86
0
  *sc = gnutls_calloc(1, sizeof(psk_client_credentials_st));
87
88
0
  if (*sc == NULL)
89
0
    return GNUTLS_E_MEMORY_ERROR;
90
91
0
  (*sc)->binder_algo = _gnutls_mac_to_entry(mac);
92
0
  return 0;
93
0
}
94
95
/**
96
 * gnutls_psk_set_client_credentials:
97
 * @res: is a #gnutls_psk_client_credentials_t type.
98
 * @username: is the user's zero-terminated userid
99
 * @key: is the user's key
100
 * @flags: indicate the format of the key, either
101
 *   %GNUTLS_PSK_KEY_RAW or %GNUTLS_PSK_KEY_HEX.
102
 *
103
 * This function sets the username and password, in a
104
 * gnutls_psk_client_credentials_t type.  Those will be used in
105
 * PSK authentication.  @username should be an ASCII string or UTF-8
106
 * string. In case of a UTF-8 string it is recommended to be following
107
 * the PRECIS framework for usernames (rfc8265). The key can be either
108
 * in raw byte format or in Hex format (without the 0x prefix).
109
 *
110
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
111
 *   an error code is returned.
112
 **/
113
int gnutls_psk_set_client_credentials(gnutls_psk_client_credentials_t res,
114
              const char *username,
115
              const gnutls_datum_t *key,
116
              gnutls_psk_key_flags flags)
117
0
{
118
0
  gnutls_datum_t dat;
119
120
0
  if (username == NULL)
121
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
122
123
0
  dat.data = (unsigned char *)username;
124
0
  dat.size = strlen(username);
125
126
0
  return gnutls_psk_set_client_credentials2(res, &dat, key, flags);
127
0
}
128
129
/**
130
 * gnutls_psk_set_client_credentials2:
131
 * @res: is a #gnutls_psk_client_credentials_t type.
132
 * @username: is the userid
133
 * @key: is the user's key
134
 * @flags: indicate the format of the key, either
135
 *   %GNUTLS_PSK_KEY_RAW or %GNUTLS_PSK_KEY_HEX.
136
 *
137
 * This function is identical to gnutls_psk_set_client_credentials(),
138
 * except that it allows a non-null-terminated username to be introduced.
139
 *
140
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
141
 *   an error code is returned.
142
 */
143
int gnutls_psk_set_client_credentials2(gnutls_psk_client_credentials_t res,
144
               const gnutls_datum_t *username,
145
               const gnutls_datum_t *key,
146
               gnutls_psk_key_flags flags)
147
0
{
148
0
  int ret;
149
150
0
  if (username == NULL || username->data == NULL || key == NULL ||
151
0
      key->data == NULL) {
152
0
    gnutls_assert();
153
0
    return GNUTLS_E_INVALID_REQUEST;
154
0
  }
155
156
0
  ret = _gnutls_set_datum(&res->username, username->data, username->size);
157
0
  if (ret < 0)
158
0
    return ret;
159
160
0
  if (flags == GNUTLS_PSK_KEY_RAW) {
161
0
    if (_gnutls_set_datum(&res->key, key->data, key->size) < 0) {
162
0
      gnutls_assert();
163
0
      ret = GNUTLS_E_MEMORY_ERROR;
164
0
      goto error;
165
0
    }
166
0
  } else { /* HEX key */
167
0
    size_t size;
168
0
    size = res->key.size = key->size / 2;
169
0
    res->key.data = gnutls_malloc(size);
170
0
    if (res->key.data == NULL) {
171
0
      gnutls_assert();
172
0
      ret = GNUTLS_E_MEMORY_ERROR;
173
0
      goto error;
174
0
    }
175
176
0
    ret = gnutls_hex_decode(key, (char *)res->key.data, &size);
177
0
    res->key.size = (unsigned int)size;
178
0
    if (ret < 0) {
179
0
      gnutls_assert();
180
0
      goto error;
181
0
    }
182
183
0
    if (size < 4) {
184
0
      gnutls_assert();
185
0
      ret = GNUTLS_E_INVALID_REQUEST;
186
0
      goto error;
187
0
    }
188
0
  }
189
190
0
  return 0;
191
192
0
error:
193
0
  _gnutls_free_datum(&res->username);
194
0
  _gnutls_free_datum(&res->key);
195
196
0
  return ret;
197
0
}
198
199
/**
200
 * gnutls_psk_free_server_credentials:
201
 * @sc: is a #gnutls_psk_server_credentials_t type.
202
 *
203
 * Free a gnutls_psk_server_credentials_t structure.
204
 **/
205
void gnutls_psk_free_server_credentials(gnutls_psk_server_credentials_t sc)
206
0
{
207
0
  if (sc->deinit_dh_params) {
208
0
    gnutls_dh_params_deinit(sc->dh_params);
209
0
  }
210
211
0
  gnutls_free(sc->password_file);
212
0
  gnutls_free(sc->hint);
213
0
  gnutls_free(sc);
214
0
}
215
216
/**
217
 * gnutls_psk_allocate_server_credentials:
218
 * @sc: is a pointer to a #gnutls_psk_server_credentials_t type.
219
 *
220
 * Allocate a gnutls_psk_server_credentials_t structure.
221
 *
222
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
223
 *   an error code is returned.
224
 **/
225
int gnutls_psk_allocate_server_credentials(gnutls_psk_server_credentials_t *sc)
226
0
{
227
  /* TLS 1.3 - Default binder HMAC algorithm is SHA-256 */
228
0
  return gnutls_psk_allocate_server_credentials2(sc, GNUTLS_MAC_SHA256);
229
0
}
230
231
/**
232
 * gnutls_psk_allocate_server_credentials2:
233
 * @sc: is a pointer to a #gnutls_psk_server_credentials_t type.
234
 * @mac: encryption algorithm to use
235
 *
236
 * Allocate a gnutls_psk_server_credentials_t structure and initializes
237
 * the HMAC binder algorithm to @mac. If @mac is set to GNUTLS_MAC_UNKNOWN
238
 * both possible algorithms SHA384 and SHA256 are applied to find a matching
239
 * binder value.
240
 *
241
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
242
 *   an error code is returned.
243
 **/
244
int gnutls_psk_allocate_server_credentials2(gnutls_psk_server_credentials_t *sc,
245
              gnutls_mac_algorithm_t mac)
246
0
{
247
  /*
248
   * TLS 1.3 - Only SHA-256 and SHA-384 are allowed;
249
   * additionally allow GNUTLS_MAC_UNKNOWN for autodetection.
250
   */
251
0
  if (mac != GNUTLS_MAC_SHA256 && mac != GNUTLS_MAC_SHA384 &&
252
0
      mac != GNUTLS_MAC_UNKNOWN)
253
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
254
255
0
  *sc = gnutls_calloc(1, sizeof(psk_server_cred_st));
256
257
0
  if (*sc == NULL)
258
0
    return GNUTLS_E_MEMORY_ERROR;
259
  /*
260
   * For GNUTLS_MAC_UNKNOWN, setting binder_algo to NULL allows
261
   * for auto-detction.
262
   */
263
0
  (*sc)->binder_algo =
264
0
    (mac == GNUTLS_MAC_UNKNOWN ? NULL : _gnutls_mac_to_entry(mac));
265
0
  return 0;
266
0
}
267
268
/**
269
 * gnutls_psk_set_server_credentials_file:
270
 * @res: is a #gnutls_psk_server_credentials_t type.
271
 * @password_file: is the PSK password file (passwd.psk)
272
 *
273
 * This function sets the password file, in a
274
 * #gnutls_psk_server_credentials_t type.  This password file
275
 * holds usernames and keys and will be used for PSK authentication.
276
 *
277
 * Each entry in the file consists of a username, followed by a colon
278
 * (':') and a hex-encoded key.  If the username contains a colon or
279
 * any other special character, it can be hex-encoded preceded by a
280
 * '#'.
281
 *
282
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
283
 *   an error code is returned.
284
 **/
285
int gnutls_psk_set_server_credentials_file(gnutls_psk_server_credentials_t res,
286
             const char *password_file)
287
0
{
288
0
  if (password_file == NULL) {
289
0
    gnutls_assert();
290
0
    return GNUTLS_E_INVALID_REQUEST;
291
0
  }
292
293
  /* Check if the files can be opened */
294
0
  if (_gnutls_file_exists(password_file) != 0) {
295
0
    gnutls_assert();
296
0
    return GNUTLS_E_FILE_ERROR;
297
0
  }
298
299
0
  res->password_file = gnutls_strdup(password_file);
300
0
  if (res->password_file == NULL) {
301
0
    gnutls_assert();
302
0
    return GNUTLS_E_MEMORY_ERROR;
303
0
  }
304
305
0
  return 0;
306
0
}
307
308
/**
309
 * gnutls_psk_set_server_credentials_hint:
310
 * @res: is a #gnutls_psk_server_credentials_t type.
311
 * @hint: is the PSK identity hint string
312
 *
313
 * This function sets the identity hint, in a
314
 * #gnutls_psk_server_credentials_t type.  This hint is sent to
315
 * the client to help it chose a good PSK credential (i.e., username
316
 * and password).
317
 *
318
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
319
 *   an error code is returned.
320
 *
321
 * Since: 2.4.0
322
 **/
323
int gnutls_psk_set_server_credentials_hint(gnutls_psk_server_credentials_t res,
324
             const char *hint)
325
0
{
326
0
  res->hint = gnutls_strdup(hint);
327
0
  if (res->hint == NULL) {
328
0
    gnutls_assert();
329
0
    return GNUTLS_E_MEMORY_ERROR;
330
0
  }
331
332
0
  return 0;
333
0
}
334
335
static int call_server_callback1(gnutls_session_t session,
336
         const gnutls_datum_t *username,
337
         gnutls_datum_t *key)
338
0
{
339
0
  gnutls_psk_server_credentials_t cred =
340
0
    (gnutls_psk_server_credentials_t)_gnutls_get_cred(
341
0
      session, GNUTLS_CRD_PSK);
342
0
  if (unlikely(cred == NULL))
343
0
    return gnutls_assert_val(-1);
344
345
0
  return cred->pwd_callback1(session, (const char *)username->data, key);
346
0
}
347
348
static int call_server_callback2(gnutls_session_t session,
349
         const gnutls_datum_t *username,
350
         gnutls_datum_t *key,
351
         gnutls_psk_key_flags *flags)
352
0
{
353
0
  gnutls_psk_server_credentials_t cred;
354
0
  int ret;
355
356
0
  cred = (gnutls_psk_server_credentials_t)_gnutls_get_cred(
357
0
    session, GNUTLS_CRD_PSK);
358
0
  if (unlikely(cred == NULL))
359
0
    return gnutls_assert_val(-1);
360
361
0
  ret = cred->pwd_callback2(session, username, key);
362
0
  if (ret >= 0) {
363
0
    if (flags) {
364
0
      *flags = 0;
365
0
    }
366
0
  }
367
0
  return ret;
368
0
}
369
370
/**
371
 * gnutls_psk_set_server_credentials_function:
372
 * @cred: is a #gnutls_psk_server_credentials_t type.
373
 * @func: is the callback function
374
 *
375
 * This function can be used to set a callback to retrieve the user's PSK credentials.
376
 * The callback's function form is:
377
 * int (*callback)(gnutls_session_t, const char* username,
378
 *  gnutls_datum_t* key);
379
 *
380
 * @username contains the actual username.
381
 * The @key must be filled in using the gnutls_malloc().
382
 *
383
 * In case the callback returned a negative number then gnutls will
384
 * assume that the username does not exist.
385
 *
386
 * The callback function will only be called once per handshake.  The
387
 * callback function should return 0 on success, while -1 indicates
388
 * an error.
389
 **/
390
void gnutls_psk_set_server_credentials_function(
391
  gnutls_psk_server_credentials_t cred,
392
  gnutls_psk_server_credentials_function *func)
393
0
{
394
0
  cred->pwd_callback1 = func;
395
0
  cred->pwd_callback2 = call_server_callback1;
396
0
  cred->pwd_callback = call_server_callback2;
397
0
}
398
399
/**
400
 * gnutls_psk_set_server_credentials_function2:
401
 * @cred: is a #gnutls_psk_server_credentials_t type.
402
 * @func: is the callback function
403
 *
404
 * This function can be used to set a callback to retrieve the user's PSK credentials.
405
 * The callback's function form is:
406
 * int (*callback)(gnutls_session_t, const gnutls_datum_t* username,
407
 *  gnutls_datum_t* key);
408
 *
409
 * This callback function has the same semantics as that of gnutls_psk_set_server_credentials_function(),
410
 * but it allows non-string usernames to be used.
411
 *
412
 * @username contains the actual username.
413
 * The @key must be filled in using the gnutls_malloc().
414
 *
415
 * In case the callback returned a negative number then gnutls will
416
 * assume that the username does not exist.
417
 *
418
 * The callback function will only be called once per handshake.  The
419
 * callback function should return 0 on success, while -1 indicates
420
 * an error.
421
 **/
422
void gnutls_psk_set_server_credentials_function2(
423
  gnutls_psk_server_credentials_t cred,
424
  gnutls_psk_server_credentials_function2 func)
425
0
{
426
0
  cred->pwd_callback1 = NULL;
427
0
  cred->pwd_callback2 = func;
428
0
  cred->pwd_callback = call_server_callback2;
429
0
}
430
431
/**
432
 * gnutls_psk_set_server_credentials_function3:
433
 * @cred: is a #gnutls_psk_server_credentials_t type.
434
 * @func: is the callback function
435
 *
436
 * This function can be used to set a callback to retrieve the user's PSK credentials.
437
 * The callback's function form is:
438
 * int (*callback)(gnutls_session_t, const gnutls_datum_t* username,
439
 *  gnutls_datum_t* key, gnutls_psk_key_flags *flags);
440
 *
441
 * This callback function has the same semantics as that of
442
 * gnutls_psk_set_server_credentials_function2(), but it returns flags
443
 * associated with the key.  The callback may import external PSK
444
 * using the method described in RFC 9258 by using
445
 * gnutls_psk_format_imported_identity().
446
 *
447
 * @username contains the actual username.
448
 * The @key must be filled in using the gnutls_malloc().
449
 *
450
 * In case the callback returned a negative number then gnutls will
451
 * assume that the username does not exist.
452
 *
453
 * The callback function will only be called once per handshake.  The
454
 * callback function should return 0 on success, while -1 indicates
455
 * an error.
456
 **/
457
void gnutls_psk_set_server_credentials_function3(
458
  gnutls_psk_server_credentials_t cred,
459
  gnutls_psk_server_credentials_function3 func)
460
0
{
461
0
  cred->pwd_callback1 = NULL;
462
0
  cred->pwd_callback2 = NULL;
463
0
  cred->pwd_callback = func;
464
0
}
465
466
static int call_client_callback1(gnutls_session_t session,
467
         gnutls_datum_t *username, gnutls_datum_t *key)
468
0
{
469
0
  gnutls_psk_client_credentials_t cred;
470
0
  int ret;
471
0
  char *user_p;
472
473
0
  cred = (gnutls_psk_client_credentials_t)_gnutls_get_cred(
474
0
    session, GNUTLS_CRD_PSK);
475
0
  if (unlikely(cred == NULL))
476
0
    return gnutls_assert_val(-1);
477
478
0
  ret = cred->get_function1(session, &user_p, key);
479
0
  if (ret >= 0) {
480
0
    username->data = (uint8_t *)user_p;
481
0
    username->size = strlen(user_p);
482
0
  }
483
484
0
  return ret;
485
0
}
486
487
static int call_client_callback2(gnutls_session_t session,
488
         gnutls_datum_t *username, gnutls_datum_t *key,
489
         gnutls_psk_key_flags *flags)
490
0
{
491
0
  gnutls_psk_client_credentials_t cred;
492
0
  int ret;
493
494
0
  cred = (gnutls_psk_client_credentials_t)_gnutls_get_cred(
495
0
    session, GNUTLS_CRD_PSK);
496
0
  if (unlikely(cred == NULL))
497
0
    return gnutls_assert_val(-1);
498
499
0
  ret = cred->get_function2(session, username, key);
500
0
  if (ret < 0) {
501
0
    return ret;
502
0
  }
503
504
0
  if (flags) {
505
0
    *flags = 0;
506
0
  }
507
508
0
  return ret;
509
0
}
510
511
/**
512
 * gnutls_psk_set_client_credentials_function:
513
 * @cred: is a #gnutls_psk_server_credentials_t type.
514
 * @func: is the callback function
515
 *
516
 * This function can be used to set a callback to retrieve the username and
517
 * password for client PSK authentication.
518
 * The callback's function form is:
519
 * int (*callback)(gnutls_session_t, char** username,
520
 *  gnutls_datum_t* key);
521
 *
522
 * The @username and @key->data must be allocated using gnutls_malloc().
523
 * The @username should be an ASCII string or UTF-8
524
 * string. In case of a UTF-8 string it is recommended to be following
525
 * the PRECIS framework for usernames (rfc8265).
526
 *
527
 * The callback function will be called once per handshake.
528
 *
529
 * The callback function should return 0 on success.
530
 * -1 indicates an error.
531
 **/
532
void gnutls_psk_set_client_credentials_function(
533
  gnutls_psk_client_credentials_t cred,
534
  gnutls_psk_client_credentials_function *func)
535
0
{
536
0
  cred->get_function1 = func;
537
0
  cred->get_function2 = call_client_callback1;
538
0
  cred->get_function = call_client_callback2;
539
0
}
540
541
/**
542
 * gnutls_psk_set_client_credentials_function2:
543
 * @cred: is a #gnutls_psk_server_credentials_t type.
544
 * @func: is the callback function
545
 *
546
 * This function can be used to set a callback to retrieve the username and
547
 * password for client PSK authentication.
548
 * The callback's function form is:
549
 * int (*callback)(gnutls_session_t, gnutls_datum_t* username,
550
 *  gnutls_datum_t* key);
551
 *
552
 * This callback function has the same semantics as that of gnutls_psk_set_client_credentials_function(),
553
 * but it allows non-string usernames to be used.
554
 *
555
 * The @username and @key->data must be allocated using gnutls_malloc().
556
 * The @username should be an ASCII string or UTF-8
557
 * string. In case of a UTF-8 string it is recommended to be following
558
 * the PRECIS framework for usernames (rfc8265).
559
 *
560
 * The callback function will be called once per handshake.
561
 *
562
 * The callback function should return 0 on success.
563
 * -1 indicates an error.
564
 **/
565
void gnutls_psk_set_client_credentials_function2(
566
  gnutls_psk_client_credentials_t cred,
567
  gnutls_psk_client_credentials_function2 *func)
568
0
{
569
0
  cred->get_function1 = NULL;
570
0
  cred->get_function2 = func;
571
0
  cred->get_function = call_client_callback2;
572
0
}
573
574
/**
575
 * gnutls_psk_set_client_credentials_function3:
576
 * @cred: is a #gnutls_psk_server_credentials_t type.
577
 * @func: is the callback function
578
 *
579
 * This function can be used to set a callback to retrieve the username and
580
 * password for client PSK authentication.
581
 * The callback's function form is:
582
 * int (*callback)(gnutls_session_t, gnutls_datum_t* username,
583
 *  gnutls_datum_t* key, gnutls_datum_t* context, gnutls_psk_key_flags *flags);
584
 *
585
 * This callback function has the same semantics as that of
586
 * gnutls_psk_set_client_credentials_function2(), but it returns flags
587
 * associated with the key.  The callback may import external PSK
588
 * using the method described in RFC 9258 by using
589
 * gnutls_psk_format_imported_identity().
590
 *
591
 * The data field of @username, @key, and @context must be allocated
592
 * using gnutls_malloc().  The @username should be an ASCII string or
593
 * UTF-8 string. In case of a UTF-8 string it is recommended to be
594
 * following the PRECIS framework for usernames (rfc8265).
595
 *
596
 * The callback function will be called once per handshake.
597
 *
598
 * The callback function should return 0 on success.
599
 * -1 indicates an error.
600
 **/
601
void gnutls_psk_set_client_credentials_function3(
602
  gnutls_psk_client_credentials_t cred,
603
  gnutls_psk_client_credentials_function3 *func)
604
0
{
605
0
  cred->get_function1 = NULL;
606
0
  cred->get_function2 = NULL;
607
0
  cred->get_function = func;
608
0
}
609
610
/**
611
 * gnutls_psk_server_get_username:
612
 * @session: is a gnutls session
613
 *
614
 * This should only be called in case of PSK authentication and in
615
 * case of a server.
616
 *
617
 * The returned pointer should be considered constant (do not free) and valid 
618
 * for the lifetime of the session.
619
 *
620
 * This function will return %NULL if the username has embedded NULL bytes.
621
 * In that case, gnutls_psk_server_get_username2() should be used to retrieve the username.
622
 *
623
 * Returns: the username of the peer, or %NULL in case of an error,
624
 * or if the username has embedded NULLs.
625
 **/
626
const char *gnutls_psk_server_get_username(gnutls_session_t session)
627
0
{
628
0
  psk_auth_info_t info;
629
630
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_PSK, NULL);
631
632
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
633
0
  if (info == NULL)
634
0
    return NULL;
635
636
0
  if (info->username && !memchr(info->username, '\0', info->username_len))
637
0
    return info->username;
638
639
0
  return NULL;
640
0
}
641
642
/**
643
 * gnutls_psk_server_get_username2:
644
 * @session: is a gnutls session
645
 * @username: a datum that will be filled in by this function
646
 *
647
 * Return a pointer to the username of the peer in the supplied datum. Does not
648
 * need to be null-terminated.
649
 *
650
 * This should only be called in case of PSK authentication and in
651
 * case of a server.
652
 *
653
 * The returned pointer should be considered constant (do not free) and valid 
654
 * for the lifetime of the session.
655
 *
656
 * Returns: %GNUTLS_E_SUCCESS, or a negative value in case of an error.
657
 **/
658
int gnutls_psk_server_get_username2(gnutls_session_t session,
659
            gnutls_datum_t *username)
660
0
{
661
0
  psk_auth_info_t info;
662
663
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_PSK, GNUTLS_E_INVALID_REQUEST);
664
665
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
666
0
  if (info == NULL)
667
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
668
669
0
  if (info->username_len > 0) {
670
0
    username->data = (unsigned char *)info->username;
671
0
    username->size = info->username_len;
672
0
    return 0;
673
0
  }
674
675
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
676
0
}
677
678
/**
679
 * gnutls_psk_client_get_hint:
680
 * @session: is a gnutls session
681
 *
682
 * The PSK identity hint may give the client help in deciding which
683
 * username to use.  This should only be called in case of PSK
684
 * authentication and in case of a client.
685
 *
686
 * Note: there is no hint in TLS 1.3, so this function will return %NULL
687
 * if TLS 1.3 has been negotiated.
688
 *
689
 * Returns: the identity hint of the peer, or %NULL in case of an error or if TLS 1.3 is being used.
690
 *
691
 * Since: 2.4.0
692
 **/
693
const char *gnutls_psk_client_get_hint(gnutls_session_t session)
694
0
{
695
0
  psk_auth_info_t info;
696
697
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_PSK, NULL);
698
699
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
700
0
  return info ? info->hint : NULL;
701
0
}
702
703
/**
704
 * gnutls_psk_set_server_dh_params:
705
 * @res: is a gnutls_psk_server_credentials_t type
706
 * @dh_params: is a structure that holds Diffie-Hellman parameters.
707
 *
708
 * This function will set the Diffie-Hellman parameters for an
709
 * anonymous server to use. These parameters will be used in
710
 * Diffie-Hellman exchange with PSK cipher suites.
711
 *
712
 * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
713
 * or later. Since 3.6.0, DH parameters are negotiated
714
 * following RFC7919.
715
 *
716
 **/
717
void gnutls_psk_set_server_dh_params(gnutls_psk_server_credentials_t res,
718
             gnutls_dh_params_t dh_params)
719
0
{
720
0
  if (res->deinit_dh_params) {
721
0
    res->deinit_dh_params = 0;
722
0
    gnutls_dh_params_deinit(res->dh_params);
723
0
    res->dh_params = NULL;
724
0
  }
725
726
0
  res->dh_params = dh_params;
727
0
  res->dh_sec_param = gnutls_pk_bits_to_sec_param(
728
0
    GNUTLS_PK_DH, _gnutls_mpi_get_nbits(dh_params->params[0]));
729
0
}
730
731
/**
732
 * gnutls_psk_set_server_known_dh_params:
733
 * @res: is a gnutls_psk_server_credentials_t type
734
 * @sec_param: is an option of the %gnutls_sec_param_t enumeration
735
 *
736
 * This function will set the Diffie-Hellman parameters for a
737
 * PSK server to use. These parameters will be used in
738
 * Ephemeral Diffie-Hellman cipher suites and will be selected from
739
 * the FFDHE set of RFC7919 according to the security level provided.
740
 *
741
 * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
742
 * or later. Since 3.6.0, DH parameters are negotiated
743
 * following RFC7919.
744
 *
745
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
746
 *   negative error value.
747
 *
748
 * Since: 3.5.6
749
 **/
750
int gnutls_psk_set_server_known_dh_params(gnutls_psk_server_credentials_t res,
751
            gnutls_sec_param_t sec_param)
752
0
{
753
0
  res->dh_sec_param = sec_param;
754
755
0
  return 0;
756
0
}
757
758
/**
759
 * gnutls_psk_set_server_params_function:
760
 * @res: is a #gnutls_certificate_credentials_t type
761
 * @func: is the function to be called
762
 *
763
 * This function will set a callback in order for the server to get
764
 * the Diffie-Hellman parameters for PSK authentication.  The callback
765
 * should return %GNUTLS_E_SUCCESS (0) on success.
766
 *
767
 * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
768
 * or later. Since 3.6.0, DH parameters are negotiated
769
 * following RFC7919.
770
 *
771
 **/
772
void gnutls_psk_set_server_params_function(gnutls_psk_server_credentials_t res,
773
             gnutls_params_function *func)
774
0
{
775
0
  res->params_func = func;
776
0
}
777
778
/**
779
 * gnutls_psk_set_params_function:
780
 * @res: is a gnutls_psk_server_credentials_t type
781
 * @func: is the function to be called
782
 *
783
 * This function will set a callback in order for the server to get
784
 * the Diffie-Hellman or RSA parameters for PSK authentication.  The
785
 * callback should return %GNUTLS_E_SUCCESS (0) on success.
786
 *
787
 * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
788
 * or later. Since 3.6.0, DH parameters are negotiated
789
 * following RFC7919.
790
 *
791
 **/
792
void gnutls_psk_set_params_function(gnutls_psk_server_credentials_t res,
793
            gnutls_params_function *func)
794
0
{
795
0
  res->params_func = func;
796
0
}
797
798
#endif /* ENABLE_PSK */