Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/session_pack.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2017 Red Hat, Inc.
4
 *
5
 * Author: 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
/* Contains functions that are supposed to pack and unpack session data,
25
 * before and after they are sent to the database backend.
26
 */
27
28
#include "gnutls_int.h"
29
#ifdef ENABLE_SRP
30
#include "auth/srp_kx.h"
31
#endif
32
#ifdef ENABLE_PSK
33
#include "auth/psk.h"
34
#endif
35
#include "auth/anon.h"
36
#include "auth/cert.h"
37
#include "errors.h"
38
#include "auth.h"
39
#include "session_pack.h"
40
#include "datum.h"
41
#include "num.h"
42
#include "hello_ext.h"
43
#include "constate.h"
44
#include "algorithms.h"
45
#include "state.h"
46
#include "db.h"
47
#include "tls13/session_ticket.h"
48
49
static int pack_certificate_auth_info(gnutls_session_t,
50
              gnutls_buffer_st *packed_session);
51
static int unpack_certificate_auth_info(gnutls_session_t,
52
          gnutls_buffer_st *packed_session);
53
54
#ifdef ENABLE_SRP
55
static int unpack_srp_auth_info(gnutls_session_t session,
56
        gnutls_buffer_st *packed_session);
57
static int pack_srp_auth_info(gnutls_session_t session,
58
            gnutls_buffer_st *packed_session);
59
#endif
60
61
static int unpack_psk_auth_info(gnutls_session_t session,
62
        gnutls_buffer_st *packed_session);
63
static int pack_psk_auth_info(gnutls_session_t session,
64
            gnutls_buffer_st *packed_session);
65
66
static int unpack_anon_auth_info(gnutls_session_t session,
67
         gnutls_buffer_st *packed_session);
68
static int pack_anon_auth_info(gnutls_session_t session,
69
             gnutls_buffer_st *packed_session);
70
71
static int unpack_security_parameters(gnutls_session_t session,
72
              gnutls_buffer_st *packed_session);
73
static int pack_security_parameters(gnutls_session_t session,
74
            gnutls_buffer_st *packed_session);
75
static int tls13_unpack_security_parameters(gnutls_session_t session,
76
              gnutls_buffer_st *packed_session);
77
static int tls13_pack_security_parameters(gnutls_session_t session,
78
            gnutls_buffer_st *packed_session);
79
80
/* Since auth_info structures contain malloced data, this function
81
 * is required in order to pack these structures in a vector in
82
 * order to store them to the DB.
83
 *
84
 * packed_session will contain the session data.
85
 *
86
 * The data will be in a platform independent format.
87
 */
88
int _gnutls_session_pack(gnutls_session_t session,
89
       gnutls_datum_t *packed_session)
90
0
{
91
0
  int ret;
92
0
  gnutls_buffer_st sb;
93
0
  uint8_t id;
94
95
0
  if (packed_session == NULL) {
96
0
    gnutls_assert();
97
0
    return GNUTLS_E_INTERNAL_ERROR;
98
0
  }
99
100
0
  _gnutls_buffer_init(&sb);
101
102
0
  id = gnutls_auth_get_type(session);
103
104
0
  BUFFER_APPEND_NUM(&sb, PACKED_SESSION_MAGIC);
105
0
  BUFFER_APPEND_NUM(&sb, session->security_parameters.timestamp);
106
0
  BUFFER_APPEND_NUM(&sb, session->internals.expire_time);
107
0
  BUFFER_APPEND(&sb, &id, 1);
108
109
0
  switch (id) {
110
#ifdef ENABLE_SRP
111
  case GNUTLS_CRD_SRP:
112
    ret = pack_srp_auth_info(session, &sb);
113
    if (ret < 0) {
114
      gnutls_assert();
115
      goto fail;
116
    }
117
    break;
118
#endif
119
0
#ifdef ENABLE_PSK
120
0
  case GNUTLS_CRD_PSK:
121
0
    ret = pack_psk_auth_info(session, &sb);
122
0
    if (ret < 0) {
123
0
      gnutls_assert();
124
0
      goto fail;
125
0
    }
126
0
    break;
127
0
#endif
128
0
#ifdef ENABLE_ANON
129
0
  case GNUTLS_CRD_ANON:
130
0
    ret = pack_anon_auth_info(session, &sb);
131
0
    if (ret < 0) {
132
0
      gnutls_assert();
133
0
      goto fail;
134
0
    }
135
0
    break;
136
0
#endif
137
0
  case GNUTLS_CRD_CERTIFICATE:
138
0
    ret = pack_certificate_auth_info(session, &sb);
139
0
    if (ret < 0) {
140
0
      gnutls_assert();
141
0
      goto fail;
142
0
    }
143
0
    break;
144
0
  default:
145
0
    ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
146
0
    goto fail;
147
0
  }
148
149
  /* Auth_info structures copied. Now copy security_parameters_st. 
150
   * packed_session must have allocated space for the security parameters.
151
   */
152
0
  ret = pack_security_parameters(session, &sb);
153
0
  if (ret < 0) {
154
0
    gnutls_assert();
155
0
    goto fail;
156
0
  }
157
158
0
  if (session->security_parameters.pversion->tls13_sem) {
159
0
    ret = tls13_pack_security_parameters(session, &sb);
160
0
    if (ret < 0) {
161
0
      gnutls_assert();
162
0
      goto fail;
163
0
    }
164
0
  }
165
166
  /* Extensions are re-negotiated in a resumed session under TLS 1.3 */
167
0
  if (!session->security_parameters.pversion->tls13_sem) {
168
0
    ret = _gnutls_hello_ext_pack(session, &sb);
169
0
    if (ret < 0) {
170
0
      gnutls_assert();
171
0
      goto fail;
172
0
    }
173
0
  }
174
175
0
  return _gnutls_buffer_to_datum(&sb, packed_session, 0);
176
177
0
fail:
178
0
  _gnutls_buffer_clear(&sb);
179
0
  return ret;
180
0
}
181
182
/* Load session data from a buffer.
183
 */
184
int _gnutls_session_unpack(gnutls_session_t session,
185
         const gnutls_datum_t *packed_session)
186
0
{
187
0
  int ret;
188
0
  gnutls_buffer_st sb;
189
0
  uint32_t magic;
190
0
  uint32_t expire_time;
191
0
  uint8_t id;
192
193
0
  _gnutls_buffer_init(&sb);
194
195
0
  if (packed_session == NULL || packed_session->size == 0) {
196
0
    gnutls_assert();
197
0
    return GNUTLS_E_INTERNAL_ERROR;
198
0
  }
199
200
0
  ret = _gnutls_buffer_append_data(&sb, packed_session->data,
201
0
           packed_session->size);
202
0
  if (ret < 0) {
203
0
    gnutls_assert();
204
0
    return ret;
205
0
  }
206
207
0
  if (session->key.auth_info != NULL) {
208
0
    _gnutls_free_auth_info(session);
209
0
  }
210
211
0
  BUFFER_POP_NUM(&sb, magic);
212
0
  if (magic != PACKED_SESSION_MAGIC) {
213
0
    ret = gnutls_assert_val(GNUTLS_E_DB_ERROR);
214
0
    goto error;
215
0
  }
216
217
0
  BUFFER_POP_NUM(
218
0
    &sb, session->internals.resumed_security_parameters.timestamp);
219
0
  BUFFER_POP_NUM(&sb, expire_time);
220
0
  (void)expire_time;
221
0
  BUFFER_POP(&sb, &id, 1);
222
223
0
  switch (id) {
224
#ifdef ENABLE_SRP
225
  case GNUTLS_CRD_SRP:
226
    ret = unpack_srp_auth_info(session, &sb);
227
    if (ret < 0) {
228
      gnutls_assert();
229
      goto error;
230
    }
231
    break;
232
#endif
233
0
#ifdef ENABLE_PSK
234
0
  case GNUTLS_CRD_PSK:
235
0
    ret = unpack_psk_auth_info(session, &sb);
236
0
    if (ret < 0) {
237
0
      gnutls_assert();
238
0
      goto error;
239
0
    }
240
0
    break;
241
0
#endif
242
0
#ifdef ENABLE_ANON
243
0
  case GNUTLS_CRD_ANON:
244
0
    ret = unpack_anon_auth_info(session, &sb);
245
0
    if (ret < 0) {
246
0
      gnutls_assert();
247
0
      return ret;
248
0
    }
249
0
    break;
250
0
#endif
251
0
  case GNUTLS_CRD_CERTIFICATE:
252
0
    ret = unpack_certificate_auth_info(session, &sb);
253
0
    if (ret < 0) {
254
0
      gnutls_assert();
255
0
      goto error;
256
0
    }
257
0
    break;
258
0
  default:
259
0
    gnutls_assert();
260
0
    ret = GNUTLS_E_INTERNAL_ERROR;
261
0
    goto error;
262
0
  }
263
264
  /* Auth_info structures copied. Now copy security_parameters_st. 
265
   * packed_session must have allocated space for the security parameters.
266
   */
267
0
  ret = unpack_security_parameters(session, &sb);
268
0
  if (ret < 0) {
269
0
    gnutls_assert();
270
0
    goto error;
271
0
  }
272
273
0
  if (session->internals.resumed_security_parameters.pversion->tls13_sem) {
274
    /* 'prf' will not be NULL at this point, else unpack_security_parameters() would have failed */
275
0
    ret = tls13_unpack_security_parameters(session, &sb);
276
0
    if (ret < 0) {
277
0
      gnutls_assert();
278
0
      goto error;
279
0
    }
280
0
  }
281
282
0
  if (!session->internals.resumed_security_parameters.pversion->tls13_sem) {
283
0
    ret = _gnutls_hello_ext_unpack(session, &sb);
284
0
    if (ret < 0) {
285
0
      gnutls_assert();
286
0
      goto error;
287
0
    }
288
0
  }
289
290
0
  ret = 0;
291
292
0
error:
293
0
  _gnutls_buffer_clear(&sb);
294
295
0
  return ret;
296
0
}
297
298
/*
299
 * If we're using TLS 1.3 semantics, we might have TLS 1.3-specific data.
300
 * Format:
301
 *      4 bytes the total length
302
 *      4 bytes the ticket lifetime
303
 *      4 bytes the ticket age add value
304
 *      1 byte the ticket nonce length
305
 *      x bytes the ticket nonce
306
 *      4 bytes the ticket length
307
 *      x bytes the ticket
308
 *      1 bytes the resumption master secret length
309
 *      x bytes the resumption master secret
310
 *     12 bytes the ticket arrival time
311
 *      4 bytes the max early data size
312
 *
313
 * We only store that info if we received a TLS 1.3 NewSessionTicket at some point.
314
 * If we didn't receive any NST then we cannot resume a TLS 1.3 session and hence
315
 * its nonsense to store all that info.
316
 */
317
static int tls13_pack_security_parameters(gnutls_session_t session,
318
            gnutls_buffer_st *ps)
319
0
{
320
0
  int ret = 0;
321
0
  uint32_t length = 0;
322
0
  size_t length_pos;
323
0
  tls13_ticket_st *ticket = &session->internals.tls13_ticket;
324
325
0
  length_pos = ps->length;
326
0
  BUFFER_APPEND_NUM(ps, 0);
327
328
0
  if (ticket->ticket.data != NULL) {
329
0
    BUFFER_APPEND_NUM(ps, ticket->lifetime);
330
0
    length += 4;
331
0
    BUFFER_APPEND_NUM(ps, ticket->age_add);
332
0
    length += 4;
333
0
    BUFFER_APPEND_PFX1(ps, ticket->nonce, ticket->nonce_size);
334
0
    length += (1 + ticket->nonce_size);
335
0
    BUFFER_APPEND_PFX4(ps, ticket->ticket.data,
336
0
           ticket->ticket.size);
337
0
    length += (4 + ticket->ticket.size);
338
0
    BUFFER_APPEND_PFX1(ps, ticket->resumption_master_secret,
339
0
           ticket->prf->output_size);
340
0
    length += (1 + ticket->prf->output_size);
341
0
    BUFFER_APPEND_TS(ps, ticket->arrival_time);
342
0
    length += 12;
343
0
    BUFFER_APPEND_NUM(
344
0
      ps, session->security_parameters.max_early_data_size);
345
0
    length += 4;
346
347
    /* Overwrite the length field */
348
0
    _gnutls_write_uint32(length, ps->data + length_pos);
349
0
  }
350
351
0
  return ret;
352
0
}
353
354
static int tls13_unpack_security_parameters(gnutls_session_t session,
355
              gnutls_buffer_st *ps)
356
0
{
357
0
  uint32_t ttl_len;
358
0
  tls13_ticket_st *ticket = &session->internals.tls13_ticket;
359
0
  gnutls_datum_t t;
360
0
  int ret = 0;
361
362
0
  BUFFER_POP_NUM(ps, ttl_len);
363
364
0
  if (ttl_len > 0) {
365
0
    BUFFER_POP_NUM(ps, ticket->lifetime);
366
0
    BUFFER_POP_NUM(ps, ticket->age_add);
367
368
0
    ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
369
0
    if (ret < 0 || t.size > sizeof(ticket->nonce)) {
370
0
      ret = GNUTLS_E_PARSING_ERROR;
371
0
      gnutls_assert();
372
0
      goto error;
373
0
    }
374
0
    ticket->nonce_size = t.size;
375
0
    memcpy(ticket->nonce, t.data, t.size);
376
377
0
    BUFFER_POP_DATUM(ps, &ticket->ticket);
378
379
0
    ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
380
0
    if (ret < 0 ||
381
0
        t.size > sizeof(ticket->resumption_master_secret)) {
382
0
      ret = GNUTLS_E_PARSING_ERROR;
383
0
      gnutls_assert();
384
0
      goto error;
385
0
    }
386
0
    memcpy(ticket->resumption_master_secret, t.data, t.size);
387
388
0
    if (unlikely(session->internals.resumed_security_parameters
389
0
               .prf == NULL ||
390
0
           session->internals.resumed_security_parameters.prf
391
0
               ->output_size != t.size))
392
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
393
394
0
    ticket->prf =
395
0
      session->internals.resumed_security_parameters.prf;
396
397
0
    BUFFER_POP_TS(ps, ticket->arrival_time);
398
0
    BUFFER_POP_NUM(
399
0
      ps, session->security_parameters.max_early_data_size);
400
0
  }
401
402
0
error:
403
0
  return ret;
404
0
}
405
406
/* Format: 
407
 *      1 byte the credentials type
408
 *      4 bytes the size of the whole structure
409
 *  DH stuff
410
 *      2 bytes the size of secret key in bits
411
 *      4 bytes the size of the prime
412
 *      x bytes the prime
413
 *      4 bytes the size of the generator
414
 *      x bytes the generator
415
 *      4 bytes the size of the public key
416
 *      x bytes the public key
417
 *  RSA stuff
418
 *      4 bytes the size of the modulus
419
 *      x bytes the modulus
420
 *      4 bytes the size of the exponent
421
 *      x bytes the exponent
422
 *  CERTIFICATES
423
 *      4 bytes the length of the certificate list
424
 *      4 bytes the size of first certificate
425
 *      x bytes the certificate
426
 *       and so on...
427
 */
428
static int pack_certificate_auth_info(gnutls_session_t session,
429
              gnutls_buffer_st *ps)
430
0
{
431
0
  unsigned int i;
432
0
  int cur_size, ret;
433
0
  cert_auth_info_t info =
434
0
    _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
435
0
  int size_offset;
436
437
0
  size_offset = ps->length;
438
0
  BUFFER_APPEND_NUM(ps, 0);
439
0
  cur_size = ps->length;
440
441
0
  if (info) {
442
0
    BUFFER_APPEND_NUM(ps, info->dh.secret_bits);
443
0
    BUFFER_APPEND_PFX4(ps, info->dh.prime.data,
444
0
           info->dh.prime.size);
445
0
    BUFFER_APPEND_PFX4(ps, info->dh.generator.data,
446
0
           info->dh.generator.size);
447
0
    BUFFER_APPEND_PFX4(ps, info->dh.public_key.data,
448
0
           info->dh.public_key.size);
449
450
0
    BUFFER_APPEND_NUM(ps, info->ncerts);
451
452
0
    for (i = 0; i < info->ncerts; i++) {
453
0
      BUFFER_APPEND_PFX4(ps,
454
0
             info->raw_certificate_list[i].data,
455
0
             info->raw_certificate_list[i].size);
456
0
    }
457
458
0
    BUFFER_APPEND_NUM(ps, info->nocsp);
459
460
0
    for (i = 0; i < info->nocsp; i++) {
461
0
      BUFFER_APPEND_PFX4(ps, info->raw_ocsp_list[i].data,
462
0
             info->raw_ocsp_list[i].size);
463
0
    }
464
0
  }
465
466
  /* write the real size */
467
0
  _gnutls_write_uint32(ps->length - cur_size, ps->data + size_offset);
468
469
0
  return 0;
470
0
}
471
472
/* Upack certificate info.
473
 */
474
static int unpack_certificate_auth_info(gnutls_session_t session,
475
          gnutls_buffer_st *ps)
476
0
{
477
0
  int ret;
478
0
  unsigned int i = 0, j = 0;
479
0
  size_t pack_size;
480
0
  cert_auth_info_t info = NULL;
481
0
  unsigned cur_ncerts = 0;
482
0
  unsigned cur_nocsp = 0;
483
484
0
  BUFFER_POP_NUM(ps, pack_size);
485
486
0
  if (pack_size == 0)
487
0
    return 0; /* nothing to be done */
488
489
  /* client and server have the same auth_info here
490
   */
491
0
  ret = _gnutls_auth_info_init(session, GNUTLS_CRD_CERTIFICATE,
492
0
             sizeof(cert_auth_info_st), 1);
493
0
  if (ret < 0) {
494
0
    gnutls_assert();
495
0
    return ret;
496
0
  }
497
498
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
499
0
  if (info == NULL)
500
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
501
502
0
  BUFFER_POP_NUM(ps, info->dh.secret_bits);
503
504
0
  BUFFER_POP_DATUM(ps, &info->dh.prime);
505
0
  BUFFER_POP_DATUM(ps, &info->dh.generator);
506
0
  BUFFER_POP_DATUM(ps, &info->dh.public_key);
507
508
0
  BUFFER_POP_NUM(ps, info->ncerts);
509
510
0
  if (info->ncerts > 0) {
511
0
    info->raw_certificate_list =
512
0
      gnutls_calloc(info->ncerts, sizeof(gnutls_datum_t));
513
0
    if (info->raw_certificate_list == NULL) {
514
0
      gnutls_assert();
515
0
      ret = GNUTLS_E_MEMORY_ERROR;
516
0
      goto error;
517
0
    }
518
0
  }
519
520
0
  for (i = 0; i < info->ncerts; i++) {
521
0
    BUFFER_POP_DATUM(ps, &info->raw_certificate_list[i]);
522
0
    cur_ncerts++;
523
0
  }
524
525
  /* read OCSP responses */
526
0
  BUFFER_POP_NUM(ps, info->nocsp);
527
528
0
  if (info->nocsp > 0) {
529
0
    info->raw_ocsp_list =
530
0
      gnutls_calloc(info->nocsp, sizeof(gnutls_datum_t));
531
0
    if (info->raw_ocsp_list == NULL) {
532
0
      gnutls_assert();
533
0
      ret = GNUTLS_E_MEMORY_ERROR;
534
0
      goto error;
535
0
    }
536
0
  }
537
538
0
  for (i = 0; i < info->nocsp; i++) {
539
0
    BUFFER_POP_DATUM(ps, &info->raw_ocsp_list[i]);
540
0
    cur_nocsp++;
541
0
  }
542
543
0
  return 0;
544
545
0
error:
546
0
  if (info) {
547
0
    _gnutls_free_datum(&info->dh.prime);
548
0
    _gnutls_free_datum(&info->dh.generator);
549
0
    _gnutls_free_datum(&info->dh.public_key);
550
551
0
    for (j = 0; j < cur_ncerts; j++)
552
0
      _gnutls_free_datum(&info->raw_certificate_list[j]);
553
554
0
    for (j = 0; j < cur_nocsp; j++)
555
0
      _gnutls_free_datum(&info->raw_ocsp_list[j]);
556
557
0
    gnutls_free(info->raw_certificate_list);
558
0
    gnutls_free(info->raw_ocsp_list);
559
0
  }
560
561
0
  return ret;
562
0
}
563
564
#ifdef ENABLE_SRP
565
/* Packs the SRP session authentication data.
566
 */
567
568
/* Format: 
569
 *      1 byte the credentials type
570
 *      4 bytes the size of the SRP username (x)
571
 *      x bytes the SRP username
572
 */
573
static int pack_srp_auth_info(gnutls_session_t session, gnutls_buffer_st *ps)
574
{
575
  srp_server_auth_info_t info =
576
    _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
577
  int len, ret;
578
  int size_offset;
579
  size_t cur_size;
580
  const char *username = NULL;
581
582
  if (info) {
583
    if (info->username) {
584
      username = info->username;
585
      len = strlen(info->username) +
586
            1; /* include the terminating null */
587
    } else {
588
      username = "\0";
589
      len = 1;
590
    }
591
  } else
592
    len = 0;
593
594
  size_offset = ps->length;
595
  BUFFER_APPEND_NUM(ps, 0);
596
  cur_size = ps->length;
597
598
  BUFFER_APPEND_PFX4(ps, username, len);
599
600
  /* write the real size */
601
  _gnutls_write_uint32(ps->length - cur_size, ps->data + size_offset);
602
603
  return 0;
604
}
605
606
static int unpack_srp_auth_info(gnutls_session_t session, gnutls_buffer_st *ps)
607
{
608
  size_t username_size;
609
  int ret;
610
  srp_server_auth_info_t info;
611
612
  BUFFER_POP_NUM(ps, username_size);
613
  if (username_size > MAX_USERNAME_SIZE + 1)
614
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
615
616
  ret = _gnutls_auth_info_init(session, GNUTLS_CRD_SRP,
617
             sizeof(srp_server_auth_info_st), 1);
618
  if (ret < 0)
619
    return gnutls_assert_val(ret);
620
621
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
622
  if (info == NULL)
623
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
624
625
  gnutls_free(info->username);
626
  if (username_size == 0) {
627
    info->username = NULL;
628
  } else {
629
    info->username = gnutls_malloc(username_size);
630
    if (info->username == NULL)
631
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
632
  }
633
  BUFFER_POP(ps, info->username, username_size);
634
635
  ret = 0;
636
637
error:
638
  return ret;
639
}
640
#endif
641
642
#ifdef ENABLE_ANON
643
/* Packs the ANON session authentication data.
644
 */
645
646
/* Format: 
647
 *      1 byte the credentials type
648
 *      4 bytes the size of the whole structure
649
 *      2 bytes the size of secret key in bits
650
 *      4 bytes the size of the prime
651
 *      x bytes the prime
652
 *      4 bytes the size of the generator
653
 *      x bytes the generator
654
 *      4 bytes the size of the public key
655
 *      x bytes the public key
656
 */
657
static int pack_anon_auth_info(gnutls_session_t session, gnutls_buffer_st *ps)
658
0
{
659
0
  int cur_size, ret;
660
0
  anon_auth_info_t info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
661
0
  int size_offset;
662
663
0
  size_offset = ps->length;
664
0
  BUFFER_APPEND_NUM(ps, 0);
665
0
  cur_size = ps->length;
666
667
0
  if (info) {
668
0
    BUFFER_APPEND_NUM(ps, info->dh.secret_bits);
669
0
    BUFFER_APPEND_PFX4(ps, info->dh.prime.data,
670
0
           info->dh.prime.size);
671
0
    BUFFER_APPEND_PFX4(ps, info->dh.generator.data,
672
0
           info->dh.generator.size);
673
0
    BUFFER_APPEND_PFX4(ps, info->dh.public_key.data,
674
0
           info->dh.public_key.size);
675
0
  }
676
677
  /* write the real size */
678
0
  _gnutls_write_uint32(ps->length - cur_size, ps->data + size_offset);
679
680
0
  return 0;
681
0
}
682
683
static int unpack_anon_auth_info(gnutls_session_t session, gnutls_buffer_st *ps)
684
0
{
685
0
  int ret;
686
0
  size_t pack_size;
687
0
  anon_auth_info_t info = NULL;
688
689
0
  BUFFER_POP_NUM(ps, pack_size);
690
691
0
  if (pack_size == 0)
692
0
    return 0; /* nothing to be done */
693
694
  /* client and server have the same auth_info here
695
   */
696
0
  ret = _gnutls_auth_info_init(session, GNUTLS_CRD_ANON,
697
0
             sizeof(anon_auth_info_st), 1);
698
0
  if (ret < 0) {
699
0
    gnutls_assert();
700
0
    return ret;
701
0
  }
702
703
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
704
0
  if (info == NULL)
705
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
706
707
0
  BUFFER_POP_NUM(ps, info->dh.secret_bits);
708
709
0
  BUFFER_POP_DATUM(ps, &info->dh.prime);
710
0
  BUFFER_POP_DATUM(ps, &info->dh.generator);
711
0
  BUFFER_POP_DATUM(ps, &info->dh.public_key);
712
713
0
  return 0;
714
715
0
error:
716
0
  if (info) {
717
0
    _gnutls_free_datum(&info->dh.prime);
718
0
    _gnutls_free_datum(&info->dh.generator);
719
0
    _gnutls_free_datum(&info->dh.public_key);
720
0
  }
721
722
0
  return ret;
723
0
}
724
#endif /* ANON */
725
726
#ifdef ENABLE_PSK
727
/* Packs the PSK session authentication data.
728
 */
729
730
/* Format: 
731
 *      1 byte the credentials type
732
 *      4 bytes the size of the whole structure
733
 *
734
 *      4 bytes the size of the PSK username (x)
735
 *      x bytes the PSK username
736
 *      2 bytes the size of secret key in bits
737
 *      4 bytes the size of the prime
738
 *      x bytes the prime
739
 *      4 bytes the size of the generator
740
 *      x bytes the generator
741
 *      4 bytes the size of the public key
742
 *      x bytes the public key
743
 */
744
static int pack_psk_auth_info(gnutls_session_t session, gnutls_buffer_st *ps)
745
0
{
746
0
  psk_auth_info_t info;
747
0
  int username_len;
748
0
  int hint_len, ret;
749
0
  int size_offset;
750
0
  size_t cur_size;
751
752
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
753
0
  if (info == NULL)
754
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
755
756
0
  username_len = info->username_len;
757
0
  hint_len = info->hint_len + 1; /* include the terminating null */
758
759
0
  size_offset = ps->length;
760
0
  BUFFER_APPEND_NUM(ps, 0);
761
0
  cur_size = ps->length;
762
763
0
  BUFFER_APPEND_PFX4(ps, info->username, username_len);
764
0
  BUFFER_APPEND_PFX4(ps, info->hint ? info->hint : "\0", hint_len);
765
766
0
  BUFFER_APPEND_NUM(ps, info->dh.secret_bits);
767
0
  BUFFER_APPEND_PFX4(ps, info->dh.prime.data, info->dh.prime.size);
768
0
  BUFFER_APPEND_PFX4(ps, info->dh.generator.data,
769
0
         info->dh.generator.size);
770
0
  BUFFER_APPEND_PFX4(ps, info->dh.public_key.data,
771
0
         info->dh.public_key.size);
772
773
  /* write the real size */
774
0
  _gnutls_write_uint32(ps->length - cur_size, ps->data + size_offset);
775
0
  return 0;
776
0
}
777
778
static int unpack_psk_auth_info(gnutls_session_t session, gnutls_buffer_st *ps)
779
0
{
780
0
  size_t username_size, hint_size;
781
0
  int ret;
782
0
  psk_auth_info_t info;
783
0
  unsigned pack_size;
784
785
0
  ret = _gnutls_auth_info_init(session, GNUTLS_CRD_PSK,
786
0
             sizeof(psk_auth_info_st), 1);
787
0
  if (ret < 0) {
788
0
    gnutls_assert();
789
0
    return ret;
790
0
  }
791
792
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
793
0
  if (info == NULL)
794
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
795
796
0
  BUFFER_POP_NUM(ps, pack_size);
797
0
  if (pack_size == 0)
798
0
    return GNUTLS_E_INVALID_REQUEST;
799
800
0
  BUFFER_POP_NUM(ps, username_size);
801
0
  if (username_size > MAX_USERNAME_SIZE)
802
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
803
804
0
  gnutls_free(info->username);
805
0
  info->username = gnutls_malloc(username_size + 1);
806
0
  if (info->username == NULL)
807
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
808
0
  BUFFER_POP(ps, info->username, username_size);
809
0
  info->username[username_size] = 0;
810
0
  info->username_len = username_size;
811
812
  /* hint_size includes the terminating null */
813
0
  BUFFER_POP_NUM(ps, hint_size);
814
0
  if (hint_size > MAX_USERNAME_SIZE + 1)
815
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
816
817
0
  gnutls_free(info->hint);
818
0
  info->hint = gnutls_malloc(hint_size);
819
0
  if (info->hint == NULL)
820
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
821
0
  BUFFER_POP(ps, info->hint, hint_size);
822
0
  info->hint_len = hint_size - 1;
823
824
0
  BUFFER_POP_NUM(ps, info->dh.secret_bits);
825
826
0
  BUFFER_POP_DATUM(ps, &info->dh.prime);
827
0
  BUFFER_POP_DATUM(ps, &info->dh.generator);
828
0
  BUFFER_POP_DATUM(ps, &info->dh.public_key);
829
830
0
  ret = 0;
831
832
0
error:
833
0
  _gnutls_free_datum(&info->dh.prime);
834
0
  _gnutls_free_datum(&info->dh.generator);
835
0
  _gnutls_free_datum(&info->dh.public_key);
836
837
0
  return ret;
838
0
}
839
#endif
840
841
/* Packs the security parameters.
842
 */
843
static int pack_security_parameters(gnutls_session_t session,
844
            gnutls_buffer_st *ps)
845
0
{
846
0
  int ret;
847
0
  int size_offset;
848
0
  size_t cur_size;
849
850
0
  if (session->security_parameters.epoch_read !=
851
0
        session->security_parameters.epoch_write &&
852
0
      !(session->internals.hsk_flags & HSK_EARLY_START_USED)) {
853
0
    gnutls_assert();
854
0
    return GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE;
855
0
  }
856
857
0
  ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, NULL);
858
0
  if (ret < 0) {
859
0
    gnutls_assert();
860
0
    return ret;
861
0
  }
862
863
  /* move after the auth info stuff.
864
   */
865
0
  size_offset = ps->length;
866
0
  BUFFER_APPEND_NUM(ps, 0);
867
0
  cur_size = ps->length;
868
869
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.entity);
870
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.prf->id);
871
872
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.client_auth_type);
873
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.server_auth_type);
874
875
0
  BUFFER_APPEND(ps, &session->security_parameters.session_id_size, 1);
876
0
  BUFFER_APPEND(ps, session->security_parameters.session_id,
877
0
          session->security_parameters.session_id_size);
878
879
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.pversion->id);
880
881
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.client_ctype);
882
0
  BUFFER_APPEND_NUM(ps, session->security_parameters.server_ctype);
883
884
0
  BUFFER_APPEND(ps, session->security_parameters.cs->id, 2);
885
886
  /* if we are under TLS 1.3 do not pack keys or params negotiated using an extension
887
   * they are not necessary */
888
0
  if (!session->security_parameters.pversion->tls13_sem) {
889
0
    BUFFER_APPEND_PFX1(ps,
890
0
           session->security_parameters.master_secret,
891
0
           GNUTLS_MASTER_SIZE);
892
0
    BUFFER_APPEND_PFX1(ps,
893
0
           session->security_parameters.client_random,
894
0
           GNUTLS_RANDOM_SIZE);
895
0
    BUFFER_APPEND_PFX1(ps,
896
0
           session->security_parameters.server_random,
897
0
           GNUTLS_RANDOM_SIZE);
898
899
    /* reset max_record_recv_size if it was negotiated
900
     * using the record_size_limit extension */
901
0
    if (session->internals.hsk_flags &
902
0
        HSK_RECORD_SIZE_LIMIT_NEGOTIATED) {
903
0
      BUFFER_APPEND_NUM(ps,
904
0
            session->security_parameters
905
0
              .max_user_record_send_size);
906
0
      BUFFER_APPEND_NUM(ps,
907
0
            session->security_parameters
908
0
              .max_user_record_recv_size);
909
0
    } else {
910
0
      BUFFER_APPEND_NUM(ps, session->security_parameters
911
0
                  .max_record_recv_size);
912
0
      BUFFER_APPEND_NUM(ps, session->security_parameters
913
0
                  .max_record_send_size);
914
0
    }
915
916
0
    if (session->security_parameters.grp) {
917
0
      BUFFER_APPEND_NUM(ps,
918
0
            session->security_parameters.grp->id);
919
0
    } else {
920
0
      BUFFER_APPEND_NUM(ps, 0);
921
0
    }
922
923
0
    BUFFER_APPEND_NUM(
924
0
      ps, session->security_parameters.server_sign_algo);
925
0
    BUFFER_APPEND_NUM(
926
0
      ps, session->security_parameters.client_sign_algo);
927
0
    BUFFER_APPEND_NUM(
928
0
      ps, session->security_parameters.ext_master_secret);
929
0
    BUFFER_APPEND_NUM(ps, session->security_parameters.etm);
930
0
  }
931
932
0
  _gnutls_write_uint32(ps->length - cur_size, ps->data + size_offset);
933
934
0
  return 0;
935
0
}
936
937
static int unpack_security_parameters(gnutls_session_t session,
938
              gnutls_buffer_st *ps)
939
0
{
940
0
  size_t pack_size;
941
0
  int ret;
942
0
  unsigned version;
943
0
  gnutls_datum_t t;
944
0
  time_t timestamp;
945
0
  uint8_t cs[2];
946
947
0
  BUFFER_POP_NUM(ps, pack_size);
948
949
0
  if (pack_size == 0)
950
0
    return GNUTLS_E_INVALID_REQUEST;
951
952
0
  timestamp = session->internals.resumed_security_parameters.timestamp;
953
0
  memset(&session->internals.resumed_security_parameters, 0,
954
0
         sizeof(session->internals.resumed_security_parameters));
955
0
  session->internals.resumed_security_parameters.timestamp = timestamp;
956
957
0
  BUFFER_POP_NUM(ps,
958
0
           session->internals.resumed_security_parameters.entity);
959
960
0
  BUFFER_POP_NUM(ps, version);
961
0
  session->internals.resumed_security_parameters.prf =
962
0
    mac_to_entry(version);
963
0
  if (session->internals.resumed_security_parameters.prf == NULL)
964
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
965
966
0
  BUFFER_POP_NUM(ps, session->internals.resumed_security_parameters
967
0
           .client_auth_type);
968
0
  BUFFER_POP_NUM(ps, session->internals.resumed_security_parameters
969
0
           .server_auth_type);
970
971
0
  BUFFER_POP(
972
0
    ps,
973
0
    &session->internals.resumed_security_parameters.session_id_size,
974
0
    1);
975
976
0
  BUFFER_POP(
977
0
    ps, session->internals.resumed_security_parameters.session_id,
978
0
    session->internals.resumed_security_parameters.session_id_size);
979
980
0
  BUFFER_POP_NUM(ps, version);
981
0
  session->internals.resumed_security_parameters.pversion =
982
0
    version_to_entry(version);
983
0
  if (session->internals.resumed_security_parameters.pversion == NULL)
984
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
985
986
0
  BUFFER_POP_NUM(
987
0
    ps,
988
0
    session->internals.resumed_security_parameters.client_ctype);
989
0
  BUFFER_POP_NUM(
990
0
    ps,
991
0
    session->internals.resumed_security_parameters.server_ctype);
992
993
0
  BUFFER_POP(ps, cs, 2);
994
0
  session->internals.resumed_security_parameters.cs =
995
0
    ciphersuite_to_entry(cs);
996
0
  if (session->internals.resumed_security_parameters.cs == NULL)
997
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
998
999
0
  if (!session->internals.resumed_security_parameters.pversion->tls13_sem) {
1000
    /* master secret */
1001
0
    ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
1002
0
    if (ret < 0) {
1003
0
      ret = GNUTLS_E_PARSING_ERROR;
1004
0
      gnutls_assert();
1005
0
      goto error;
1006
0
    }
1007
0
    if (t.size == GNUTLS_MASTER_SIZE)
1008
0
      memcpy(session->internals.resumed_security_parameters
1009
0
               .master_secret,
1010
0
             t.data, t.size);
1011
1012
    /* client random */
1013
0
    ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
1014
0
    if (ret < 0) {
1015
0
      ret = GNUTLS_E_PARSING_ERROR;
1016
0
      gnutls_assert();
1017
0
      goto error;
1018
0
    }
1019
0
    if (t.size == GNUTLS_RANDOM_SIZE)
1020
0
      memcpy(session->internals.resumed_security_parameters
1021
0
               .client_random,
1022
0
             t.data, t.size);
1023
1024
    /* server random */
1025
0
    ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
1026
0
    if (ret < 0) {
1027
0
      ret = GNUTLS_E_PARSING_ERROR;
1028
0
      gnutls_assert();
1029
0
      goto error;
1030
0
    }
1031
0
    if (t.size == GNUTLS_RANDOM_SIZE)
1032
0
      memcpy(session->internals.resumed_security_parameters
1033
0
               .server_random,
1034
0
             t.data, t.size);
1035
1036
0
    BUFFER_POP_NUM(ps,
1037
0
             session->internals.resumed_security_parameters
1038
0
               .max_record_send_size);
1039
0
    BUFFER_POP_NUM(ps,
1040
0
             session->internals.resumed_security_parameters
1041
0
               .max_record_recv_size);
1042
1043
0
    BUFFER_POP_NUM(ps, ret);
1044
0
    session->internals.resumed_security_parameters.grp =
1045
0
      _gnutls_id_to_group(ret);
1046
    /* it can be null */
1047
1048
0
    BUFFER_POP_NUM(ps,
1049
0
             session->internals.resumed_security_parameters
1050
0
               .server_sign_algo);
1051
0
    BUFFER_POP_NUM(ps,
1052
0
             session->internals.resumed_security_parameters
1053
0
               .client_sign_algo);
1054
0
    BUFFER_POP_NUM(ps,
1055
0
             session->internals.resumed_security_parameters
1056
0
               .ext_master_secret);
1057
0
    BUFFER_POP_NUM(
1058
0
      ps, session->internals.resumed_security_parameters.etm);
1059
1060
0
    if (session->internals.resumed_security_parameters
1061
0
            .max_record_recv_size == 0 ||
1062
0
        session->internals.resumed_security_parameters
1063
0
            .max_record_send_size == 0) {
1064
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1065
0
    }
1066
0
  }
1067
1068
0
  ret = 0;
1069
1070
0
error:
1071
0
  return ret;
1072
0
}
1073
1074
/**
1075
 * gnutls_session_set_premaster:
1076
 * @session: is a #gnutls_session_t type.
1077
 * @entity: GNUTLS_SERVER or GNUTLS_CLIENT
1078
 * @version: the TLS protocol version
1079
 * @kx: the key exchange method
1080
 * @cipher: the cipher
1081
 * @mac: the MAC algorithm
1082
 * @comp: the compression method (ignored)
1083
 * @master: the master key to use
1084
 * @session_id: the session identifier
1085
 *
1086
 * This function sets the premaster secret in a session. This is
1087
 * a function intended for exceptional uses. Do not use this
1088
 * function unless you are implementing a legacy protocol.
1089
 * Use gnutls_session_set_data() instead.
1090
 *
1091
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
1092
 *   an error code is returned.
1093
 **/
1094
int gnutls_session_set_premaster(gnutls_session_t session, unsigned int entity,
1095
         gnutls_protocol_t version,
1096
         gnutls_kx_algorithm_t kx,
1097
         gnutls_cipher_algorithm_t cipher,
1098
         gnutls_mac_algorithm_t mac,
1099
         gnutls_compression_method_t comp,
1100
         const gnutls_datum_t *master,
1101
         const gnutls_datum_t *session_id)
1102
0
{
1103
0
  int ret;
1104
0
  uint8_t cs[2];
1105
1106
0
  memset(&session->internals.resumed_security_parameters, 0,
1107
0
         sizeof(session->internals.resumed_security_parameters));
1108
1109
0
  session->internals.resumed_security_parameters.entity = entity;
1110
1111
0
  ret = _gnutls_cipher_suite_get_id(kx, cipher, mac, cs);
1112
0
  if (ret < 0)
1113
0
    return gnutls_assert_val(ret);
1114
1115
0
  session->internals.resumed_security_parameters.cs =
1116
0
    ciphersuite_to_entry(cs);
1117
0
  if (session->internals.resumed_security_parameters.cs == NULL)
1118
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1119
1120
0
  session->internals.resumed_security_parameters.client_ctype =
1121
0
    DEFAULT_CERT_TYPE;
1122
0
  session->internals.resumed_security_parameters.server_ctype =
1123
0
    DEFAULT_CERT_TYPE;
1124
0
  session->internals.resumed_security_parameters.pversion =
1125
0
    version_to_entry(version);
1126
0
  if (session->internals.resumed_security_parameters.pversion == NULL)
1127
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1128
1129
0
  if (session->internals.resumed_security_parameters.pversion
1130
0
        ->selectable_prf)
1131
0
    session->internals.resumed_security_parameters
1132
0
      .prf = mac_to_entry(
1133
0
      session->internals.resumed_security_parameters.cs->prf);
1134
0
  else
1135
0
    session->internals.resumed_security_parameters.prf =
1136
0
      mac_to_entry(GNUTLS_MAC_MD5_SHA1);
1137
0
  if (session->internals.resumed_security_parameters.prf == NULL)
1138
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1139
1140
0
  if (master->size != GNUTLS_MASTER_SIZE)
1141
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1142
1143
0
  memcpy(session->internals.resumed_security_parameters.master_secret,
1144
0
         master->data, master->size);
1145
1146
0
  if (session_id->size > GNUTLS_MAX_SESSION_ID)
1147
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1148
1149
0
  session->internals.resumed_security_parameters.session_id_size =
1150
0
    session_id->size;
1151
0
  memcpy(session->internals.resumed_security_parameters.session_id,
1152
0
         session_id->data, session_id->size);
1153
1154
0
  session->internals.resumed_security_parameters.max_record_send_size =
1155
0
    session->internals.resumed_security_parameters
1156
0
      .max_record_recv_size = DEFAULT_MAX_RECORD_SIZE;
1157
1158
0
  session->internals.resumed_security_parameters.timestamp =
1159
0
    gnutls_time(0);
1160
1161
0
  session->internals.resumed_security_parameters.grp = 0;
1162
1163
0
  session->internals.resumed_security_parameters.post_handshake_auth = 0;
1164
1165
0
  session->internals.premaster_set = 1;
1166
1167
0
  return 0;
1168
0
}