Coverage Report

Created: 2026-08-14 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/ext/pre_shared_key.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2017-2018 Free Software Foundation, Inc.
3
 * Copyright (C) 2018 Red Hat, Inc.
4
 *
5
 * Author: Ander Juaristi, Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS 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.
13
 *
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.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
#include "gnutls_int.h"
25
#include "auth/psk.h"
26
#include "handshake.h"
27
#include "kx.h"
28
#include "secrets.h"
29
#include "tls13/anti_replay.h"
30
#include "tls13/psk_ext_parser.h"
31
#include "tls13/finished.h"
32
#include "tls13/session_ticket.h"
33
#include "auth/psk_passwd.h"
34
#include "ext/session_ticket.h"
35
#include "ext/pre_shared_key.h"
36
#include <assert.h>
37
38
inline static bool
39
have_psk_credentials(const gnutls_psk_client_credentials_t cred,
40
         gnutls_session_t session)
41
0
{
42
0
  return (cred->get_function || cred->username.data) &&
43
0
         session->internals.priorities->have_psk;
44
0
}
45
46
static int compute_psk_from_ticket(const tls13_ticket_st *ticket,
47
           gnutls_datum_t *key)
48
0
{
49
0
  int ret;
50
51
0
  if (unlikely(ticket->prf == NULL || ticket->prf->output_size == 0))
52
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
53
54
0
  key->data = gnutls_malloc(ticket->prf->output_size);
55
0
  if (!key->data) {
56
0
    gnutls_assert();
57
0
    return GNUTLS_E_MEMORY_ERROR;
58
0
  }
59
0
  key->size = ticket->prf->output_size;
60
61
0
  ret = _tls13_expand_secret2(ticket->prf, RESUMPTION_LABEL,
62
0
            sizeof(RESUMPTION_LABEL) - 1, ticket->nonce,
63
0
            ticket->nonce_size,
64
0
            ticket->resumption_master_secret, key->size,
65
0
            key->data);
66
0
  if (ret < 0)
67
0
    gnutls_assert();
68
69
0
  return ret;
70
0
}
71
72
enum binder_type {
73
  BINDER_EXT,
74
  BINDER_RES,
75
  BINDER_IMP
76
};
77
78
static const char *get_binder_label(enum binder_type type, size_t *size)
79
0
{
80
0
  static const char ext_label[] = EXT_BINDER_LABEL;
81
0
  static const char res_label[] = RES_BINDER_LABEL;
82
0
  static const char imp_label[] = IMP_BINDER_LABEL;
83
0
  const char *label;
84
85
0
  switch (type) {
86
0
  case BINDER_EXT:
87
0
    label = ext_label;
88
0
    *size = sizeof(ext_label) - 1;
89
0
    break;
90
0
  case BINDER_RES:
91
0
    label = res_label;
92
0
    *size = sizeof(res_label) - 1;
93
0
    break;
94
0
  case BINDER_IMP:
95
0
    label = imp_label;
96
0
    *size = sizeof(imp_label) - 1;
97
0
    break;
98
0
  default:
99
0
    assert(0);
100
0
  }
101
102
0
  return label;
103
0
}
104
105
static int compute_binder_key(const mac_entry_st *prf, const uint8_t *key,
106
            size_t keylen, enum binder_type type, void *out)
107
0
{
108
0
  int ret;
109
0
  size_t label_len;
110
0
  const char *label = get_binder_label(type, &label_len);
111
0
  uint8_t tmp_key[MAX_HASH_SIZE];
112
113
  /* Compute HKDF-Extract(0, psk) */
114
0
  ret = _tls13_init_secret2(prf, key, keylen, tmp_key);
115
0
  if (ret < 0)
116
0
    return ret;
117
118
  /* Compute Derive-Secret(secret, label, transcript_hash) */
119
0
  ret = _tls13_derive_secret2(prf, label, label_len, NULL, 0, tmp_key,
120
0
            out);
121
0
  if (ret < 0)
122
0
    return ret;
123
124
0
  return 0;
125
0
}
126
127
static int compute_psk_binder(gnutls_session_t session, const mac_entry_st *prf,
128
            unsigned binders_length, int exts_length,
129
            int ext_offset, const gnutls_datum_t *psk,
130
            const gnutls_datum_t *client_hello,
131
            enum binder_type type, void *out)
132
0
{
133
0
  int ret;
134
0
  unsigned client_hello_pos, extensions_len_pos;
135
0
  gnutls_buffer_st handshake_buf;
136
0
  uint8_t binder_key[MAX_HASH_SIZE];
137
138
0
  _gnutls_buffer_init(&handshake_buf);
139
140
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
141
0
    if (session->internals.hsk_flags & HSK_HRR_RECEIVED) {
142
0
      ret = gnutls_buffer_append_data(
143
0
        &handshake_buf,
144
0
        (const void *)session->internals
145
0
          .handshake_hash_buffer.data,
146
0
        session->internals.handshake_hash_buffer.length);
147
0
      if (ret < 0) {
148
0
        gnutls_assert();
149
0
        goto error;
150
0
      }
151
0
    }
152
153
0
    client_hello_pos = handshake_buf.length;
154
0
    ret = gnutls_buffer_append_data(
155
0
      &handshake_buf, client_hello->data, client_hello->size);
156
0
    if (ret < 0) {
157
0
      gnutls_assert();
158
0
      goto error;
159
0
    }
160
161
    /* This is a ClientHello message */
162
0
    handshake_buf.data[client_hello_pos] =
163
0
      GNUTLS_HANDSHAKE_CLIENT_HELLO;
164
165
    /* At this point we have not yet added the binders to the ClientHello,
166
     * but we have to overwrite the size field, pretending as if binders
167
     * of the correct length were present.
168
     */
169
0
    _gnutls_write_uint24(handshake_buf.length - client_hello_pos +
170
0
               binders_length - 2,
171
0
             &handshake_buf.data[client_hello_pos + 1]);
172
0
    _gnutls_write_uint16(
173
0
      handshake_buf.length - client_hello_pos +
174
0
        binders_length - ext_offset,
175
0
      &handshake_buf.data[client_hello_pos + ext_offset]);
176
0
    extensions_len_pos = handshake_buf.length - client_hello_pos -
177
0
             exts_length - 2;
178
0
    _gnutls_write_uint16(exts_length + binders_length + 2,
179
0
             &handshake_buf.data[client_hello_pos +
180
0
               extensions_len_pos]);
181
0
  } else {
182
0
    if (session->internals.hsk_flags & HSK_HRR_SENT) {
183
0
      if (unlikely(session->internals.handshake_hash_buffer
184
0
               .length <= client_hello->size)) {
185
0
        ret = gnutls_assert_val(
186
0
          GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
187
0
        goto error;
188
0
      }
189
190
0
      ret = gnutls_buffer_append_data(
191
0
        &handshake_buf,
192
0
        session->internals.handshake_hash_buffer.data,
193
0
        session->internals.handshake_hash_buffer.length -
194
0
          client_hello->size);
195
0
      if (ret < 0) {
196
0
        gnutls_assert();
197
0
        goto error;
198
0
      }
199
0
    }
200
201
0
    if (unlikely(client_hello->size <= binders_length)) {
202
0
      ret = gnutls_assert_val(
203
0
        GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
204
0
      goto error;
205
0
    }
206
207
0
    ret = gnutls_buffer_append_data(
208
0
      &handshake_buf, (const void *)client_hello->data,
209
0
      client_hello->size - binders_length);
210
0
    if (ret < 0) {
211
0
      gnutls_assert();
212
0
      goto error;
213
0
    }
214
0
  }
215
216
0
  ret = compute_binder_key(prf, psk->data, psk->size, type, binder_key);
217
0
  if (ret < 0) {
218
0
    gnutls_assert();
219
0
    goto error;
220
0
  }
221
222
0
  ret = _gnutls13_compute_finished(prf, binder_key, &handshake_buf, out);
223
0
  if (ret < 0) {
224
0
    gnutls_assert();
225
0
    goto error;
226
0
  }
227
228
0
  ret = 0;
229
0
error:
230
0
  _gnutls_buffer_clear(&handshake_buf);
231
0
  return ret;
232
0
}
233
234
static int generate_early_secrets(gnutls_session_t session,
235
          const mac_entry_st *prf)
236
0
{
237
0
  int ret;
238
239
0
  ret = _tls13_derive_secret2(
240
0
    prf, EARLY_TRAFFIC_LABEL, sizeof(EARLY_TRAFFIC_LABEL) - 1,
241
0
    session->internals.handshake_hash_buffer.data,
242
0
    session->internals.handshake_hash_buffer_client_hello_len,
243
0
    session->key.proto.tls13.temp_secret,
244
0
    session->key.proto.tls13.e_ckey);
245
0
  if (ret < 0)
246
0
    return gnutls_assert_val(ret);
247
248
0
  ret = _gnutls_call_keylog_func(session, "CLIENT_EARLY_TRAFFIC_SECRET",
249
0
               session->key.proto.tls13.e_ckey,
250
0
               prf->output_size);
251
0
  if (ret < 0)
252
0
    return gnutls_assert_val(ret);
253
254
0
  ret = _tls13_derive_secret2(
255
0
    prf, EARLY_EXPORTER_MASTER_LABEL,
256
0
    sizeof(EARLY_EXPORTER_MASTER_LABEL) - 1,
257
0
    session->internals.handshake_hash_buffer.data,
258
0
    session->internals.handshake_hash_buffer_client_hello_len,
259
0
    session->key.proto.tls13.temp_secret,
260
0
    session->key.proto.tls13.ap_expkey);
261
0
  if (ret < 0)
262
0
    return gnutls_assert_val(ret);
263
264
0
  ret = _gnutls_call_keylog_func(session, "EARLY_EXPORTER_SECRET",
265
0
               session->key.proto.tls13.ap_expkey,
266
0
               prf->output_size);
267
0
  if (ret < 0)
268
0
    return gnutls_assert_val(ret);
269
270
0
  return 0;
271
0
}
272
273
/* Calculate TLS 1.3 Early Secret and the derived secrets from the
274
 * selected PSK. */
275
int _gnutls_generate_early_secrets_for_psk(gnutls_session_t session)
276
0
{
277
0
  const uint8_t *psk;
278
0
  size_t psk_size;
279
0
  const mac_entry_st *prf;
280
0
  int ret;
281
282
0
  psk = session->key.binders[0].psk.data;
283
0
  psk_size = session->key.binders[0].psk.size;
284
0
  prf = session->key.binders[0].prf;
285
286
0
  if (unlikely(psk_size == 0))
287
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
288
289
0
  ret = _tls13_init_secret2(prf, psk, psk_size,
290
0
          session->key.proto.tls13.temp_secret);
291
0
  if (ret < 0)
292
0
    return gnutls_assert_val(ret);
293
294
0
  session->key.proto.tls13.temp_secret_size = prf->output_size;
295
296
0
  ret = generate_early_secrets(session, session->key.binders[0].prf);
297
0
  if (ret < 0)
298
0
    return gnutls_assert_val(ret);
299
300
0
  return 0;
301
0
}
302
303
/**
304
 * gnutls_psk_format_imported_identity:
305
 * @identity: external identity
306
 * @context: optional contextual information
307
 * @version: protocol version to which the PSK is imported
308
 * @hash: hash algorithm used for KDF
309
 * @imported_identity: where the imported identity is stored
310
 *
311
 * This formats an external PSK identity @identity into an imported
312
 * form, described in RFC 9258 as ImportedIdentity.
313
 *
314
 * Upon success, the data field of @imported_identity is allocated
315
 * using gnutls_malloc() and the caller must free the memory after
316
 * use.
317
 *
318
 * Returns: %GNUTLS_E_SUCCESS (0) on success, otherwise a negative error code.
319
 * Since: 3.8.1
320
 */
321
int gnutls_psk_format_imported_identity(const gnutls_datum_t *identity,
322
          const gnutls_datum_t *context,
323
          gnutls_protocol_t version,
324
          gnutls_digest_algorithm_t hash,
325
          gnutls_datum_t *imported_identity)
326
0
{
327
0
  gnutls_buffer_st buf;
328
0
  const version_entry_st *ver = version_to_entry(version);
329
0
  const mac_entry_st *prf = hash_to_entry(hash);
330
0
  uint16_t target_protocol;
331
0
  uint16_t target_kdf;
332
0
  int ret;
333
334
0
  _gnutls_buffer_init(&buf);
335
336
  /* external_identity */
337
0
  ret = _gnutls_buffer_append_data_prefix16(&buf, identity->data,
338
0
              identity->size);
339
0
  if (ret < 0) {
340
0
    goto error;
341
0
  }
342
343
  /* context */
344
0
  ret = _gnutls_buffer_append_data_prefix16(&buf, context->data,
345
0
              context->size);
346
0
  if (ret < 0) {
347
0
    goto error;
348
0
  }
349
350
  /* target_protocol */
351
0
  target_protocol = ver->major << 8 | ver->minor;
352
0
  ret = _gnutls_buffer_append_uint16(&buf, target_protocol);
353
0
  if (ret < 0) {
354
0
    goto error;
355
0
  }
356
357
  /* target_kdf */
358
0
  switch (prf->id) {
359
0
  case GNUTLS_MAC_SHA256:
360
0
    target_kdf = 0x0001;
361
0
    break;
362
0
  case GNUTLS_MAC_SHA384:
363
0
    target_kdf = 0x0002;
364
0
    break;
365
0
  default:
366
0
    ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
367
0
    goto error;
368
0
  }
369
0
  ret = _gnutls_buffer_append_uint16(&buf, target_kdf);
370
0
  if (ret < 0) {
371
0
    goto error;
372
0
  }
373
374
0
  ret = _gnutls_buffer_to_datum(&buf, imported_identity, 0);
375
0
  if (ret < 0) {
376
0
    goto error;
377
0
  }
378
0
  return 0;
379
380
0
error:
381
0
  _gnutls_buffer_clear(&buf);
382
0
  return ret;
383
0
}
384
385
static int derive_ipsk(const mac_entry_st *prf,
386
           const gnutls_datum_t *imported_identity,
387
           const gnutls_datum_t *epsk, uint8_t ipsk[MAX_HASH_SIZE])
388
0
{
389
0
  uint8_t epskx[MAX_HASH_SIZE];
390
0
  uint8_t hashed_identity[MAX_HASH_SIZE];
391
0
  int ret;
392
393
  /* epskx = HKDF-Extract(0, epsk) */
394
0
  ret = _tls13_init_secret2(prf, epsk->data, epsk->size, epskx);
395
0
  if (ret < 0) {
396
0
    return ret;
397
0
  }
398
0
  ret = gnutls_hash_fast((gnutls_digest_algorithm_t)prf->id,
399
0
             imported_identity->data, imported_identity->size,
400
0
             hashed_identity);
401
0
  if (ret < 0) {
402
0
    return ret;
403
0
  }
404
  /* ipskx = HKDF-Expand-Label(epskx, "derived psk", Hash(ImportedIdentity), L) */
405
0
  return _tls13_expand_secret2(prf, DERIVED_PSK_LABEL,
406
0
             sizeof(DERIVED_PSK_LABEL) - 1,
407
0
             hashed_identity, prf->output_size, epskx,
408
0
             prf->output_size, ipsk);
409
0
}
410
411
/* This does the opposite of gnutls_psk_format_imported_identity.
412
 * Note that this does not allocate memory, and the data field of
413
 * identity and context must not be freed.
414
 */
415
static int parse_imported_identity(const gnutls_datum_t *imported_identity,
416
           gnutls_datum_t *identity,
417
           gnutls_datum_t *context,
418
           gnutls_protocol_t *version,
419
           gnutls_digest_algorithm_t *hash)
420
0
{
421
0
  uint16_t target_protocol;
422
0
  uint16_t target_kdf;
423
0
  gnutls_buffer_st buf;
424
0
  int ret;
425
426
0
  _gnutls_ro_buffer_from_datum(&buf, (gnutls_datum_t *)imported_identity);
427
428
  /* external_identity */
429
0
  ret = _gnutls_buffer_pop_datum_prefix16(&buf, identity);
430
0
  if (ret < 0) {
431
0
    return ret;
432
0
  }
433
434
  /* context */
435
0
  ret = _gnutls_buffer_pop_datum_prefix16(&buf, context);
436
0
  if (ret < 0) {
437
0
    return ret;
438
0
  }
439
440
  /* target_protocol */
441
0
  ret = _gnutls_buffer_pop_uint16(&buf, &target_protocol);
442
0
  if (ret < 0) {
443
0
    return ret;
444
0
  }
445
0
  *version = _gnutls_version_get((target_protocol >> 8) & 0xFF,
446
0
               target_protocol & 0xFF);
447
448
  /* target_kdf */
449
0
  ret = _gnutls_buffer_pop_uint16(&buf, &target_kdf);
450
0
  if (ret < 0) {
451
0
    return ret;
452
0
  }
453
0
  switch (target_kdf) {
454
0
  case 0x0001:
455
0
    *hash = GNUTLS_DIG_SHA256;
456
0
    break;
457
0
  case 0x0002:
458
0
    *hash = GNUTLS_DIG_SHA384;
459
0
    break;
460
0
  default:
461
0
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
462
0
  }
463
0
  return 0;
464
0
}
465
466
static int client_send_params(gnutls_session_t session, gnutls_buffer_t extdata,
467
            const gnutls_psk_client_credentials_t cred)
468
0
{
469
0
  int ret, ext_offset = 0;
470
0
  uint8_t binder_value[MAX_HASH_SIZE];
471
0
  size_t spos;
472
0
  gnutls_datum_t username = { NULL, 0 };
473
0
  gnutls_datum_t user_key = { NULL, 0 }, rkey = { NULL, 0 };
474
0
  unsigned client_hello_len;
475
0
  unsigned next_idx;
476
0
  const mac_entry_st *prf_res = NULL;
477
0
  const mac_entry_st *prf_psk = NULL;
478
0
  struct timespec cur_time;
479
0
  uint32_t ticket_age, ob_ticket_age;
480
0
  int free_username = 0;
481
0
  psk_auth_info_t info = NULL;
482
0
  unsigned psk_id_len = 0;
483
0
  unsigned binders_len, binders_pos;
484
0
  bool imported = false;
485
0
  tls13_ticket_st *ticket = &session->internals.tls13_ticket;
486
487
0
  if (((session->internals.flags & GNUTLS_NO_TICKETS) ||
488
0
       session->internals.tls13_ticket.ticket.data == NULL) &&
489
0
      (!cred || !have_psk_credentials(cred, session))) {
490
0
    return 0;
491
0
  }
492
493
0
  binders_len = 0;
494
495
  /* placeholder to be filled later */
496
0
  spos = extdata->length;
497
0
  ret = _gnutls_buffer_append_uint16(extdata, 0);
498
0
  if (ret < 0)
499
0
    return gnutls_assert_val(ret);
500
501
  /* First, let's see if we have a session ticket to send */
502
0
  if (!(session->internals.flags & GNUTLS_NO_TICKETS) &&
503
0
      ticket->ticket.data != NULL) {
504
    /* We found a session ticket */
505
0
    if (unlikely(ticket->prf == NULL)) {
506
0
      tls13_ticket_deinit(ticket);
507
0
      ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
508
0
      goto cleanup;
509
0
    }
510
511
0
    prf_res = ticket->prf;
512
513
0
    gnutls_gettime(&cur_time);
514
0
    if (unlikely(_gnutls_timespec_cmp(&cur_time,
515
0
              &ticket->arrival_time) < 0)) {
516
0
      gnutls_assert();
517
0
      tls13_ticket_deinit(ticket);
518
0
      goto ignore_ticket;
519
0
    }
520
521
    /* Check whether the ticket is stale */
522
0
    ticket_age = timespec_sub_ms(&cur_time, &ticket->arrival_time);
523
0
    if (ticket_age / 1000 > ticket->lifetime) {
524
0
      tls13_ticket_deinit(ticket);
525
0
      goto ignore_ticket;
526
0
    }
527
528
0
    ret = compute_psk_from_ticket(ticket, &rkey);
529
0
    if (ret < 0) {
530
0
      tls13_ticket_deinit(ticket);
531
0
      goto ignore_ticket;
532
0
    }
533
534
    /* Calculate obfuscated ticket age, in milliseconds, mod 2^32 */
535
0
    ob_ticket_age = ticket_age + ticket->age_add;
536
537
0
    if ((ret = _gnutls_buffer_append_data_prefix16(
538
0
           extdata, ticket->ticket.data,
539
0
           ticket->ticket.size)) < 0) {
540
0
      gnutls_assert();
541
0
      goto cleanup;
542
0
    }
543
544
    /* Now append the obfuscated ticket age */
545
0
    if ((ret = _gnutls_buffer_append_uint32(extdata,
546
0
              ob_ticket_age)) < 0) {
547
0
      gnutls_assert();
548
0
      goto cleanup;
549
0
    }
550
551
0
    psk_id_len += 6 + ticket->ticket.size;
552
0
    binders_len += 1 + _gnutls_mac_get_algo_len(prf_res);
553
0
  }
554
555
0
ignore_ticket:
556
0
  if (cred && have_psk_credentials(cred, session)) {
557
0
    gnutls_datum_t tkey;
558
0
    gnutls_psk_key_flags flags;
559
560
0
    if (cred->binder_algo == NULL) {
561
0
      gnutls_assert();
562
0
      ret = gnutls_assert_val(
563
0
        GNUTLS_E_INSUFFICIENT_CREDENTIALS);
564
0
      goto cleanup;
565
0
    }
566
567
0
    prf_psk = cred->binder_algo;
568
569
0
    ret = _gnutls_find_psk_key(session, cred, &username, &tkey,
570
0
             &flags, &free_username);
571
0
    if (ret < 0) {
572
0
      gnutls_assert();
573
0
      goto cleanup;
574
0
    }
575
576
0
    if (username.size == 0 || username.size > UINT16_MAX) {
577
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_PASSWORD);
578
0
      goto cleanup;
579
0
    }
580
581
0
    if (!free_username) {
582
      /* we need to copy the key */
583
0
      ret = _gnutls_set_datum(&user_key, tkey.data,
584
0
            tkey.size);
585
0
      if (ret < 0) {
586
0
        gnutls_assert();
587
0
        goto cleanup;
588
0
      }
589
0
    } else {
590
0
      user_key.data = tkey.data;
591
0
      user_key.size = tkey.size;
592
0
    }
593
594
0
    if (flags & GNUTLS_PSK_KEY_EXT) {
595
0
      uint8_t ipsk[MAX_HASH_SIZE];
596
0
      gnutls_datum_t imported_identity = { NULL, 0 };
597
0
      gnutls_datum_t context = { NULL, 0 };
598
0
      gnutls_protocol_t version;
599
0
      gnutls_digest_algorithm_t hash;
600
0
      const version_entry_st *vers;
601
602
0
      ret = parse_imported_identity(&username,
603
0
                  &imported_identity,
604
0
                  &context, &version,
605
0
                  &hash);
606
0
      if (ret < 0) {
607
0
        gnutls_assert();
608
0
        goto cleanup;
609
0
      }
610
611
0
      vers = version_to_entry(version);
612
0
      if (unlikely(!vers || !vers->tls13_sem)) {
613
0
        gnutls_assert();
614
0
        goto cleanup;
615
0
      }
616
0
      if (hash != MAC_TO_DIG(prf_psk->id)) {
617
0
        gnutls_assert();
618
0
        goto cleanup;
619
0
      }
620
621
0
      ret = derive_ipsk(prf_psk, &username, &user_key, ipsk);
622
0
      if (ret < 0) {
623
0
        gnutls_assert();
624
0
        goto cleanup;
625
0
      }
626
627
0
      _gnutls_free_datum(&user_key);
628
0
      ret = _gnutls_set_datum(&user_key, ipsk,
629
0
            prf_psk->output_size);
630
0
      zeroize_key(ipsk, sizeof(ipsk));
631
0
      if (ret < 0) {
632
0
        gnutls_assert();
633
0
        goto cleanup;
634
0
      }
635
0
      imported = true;
636
0
    }
637
638
0
    ret = _gnutls_auth_info_init(session, GNUTLS_CRD_PSK,
639
0
               sizeof(psk_auth_info_st), 1);
640
0
    if (ret < 0) {
641
0
      gnutls_assert();
642
0
      goto cleanup;
643
0
    }
644
645
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
646
0
    assert(info != NULL);
647
648
0
    ret = _gnutls_copy_psk_username(info, username);
649
0
    if (ret < 0) {
650
0
      gnutls_assert();
651
0
      goto cleanup;
652
0
    }
653
654
0
    if ((ret = _gnutls_buffer_append_data_prefix16(
655
0
           extdata, username.data, username.size)) < 0) {
656
0
      gnutls_assert();
657
0
      goto cleanup;
658
0
    }
659
660
    /* Now append the obfuscated ticket age */
661
0
    if ((ret = _gnutls_buffer_append_uint32(extdata, 0)) < 0) {
662
0
      gnutls_assert();
663
0
      goto cleanup;
664
0
    }
665
666
0
    psk_id_len += 6 + username.size;
667
0
    binders_len += 1 + _gnutls_mac_get_algo_len(prf_psk);
668
0
  }
669
670
  /* if no tickets or identities to be sent */
671
0
  if (psk_id_len == 0) {
672
    /* reset extensions buffer */
673
0
    extdata->length = spos;
674
0
    return 0;
675
0
  }
676
677
0
  _gnutls_write_uint16(psk_id_len, &extdata->data[spos]);
678
679
0
  binders_pos = extdata->length - spos;
680
0
  ext_offset = _gnutls_ext_get_extensions_offset(session);
681
682
  /* Compute the binders. extdata->data points to the start
683
   * of this client hello. */
684
0
  assert(extdata->length >= sizeof(mbuffer_st));
685
0
  assert(ext_offset >= (ssize_t)sizeof(mbuffer_st));
686
0
  ext_offset -= sizeof(mbuffer_st);
687
0
  client_hello_len = extdata->length - sizeof(mbuffer_st);
688
689
0
  next_idx = 0;
690
691
0
  ret = _gnutls_buffer_append_uint16(extdata, binders_len);
692
0
  if (ret < 0) {
693
0
    gnutls_assert_val(ret);
694
0
    goto cleanup;
695
0
  }
696
697
0
  if (prf_res && rkey.size > 0) {
698
0
    gnutls_datum_t client_hello;
699
700
0
    client_hello.data = extdata->data + sizeof(mbuffer_st);
701
0
    client_hello.size = client_hello_len;
702
703
0
    ret = compute_psk_binder(session, prf_res, binders_len,
704
0
           binders_pos, ext_offset, &rkey,
705
0
           &client_hello, BINDER_RES,
706
0
           binder_value);
707
0
    if (ret < 0) {
708
0
      gnutls_assert();
709
0
      goto cleanup;
710
0
    }
711
712
    /* Associate the selected pre-shared key with the session */
713
0
    gnutls_free(session->key.binders[next_idx].psk.data);
714
0
    session->key.binders[next_idx].psk.data = rkey.data;
715
0
    session->key.binders[next_idx].psk.size = rkey.size;
716
0
    rkey.data = NULL;
717
718
0
    session->key.binders[next_idx].prf = prf_res;
719
0
    session->key.binders[next_idx].resumption = 1;
720
0
    session->key.binders[next_idx].idx = next_idx;
721
722
0
    _gnutls_handshake_log(
723
0
      "EXT[%p]: sent PSK resumption identity (%d)\n", session,
724
0
      next_idx);
725
726
0
    next_idx++;
727
728
    /* Add the binder */
729
0
    ret = _gnutls_buffer_append_data_prefix8(extdata, binder_value,
730
0
               prf_res->output_size);
731
0
    if (ret < 0) {
732
0
      gnutls_assert();
733
0
      goto cleanup;
734
0
    }
735
736
0
    session->internals.hsk_flags |= HSK_TLS13_TICKET_SENT;
737
0
  }
738
739
0
  if (prf_psk && user_key.size > 0 && info) {
740
0
    gnutls_datum_t client_hello;
741
742
0
    client_hello.data = extdata->data + sizeof(mbuffer_st);
743
0
    client_hello.size = client_hello_len;
744
745
0
    ret = compute_psk_binder(session, prf_psk, binders_len,
746
0
           binders_pos, ext_offset, &user_key,
747
0
           &client_hello,
748
0
           imported ? BINDER_IMP : BINDER_EXT,
749
0
           binder_value);
750
0
    if (ret < 0) {
751
0
      gnutls_assert();
752
0
      goto cleanup;
753
0
    }
754
755
    /* Associate the selected pre-shared key with the session */
756
0
    gnutls_free(session->key.binders[next_idx].psk.data);
757
0
    session->key.binders[next_idx].psk.data = user_key.data;
758
0
    session->key.binders[next_idx].psk.size = user_key.size;
759
0
    user_key.data = NULL;
760
761
0
    session->key.binders[next_idx].prf = prf_psk;
762
0
    session->key.binders[next_idx].resumption = 0;
763
0
    session->key.binders[next_idx].idx = next_idx;
764
765
0
    _gnutls_handshake_log("EXT[%p]: sent PSK identity '%s' (%d)\n",
766
0
              session, info->username, next_idx);
767
768
0
    next_idx++;
769
770
    /* Add the binder */
771
0
    ret = _gnutls_buffer_append_data_prefix8(extdata, binder_value,
772
0
               prf_psk->output_size);
773
0
    if (ret < 0) {
774
0
      gnutls_assert();
775
0
      goto cleanup;
776
0
    }
777
0
  }
778
779
0
  ret = 0;
780
781
0
cleanup:
782
0
  if (free_username)
783
0
    _gnutls_free_datum(&username);
784
785
0
  _gnutls_free_key_datum(&user_key);
786
0
  _gnutls_free_key_datum(&rkey);
787
788
0
  return ret;
789
0
}
790
791
static int server_send_params(gnutls_session_t session, gnutls_buffer_t extdata)
792
0
{
793
0
  int ret;
794
795
0
  if (!(session->internals.hsk_flags & HSK_PSK_SELECTED))
796
0
    return 0;
797
798
0
  ret = _gnutls_buffer_append_uint16(extdata,
799
0
             session->key.binders[0].idx);
800
0
  if (ret < 0)
801
0
    return gnutls_assert_val(ret);
802
803
0
  return 2;
804
0
}
805
806
static int server_recv_params(gnutls_session_t session,
807
            const unsigned char *data, size_t len,
808
            const gnutls_psk_server_credentials_t pskcred)
809
0
{
810
0
  int ret;
811
0
  const mac_entry_st *prf;
812
0
  gnutls_datum_t full_client_hello;
813
0
  uint8_t binder_value[MAX_HASH_SIZE];
814
0
  uint16_t psk_index, i;
815
0
  gnutls_datum_t binder_recvd = { NULL, 0 };
816
0
  gnutls_datum_t key = { NULL, 0 };
817
0
  psk_ext_parser_st psk_parser;
818
0
  psk_ext_iter_st psk_iter;
819
0
  struct psk_st psk;
820
0
  psk_auth_info_t info;
821
0
  tls13_ticket_st ticket_data;
822
  /* These values should be set properly when session ticket is accepted. */
823
0
  uint32_t ticket_age = UINT32_MAX;
824
0
  struct timespec ticket_creation_time = { 0, 0 };
825
0
  enum binder_type binder_type;
826
0
  bool refuse_early_data = false;
827
0
  gnutls_mac_algorithm_t mac = GNUTLS_MAC_SHA384;
828
829
0
retry_binder:
830
0
  ret = _gnutls13_psk_ext_parser_init(&psk_parser, data, len);
831
0
  if (ret < 0) {
832
    /* No PSKs advertised by client */
833
0
    if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
834
0
      return 0;
835
0
    return gnutls_assert_val(ret);
836
0
  }
837
838
0
  _gnutls13_psk_ext_iter_init(&psk_iter, &psk_parser);
839
0
  for (psk_index = 0;; psk_index++) {
840
0
    ret = _gnutls13_psk_ext_iter_next_identity(&psk_iter, &psk);
841
0
    if (ret < 0) {
842
      /* We couldn't find any usable PSK */
843
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
844
0
        return 0;
845
0
      return gnutls_assert_val(ret);
846
0
    }
847
848
    /* This will unpack the session ticket if it is well
849
     * formed and has the expected name */
850
0
    if (!(session->internals.flags & GNUTLS_NO_TICKETS) &&
851
0
        _gnutls13_unpack_session_ticket(session, &psk.identity,
852
0
                &ticket_data) == 0) {
853
0
      prf = ticket_data.prf;
854
855
0
      session->internals.resumption_requested = 1;
856
857
      /* Check whether ticket is stale or not */
858
0
      ticket_age = psk.ob_ticket_age - ticket_data.age_add;
859
0
      if (ticket_age / 1000 > ticket_data.lifetime) {
860
0
        gnutls_assert();
861
0
        tls13_ticket_deinit(&ticket_data);
862
0
        continue;
863
0
      }
864
865
0
      ret = compute_psk_from_ticket(&ticket_data, &key);
866
0
      if (ret < 0) {
867
0
        gnutls_assert();
868
0
        tls13_ticket_deinit(&ticket_data);
869
0
        continue;
870
0
      }
871
872
0
      memcpy(&ticket_creation_time,
873
0
             &ticket_data.creation_time,
874
0
             sizeof(struct timespec));
875
876
0
      tls13_ticket_deinit(&ticket_data);
877
878
0
      binder_type = BINDER_RES;
879
0
      break;
880
0
    } else if (pskcred && psk.ob_ticket_age == 0 &&
881
0
         psk.identity.size > 0 &&
882
0
         psk.identity.size <= MAX_USERNAME_SIZE) {
883
0
      gnutls_psk_key_flags flags;
884
0
      uint8_t ipsk[MAX_HASH_SIZE];
885
886
0
      prf = pskcred->binder_algo == NULL ?
887
0
              _gnutls_mac_to_entry(mac) :
888
0
              pskcred->binder_algo;
889
890
      /* this fails only on configuration errors; as such we always
891
       * return its error code in that case */
892
0
      ret = _gnutls_psk_pwd_find_entry(
893
0
        session, (char *)psk.identity.data,
894
0
        psk.identity.size, &key, &flags);
895
0
      if (ret < 0) {
896
0
        return gnutls_assert_val(ret);
897
0
      }
898
899
0
      if (flags & GNUTLS_PSK_KEY_EXT) {
900
0
        gnutls_datum_t imported_identity = { NULL, 0 };
901
0
        gnutls_datum_t context = { NULL, 0 };
902
0
        gnutls_protocol_t version;
903
0
        gnutls_digest_algorithm_t hash;
904
0
        const version_entry_st *vers;
905
906
0
        ret = parse_imported_identity(
907
0
          &psk.identity, &imported_identity,
908
0
          &context, &version, &hash);
909
0
        if (ret < 0) {
910
0
          gnutls_assert();
911
0
          goto fail;
912
0
        }
913
914
0
        vers = version_to_entry(version);
915
0
        if (unlikely(!vers || !vers->tls13_sem)) {
916
0
          gnutls_assert();
917
0
          goto fail;
918
0
        }
919
0
        if (hash != MAC_TO_DIG(prf->id)) {
920
0
          gnutls_assert();
921
0
          goto fail;
922
0
        }
923
924
0
        ret = derive_ipsk(prf, &psk.identity, &key,
925
0
              ipsk);
926
0
        if (ret < 0) {
927
0
          gnutls_assert();
928
0
          goto fail;
929
0
        }
930
0
        _gnutls_free_key_datum(&key);
931
0
        ret = _gnutls_set_datum(&key, ipsk,
932
0
              prf->output_size);
933
0
        zeroize_key(ipsk, sizeof(ipsk));
934
0
        if (ret < 0) {
935
0
          gnutls_assert();
936
0
          goto fail;
937
0
        }
938
939
0
        binder_type = BINDER_IMP;
940
0
      } else {
941
0
        binder_type = BINDER_EXT;
942
0
      }
943
0
      break;
944
0
    }
945
0
  }
946
947
0
  _gnutls13_psk_ext_iter_init(&psk_iter, &psk_parser);
948
0
  for (i = 0; i <= psk_index; i++) {
949
0
    ret = _gnutls13_psk_ext_iter_next_binder(&psk_iter,
950
0
               &binder_recvd);
951
0
    if (ret < 0) {
952
0
      gnutls_assert();
953
      /* We couldn't extract binder */
954
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
955
0
        ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
956
0
      goto fail;
957
0
    }
958
0
  }
959
960
  /* Get full ClientHello */
961
0
  if (!_gnutls_ext_get_full_client_hello(session, &full_client_hello)) {
962
0
    ret = GNUTLS_E_INTERNAL_ERROR;
963
0
    gnutls_assert();
964
0
    goto fail;
965
0
  }
966
967
  /* Compute the binder value for this PSK */
968
0
  ret = compute_psk_binder(session, prf, psk_parser.binders_len + 2, 0, 0,
969
0
         &key, &full_client_hello, binder_type,
970
0
         binder_value);
971
0
  if (ret < 0) {
972
0
    gnutls_assert();
973
0
    goto fail;
974
0
  }
975
976
0
  if (_gnutls_mac_get_algo_len(prf) != binder_recvd.size ||
977
0
      gnutls_memcmp(binder_value, binder_recvd.data, binder_recvd.size)) {
978
    /*
979
     * Older clients will always use SHA256 as binder algorithm
980
     * even for SHA384 PSKs, so we need to retry with SHA256
981
     * to calculate the correct binder value for those.
982
     */
983
0
    if (pskcred && pskcred->binder_algo == NULL &&
984
0
        mac == GNUTLS_MAC_SHA384) {
985
0
      mac = GNUTLS_MAC_SHA256;
986
0
      _gnutls_free_key_datum(&key);
987
0
      goto retry_binder;
988
0
    }
989
0
    gnutls_assert();
990
0
    ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
991
0
    goto fail;
992
0
  }
993
994
0
  if (session->internals.hsk_flags & HSK_PSK_KE_MODE_DHE_PSK)
995
0
    _gnutls_handshake_log("EXT[%p]: selected DHE-PSK mode\n",
996
0
              session);
997
0
  else {
998
0
    reset_cand_groups(session);
999
0
    _gnutls_handshake_log("EXT[%p]: selected PSK mode\n", session);
1000
0
  }
1001
1002
  /* save the username in psk_auth_info to make it available
1003
   * using gnutls_psk_server_get_username() */
1004
0
  if (binder_type != BINDER_RES) {
1005
0
    assert(psk.identity.size <= MAX_USERNAME_SIZE);
1006
1007
0
    ret = _gnutls_auth_info_init(session, GNUTLS_CRD_PSK,
1008
0
               sizeof(psk_auth_info_st), 1);
1009
0
    if (ret < 0) {
1010
0
      gnutls_assert();
1011
0
      goto fail;
1012
0
    }
1013
1014
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
1015
0
    assert(info != NULL);
1016
1017
0
    ret = _gnutls_copy_psk_username(info, psk.identity);
1018
0
    if (ret < 0) {
1019
0
      gnutls_assert();
1020
0
      goto fail;
1021
0
    }
1022
1023
0
    _gnutls_handshake_log(
1024
0
      "EXT[%p]: selected PSK identity: %s (%d)\n", session,
1025
0
      info->username, psk_index);
1026
1027
    /* We currently only support early data in resuming connection,
1028
     * due to lack of API function to associate encryption
1029
     * parameters with external PSK.
1030
     */
1031
0
    refuse_early_data = true;
1032
0
  } else {
1033
0
    if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
1034
0
      if (session->internals.anti_replay) {
1035
0
        ret = _gnutls_anti_replay_check(
1036
0
          session->internals.anti_replay,
1037
0
          ticket_age, &ticket_creation_time,
1038
0
          &binder_recvd);
1039
0
        if (ret < 0) {
1040
0
          refuse_early_data = true;
1041
0
          _gnutls_handshake_log(
1042
0
            "EXT[%p]: replay detected; rejecting early data\n",
1043
0
            session);
1044
0
        }
1045
0
      } else {
1046
0
        refuse_early_data = true;
1047
0
        _gnutls_handshake_log(
1048
0
          "EXT[%p]: anti-replay is not enabled; rejecting early data\n",
1049
0
          session);
1050
0
      }
1051
0
    }
1052
1053
0
    session->internals.resumed = true;
1054
0
    _gnutls_handshake_log(
1055
0
      "EXT[%p]: selected resumption PSK identity (%d)\n",
1056
0
      session, psk_index);
1057
0
  }
1058
1059
0
  session->internals.hsk_flags |= HSK_PSK_SELECTED;
1060
1061
0
  if ((session->internals.flags & GNUTLS_ENABLE_EARLY_DATA) &&
1062
0
      (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) &&
1063
0
      !refuse_early_data &&
1064
0
      !(session->internals.hsk_flags & HSK_HRR_SENT)) {
1065
0
    session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED;
1066
0
    _gnutls_handshake_log("EXT[%p]: early data accepted\n",
1067
0
              session);
1068
0
  }
1069
1070
  /* Reference the selected pre-shared key */
1071
0
  session->key.binders[0].psk.data = key.data;
1072
0
  session->key.binders[0].psk.size = key.size;
1073
0
  key.data = NULL;
1074
0
  key.size = 0;
1075
1076
0
  session->key.binders[0].idx = psk_index;
1077
0
  session->key.binders[0].prf = prf;
1078
0
  session->key.binders[0].resumption = binder_type == BINDER_RES;
1079
1080
0
  ret = _gnutls_generate_early_secrets_for_psk(session);
1081
0
  if (ret < 0) {
1082
0
    gnutls_assert();
1083
0
    goto fail;
1084
0
  }
1085
1086
0
fail:
1087
0
  _gnutls_free_key_datum(&key);
1088
0
  return ret;
1089
0
}
1090
1091
/*
1092
 * Return values for this function:
1093
 *  -  0 : Not applicable.
1094
 *  - >0 : Ok. Return size of extension data.
1095
 *  - GNUTLS_E_INT_RET_0 : Size of extension data is zero.
1096
 *  - <0 : There's been an error.
1097
 *
1098
 * In the client, generates the PskIdentity and PskBinderEntry messages.
1099
 *
1100
 *      PskIdentity identities<7..2^16-1>;
1101
 *      PskBinderEntry binders<33..2^16-1>;
1102
 *
1103
 *      struct {
1104
 *          opaque identity<1..2^16-1>;
1105
 *          uint32 obfuscated_ticket_age;
1106
 *      } PskIdentity;
1107
 *
1108
 *      opaque PskBinderEntry<32..255>;
1109
 *
1110
 * The server sends the selected identity, which is a zero-based index
1111
 * of the PSKs offered by the client:
1112
 *
1113
 *      struct {
1114
 *          uint16 selected_identity;
1115
 *      } PreSharedKeyExtension;
1116
 */
1117
static int _gnutls_psk_send_params(gnutls_session_t session,
1118
           gnutls_buffer_t extdata)
1119
0
{
1120
0
  gnutls_psk_client_credentials_t cred = NULL;
1121
0
  const version_entry_st *vers;
1122
1123
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
1124
0
    vers = _gnutls_version_max(session);
1125
1126
0
    if (!vers || !vers->tls13_sem)
1127
0
      return 0;
1128
1129
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_SENT) {
1130
0
      cred = (gnutls_psk_client_credentials_t)
1131
0
        _gnutls_get_cred(session, GNUTLS_CRD_PSK);
1132
0
    }
1133
1134
0
    if ((session->internals.flags & GNUTLS_NO_TICKETS) &&
1135
0
        !session->internals.priorities->have_psk)
1136
0
      return 0;
1137
1138
0
    return client_send_params(session, extdata, cred);
1139
0
  } else {
1140
0
    vers = get_version(session);
1141
1142
0
    if (!vers || !vers->tls13_sem)
1143
0
      return 0;
1144
1145
0
    if ((session->internals.flags & GNUTLS_NO_TICKETS) &&
1146
0
        !session->internals.priorities->have_psk)
1147
0
      return 0;
1148
1149
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_RECEIVED)
1150
0
      return server_send_params(session, extdata);
1151
0
    else
1152
0
      return 0;
1153
0
  }
1154
0
}
1155
1156
static void swap_binders(gnutls_session_t session)
1157
0
{
1158
0
  struct binder_data_st tmp;
1159
1160
0
  memcpy(&tmp, &session->key.binders[0], sizeof(struct binder_data_st));
1161
0
  memcpy(&session->key.binders[0], &session->key.binders[1],
1162
0
         sizeof(struct binder_data_st));
1163
0
  memcpy(&session->key.binders[1], &tmp, sizeof(struct binder_data_st));
1164
0
}
1165
1166
/*
1167
 * Return values for this function:
1168
 *  -  0 : Not applicable.
1169
 *  - >0 : Ok. Return size of extension data.
1170
 *  - <0 : There's been an error.
1171
 */
1172
static int _gnutls_psk_recv_params(gnutls_session_t session,
1173
           const unsigned char *data, size_t len)
1174
0
{
1175
0
  unsigned i;
1176
0
  gnutls_psk_server_credentials_t pskcred;
1177
0
  const version_entry_st *vers = get_version(session);
1178
0
  int ret;
1179
1180
0
  if (!vers || !vers->tls13_sem)
1181
0
    return 0;
1182
1183
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
1184
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_SENT) {
1185
0
      DECR_LEN(len, 2);
1186
1187
0
      uint16_t selected_identity = _gnutls_read_uint16(data);
1188
1189
0
      for (i = 0; i < sizeof(session->key.binders) /
1190
0
            sizeof(session->key.binders[0]);
1191
0
           i++) {
1192
0
        if (session->key.binders[i].prf != NULL &&
1193
0
            session->key.binders[i].idx ==
1194
0
              selected_identity) {
1195
0
          if (session->key.binders[i].resumption) {
1196
0
            session->internals.resumed =
1197
0
              true;
1198
0
            _gnutls_handshake_log(
1199
0
              "EXT[%p]: selected PSK-resumption mode\n",
1200
0
              session);
1201
0
          } else {
1202
0
            _gnutls_handshake_log(
1203
0
              "EXT[%p]: selected PSK mode\n",
1204
0
              session);
1205
0
          }
1206
1207
          /* different PSK is selected, than the one we calculated early secrets */
1208
0
          if (i != 0) {
1209
            /* ensure that selected binder is set on (our) index zero */
1210
0
            swap_binders(session);
1211
1212
0
            ret = _gnutls_generate_early_secrets_for_psk(
1213
0
              session);
1214
0
            if (ret < 0)
1215
0
              return gnutls_assert_val(
1216
0
                ret);
1217
0
          }
1218
0
          session->internals.hsk_flags |=
1219
0
            HSK_PSK_SELECTED;
1220
0
        }
1221
0
      }
1222
1223
0
      return 0;
1224
0
    } else {
1225
0
      return gnutls_assert_val(
1226
0
        GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
1227
0
    }
1228
0
  } else {
1229
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_RECEIVED) {
1230
0
      if (session->internals.hsk_flags &
1231
0
          HSK_PSK_KE_MODE_INVALID) {
1232
        /* We received a "psk_ke_modes" extension, but with a value we don't support */
1233
0
        return 0;
1234
0
      }
1235
1236
0
      pskcred = (gnutls_psk_server_credentials_t)
1237
0
        _gnutls_get_cred(session, GNUTLS_CRD_PSK);
1238
1239
      /* If there are no PSK credentials, this extension is not applicable,
1240
       * so we return zero. */
1241
0
      if (pskcred == NULL &&
1242
0
          (session->internals.flags & GNUTLS_NO_TICKETS))
1243
0
        return 0;
1244
1245
0
      return server_recv_params(session, data, len, pskcred);
1246
0
    } else {
1247
0
      return gnutls_assert_val(
1248
0
        GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
1249
0
    }
1250
0
  }
1251
0
}
1252
1253
const hello_ext_entry_st ext_mod_pre_shared_key = {
1254
  .name = "Pre Shared Key",
1255
  .tls_id = PRE_SHARED_KEY_TLS_ID,
1256
  .gid = GNUTLS_EXTENSION_PRE_SHARED_KEY,
1257
  .client_parse_point = GNUTLS_EXT_TLS,
1258
  .server_parse_point = GNUTLS_EXT_TLS,
1259
  .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO |
1260
        GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO,
1261
  .send_func = _gnutls_psk_send_params,
1262
  .recv_func = _gnutls_psk_recv_params
1263
};