Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/ext/pre_shared_key.c
Line
Count
Source (jump to first uncovered line)
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
static int
39
compute_psk_from_ticket(const tls13_ticket_st * ticket, gnutls_datum_t * key)
40
0
{
41
0
  int ret;
42
43
0
  if (unlikely(ticket->prf == NULL || ticket->prf->output_size == 0))
44
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
45
46
0
  key->data = gnutls_malloc(ticket->prf->output_size);
47
0
  if (!key->data) {
48
0
    gnutls_assert();
49
0
    return GNUTLS_E_MEMORY_ERROR;
50
0
  }
51
0
  key->size = ticket->prf->output_size;
52
53
0
  ret = _tls13_expand_secret2(ticket->prf,
54
0
            RESUMPTION_LABEL,
55
0
            sizeof(RESUMPTION_LABEL) - 1, ticket->nonce,
56
0
            ticket->nonce_size,
57
0
            ticket->resumption_master_secret, key->size,
58
0
            key->data);
59
0
  if (ret < 0)
60
0
    gnutls_assert();
61
62
0
  return ret;
63
0
}
64
65
static int
66
compute_binder_key(const mac_entry_st * prf,
67
       const uint8_t * key, size_t keylen, bool resuming, void *out)
68
0
{
69
0
  int ret;
70
0
  const char ext_label[] = EXT_BINDER_LABEL;
71
0
  const size_t ext_label_len = sizeof(ext_label) - 1;
72
0
  const char res_label[] = RES_BINDER_LABEL;
73
0
  const size_t res_label_len = sizeof(res_label) - 1;
74
0
  const char *label = resuming ? res_label : ext_label;
75
0
  size_t label_len = resuming ? res_label_len : ext_label_len;
76
0
  uint8_t tmp_key[MAX_HASH_SIZE];
77
78
  /* Compute HKDF-Extract(0, psk) */
79
0
  ret = _tls13_init_secret2(prf, key, keylen, tmp_key);
80
0
  if (ret < 0)
81
0
    return ret;
82
83
  /* Compute Derive-Secret(secret, label, transcript_hash) */
84
0
  ret = _tls13_derive_secret2(prf, label, label_len,
85
0
            NULL, 0, tmp_key, out);
86
0
  if (ret < 0)
87
0
    return ret;
88
89
0
  return 0;
90
0
}
91
92
static int
93
compute_psk_binder(gnutls_session_t session,
94
       const mac_entry_st * prf, unsigned binders_length,
95
       int exts_length, int ext_offset,
96
       const gnutls_datum_t * psk,
97
       const gnutls_datum_t * client_hello, bool resuming,
98
       void *out)
99
0
{
100
0
  int ret;
101
0
  unsigned client_hello_pos, extensions_len_pos;
102
0
  gnutls_buffer_st handshake_buf;
103
0
  uint8_t binder_key[MAX_HASH_SIZE];
104
105
0
  _gnutls_buffer_init(&handshake_buf);
106
107
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
108
0
    if (session->internals.hsk_flags & HSK_HRR_RECEIVED) {
109
0
      ret = gnutls_buffer_append_data(&handshake_buf,
110
0
              (const void *)
111
0
              session->
112
0
              internals.handshake_hash_buffer.data,
113
0
              session->
114
0
              internals.handshake_hash_buffer.length);
115
0
      if (ret < 0) {
116
0
        gnutls_assert();
117
0
        goto error;
118
0
      }
119
0
    }
120
121
0
    client_hello_pos = handshake_buf.length;
122
0
    ret =
123
0
        gnutls_buffer_append_data(&handshake_buf,
124
0
                client_hello->data,
125
0
                client_hello->size);
126
0
    if (ret < 0) {
127
0
      gnutls_assert();
128
0
      goto error;
129
0
    }
130
131
    /* This is a ClientHello message */
132
0
    handshake_buf.data[client_hello_pos] =
133
0
        GNUTLS_HANDSHAKE_CLIENT_HELLO;
134
135
    /* At this point we have not yet added the binders to the ClientHello,
136
     * but we have to overwrite the size field, pretending as if binders
137
     * of the correct length were present.
138
     */
139
0
    _gnutls_write_uint24(handshake_buf.length - client_hello_pos +
140
0
             binders_length - 2,
141
0
             &handshake_buf.data[client_hello_pos + 1]);
142
0
    _gnutls_write_uint16(handshake_buf.length - client_hello_pos +
143
0
             binders_length - ext_offset,
144
0
             &handshake_buf.data[client_hello_pos +
145
0
               ext_offset]);
146
0
    extensions_len_pos =
147
0
        handshake_buf.length - client_hello_pos - exts_length - 2;
148
0
    _gnutls_write_uint16(exts_length + binders_length + 2,
149
0
             &handshake_buf.data[client_hello_pos +
150
0
               extensions_len_pos]);
151
0
  } else {
152
0
    if (session->internals.hsk_flags & HSK_HRR_SENT) {
153
0
      if (unlikely
154
0
          (session->internals.handshake_hash_buffer.length <=
155
0
           client_hello->size)) {
156
0
        ret =
157
0
            gnutls_assert_val
158
0
            (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
159
0
        goto error;
160
0
      }
161
162
0
      ret = gnutls_buffer_append_data(&handshake_buf,
163
0
              session->
164
0
              internals.handshake_hash_buffer.data,
165
0
              session->
166
0
              internals.handshake_hash_buffer.length
167
0
              - client_hello->size);
168
0
      if (ret < 0) {
169
0
        gnutls_assert();
170
0
        goto error;
171
0
      }
172
0
    }
173
174
0
    if (unlikely(client_hello->size <= binders_length)) {
175
0
      ret =
176
0
          gnutls_assert_val
177
0
          (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
178
0
      goto error;
179
0
    }
180
181
0
    ret = gnutls_buffer_append_data(&handshake_buf, (const void *)
182
0
            client_hello->data,
183
0
            client_hello->size -
184
0
            binders_length);
185
0
    if (ret < 0) {
186
0
      gnutls_assert();
187
0
      goto error;
188
0
    }
189
0
  }
190
191
0
  ret = compute_binder_key(prf,
192
0
         psk->data, psk->size, resuming, binder_key);
193
0
  if (ret < 0) {
194
0
    gnutls_assert();
195
0
    goto error;
196
0
  }
197
198
0
  ret = _gnutls13_compute_finished(prf, binder_key, &handshake_buf, out);
199
0
  if (ret < 0) {
200
0
    gnutls_assert();
201
0
    goto error;
202
0
  }
203
204
0
  ret = 0;
205
0
 error:
206
0
  _gnutls_buffer_clear(&handshake_buf);
207
0
  return ret;
208
0
}
209
210
static int
211
generate_early_secrets(gnutls_session_t session, const mac_entry_st * prf)
212
0
{
213
0
  int ret;
214
215
0
  ret =
216
0
      _tls13_derive_secret2(prf, EARLY_TRAFFIC_LABEL,
217
0
          sizeof(EARLY_TRAFFIC_LABEL) - 1,
218
0
          session->internals.handshake_hash_buffer.data,
219
0
          session->
220
0
          internals.handshake_hash_buffer_client_hello_len,
221
0
          session->key.proto.tls13.temp_secret,
222
0
          session->key.proto.tls13.e_ckey);
223
0
  if (ret < 0)
224
0
    return gnutls_assert_val(ret);
225
226
0
  ret = _gnutls_call_keylog_func(session, "CLIENT_EARLY_TRAFFIC_SECRET",
227
0
               session->key.proto.tls13.e_ckey,
228
0
               prf->output_size);
229
0
  if (ret < 0)
230
0
    return gnutls_assert_val(ret);
231
232
0
  ret =
233
0
      _tls13_derive_secret2(prf, EARLY_EXPORTER_MASTER_LABEL,
234
0
          sizeof(EARLY_EXPORTER_MASTER_LABEL) - 1,
235
0
          session->internals.handshake_hash_buffer.data,
236
0
          session->
237
0
          internals.handshake_hash_buffer_client_hello_len,
238
0
          session->key.proto.tls13.temp_secret,
239
0
          session->key.proto.tls13.ap_expkey);
240
0
  if (ret < 0)
241
0
    return gnutls_assert_val(ret);
242
243
0
  ret = _gnutls_call_keylog_func(session, "EARLY_EXPORTER_SECRET",
244
0
               session->key.proto.tls13.ap_expkey,
245
0
               prf->output_size);
246
0
  if (ret < 0)
247
0
    return gnutls_assert_val(ret);
248
249
0
  return 0;
250
0
}
251
252
/* Calculate TLS 1.3 Early Secret and the derived secrets from the
253
 * selected PSK. */
254
int _gnutls_generate_early_secrets_for_psk(gnutls_session_t session)
255
0
{
256
0
  const uint8_t *psk;
257
0
  size_t psk_size;
258
0
  const mac_entry_st *prf;
259
0
  int ret;
260
261
0
  psk = session->key.binders[0].psk.data;
262
0
  psk_size = session->key.binders[0].psk.size;
263
0
  prf = session->key.binders[0].prf;
264
265
0
  if (unlikely(psk_size == 0))
266
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
267
268
0
  ret = _tls13_init_secret2(prf, psk, psk_size,
269
0
          session->key.proto.tls13.temp_secret);
270
0
  if (ret < 0)
271
0
    return gnutls_assert_val(ret);
272
273
0
  session->key.proto.tls13.temp_secret_size = prf->output_size;
274
275
0
  ret = generate_early_secrets(session, session->key.binders[0].prf);
276
0
  if (ret < 0)
277
0
    return gnutls_assert_val(ret);
278
279
0
  return 0;
280
0
}
281
282
static int
283
client_send_params(gnutls_session_t session,
284
       gnutls_buffer_t extdata,
285
       const gnutls_psk_client_credentials_t cred)
286
0
{
287
0
  int ret, ext_offset = 0;
288
0
  uint8_t binder_value[MAX_HASH_SIZE];
289
0
  size_t spos;
290
0
  gnutls_datum_t username = { NULL, 0 };
291
0
  gnutls_datum_t user_key = { NULL, 0 }, rkey = { NULL, 0 };
292
0
  unsigned client_hello_len;
293
0
  unsigned next_idx;
294
0
  const mac_entry_st *prf_res = NULL;
295
0
  const mac_entry_st *prf_psk = NULL;
296
0
  struct timespec cur_time;
297
0
  uint32_t ticket_age, ob_ticket_age;
298
0
  int free_username = 0;
299
0
  psk_auth_info_t info = NULL;
300
0
  unsigned psk_id_len = 0;
301
0
  unsigned binders_len, binders_pos;
302
0
  tls13_ticket_st *ticket = &session->internals.tls13_ticket;
303
304
0
  if (((session->internals.flags & GNUTLS_NO_TICKETS) ||
305
0
       session->internals.tls13_ticket.ticket.data == NULL) &&
306
0
      (!cred || !_gnutls_have_psk_credentials(cred, session))) {
307
308
0
    return 0;
309
0
  }
310
311
0
  binders_len = 0;
312
313
  /* placeholder to be filled later */
314
0
  spos = extdata->length;
315
0
  ret = _gnutls_buffer_append_prefix(extdata, 16, 0);
316
0
  if (ret < 0)
317
0
    return gnutls_assert_val(ret);
318
319
  /* First, let's see if we have a session ticket to send */
320
0
  if (!(session->internals.flags & GNUTLS_NO_TICKETS) &&
321
0
      ticket->ticket.data != NULL) {
322
323
    /* We found a session ticket */
324
0
    if (unlikely(ticket->prf == NULL)) {
325
0
      tls13_ticket_deinit(ticket);
326
0
      ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
327
0
      goto cleanup;
328
0
    }
329
330
0
    prf_res = ticket->prf;
331
332
0
    gnutls_gettime(&cur_time);
333
0
    if (unlikely(_gnutls_timespec_cmp(&cur_time,
334
0
              &ticket->arrival_time) < 0)) {
335
0
      gnutls_assert();
336
0
      tls13_ticket_deinit(ticket);
337
0
      goto ignore_ticket;
338
0
    }
339
340
    /* Check whether the ticket is stale */
341
0
    ticket_age = timespec_sub_ms(&cur_time, &ticket->arrival_time);
342
0
    if (ticket_age / 1000 > ticket->lifetime) {
343
0
      tls13_ticket_deinit(ticket);
344
0
      goto ignore_ticket;
345
0
    }
346
347
0
    ret = compute_psk_from_ticket(ticket, &rkey);
348
0
    if (ret < 0) {
349
0
      tls13_ticket_deinit(ticket);
350
0
      goto ignore_ticket;
351
0
    }
352
353
    /* Calculate obfuscated ticket age, in milliseconds, mod 2^32 */
354
0
    ob_ticket_age = ticket_age + ticket->age_add;
355
356
0
    if ((ret = _gnutls_buffer_append_data_prefix(extdata, 16,
357
0
                   ticket->
358
0
                   ticket.data,
359
0
                   ticket->
360
0
                   ticket.size)) <
361
0
        0) {
362
0
      gnutls_assert();
363
0
      goto cleanup;
364
0
    }
365
366
    /* Now append the obfuscated ticket age */
367
0
    if ((ret =
368
0
         _gnutls_buffer_append_prefix(extdata, 32,
369
0
              ob_ticket_age)) < 0) {
370
0
      gnutls_assert();
371
0
      goto cleanup;
372
0
    }
373
374
0
    psk_id_len += 6 + ticket->ticket.size;
375
0
    binders_len += 1 + _gnutls_mac_get_algo_len(prf_res);
376
0
  }
377
378
0
 ignore_ticket:
379
0
  if (cred && _gnutls_have_psk_credentials(cred, session)) {
380
0
    gnutls_datum_t tkey;
381
382
0
    if (cred->binder_algo == NULL) {
383
0
      gnutls_assert();
384
0
      ret =
385
0
          gnutls_assert_val
386
0
          (GNUTLS_E_INSUFFICIENT_CREDENTIALS);
387
0
      goto cleanup;
388
0
    }
389
390
0
    prf_psk = cred->binder_algo;
391
392
0
    ret =
393
0
        _gnutls_find_psk_key(session, cred, &username, &tkey,
394
0
           &free_username);
395
0
    if (ret < 0) {
396
0
      gnutls_assert();
397
0
      goto cleanup;
398
0
    }
399
400
0
    if (username.size == 0 || username.size > UINT16_MAX) {
401
0
      ret = gnutls_assert_val(GNUTLS_E_INVALID_PASSWORD);
402
0
      goto cleanup;
403
0
    }
404
405
0
    if (!free_username) {
406
      /* we need to copy the key */
407
0
      ret =
408
0
          _gnutls_set_datum(&user_key, tkey.data, tkey.size);
409
0
      if (ret < 0) {
410
0
        gnutls_assert();
411
0
        goto cleanup;
412
0
      }
413
0
    } else {
414
0
      user_key.data = tkey.data;
415
0
      user_key.size = tkey.size;
416
0
    }
417
418
0
    ret =
419
0
        _gnutls_auth_info_init(session, GNUTLS_CRD_PSK,
420
0
             sizeof(psk_auth_info_st), 1);
421
0
    if (ret < 0) {
422
0
      gnutls_assert();
423
0
      goto cleanup;
424
0
    }
425
426
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
427
0
    assert(info != NULL);
428
429
0
    ret = _gnutls_copy_psk_username(info, username);
430
0
    if (ret < 0) {
431
0
      gnutls_assert();
432
0
      goto cleanup;
433
0
    }
434
435
0
    if ((ret = _gnutls_buffer_append_data_prefix(extdata, 16,
436
0
                   username.data,
437
0
                   username.size)) <
438
0
        0) {
439
0
      gnutls_assert();
440
0
      goto cleanup;
441
0
    }
442
443
    /* Now append the obfuscated ticket age */
444
0
    if ((ret = _gnutls_buffer_append_prefix(extdata, 32, 0)) < 0) {
445
0
      gnutls_assert();
446
0
      goto cleanup;
447
0
    }
448
449
0
    psk_id_len += 6 + username.size;
450
0
    binders_len += 1 + _gnutls_mac_get_algo_len(prf_psk);
451
0
  }
452
453
  /* if no tickets or identities to be sent */
454
0
  if (psk_id_len == 0) {
455
    /* reset extensions buffer */
456
0
    extdata->length = spos;
457
0
    return 0;
458
0
  }
459
460
0
  _gnutls_write_uint16(psk_id_len, &extdata->data[spos]);
461
462
0
  binders_pos = extdata->length - spos;
463
0
  ext_offset = _gnutls_ext_get_extensions_offset(session);
464
465
  /* Compute the binders. extdata->data points to the start
466
   * of this client hello. */
467
0
  assert(extdata->length >= sizeof(mbuffer_st));
468
0
  assert(ext_offset >= (ssize_t) sizeof(mbuffer_st));
469
0
  ext_offset -= sizeof(mbuffer_st);
470
0
  client_hello_len = extdata->length - sizeof(mbuffer_st);
471
472
0
  next_idx = 0;
473
474
0
  ret = _gnutls_buffer_append_prefix(extdata, 16, binders_len);
475
0
  if (ret < 0) {
476
0
    gnutls_assert_val(ret);
477
0
    goto cleanup;
478
0
  }
479
480
0
  if (prf_res && rkey.size > 0) {
481
0
    gnutls_datum_t client_hello;
482
483
0
    client_hello.data = extdata->data + sizeof(mbuffer_st);
484
0
    client_hello.size = client_hello_len;
485
486
0
    ret = compute_psk_binder(session, prf_res,
487
0
           binders_len, binders_pos,
488
0
           ext_offset, &rkey, &client_hello, 1,
489
0
           binder_value);
490
0
    if (ret < 0) {
491
0
      gnutls_assert();
492
0
      goto cleanup;
493
0
    }
494
495
    /* Associate the selected pre-shared key with the session */
496
0
    gnutls_free(session->key.binders[next_idx].psk.data);
497
0
    session->key.binders[next_idx].psk.data = rkey.data;
498
0
    session->key.binders[next_idx].psk.size = rkey.size;
499
0
    rkey.data = NULL;
500
501
0
    session->key.binders[next_idx].prf = prf_res;
502
0
    session->key.binders[next_idx].resumption = 1;
503
0
    session->key.binders[next_idx].idx = next_idx;
504
505
0
    _gnutls_handshake_log
506
0
        ("EXT[%p]: sent PSK resumption identity (%d)\n", session,
507
0
         next_idx);
508
509
0
    next_idx++;
510
511
    /* Add the binder */
512
0
    ret =
513
0
        _gnutls_buffer_append_data_prefix(extdata, 8, binder_value,
514
0
                  prf_res->output_size);
515
0
    if (ret < 0) {
516
0
      gnutls_assert();
517
0
      goto cleanup;
518
0
    }
519
520
0
    session->internals.hsk_flags |= HSK_TLS13_TICKET_SENT;
521
0
  }
522
523
0
  if (prf_psk && user_key.size > 0 && info) {
524
0
    gnutls_datum_t client_hello;
525
526
0
    client_hello.data = extdata->data + sizeof(mbuffer_st);
527
0
    client_hello.size = client_hello_len;
528
529
0
    ret = compute_psk_binder(session, prf_psk,
530
0
           binders_len, binders_pos,
531
0
           ext_offset, &user_key, &client_hello,
532
0
           0, binder_value);
533
0
    if (ret < 0) {
534
0
      gnutls_assert();
535
0
      goto cleanup;
536
0
    }
537
538
    /* Associate the selected pre-shared key with the session */
539
0
    gnutls_free(session->key.binders[next_idx].psk.data);
540
0
    session->key.binders[next_idx].psk.data = user_key.data;
541
0
    session->key.binders[next_idx].psk.size = user_key.size;
542
0
    user_key.data = NULL;
543
544
0
    session->key.binders[next_idx].prf = prf_psk;
545
0
    session->key.binders[next_idx].resumption = 0;
546
0
    session->key.binders[next_idx].idx = next_idx;
547
548
0
    _gnutls_handshake_log("EXT[%p]: sent PSK identity '%s' (%d)\n",
549
0
              session, info->username, next_idx);
550
551
0
    next_idx++;
552
553
    /* Add the binder */
554
0
    ret =
555
0
        _gnutls_buffer_append_data_prefix(extdata, 8, binder_value,
556
0
                  prf_psk->output_size);
557
0
    if (ret < 0) {
558
0
      gnutls_assert();
559
0
      goto cleanup;
560
0
    }
561
0
  }
562
563
0
  ret = 0;
564
565
0
 cleanup:
566
0
  if (free_username)
567
0
    _gnutls_free_datum(&username);
568
569
0
  _gnutls_free_temp_key_datum(&user_key);
570
0
  _gnutls_free_temp_key_datum(&rkey);
571
572
0
  return ret;
573
0
}
574
575
static int server_send_params(gnutls_session_t session, gnutls_buffer_t extdata)
576
0
{
577
0
  int ret;
578
579
0
  if (!(session->internals.hsk_flags & HSK_PSK_SELECTED))
580
0
    return 0;
581
582
0
  ret = _gnutls_buffer_append_prefix(extdata, 16,
583
0
             session->key.binders[0].idx);
584
0
  if (ret < 0)
585
0
    return gnutls_assert_val(ret);
586
587
0
  return 2;
588
0
}
589
590
static int server_recv_params(gnutls_session_t session,
591
            const unsigned char *data, size_t len,
592
            const gnutls_psk_server_credentials_t pskcred)
593
0
{
594
0
  int ret;
595
0
  const mac_entry_st *prf;
596
0
  gnutls_datum_t full_client_hello;
597
0
  uint8_t binder_value[MAX_HASH_SIZE];
598
0
  uint16_t psk_index, i;
599
0
  gnutls_datum_t binder_recvd = { NULL, 0 };
600
0
  gnutls_datum_t key = { NULL, 0 };
601
0
  psk_ext_parser_st psk_parser;
602
0
  psk_ext_iter_st psk_iter;
603
0
  struct psk_st psk;
604
0
  psk_auth_info_t info;
605
0
  tls13_ticket_st ticket_data;
606
  /* These values should be set properly when session ticket is accepted. */
607
0
  uint32_t ticket_age = UINT32_MAX;
608
0
  struct timespec ticket_creation_time = { 0, 0 };
609
0
  bool resuming;
610
0
  bool refuse_early_data = false;
611
612
0
  ret = _gnutls13_psk_ext_parser_init(&psk_parser, data, len);
613
0
  if (ret < 0) {
614
    /* No PSKs advertised by client */
615
0
    if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
616
0
      return 0;
617
0
    return gnutls_assert_val(ret);
618
0
  }
619
620
0
  _gnutls13_psk_ext_iter_init(&psk_iter, &psk_parser);
621
0
  for (psk_index = 0;; psk_index++) {
622
0
    ret = _gnutls13_psk_ext_iter_next_identity(&psk_iter, &psk);
623
0
    if (ret < 0) {
624
      /* We couldn't find any usable PSK */
625
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
626
0
        return 0;
627
0
      return gnutls_assert_val(ret);
628
0
    }
629
630
    /* This will unpack the session ticket if it is well
631
     * formed and has the expected name */
632
0
    if (!(session->internals.flags & GNUTLS_NO_TICKETS) &&
633
0
        _gnutls13_unpack_session_ticket(session, &psk.identity,
634
0
                &ticket_data) == 0) {
635
0
      prf = ticket_data.prf;
636
637
0
      session->internals.resumption_requested = 1;
638
639
      /* Check whether ticket is stale or not */
640
0
      ticket_age = psk.ob_ticket_age - ticket_data.age_add;
641
0
      if (ticket_age / 1000 > ticket_data.lifetime) {
642
0
        gnutls_assert();
643
0
        tls13_ticket_deinit(&ticket_data);
644
0
        continue;
645
0
      }
646
647
0
      ret = compute_psk_from_ticket(&ticket_data, &key);
648
0
      if (ret < 0) {
649
0
        gnutls_assert();
650
0
        tls13_ticket_deinit(&ticket_data);
651
0
        continue;
652
0
      }
653
654
0
      memcpy(&ticket_creation_time,
655
0
             &ticket_data.creation_time,
656
0
             sizeof(struct timespec));
657
658
0
      tls13_ticket_deinit(&ticket_data);
659
660
0
      resuming = 1;
661
0
      break;
662
0
    } else if (pskcred &&
663
0
         psk.ob_ticket_age == 0 &&
664
0
         psk.identity.size > 0
665
0
         && psk.identity.size <= MAX_USERNAME_SIZE) {
666
0
      prf = pskcred->binder_algo;
667
668
      /* this fails only on configuration errors; as such we always
669
       * return its error code in that case */
670
0
      ret =
671
0
          _gnutls_psk_pwd_find_entry(session,
672
0
                   (char *)psk.
673
0
                   identity.data,
674
0
                   psk.identity.size, &key);
675
0
      if (ret < 0)
676
0
        return gnutls_assert_val(ret);
677
678
0
      resuming = 0;
679
0
      break;
680
0
    }
681
0
  }
682
683
0
  _gnutls13_psk_ext_iter_init(&psk_iter, &psk_parser);
684
0
  for (i = 0; i <= psk_index; i++) {
685
0
    ret =
686
0
        _gnutls13_psk_ext_iter_next_binder(&psk_iter,
687
0
                   &binder_recvd);
688
0
    if (ret < 0) {
689
0
      gnutls_assert();
690
      /* We couldn't extract binder */
691
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
692
0
        ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
693
0
      goto fail;
694
0
    }
695
0
  }
696
697
  /* Get full ClientHello */
698
0
  if (!_gnutls_ext_get_full_client_hello(session, &full_client_hello)) {
699
0
    ret = GNUTLS_E_INTERNAL_ERROR;
700
0
    gnutls_assert();
701
0
    goto fail;
702
0
  }
703
704
  /* Compute the binder value for this PSK */
705
0
  ret = compute_psk_binder(session, prf, psk_parser.binders_len + 2, 0, 0,
706
0
         &key, &full_client_hello, resuming,
707
0
         binder_value);
708
0
  if (ret < 0) {
709
0
    gnutls_assert();
710
0
    goto fail;
711
0
  }
712
713
0
  if (_gnutls_mac_get_algo_len(prf) != binder_recvd.size ||
714
0
      gnutls_memcmp(binder_value, binder_recvd.data, binder_recvd.size)) {
715
0
    gnutls_assert();
716
0
    ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
717
0
    goto fail;
718
0
  }
719
720
0
  if (session->internals.hsk_flags & HSK_PSK_KE_MODE_DHE_PSK)
721
0
    _gnutls_handshake_log("EXT[%p]: selected DHE-PSK mode\n",
722
0
              session);
723
0
  else {
724
0
    reset_cand_groups(session);
725
0
    _gnutls_handshake_log("EXT[%p]: selected PSK mode\n", session);
726
0
  }
727
728
  /* save the username in psk_auth_info to make it available
729
   * using gnutls_psk_server_get_username() */
730
0
  if (!resuming) {
731
0
    assert(psk.identity.size <= MAX_USERNAME_SIZE);
732
733
0
    ret =
734
0
        _gnutls_auth_info_init(session, GNUTLS_CRD_PSK,
735
0
             sizeof(psk_auth_info_st), 1);
736
0
    if (ret < 0) {
737
0
      gnutls_assert();
738
0
      goto fail;
739
0
    }
740
741
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
742
0
    assert(info != NULL);
743
744
0
    ret = _gnutls_copy_psk_username(info, psk.identity);
745
0
    if (ret < 0) {
746
0
      gnutls_assert();
747
0
      goto fail;
748
0
    }
749
750
0
    _gnutls_handshake_log
751
0
        ("EXT[%p]: selected PSK identity: %s (%d)\n", session,
752
0
         info->username, psk_index);
753
754
    /* We currently only support early data in resuming connection,
755
     * due to lack of API function to associate encryption
756
     * parameters with external PSK.
757
     */
758
0
    refuse_early_data = true;
759
0
  } else {
760
0
    if (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) {
761
0
      if (session->internals.anti_replay) {
762
0
        ret =
763
0
            _gnutls_anti_replay_check
764
0
            (session->internals.anti_replay, ticket_age,
765
0
             &ticket_creation_time, &binder_recvd);
766
0
        if (ret < 0) {
767
0
          refuse_early_data = true;
768
0
          _gnutls_handshake_log
769
0
              ("EXT[%p]: replay detected; rejecting early data\n",
770
0
               session);
771
0
        }
772
0
      } else {
773
0
        refuse_early_data = true;
774
0
        _gnutls_handshake_log
775
0
            ("EXT[%p]: anti-replay is not enabled; rejecting early data\n",
776
0
             session);
777
0
      }
778
0
    }
779
780
0
    session->internals.resumed = true;
781
0
    _gnutls_handshake_log
782
0
        ("EXT[%p]: selected resumption PSK identity (%d)\n",
783
0
         session, psk_index);
784
0
  }
785
786
0
  session->internals.hsk_flags |= HSK_PSK_SELECTED;
787
788
0
  if ((session->internals.flags & GNUTLS_ENABLE_EARLY_DATA) &&
789
0
      (session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT) &&
790
0
      !refuse_early_data &&
791
0
      !(session->internals.hsk_flags & HSK_HRR_SENT)) {
792
0
    session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED;
793
0
    _gnutls_handshake_log("EXT[%p]: early data accepted\n",
794
0
              session);
795
0
  }
796
797
  /* Reference the selected pre-shared key */
798
0
  session->key.binders[0].psk.data = key.data;
799
0
  session->key.binders[0].psk.size = key.size;
800
801
0
  session->key.binders[0].idx = psk_index;
802
0
  session->key.binders[0].prf = prf;
803
0
  session->key.binders[0].resumption = resuming;
804
805
0
  ret = _gnutls_generate_early_secrets_for_psk(session);
806
0
  if (ret < 0) {
807
0
    gnutls_assert();
808
0
    goto fail;
809
0
  }
810
811
0
  return 0;
812
813
0
 fail:
814
0
  gnutls_free(key.data);
815
0
  return ret;
816
0
}
817
818
/*
819
 * Return values for this function:
820
 *  -  0 : Not applicable.
821
 *  - >0 : Ok. Return size of extension data.
822
 *  - GNUTLS_E_INT_RET_0 : Size of extension data is zero.
823
 *  - <0 : There's been an error.
824
 *
825
 * In the client, generates the PskIdentity and PskBinderEntry messages.
826
 *
827
 *      PskIdentity identities<7..2^16-1>;
828
 *      PskBinderEntry binders<33..2^16-1>;
829
 *
830
 *      struct {
831
 *          opaque identity<1..2^16-1>;
832
 *          uint32 obfuscated_ticket_age;
833
 *      } PskIdentity;
834
 *
835
 *      opaque PskBinderEntry<32..255>;
836
 *
837
 * The server sends the selected identity, which is a zero-based index
838
 * of the PSKs offered by the client:
839
 *
840
 *      struct {
841
 *          uint16 selected_identity;
842
 *      } PreSharedKeyExtension;
843
 */
844
static int _gnutls_psk_send_params(gnutls_session_t session,
845
           gnutls_buffer_t extdata)
846
0
{
847
0
  gnutls_psk_client_credentials_t cred = NULL;
848
0
  const version_entry_st *vers;
849
850
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
851
0
    vers = _gnutls_version_max(session);
852
853
0
    if (!vers || !vers->tls13_sem)
854
0
      return 0;
855
856
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_SENT) {
857
0
      cred = (gnutls_psk_client_credentials_t)
858
0
          _gnutls_get_cred(session, GNUTLS_CRD_PSK);
859
0
    }
860
861
0
    if ((session->internals.flags & GNUTLS_NO_TICKETS)
862
0
        && !session->internals.priorities->have_psk)
863
0
      return 0;
864
865
0
    return client_send_params(session, extdata, cred);
866
0
  } else {
867
0
    vers = get_version(session);
868
869
0
    if (!vers || !vers->tls13_sem)
870
0
      return 0;
871
872
0
    if ((session->internals.flags & GNUTLS_NO_TICKETS)
873
0
        && !session->internals.priorities->have_psk)
874
0
      return 0;
875
876
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_RECEIVED)
877
0
      return server_send_params(session, extdata);
878
0
    else
879
0
      return 0;
880
0
  }
881
0
}
882
883
static void swap_binders(gnutls_session_t session)
884
0
{
885
0
  struct binder_data_st tmp;
886
887
0
  memcpy(&tmp, &session->key.binders[0], sizeof(struct binder_data_st));
888
0
  memcpy(&session->key.binders[0], &session->key.binders[1],
889
0
         sizeof(struct binder_data_st));
890
0
  memcpy(&session->key.binders[1], &tmp, sizeof(struct binder_data_st));
891
0
}
892
893
/*
894
 * Return values for this function:
895
 *  -  0 : Not applicable.
896
 *  - >0 : Ok. Return size of extension data.
897
 *  - <0 : There's been an error.
898
 */
899
static int _gnutls_psk_recv_params(gnutls_session_t session,
900
           const unsigned char *data, size_t len)
901
0
{
902
0
  unsigned i;
903
0
  gnutls_psk_server_credentials_t pskcred;
904
0
  const version_entry_st *vers = get_version(session);
905
0
  int ret;
906
907
0
  if (!vers || !vers->tls13_sem)
908
0
    return 0;
909
910
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
911
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_SENT) {
912
0
      uint16_t selected_identity = _gnutls_read_uint16(data);
913
914
0
      for (i = 0;
915
0
           i <
916
0
           sizeof(session->key.binders) /
917
0
           sizeof(session->key.binders[0]); i++) {
918
0
        if (session->key.binders[i].prf != NULL
919
0
            && session->key.binders[i].idx ==
920
0
            selected_identity) {
921
0
          if (session->key.binders[i].resumption) {
922
0
            session->internals.resumed =
923
0
                true;
924
0
            _gnutls_handshake_log
925
0
                ("EXT[%p]: selected PSK-resumption mode\n",
926
0
                 session);
927
0
          } else {
928
0
            _gnutls_handshake_log
929
0
                ("EXT[%p]: selected PSK mode\n",
930
0
                 session);
931
0
          }
932
933
          /* different PSK is selected, than the one we calculated early secrets */
934
0
          if (i != 0) {
935
            /* ensure that selected binder is set on (our) index zero */
936
0
            swap_binders(session);
937
938
0
            ret =
939
0
                _gnutls_generate_early_secrets_for_psk
940
0
                (session);
941
0
            if (ret < 0)
942
0
              return
943
0
                  gnutls_assert_val
944
0
                  (ret);
945
0
          }
946
0
          session->internals.hsk_flags |=
947
0
              HSK_PSK_SELECTED;
948
0
        }
949
0
      }
950
951
0
      return 0;
952
0
    } else {
953
0
      return
954
0
          gnutls_assert_val
955
0
          (GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
956
0
    }
957
0
  } else {
958
0
    if (session->internals.hsk_flags & HSK_PSK_KE_MODES_RECEIVED) {
959
0
      if (session->
960
0
          internals.hsk_flags & HSK_PSK_KE_MODE_INVALID) {
961
        /* We received a "psk_ke_modes" extension, but with a value we don't support */
962
0
        return 0;
963
0
      }
964
965
0
      pskcred = (gnutls_psk_server_credentials_t)
966
0
          _gnutls_get_cred(session, GNUTLS_CRD_PSK);
967
968
      /* If there are no PSK credentials, this extension is not applicable,
969
       * so we return zero. */
970
0
      if (pskcred == NULL
971
0
          && (session->internals.flags & GNUTLS_NO_TICKETS))
972
0
        return 0;
973
974
0
      return server_recv_params(session, data, len, pskcred);
975
0
    } else {
976
0
      return
977
0
          gnutls_assert_val
978
0
          (GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
979
0
    }
980
0
  }
981
0
}
982
983
const hello_ext_entry_st ext_mod_pre_shared_key = {
984
  .name = "Pre Shared Key",
985
  .tls_id = PRE_SHARED_KEY_TLS_ID,
986
  .gid = GNUTLS_EXTENSION_PRE_SHARED_KEY,
987
  .client_parse_point = GNUTLS_EXT_TLS,
988
  .server_parse_point = GNUTLS_EXT_TLS,
989
  .validity =
990
      GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO |
991
      GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO,
992
  .send_func = _gnutls_psk_send_params,
993
  .recv_func = _gnutls_psk_recv_params
994
};