Coverage Report

Created: 2023-03-26 07:33

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