Coverage Report

Created: 2025-07-23 07:16

/src/gnutls/lib/state.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2002-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2014-2016 Nikos Mavrogiannopoulos
4
 * Copyright (C) 2015-2018 Red Hat, Inc.
5
 *
6
 * Author: Nikos Mavrogiannopoulos
7
 *
8
 * This file is part of GnuTLS.
9
 *
10
 * The GnuTLS is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public License
12
 * as published by the Free Software Foundation; either version 2.1 of
13
 * the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
22
 *
23
 */
24
25
/* Functions to manipulate the session (gnutls_int.h), and some other stuff
26
 * are included here. The file's name is traditionally gnutls_state even if the
27
 * state has been renamed to session.
28
 */
29
30
#include "gnutls_int.h"
31
#include "errors.h"
32
#include "auth.h"
33
#include "num.h"
34
#include "datum.h"
35
#include "db.h"
36
#include "record.h"
37
#include "handshake.h"
38
#include "dh.h"
39
#include "buffers.h"
40
#include "mbuffers.h"
41
#include "state.h"
42
#include "constate.h"
43
#include "auth/cert.h"
44
#include "auth/anon.h"
45
#include "auth/psk.h"
46
#include "algorithms.h"
47
#include "hello_ext.h"
48
#include "system.h"
49
#include "random.h"
50
#include "fips.h"
51
#include <intprops.h>
52
#include <gnutls/dtls.h>
53
#include "dtls.h"
54
#include "tls13/session_ticket.h"
55
#include "ext/cert_types.h"
56
#include "locks.h"
57
#include "kx.h"
58
59
/* to be used by supplemental data support to disable TLS1.3
60
 * when supplemental data have been globally registered */
61
unsigned _gnutls_disable_tls13 = 0;
62
63
/* These should really be static, but src/tests.c calls them.  Make
64
   them public functions?  */
65
void _gnutls_rsa_pms_set_version(gnutls_session_t session, unsigned char major,
66
         unsigned char minor);
67
68
/**
69
 * gnutls_cipher_get:
70
 * @session: is a #gnutls_session_t type.
71
 *
72
 * Get the currently used cipher.
73
 *
74
 * Returns: the currently used cipher, a #gnutls_cipher_algorithm_t
75
 *   type.
76
 **/
77
gnutls_cipher_algorithm_t gnutls_cipher_get(gnutls_session_t session)
78
0
{
79
0
  record_parameters_st *record_params;
80
0
  int ret;
81
82
0
  ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
83
0
  if (ret < 0)
84
0
    return gnutls_assert_val(GNUTLS_CIPHER_NULL);
85
86
0
  return record_params->cipher->id;
87
0
}
88
89
/**
90
 * gnutls_early_cipher_get:
91
 * @session: is a #gnutls_session_t type.
92
 *
93
 * Get the cipher algorithm used for encrypting early data.
94
 *
95
 * Returns: the cipher used for early data, a
96
 *   #gnutls_cipher_algorithm_t type.
97
 *
98
 * Since: 3.7.2
99
 **/
100
gnutls_cipher_algorithm_t gnutls_early_cipher_get(gnutls_session_t session)
101
0
{
102
0
  const cipher_entry_st *ce;
103
104
0
  if (!(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)) {
105
0
    return gnutls_assert_val(GNUTLS_CIPHER_UNKNOWN);
106
0
  }
107
108
0
  if (unlikely(session->internals.resumed_security_parameters.cs ==
109
0
         NULL)) {
110
0
    return gnutls_assert_val(GNUTLS_CIPHER_UNKNOWN);
111
0
  }
112
113
0
  ce = cipher_to_entry(session->internals.resumed_security_parameters.cs
114
0
             ->block_algorithm);
115
0
  if (unlikely(ce == NULL)) {
116
0
    return gnutls_assert_val(GNUTLS_CIPHER_UNKNOWN);
117
0
  }
118
119
0
  return ce->id;
120
0
}
121
122
/**
123
 * gnutls_certificate_type_get:
124
 * @session: is a #gnutls_session_t type.
125
 *
126
 * This function returns the type of the certificate that is negotiated
127
 * for this side to send to the peer. The certificate type is by default
128
 * X.509, unless an alternative certificate type is enabled by
129
 * gnutls_init() and negotiated during the session.
130
 *
131
 * Resumed sessions will return the certificate type that was negotiated
132
 * and used in the original session.
133
 *
134
 * As of version 3.6.4 it is recommended to use
135
 * gnutls_certificate_type_get2() which is more fine-grained.
136
 *
137
 * Returns: the currently used #gnutls_certificate_type_t certificate
138
 *   type as negotiated for 'our' side of the connection.
139
 **/
140
gnutls_certificate_type_t gnutls_certificate_type_get(gnutls_session_t session)
141
0
{
142
0
  return gnutls_certificate_type_get2(session, GNUTLS_CTYPE_OURS);
143
0
}
144
145
/**
146
 * gnutls_certificate_type_get2:
147
 * @session: is a #gnutls_session_t type.
148
 * @target: is a #gnutls_ctype_target_t type.
149
 *
150
 * This function returns the type of the certificate that a side
151
 * is negotiated to use.  The certificate type is by default X.509,
152
 * unless an alternative certificate type is enabled by gnutls_init() and
153
 * negotiated during the session.
154
 *
155
 * The @target parameter specifies whether to request the negotiated
156
 * certificate type for the client (%GNUTLS_CTYPE_CLIENT),
157
 * or for the server (%GNUTLS_CTYPE_SERVER). Additionally, in P2P mode
158
 * connection set up where you don't know in advance who will be client
159
 * and who will be server you can use the flag (%GNUTLS_CTYPE_OURS) and
160
 * (%GNUTLS_CTYPE_PEERS) to retrieve the corresponding certificate types.
161
 *
162
 * Resumed sessions will return the certificate type that was negotiated
163
 * and used in the original session. That is, this function can be used
164
 * to reliably determine the type of the certificate returned by
165
 * gnutls_certificate_get_peers().
166
 *
167
 * Returns: the currently used #gnutls_certificate_type_t certificate
168
 *   type for the client or the server.
169
 *
170
 * Since: 3.6.4
171
 **/
172
gnutls_certificate_type_t
173
gnutls_certificate_type_get2(gnutls_session_t session,
174
           gnutls_ctype_target_t target)
175
0
{
176
  /* We want to inline this function so therefore
177
   * we've defined it in gnutls_int.h */
178
0
  return get_certificate_type(session, target);
179
0
}
180
181
/**
182
 * gnutls_kx_get:
183
 * @session: is a #gnutls_session_t type.
184
 *
185
 * Get the currently used key exchange algorithm.
186
 *
187
 * This function will return %GNUTLS_KX_ECDHE_RSA, or %GNUTLS_KX_DHE_RSA
188
 * under TLS 1.3, to indicate an elliptic curve DH key exchange or
189
 * a finite field one. The precise group used is available
190
 * by calling gnutls_group_get() instead.
191
 *
192
 * Returns: the key exchange algorithm used in the last handshake, a
193
 *   #gnutls_kx_algorithm_t value.
194
 **/
195
gnutls_kx_algorithm_t gnutls_kx_get(gnutls_session_t session)
196
0
{
197
0
  if (session->security_parameters.cs == 0)
198
0
    return 0;
199
200
0
  if (session->security_parameters.cs->kx_algorithm == 0) { /* TLS 1.3 */
201
0
    const version_entry_st *ver = get_version(session);
202
0
    const gnutls_group_entry_st *group = get_group(session);
203
204
0
    if (ver->tls13_sem) {
205
0
      if (gnutls_auth_client_get_type(session) ==
206
0
          GNUTLS_CRD_PSK) {
207
0
        if (group) {
208
0
          if (group->pk == GNUTLS_PK_DH)
209
0
            return GNUTLS_KX_DHE_PSK;
210
0
          else
211
0
            return GNUTLS_KX_ECDHE_PSK;
212
0
        } else {
213
0
          return GNUTLS_KX_PSK;
214
0
        }
215
0
      } else if (group) {
216
0
        if (group->pk == GNUTLS_PK_DH)
217
0
          return GNUTLS_KX_DHE_RSA;
218
0
        else
219
0
          return GNUTLS_KX_ECDHE_RSA;
220
0
      }
221
0
    }
222
0
  }
223
224
0
  return session->security_parameters.cs->kx_algorithm;
225
0
}
226
227
/**
228
 * gnutls_mac_get:
229
 * @session: is a #gnutls_session_t type.
230
 *
231
 * Get the currently used MAC algorithm.
232
 *
233
 * Returns: the currently used mac algorithm, a
234
 *   #gnutls_mac_algorithm_t value.
235
 **/
236
gnutls_mac_algorithm_t gnutls_mac_get(gnutls_session_t session)
237
0
{
238
0
  record_parameters_st *record_params;
239
0
  int ret;
240
241
0
  ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
242
0
  if (ret < 0)
243
0
    return gnutls_assert_val(GNUTLS_MAC_NULL);
244
245
0
  return record_params->mac->id;
246
0
}
247
248
/**
249
 * gnutls_compression_get:
250
 * @session: is a #gnutls_session_t type.
251
 *
252
 * Get the currently used compression algorithm.
253
 *
254
 * Returns: the currently used compression method, a
255
 *   #gnutls_compression_method_t value.
256
 **/
257
gnutls_compression_method_t gnutls_compression_get(gnutls_session_t session)
258
0
{
259
0
  return GNUTLS_COMP_NULL;
260
0
}
261
262
/**
263
 * gnutls_prf_hash_get:
264
 * @session: is a #gnutls_session_t type.
265
 *
266
 * Get the currently used hash algorithm. In TLS 1.3, the hash
267
 * algorithm is used for both the key derivation function and
268
 * handshake message authentication code. In TLS 1.2, it matches the
269
 * hash algorithm used for PRF.
270
 *
271
 * Returns: the currently used hash algorithm, a
272
 *    #gnutls_digest_algorithm_t value.
273
 *
274
 * Since: 3.6.13
275
 **/
276
gnutls_digest_algorithm_t gnutls_prf_hash_get(const gnutls_session_t session)
277
0
{
278
0
  if (session->security_parameters.prf == NULL)
279
0
    return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
280
281
0
  if (session->security_parameters.prf->id >= GNUTLS_MAC_AEAD)
282
0
    return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
283
284
0
  return (gnutls_digest_algorithm_t)session->security_parameters.prf->id;
285
0
}
286
287
/**
288
 * gnutls_early_prf_hash_get:
289
 * @session: is a #gnutls_session_t type.
290
 *
291
 * Get the hash algorithm used as a PRF to derive keys for encrypting
292
 * early data in TLS 1.3.
293
 *
294
 * Returns: the hash algorithm used for early data, a
295
 *    #gnutls_digest_algorithm_t value.
296
 *
297
 * Since: 3.7.2
298
 **/
299
gnutls_digest_algorithm_t
300
gnutls_early_prf_hash_get(const gnutls_session_t session)
301
0
{
302
0
  if (!(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)) {
303
0
    return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
304
0
  }
305
306
0
  if (unlikely(session->internals.resumed_security_parameters.prf ==
307
0
         NULL)) {
308
0
    return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
309
0
  }
310
311
0
  if (unlikely(session->internals.resumed_security_parameters.prf->id >=
312
0
         GNUTLS_MAC_AEAD)) {
313
0
    return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
314
0
  }
315
316
0
  return (gnutls_digest_algorithm_t)
317
0
    session->internals.resumed_security_parameters.prf->id;
318
0
}
319
320
/**
321
 * gnutls_ciphersuite_get:
322
 * @session: is a #gnutls_session_t type.
323
 *
324
 * Get the canonical name of negotiated TLS ciphersuite.  The names
325
 * returned by this function match the IANA registry, with one
326
 * exception:
327
 *
328
 *   TLS_DHE_DSS_RC4_128_SHA { 0x00, 0x66 }
329
 *
330
 * which is reserved for compatibility.
331
 *
332
 * To get a detailed description of the current ciphersuite, it is
333
 * recommended to use gnutls_session_get_desc().
334
 *
335
 * Returns: a string that contains the canonical name of a TLS ciphersuite,
336
 *     or %NULL if the handshake is not completed.
337
 *
338
 * Since: 3.7.4
339
 **/
340
const char *gnutls_ciphersuite_get(gnutls_session_t session)
341
0
{
342
0
  if (unlikely(session->internals.handshake_in_progress)) {
343
0
    return NULL;
344
0
  }
345
0
  return session->security_parameters.cs->canonical_name;
346
0
}
347
348
void reset_binders(gnutls_session_t session)
349
0
{
350
0
  _gnutls_free_temp_key_datum(&session->key.binders[0].psk);
351
0
  _gnutls_free_temp_key_datum(&session->key.binders[1].psk);
352
0
  memset(session->key.binders, 0, sizeof(session->key.binders));
353
0
  session->internals.hsk_flags &= ~HSK_PSK_SELECTED;
354
0
}
355
356
/* Check whether certificate credentials of type @cert_type are set
357
 * for the current session.
358
 */
359
static bool _gnutls_has_cert_credentials(gnutls_session_t session,
360
           gnutls_certificate_type_t cert_type)
361
0
{
362
0
  unsigned i;
363
0
  unsigned cert_found = 0;
364
0
  gnutls_certificate_credentials_t cred;
365
366
  /* First, check for certificate credentials. If we have no certificate
367
   * credentials set then we don't support certificates at all.
368
   */
369
0
  cred = (gnutls_certificate_credentials_t)_gnutls_get_cred(
370
0
    session, GNUTLS_CRD_CERTIFICATE);
371
372
0
  if (cred == NULL)
373
0
    return false;
374
375
  /* There are credentials initialized. Now check whether we can find
376
   * pre-set certificates of the required type, but only if we don't
377
   * use the callback functions.
378
   */
379
0
  if (cred->get_cert_callback3 == NULL) {
380
0
    for (i = 0; i < cred->ncerts; i++) {
381
0
      if (cred->certs[i].cert_list[0].type == cert_type) {
382
0
        cert_found = 1;
383
0
        break;
384
0
      }
385
0
    }
386
387
0
    if (cert_found == 0) {
388
      /* No matching certificate found. */
389
0
      return false;
390
0
    }
391
0
  }
392
393
0
  return true; // OK
394
0
}
395
396
/* Check if the given certificate type is supported.
397
 * This means that it is enabled by the priority functions,
398
 * and in some cases a matching certificate exists. A check for
399
 * the latter can be toggled via the parameter @check_credentials.
400
 */
401
bool _gnutls_session_is_cert_type_supported(gnutls_session_t session,
402
              gnutls_certificate_type_t cert_type,
403
              bool check_credentials,
404
              gnutls_ctype_target_t target)
405
0
{
406
0
  unsigned i;
407
0
  priority_st *ctype_priorities;
408
409
  // Check whether this cert type is enabled by the application
410
0
  if (!is_cert_type_enabled(session, cert_type))
411
0
    return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
412
413
  // Perform a credentials check if requested
414
0
  if (check_credentials) {
415
0
    if (!_gnutls_has_cert_credentials(session, cert_type))
416
0
      return gnutls_assert_val(
417
0
        GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
418
0
  }
419
420
  /* So far so good. We have the required credentials (if needed).
421
   * Now check whether we are allowed to use them according to our
422
   * priorities.
423
   */
424
  // Which certificate type should we query?
425
0
  switch (target) {
426
0
  case GNUTLS_CTYPE_CLIENT:
427
0
    ctype_priorities =
428
0
      &(session->internals.priorities->client_ctype);
429
0
    break;
430
0
  case GNUTLS_CTYPE_SERVER:
431
0
    ctype_priorities =
432
0
      &(session->internals.priorities->server_ctype);
433
0
    break;
434
0
  default:
435
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
436
0
  }
437
438
  // No explicit priorities set, and default ctype is asked
439
0
  if (ctype_priorities->num_priorities == 0 &&
440
0
      cert_type == DEFAULT_CERT_TYPE)
441
0
    return 0;
442
443
  /* Now lets find out whether our cert type is in our priority
444
   * list, i.e. set of allowed cert types.
445
   */
446
0
  for (i = 0; i < ctype_priorities->num_priorities; i++) {
447
0
    if (ctype_priorities->priorities[i] == cert_type)
448
0
      return 0;
449
0
  }
450
451
0
  return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
452
0
}
453
454
static void deinit_keys(gnutls_session_t session)
455
0
{
456
0
  const version_entry_st *vers = get_version(session);
457
458
0
  if (vers == NULL)
459
0
    return;
460
461
0
  gnutls_pk_params_release(&session->key.kshare.ecdhx_params);
462
0
  gnutls_pk_params_release(&session->key.kshare.ecdh_params);
463
0
  gnutls_pk_params_release(&session->key.kshare.dh_params);
464
0
  gnutls_pk_params_release(&session->key.kshare.kem_params);
465
466
0
  if (!vers->tls13_sem && session->key.binders[0].prf == NULL) {
467
0
    gnutls_pk_params_release(&session->key.proto.tls12.ecdh.params);
468
0
    gnutls_pk_params_release(&session->key.proto.tls12.dh.params);
469
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.ecdh.x);
470
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.ecdh.y);
471
0
    _gnutls_free_temp_key_datum(&session->key.proto.tls12.ecdh.raw);
472
473
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.dh.client_Y);
474
475
    /* SRP */
476
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.srp_p);
477
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.srp_g);
478
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.srp_key);
479
480
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.u);
481
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.a);
482
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.x);
483
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.A);
484
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.B);
485
0
    zrelease_temp_mpi_key(&session->key.proto.tls12.srp.b);
486
0
  } else {
487
0
    gnutls_memset(session->key.proto.tls13.temp_secret, 0,
488
0
            sizeof(session->key.proto.tls13.temp_secret));
489
0
  }
490
491
0
  reset_binders(session);
492
0
  _gnutls_free_temp_key_datum(&session->key.key);
493
0
}
494
495
/* An internal version of _gnutls_handshake_internal_state_clear(),
496
 * it will not attempt to deallocate, only initialize */
497
static void handshake_internal_state_clear1(gnutls_session_t session)
498
0
{
499
  /* by default no selected certificate */
500
0
  session->internals.adv_version_major = 0;
501
0
  session->internals.adv_version_minor = 0;
502
0
  session->internals.direction = 0;
503
504
  /* use out of band data for the last
505
   * handshake messages received.
506
   */
507
0
  session->internals.last_handshake_in = -1;
508
0
  session->internals.last_handshake_out = -1;
509
510
0
  session->internals.resumable = true;
511
512
0
  session->internals.handshake_suspicious_loops = 0;
513
0
  session->internals.dtls.hsk_read_seq = 0;
514
0
  session->internals.dtls.hsk_write_seq = 0;
515
516
0
  session->internals.cand_ec_group = 0;
517
0
  session->internals.cand_dh_group = 0;
518
519
0
  session->internals.hrr_cs[0] = CS_INVALID_MAJOR;
520
0
  session->internals.hrr_cs[1] = CS_INVALID_MINOR;
521
522
0
  session->internals.client_hello_exts_set = false;
523
0
}
524
525
/* This function will clear all the variables in internals
526
 * structure within the session, which depend on the current handshake.
527
 * This is used to allow further handshakes.
528
 */
529
void _gnutls_handshake_internal_state_clear(gnutls_session_t session)
530
0
{
531
0
  handshake_internal_state_clear1(session);
532
533
0
  _gnutls_handshake_hash_buffers_clear(session);
534
0
  deinit_keys(session);
535
536
0
  _gnutls_epoch_gc(session);
537
538
0
  session->internals.handshake_abs_timeout.tv_sec = 0;
539
0
  session->internals.handshake_abs_timeout.tv_nsec = 0;
540
0
  session->internals.handshake_in_progress = 0;
541
542
0
  session->internals.tfo.connect_addrlen = 0;
543
0
  session->internals.tfo.connect_only = 0;
544
0
  session->internals.early_data_received = 0;
545
0
  session->internals.session_ticket_renew = 0;
546
0
}
547
548
/**
549
 * gnutls_init:
550
 * @session: is a pointer to a #gnutls_session_t type.
551
 * @flags: indicate if this session is to be used for server or client.
552
 *
553
 * This function initializes the provided session. Every session must
554
 * be initialized before use, and after successful initialization and
555
 * use must be deinitialized by calling gnutls_deinit().
556
 *
557
 * @flags can be any combination of flags from %gnutls_init_flags_t.
558
 *
559
 * Note that since version 3.1.2 this function enables some common
560
 * TLS extensions such as session tickets and OCSP certificate status
561
 * request in client side by default. To prevent that use the %GNUTLS_NO_DEFAULT_EXTENSIONS
562
 * flag.
563
 *
564
 * Note that it is never mandatory to use gnutls_deinit() after this
565
 * function fails.  Since gnutls 3.8.0, it is safe to unconditionally
566
 * use gnutls_deinit() even after failure regardless of whether the
567
 * memory was initialized prior to gnutls_init(); however, clients
568
 * wanting to be portable to older versions of the library should
569
 * either skip deinitialization on failure, or pre-initialize the
570
 * memory passed in to gnutls_init() to all zeroes via memset() or
571
 * similar.
572
 *
573
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
574
 **/
575
int gnutls_init(gnutls_session_t *session, unsigned int flags)
576
0
{
577
0
  int ret;
578
579
0
  *session = NULL;
580
0
  FAIL_IF_LIB_ERROR;
581
582
0
  *session = gnutls_calloc(1, sizeof(struct gnutls_session_int));
583
0
  if (*session == NULL)
584
0
    return GNUTLS_E_MEMORY_ERROR;
585
586
0
  ret = gnutls_mutex_init(&(*session)->internals.post_negotiation_lock);
587
0
  if (ret < 0) {
588
0
    gnutls_assert();
589
0
    gnutls_free(*session);
590
0
    return ret;
591
0
  }
592
593
0
  ret = gnutls_mutex_init(&(*session)->internals.epoch_lock);
594
0
  if (ret < 0) {
595
0
    gnutls_assert();
596
0
    gnutls_mutex_deinit(
597
0
      &(*session)->internals.post_negotiation_lock);
598
0
    gnutls_free(*session);
599
0
    return ret;
600
0
  }
601
602
0
  ret = _gnutls_epoch_setup_next(*session, 1, NULL);
603
0
  if (ret < 0) {
604
0
    gnutls_mutex_deinit(
605
0
      &(*session)->internals.post_negotiation_lock);
606
0
    gnutls_mutex_deinit(&(*session)->internals.epoch_lock);
607
0
    gnutls_free(*session);
608
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
609
0
  }
610
0
  _gnutls_epoch_bump(*session);
611
612
0
  (*session)->security_parameters.entity =
613
0
    (flags & GNUTLS_SERVER ? GNUTLS_SERVER : GNUTLS_CLIENT);
614
615
  /* the default certificate type for TLS */
616
0
  (*session)->security_parameters.client_ctype = DEFAULT_CERT_TYPE;
617
0
  (*session)->security_parameters.server_ctype = DEFAULT_CERT_TYPE;
618
619
  /* Initialize buffers */
620
0
  _gnutls_buffer_init(&(*session)->internals.handshake_hash_buffer);
621
0
  _gnutls_buffer_init(&(*session)->internals.post_handshake_hash_buffer);
622
0
  _gnutls_buffer_init(&(*session)->internals.hb_remote_data);
623
0
  _gnutls_buffer_init(&(*session)->internals.hb_local_data);
624
0
  _gnutls_buffer_init(&(*session)->internals.record_presend_buffer);
625
0
  _gnutls_buffer_init(&(*session)->internals.record_key_update_buffer);
626
0
  _gnutls_buffer_init(&(*session)->internals.reauth_buffer);
627
628
0
  _mbuffer_head_init(&(*session)->internals.record_buffer);
629
0
  _mbuffer_head_init(&(*session)->internals.record_send_buffer);
630
0
  _mbuffer_head_init(&(*session)->internals.record_recv_buffer);
631
0
  _mbuffer_head_init(&(*session)->internals.early_data_recv_buffer);
632
0
  _gnutls_buffer_init(&(*session)->internals.early_data_presend_buffer);
633
634
0
  _mbuffer_head_init(&(*session)->internals.handshake_send_buffer);
635
0
  _gnutls_handshake_recv_buffer_init(*session);
636
637
0
  (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME;
638
639
  /* Ticket key rotation - set the default X to 3 times the ticket expire time */
640
0
  (*session)->key.totp.last_result = 0;
641
642
0
  gnutls_handshake_set_max_packet_length((*session),
643
0
                 MAX_HANDSHAKE_PACKET_SIZE);
644
645
  /* set the socket pointers to -1;
646
   */
647
0
  (*session)->internals.transport_recv_ptr = (gnutls_transport_ptr_t)-1;
648
0
  (*session)->internals.transport_send_ptr = (gnutls_transport_ptr_t)-1;
649
650
  /* set the default maximum record size for TLS
651
   */
652
0
  (*session)->security_parameters.max_record_recv_size =
653
0
    DEFAULT_MAX_RECORD_SIZE;
654
0
  (*session)->security_parameters.max_record_send_size =
655
0
    DEFAULT_MAX_RECORD_SIZE;
656
0
  (*session)->security_parameters.max_user_record_recv_size =
657
0
    DEFAULT_MAX_RECORD_SIZE;
658
0
  (*session)->security_parameters.max_user_record_send_size =
659
0
    DEFAULT_MAX_RECORD_SIZE;
660
661
  /* set the default early data size for TLS
662
   */
663
0
  if ((*session)->security_parameters.entity == GNUTLS_SERVER) {
664
0
    (*session)->security_parameters.max_early_data_size =
665
0
      DEFAULT_MAX_EARLY_DATA_SIZE;
666
0
  } else {
667
0
    (*session)->security_parameters.max_early_data_size = 0;
668
0
  }
669
670
  /* Everything else not initialized here is initialized as NULL
671
   * or 0. This is why calloc is used. However, we want to
672
   * ensure that certain portions of data are initialized at
673
   * runtime before being used. Mark such regions with a
674
   * valgrind client request as undefined.
675
   */
676
0
  _gnutls_memory_mark_undefined(
677
0
    (*session)->security_parameters.master_secret,
678
0
    GNUTLS_MASTER_SIZE);
679
0
  _gnutls_memory_mark_undefined(
680
0
    (*session)->security_parameters.client_random,
681
0
    GNUTLS_RANDOM_SIZE);
682
0
  _gnutls_memory_mark_undefined(
683
0
    (*session)->security_parameters.server_random,
684
0
    GNUTLS_RANDOM_SIZE);
685
0
  _gnutls_memory_mark_undefined((*session)->key.session_ticket_key,
686
0
              TICKET_MASTER_KEY_SIZE);
687
0
  _gnutls_memory_mark_undefined((*session)->key.previous_ticket_key,
688
0
              TICKET_MASTER_KEY_SIZE);
689
0
  _gnutls_memory_mark_undefined((*session)->key.initial_stek,
690
0
              TICKET_MASTER_KEY_SIZE);
691
692
0
  handshake_internal_state_clear1(*session);
693
694
0
#ifdef MSG_NOSIGNAL
695
0
  if (flags & GNUTLS_NO_SIGNAL)
696
0
    gnutls_transport_set_vec_push_function(*session,
697
0
                   system_writev_nosignal);
698
0
  else
699
0
#endif
700
0
    gnutls_transport_set_vec_push_function(*session, system_writev);
701
0
  (*session)->internals.pull_timeout_func = gnutls_system_recv_timeout;
702
0
  (*session)->internals.pull_func = system_read;
703
0
  (*session)->internals.errno_func = system_errno;
704
705
0
  (*session)->internals.saved_username = NULL;
706
0
  (*session)->internals.saved_username_size = -1;
707
708
  /* heartbeat timeouts */
709
0
  (*session)->internals.hb_retrans_timeout_ms = 1000;
710
0
  (*session)->internals.hb_total_timeout_ms = 60000;
711
712
0
  if (flags & GNUTLS_DATAGRAM) {
713
0
    (*session)->internals.dtls.mtu = DTLS_DEFAULT_MTU;
714
0
    (*session)->internals.transport = GNUTLS_DGRAM;
715
716
0
    gnutls_dtls_set_timeouts(*session, DTLS_RETRANS_TIMEOUT, 60000);
717
0
  } else {
718
0
    (*session)->internals.transport = GNUTLS_STREAM;
719
0
  }
720
721
  /* Enable useful extensions */
722
0
  if ((flags & GNUTLS_CLIENT) &&
723
0
      !(flags & GNUTLS_NO_DEFAULT_EXTENSIONS)) {
724
0
#ifdef ENABLE_OCSP
725
0
    if (!(flags & GNUTLS_NO_STATUS_REQUEST))
726
0
      gnutls_ocsp_status_request_enable_client(*session, NULL,
727
0
                 0, NULL);
728
0
#endif
729
0
  }
730
731
  /* session tickets in server side are enabled by setting a key */
732
0
  if (flags & GNUTLS_SERVER)
733
0
    flags |= GNUTLS_NO_TICKETS;
734
735
0
  (*session)->internals.flags = flags;
736
737
0
  if (_gnutls_disable_tls13 != 0)
738
0
    (*session)->internals.flags |= INT_FLAG_NO_TLS13;
739
740
  /* Install the default keylog function */
741
0
  gnutls_session_set_keylog_function(*session, _gnutls_nss_keylog_func);
742
743
0
  return 0;
744
0
}
745
746
/**
747
 * gnutls_deinit:
748
 * @session: is a #gnutls_session_t type.
749
 *
750
 * This function clears all buffers associated with the @session.
751
 * This function will also remove session data from the session
752
 * database if the session was terminated abnormally.
753
 **/
754
void gnutls_deinit(gnutls_session_t session)
755
0
{
756
0
  unsigned int i;
757
758
0
  if (session == NULL)
759
0
    return;
760
761
  /* remove auth info firstly */
762
0
  _gnutls_free_auth_info(session);
763
764
0
  _gnutls_handshake_internal_state_clear(session);
765
0
  _gnutls_handshake_io_buffer_clear(session);
766
0
  _gnutls_hello_ext_priv_deinit(session);
767
768
0
  for (i = 0; i < MAX_EPOCH_INDEX; i++)
769
0
    if (session->record_parameters[i] != NULL) {
770
0
      _gnutls_epoch_free(session,
771
0
             session->record_parameters[i]);
772
0
      session->record_parameters[i] = NULL;
773
0
    }
774
775
0
  _gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
776
0
  _gnutls_buffer_clear(&session->internals.post_handshake_hash_buffer);
777
0
  _gnutls_buffer_clear(&session->internals.hb_remote_data);
778
0
  _gnutls_buffer_clear(&session->internals.hb_local_data);
779
0
  _gnutls_buffer_clear(&session->internals.record_presend_buffer);
780
0
  _gnutls_buffer_clear(&session->internals.record_key_update_buffer);
781
0
  _gnutls_buffer_clear(&session->internals.reauth_buffer);
782
783
0
  _mbuffer_head_clear(&session->internals.record_buffer);
784
0
  _mbuffer_head_clear(&session->internals.record_recv_buffer);
785
0
  _mbuffer_head_clear(&session->internals.record_send_buffer);
786
787
0
  _mbuffer_head_clear(&session->internals.early_data_recv_buffer);
788
0
  _gnutls_buffer_clear(&session->internals.early_data_presend_buffer);
789
790
0
  _gnutls_free_datum(&session->internals.resumption_data);
791
0
  _gnutls_free_datum(&session->internals.dtls.dcookie);
792
793
0
  for (i = 0; i < session->internals.rexts_size; i++)
794
0
    gnutls_free(session->internals.rexts[i].name);
795
0
  gnutls_free(session->internals.rexts);
796
0
  gnutls_free(session->internals.post_handshake_cr_context.data);
797
798
0
  gnutls_free(session->internals.saved_username);
799
0
  gnutls_free(session->internals.rsup);
800
801
0
  gnutls_credentials_clear(session);
802
0
  _gnutls_selected_certs_deinit(session);
803
804
  /* destroy any session ticket we may have received */
805
0
  tls13_ticket_deinit(&session->internals.tls13_ticket);
806
807
  /* we rely on priorities' internal reference counting */
808
0
  gnutls_priority_deinit(session->internals.priorities);
809
810
  /* overwrite any temp TLS1.3 keys */
811
0
  gnutls_memset(&session->key.proto, 0, sizeof(session->key.proto));
812
813
  /* clear session ticket keys */
814
0
  _gnutls_memory_mark_defined(session->key.session_ticket_key,
815
0
            TICKET_MASTER_KEY_SIZE);
816
0
  gnutls_memset(&session->key.session_ticket_key, 0,
817
0
          TICKET_MASTER_KEY_SIZE);
818
0
  _gnutls_memory_mark_undefined(session->key.session_ticket_key,
819
0
              TICKET_MASTER_KEY_SIZE);
820
821
0
  _gnutls_memory_mark_defined(session->key.previous_ticket_key,
822
0
            TICKET_MASTER_KEY_SIZE);
823
0
  gnutls_memset(&session->key.previous_ticket_key, 0,
824
0
          TICKET_MASTER_KEY_SIZE);
825
0
  _gnutls_memory_mark_undefined(session->key.previous_ticket_key,
826
0
              TICKET_MASTER_KEY_SIZE);
827
828
0
  _gnutls_memory_mark_defined(session->key.initial_stek,
829
0
            TICKET_MASTER_KEY_SIZE);
830
0
  gnutls_memset(&session->key.initial_stek, 0, TICKET_MASTER_KEY_SIZE);
831
0
  _gnutls_memory_mark_undefined(session->key.initial_stek,
832
0
              TICKET_MASTER_KEY_SIZE);
833
834
0
  gnutls_mutex_deinit(&session->internals.post_negotiation_lock);
835
0
  gnutls_mutex_deinit(&session->internals.epoch_lock);
836
837
0
  gnutls_free(session);
838
0
}
839
840
int _gnutls_dh_set_peer_public(gnutls_session_t session, bigint_t public)
841
0
{
842
0
  dh_info_st *dh;
843
0
  int ret;
844
845
0
  switch (gnutls_auth_get_type(session)) {
846
0
  case GNUTLS_CRD_ANON: {
847
0
    anon_auth_info_t info;
848
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
849
0
    if (info == NULL)
850
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
851
852
0
    dh = &info->dh;
853
0
    break;
854
0
  }
855
0
  case GNUTLS_CRD_PSK: {
856
0
    psk_auth_info_t info;
857
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
858
0
    if (info == NULL)
859
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
860
861
0
    dh = &info->dh;
862
0
    break;
863
0
  }
864
0
  case GNUTLS_CRD_CERTIFICATE: {
865
0
    cert_auth_info_t info;
866
867
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
868
0
    if (info == NULL)
869
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
870
871
0
    dh = &info->dh;
872
0
    break;
873
0
  }
874
0
  default:
875
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
876
0
  }
877
878
0
  if (dh->public_key.data)
879
0
    _gnutls_free_datum(&dh->public_key);
880
881
0
  ret = _gnutls_mpi_dprint_lz(public, &dh->public_key);
882
0
  if (ret < 0) {
883
0
    gnutls_assert();
884
0
    return ret;
885
0
  }
886
887
0
  return 0;
888
0
}
889
890
int _gnutls_dh_set_secret_bits(gnutls_session_t session, unsigned bits)
891
0
{
892
0
  switch (gnutls_auth_get_type(session)) {
893
0
  case GNUTLS_CRD_ANON: {
894
0
    anon_auth_info_t info;
895
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
896
0
    if (info == NULL)
897
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
898
0
    info->dh.secret_bits = bits;
899
0
    break;
900
0
  }
901
0
  case GNUTLS_CRD_PSK: {
902
0
    psk_auth_info_t info;
903
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
904
0
    if (info == NULL)
905
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
906
0
    info->dh.secret_bits = bits;
907
0
    break;
908
0
  }
909
0
  case GNUTLS_CRD_CERTIFICATE: {
910
0
    cert_auth_info_t info;
911
912
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
913
0
    if (info == NULL)
914
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
915
916
0
    info->dh.secret_bits = bits;
917
0
    break;
918
0
  default:
919
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
920
0
  }
921
0
  }
922
923
0
  return 0;
924
0
}
925
926
/* Sets the prime and the generator in the auth info structure.
927
 */
928
int _gnutls_dh_save_group(gnutls_session_t session, bigint_t gen,
929
        bigint_t prime)
930
0
{
931
0
  dh_info_st *dh;
932
0
  int ret;
933
934
0
  switch (gnutls_auth_get_type(session)) {
935
0
  case GNUTLS_CRD_ANON: {
936
0
    anon_auth_info_t info;
937
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
938
0
    if (info == NULL)
939
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
940
941
0
    dh = &info->dh;
942
0
    break;
943
0
  }
944
0
  case GNUTLS_CRD_PSK: {
945
0
    psk_auth_info_t info;
946
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
947
0
    if (info == NULL)
948
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
949
950
0
    dh = &info->dh;
951
0
    break;
952
0
  }
953
0
  case GNUTLS_CRD_CERTIFICATE: {
954
0
    cert_auth_info_t info;
955
956
0
    info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
957
0
    if (info == NULL)
958
0
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
959
960
0
    dh = &info->dh;
961
0
    break;
962
0
  }
963
0
  default:
964
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
965
0
  }
966
967
0
  if (dh->prime.data)
968
0
    _gnutls_free_datum(&dh->prime);
969
970
0
  if (dh->generator.data)
971
0
    _gnutls_free_datum(&dh->generator);
972
973
  /* prime
974
   */
975
0
  ret = _gnutls_mpi_dprint_lz(prime, &dh->prime);
976
0
  if (ret < 0) {
977
0
    gnutls_assert();
978
0
    return ret;
979
0
  }
980
981
  /* generator
982
   */
983
0
  ret = _gnutls_mpi_dprint_lz(gen, &dh->generator);
984
0
  if (ret < 0) {
985
0
    gnutls_assert();
986
0
    _gnutls_free_datum(&dh->prime);
987
0
    return ret;
988
0
  }
989
990
0
  return 0;
991
0
}
992
993
/**
994
 * gnutls_certificate_send_x509_rdn_sequence:
995
 * @session: a #gnutls_session_t type.
996
 * @status: is 0 or 1
997
 *
998
 * If status is non zero, this function will order gnutls not to send
999
 * the rdnSequence in the certificate request message. That is the
1000
 * server will not advertise its trusted CAs to the peer. If status
1001
 * is zero then the default behaviour will take effect, which is to
1002
 * advertise the server's trusted CAs.
1003
 *
1004
 * This function has no effect in clients, and in authentication
1005
 * methods other than certificate with X.509 certificates.
1006
 **/
1007
void gnutls_certificate_send_x509_rdn_sequence(gnutls_session_t session,
1008
                 int status)
1009
0
{
1010
0
  session->internals.ignore_rdn_sequence = status;
1011
0
}
1012
1013
/*-
1014
 * _gnutls_record_set_default_version - Used to set the default version for the first record packet
1015
 * @session: is a #gnutls_session_t type.
1016
 * @major: is a tls major version
1017
 * @minor: is a tls minor version
1018
 *
1019
 * This function sets the default version that we will use in the first
1020
 * record packet (client hello). This function is only useful to people
1021
 * that know TLS internals and want to debug other implementations.
1022
 -*/
1023
void _gnutls_record_set_default_version(gnutls_session_t session,
1024
          unsigned char major,
1025
          unsigned char minor)
1026
0
{
1027
0
  session->internals.default_record_version[0] = major;
1028
0
  session->internals.default_record_version[1] = minor;
1029
0
}
1030
1031
/*-
1032
 * _gnutls_hello_set_default_version - Used to set the default version for the first record packet
1033
 * @session: is a #gnutls_session_t type.
1034
 * @major: is a tls major version
1035
 * @minor: is a tls minor version
1036
 *
1037
 * This function sets the default version that we will use in the first
1038
 * record packet (client hello). This function is only useful to people
1039
 * that know TLS internals and want to debug other implementations.
1040
 -*/
1041
void _gnutls_hello_set_default_version(gnutls_session_t session,
1042
               unsigned char major, unsigned char minor)
1043
0
{
1044
0
  session->internals.default_hello_version[0] = major;
1045
0
  session->internals.default_hello_version[1] = minor;
1046
0
}
1047
1048
/**
1049
 * gnutls_handshake_set_private_extensions:
1050
 * @session: is a #gnutls_session_t type.
1051
 * @allow: is an integer (0 or 1)
1052
 *
1053
 * This function will enable or disable the use of private cipher
1054
 * suites (the ones that start with 0xFF).  By default or if @allow
1055
 * is 0 then these cipher suites will not be advertised nor used.
1056
 *
1057
 * Currently GnuTLS does not include such cipher-suites or
1058
 * compression algorithms.
1059
 *
1060
 * Enabling the private ciphersuites when talking to other than
1061
 * gnutls servers and clients may cause interoperability problems.
1062
 **/
1063
void gnutls_handshake_set_private_extensions(gnutls_session_t session,
1064
               int allow)
1065
0
{
1066
  /* we have no private extensions */
1067
0
  return;
1068
0
}
1069
1070
/**
1071
 * gnutls_session_is_resumed:
1072
 * @session: is a #gnutls_session_t type.
1073
 *
1074
 * Checks whether session is resumed or not. This is functional
1075
 * for both server and client side.
1076
 *
1077
 * Returns: non zero if this session is resumed, or a zero if this is
1078
 *   a new session.
1079
 **/
1080
int gnutls_session_is_resumed(gnutls_session_t session)
1081
0
{
1082
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
1083
0
    const version_entry_st *ver = get_version(session);
1084
0
    if (ver && ver->tls13_sem) {
1085
0
      return session->internals.resumed;
1086
0
    }
1087
1088
0
    if (session->security_parameters.session_id_size > 0 &&
1089
0
        session->security_parameters.session_id_size ==
1090
0
          session->internals.resumed_security_parameters
1091
0
            .session_id_size &&
1092
0
        memcmp(session->security_parameters.session_id,
1093
0
         session->internals.resumed_security_parameters
1094
0
           .session_id,
1095
0
         session->security_parameters.session_id_size) == 0)
1096
0
      return 1;
1097
0
  } else {
1098
0
    if (session->internals.resumed)
1099
0
      return 1;
1100
0
  }
1101
1102
0
  return 0;
1103
0
}
1104
1105
/**
1106
 * gnutls_session_resumption_requested:
1107
 * @session: is a #gnutls_session_t type.
1108
 *
1109
 * Check whether the client has asked for session resumption.
1110
 * This function is valid only on server side.
1111
 *
1112
 * Returns: non zero if session resumption was asked, or a zero if not.
1113
 **/
1114
int gnutls_session_resumption_requested(gnutls_session_t session)
1115
0
{
1116
0
  if (session->security_parameters.entity == GNUTLS_CLIENT) {
1117
0
    return 0;
1118
0
  } else {
1119
0
    return session->internals.resumption_requested;
1120
0
  }
1121
0
}
1122
1123
/*-
1124
 * _gnutls_session_is_psk - Used to check whether this session uses PSK kx
1125
 * @session: is a #gnutls_session_t type.
1126
 *
1127
 * This function will return non zero if this session uses a PSK key
1128
 * exchange algorithm.
1129
 -*/
1130
int _gnutls_session_is_psk(gnutls_session_t session)
1131
0
{
1132
0
  gnutls_kx_algorithm_t kx;
1133
1134
0
  kx = session->security_parameters.cs->kx_algorithm;
1135
0
  if (kx == GNUTLS_KX_PSK || kx == GNUTLS_KX_DHE_PSK ||
1136
0
      kx == GNUTLS_KX_RSA_PSK)
1137
0
    return 1;
1138
1139
0
  return 0;
1140
0
}
1141
1142
/*-
1143
 * _gnutls_session_is_ecc - Used to check whether this session uses ECC kx
1144
 * @session: is a #gnutls_session_t type.
1145
 *
1146
 * This function will return non zero if this session uses an elliptic
1147
 * curves key exchange exchange algorithm.
1148
 -*/
1149
int _gnutls_session_is_ecc(gnutls_session_t session)
1150
0
{
1151
0
  gnutls_kx_algorithm_t kx;
1152
1153
  /* We get the key exchange algorithm through the ciphersuite because
1154
   * the negotiated key exchange might not have been set yet.
1155
   */
1156
0
  kx = session->security_parameters.cs->kx_algorithm;
1157
1158
0
  return _gnutls_kx_is_ecc(kx);
1159
0
}
1160
1161
/**
1162
 * gnutls_session_get_ptr:
1163
 * @session: is a #gnutls_session_t type.
1164
 *
1165
 * Get user pointer for session.  Useful in callbacks.  This is the
1166
 *   pointer set with gnutls_session_set_ptr().
1167
 *
1168
 * Returns: the user given pointer from the session structure, or
1169
 *   %NULL if it was never set.
1170
 **/
1171
void *gnutls_session_get_ptr(gnutls_session_t session)
1172
0
{
1173
0
  return session->internals.user_ptr;
1174
0
}
1175
1176
/**
1177
 * gnutls_session_set_ptr:
1178
 * @session: is a #gnutls_session_t type.
1179
 * @ptr: is the user pointer
1180
 *
1181
 * This function will set (associate) the user given pointer @ptr to
1182
 * the session structure.  This pointer can be accessed with
1183
 * gnutls_session_get_ptr().
1184
 **/
1185
void gnutls_session_set_ptr(gnutls_session_t session, void *ptr)
1186
0
{
1187
0
  session->internals.user_ptr = ptr;
1188
0
}
1189
1190
/**
1191
 * gnutls_session_set_verify_function:
1192
 * @session: is a #gnutls_session_t type.
1193
 * @func: is the callback function
1194
 *
1195
 * This function sets a callback to be called when peer's certificate
1196
 * has been received in order to verify it on receipt rather than
1197
 * doing after the handshake is completed. This overrides any callback
1198
 * set using gnutls_certificate_set_verify_function().
1199
 *
1200
 * The callback's function prototype is:
1201
 * int (*callback)(gnutls_session_t);
1202
 *
1203
 * If the callback function is provided then gnutls will call it, in the
1204
 * handshake, just after the certificate message has been received.
1205
 * To verify or obtain the certificate the gnutls_certificate_verify_peers2(),
1206
 * gnutls_certificate_type_get(), gnutls_certificate_get_peers() functions
1207
 * can be used.
1208
 *
1209
 * The callback function should return 0 for the handshake to continue
1210
 * or non-zero to terminate.
1211
 *
1212
 * Since: 3.4.6
1213
 **/
1214
void gnutls_session_set_verify_function(
1215
  gnutls_session_t session, gnutls_certificate_verify_function *func)
1216
0
{
1217
0
  session->internals.verify_callback = func;
1218
0
}
1219
1220
/**
1221
 * gnutls_record_get_direction:
1222
 * @session: is a #gnutls_session_t type.
1223
 *
1224
 * This function is useful to determine whether a GnuTLS function was interrupted
1225
 * while sending or receiving, so that select() or poll() may be called appropriately.
1226
 *
1227
 * It provides information about the internals of the record
1228
 * protocol and is only useful if a prior gnutls function call,
1229
 * e.g.  gnutls_handshake(), was interrupted and returned
1230
 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN. After such an interrupt
1231
 * applications may call select() or poll() before restoring the
1232
 * interrupted GnuTLS function.
1233
 *
1234
 * This function's output is unreliable if you are using the same
1235
 * @session in different threads for sending and receiving.
1236
 *
1237
 * Returns: 0 if interrupted while trying to read data, or 1 while trying to write data.
1238
 **/
1239
int gnutls_record_get_direction(gnutls_session_t session)
1240
0
{
1241
0
  return session->internals.direction;
1242
0
}
1243
1244
/*-
1245
 * _gnutls_rsa_pms_set_version - Sets a version to be used at the RSA PMS
1246
 * @session: is a #gnutls_session_t type.
1247
 * @major: is the major version to use
1248
 * @minor: is the minor version to use
1249
 *
1250
 * This function will set the given version number to be used at the
1251
 * RSA PMS secret. This is only useful to clients, which want to
1252
 * test server's capabilities.
1253
 -*/
1254
void _gnutls_rsa_pms_set_version(gnutls_session_t session, unsigned char major,
1255
         unsigned char minor)
1256
0
{
1257
0
  session->internals.rsa_pms_version[0] = major;
1258
0
  session->internals.rsa_pms_version[1] = minor;
1259
0
}
1260
1261
void _gnutls_session_client_cert_type_set(gnutls_session_t session,
1262
            gnutls_certificate_type_t ct)
1263
0
{
1264
0
  _gnutls_handshake_log(
1265
0
    "HSK[%p]: Selected client certificate type %s (%d)\n", session,
1266
0
    gnutls_certificate_type_get_name(ct), ct);
1267
0
  session->security_parameters.client_ctype = ct;
1268
0
}
1269
1270
void _gnutls_session_server_cert_type_set(gnutls_session_t session,
1271
            gnutls_certificate_type_t ct)
1272
0
{
1273
0
  _gnutls_handshake_log(
1274
0
    "HSK[%p]: Selected server certificate type %s (%d)\n", session,
1275
0
    gnutls_certificate_type_get_name(ct), ct);
1276
0
  session->security_parameters.server_ctype = ct;
1277
0
}
1278
1279
/**
1280
 * gnutls_handshake_set_post_client_hello_function:
1281
 * @session: is a #gnutls_session_t type.
1282
 * @func: is the function to be called
1283
 *
1284
 * This function will set a callback to be called after the client
1285
 * hello has been received (callback valid in server side only). This
1286
 * allows the server to adjust settings based on received extensions.
1287
 *
1288
 * Those settings could be ciphersuites, requesting certificate, or
1289
 * anything else except for version negotiation (this is done before
1290
 * the hello message is parsed).
1291
 *
1292
 * This callback must return 0 on success or a gnutls error code to
1293
 * terminate the handshake.
1294
 *
1295
 * Since GnuTLS 3.3.5 the callback is
1296
 * allowed to return %GNUTLS_E_AGAIN or %GNUTLS_E_INTERRUPTED to
1297
 * put the handshake on hold. In that case gnutls_handshake()
1298
 * will return %GNUTLS_E_INTERRUPTED and can be resumed when needed.
1299
 *
1300
 * Warning: You should not use this function to terminate the
1301
 * handshake based on client input unless you know what you are
1302
 * doing. Before the handshake is finished there is no way to know if
1303
 * there is a man-in-the-middle attack being performed.
1304
 **/
1305
void gnutls_handshake_set_post_client_hello_function(
1306
  gnutls_session_t session, gnutls_handshake_simple_hook_func func)
1307
0
{
1308
0
  session->internals.user_hello_func = func;
1309
0
}
1310
1311
/**
1312
 * gnutls_session_enable_compatibility_mode:
1313
 * @session: is a #gnutls_session_t type.
1314
 *
1315
 * This function can be used to disable certain (security) features in
1316
 * TLS in order to maintain maximum compatibility with buggy
1317
 * clients. Because several trade-offs with security are enabled,
1318
 * if required they will be reported through the audit subsystem.
1319
 *
1320
 * Normally only servers that require maximum compatibility with
1321
 * everything out there, need to call this function.
1322
 *
1323
 * Note that this function must be called after any call to gnutls_priority
1324
 * functions.
1325
 *
1326
 * Since: 2.1.4
1327
 **/
1328
void gnutls_session_enable_compatibility_mode(gnutls_session_t session)
1329
0
{
1330
0
  ENABLE_COMPAT(&session->internals);
1331
0
}
1332
1333
/**
1334
 * gnutls_session_channel_binding:
1335
 * @session: is a #gnutls_session_t type.
1336
 * @cbtype: an #gnutls_channel_binding_t enumeration type
1337
 * @cb: output buffer array with data
1338
 *
1339
 * Extract given channel binding data of the @cbtype (e.g.,
1340
 * %GNUTLS_CB_TLS_UNIQUE) type.
1341
 *
1342
 * Returns: %GNUTLS_E_SUCCESS on success,
1343
 * %GNUTLS_E_UNIMPLEMENTED_FEATURE if the @cbtype is unsupported,
1344
 * %GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE if the data is not
1345
 * currently available, or an error code.
1346
 *
1347
 * Since: 2.12.0
1348
 **/
1349
int gnutls_session_channel_binding(gnutls_session_t session,
1350
           gnutls_channel_binding_t cbtype,
1351
           gnutls_datum_t *cb)
1352
0
{
1353
0
  if (!session->internals.initial_negotiation_completed)
1354
0
    return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
1355
1356
0
  if (cbtype == GNUTLS_CB_TLS_UNIQUE) {
1357
0
    const version_entry_st *ver = get_version(session);
1358
0
    if (unlikely(ver == NULL || ver->tls13_sem))
1359
0
      return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
1360
1361
0
    cb->size = session->internals.cb_tls_unique_len;
1362
0
    cb->data = gnutls_malloc(cb->size);
1363
0
    if (cb->data == NULL)
1364
0
      return GNUTLS_E_MEMORY_ERROR;
1365
1366
0
    memcpy(cb->data, session->internals.cb_tls_unique, cb->size);
1367
1368
0
    return 0;
1369
0
  }
1370
1371
0
  if (cbtype == GNUTLS_CB_TLS_SERVER_END_POINT) {
1372
0
    const gnutls_datum_t *ders;
1373
0
    unsigned int num_certs = 1;
1374
0
    int ret;
1375
0
    size_t rlen;
1376
0
    gnutls_x509_crt_t cert;
1377
0
    gnutls_digest_algorithm_t algo;
1378
1379
    /* Only X509 certificates are supported for this binding type */
1380
0
    ret = gnutls_certificate_type_get(session);
1381
0
    if (ret != GNUTLS_CRT_X509)
1382
0
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1383
1384
0
    if (session->security_parameters.entity == GNUTLS_CLIENT)
1385
0
      ders = gnutls_certificate_get_peers(session,
1386
0
                  &num_certs);
1387
0
    else
1388
0
      ders = gnutls_certificate_get_ours(session);
1389
1390
    /* Previous check indicated we have x509 but you never know */
1391
0
    if (!ders || num_certs == 0)
1392
0
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1393
1394
0
    ret = gnutls_x509_crt_list_import(&cert, &num_certs, ders,
1395
0
              GNUTLS_X509_FMT_DER, 0);
1396
    /* Again, this is not supposed to happen (normally) */
1397
0
    if (ret < 0 || num_certs == 0)
1398
0
      return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
1399
1400
    /* Obtain signature algorithm used by certificate */
1401
0
    ret = gnutls_x509_crt_get_signature_algorithm(cert);
1402
0
    if (ret < 0 || ret == GNUTLS_SIGN_UNKNOWN)
1403
0
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1404
1405
    /* obtain hash function from signature and normalize it */
1406
0
    algo = gnutls_sign_get_hash_algorithm(ret);
1407
0
    switch (algo) {
1408
0
    case GNUTLS_DIG_MD5:
1409
0
    case GNUTLS_DIG_SHA1:
1410
0
      algo = GNUTLS_DIG_SHA256;
1411
0
      break;
1412
0
    case GNUTLS_DIG_UNKNOWN:
1413
0
    case GNUTLS_DIG_NULL:
1414
0
    case GNUTLS_DIG_MD5_SHA1:
1415
      /* double hashing not supported either */
1416
0
      gnutls_x509_crt_deinit(cert);
1417
0
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1418
0
    default:
1419
0
      break;
1420
0
    }
1421
1422
    /* preallocate 512 bits buffer as maximum supported digest */
1423
0
    rlen = MAX_HASH_SIZE;
1424
0
    cb->data = gnutls_malloc(rlen);
1425
0
    if (cb->data == NULL) {
1426
0
      gnutls_x509_crt_deinit(cert);
1427
0
      return GNUTLS_E_MEMORY_ERROR;
1428
0
    }
1429
1430
0
    ret = gnutls_x509_crt_get_fingerprint(cert, algo, cb->data,
1431
0
                  &rlen);
1432
0
    if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
1433
0
      cb->data = gnutls_realloc_fast(cb->data, cb->size);
1434
0
      if (cb->data == NULL) {
1435
0
        gnutls_x509_crt_deinit(cert);
1436
0
        return GNUTLS_E_MEMORY_ERROR;
1437
0
      }
1438
0
      ret = gnutls_x509_crt_get_fingerprint(cert, algo,
1439
0
                    cb->data, &rlen);
1440
0
    }
1441
0
    cb->size = rlen;
1442
0
    gnutls_x509_crt_deinit(cert);
1443
0
    return ret;
1444
0
  }
1445
1446
0
  if (cbtype == GNUTLS_CB_TLS_EXPORTER) {
1447
0
#define RFC5705_LABEL_DATA "EXPORTER-Channel-Binding"
1448
0
#define RFC5705_LABEL_LEN 24
1449
0
#define EXPORTER_CTX_DATA ""
1450
0
#define EXPORTER_CTX_LEN 0
1451
1452
0
    const version_entry_st *ver = get_version(session);
1453
0
    if (unlikely(ver == NULL)) {
1454
0
      return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
1455
0
    }
1456
1457
    /* "tls-exporter" channel binding is defined only when
1458
     * the TLS handshake results in unique master secrets,
1459
     * i.e., either TLS 1.3, or TLS 1.2 with extended
1460
     * master secret negotiated.
1461
     */
1462
0
    if (!ver->tls13_sem &&
1463
0
        gnutls_session_ext_master_secret_status(session) == 0) {
1464
0
      return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
1465
0
    }
1466
1467
0
    cb->size = 32;
1468
0
    cb->data = gnutls_malloc(cb->size);
1469
0
    if (cb->data == NULL)
1470
0
      return GNUTLS_E_MEMORY_ERROR;
1471
1472
0
    return gnutls_prf_rfc5705(session, RFC5705_LABEL_LEN,
1473
0
            RFC5705_LABEL_DATA, EXPORTER_CTX_LEN,
1474
0
            EXPORTER_CTX_DATA, cb->size,
1475
0
            (char *)cb->data);
1476
0
  }
1477
1478
0
  return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1479
0
}
1480
1481
/**
1482
 * gnutls_ecc_curve_get:
1483
 * @session: is a #gnutls_session_t type.
1484
 *
1485
 * Returns the currently used elliptic curve for key exchange. Only valid
1486
 * when using an elliptic curve ciphersuite.
1487
 *
1488
 * Returns: the currently used curve, a #gnutls_ecc_curve_t
1489
 *   type.
1490
 *
1491
 * Since: 3.0
1492
 **/
1493
gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session)
1494
0
{
1495
0
  const gnutls_group_entry_st *e;
1496
1497
0
  e = get_group(session);
1498
0
  if (e == NULL || e->curve == 0)
1499
0
    return 0;
1500
0
  return e->curve;
1501
0
}
1502
1503
/**
1504
 * gnutls_group_get:
1505
 * @session: is a #gnutls_session_t type.
1506
 *
1507
 * Returns the currently used group for key exchange. Only valid
1508
 * when using an elliptic curve or DH ciphersuite.
1509
 *
1510
 * Returns: the currently used group, a #gnutls_group_t
1511
 *   type.
1512
 *
1513
 * Since: 3.6.0
1514
 **/
1515
gnutls_group_t gnutls_group_get(gnutls_session_t session)
1516
0
{
1517
0
  const gnutls_group_entry_st *e;
1518
1519
0
  e = get_group(session);
1520
0
  if (e == NULL)
1521
0
    return 0;
1522
0
  return e->id;
1523
0
}
1524
1525
/**
1526
 * gnutls_protocol_get_version:
1527
 * @session: is a #gnutls_session_t type.
1528
 *
1529
 * Get TLS version, a #gnutls_protocol_t value.
1530
 *
1531
 * Returns: The version of the currently used protocol.
1532
 **/
1533
gnutls_protocol_t gnutls_protocol_get_version(gnutls_session_t session)
1534
0
{
1535
0
  return get_num_version(session);
1536
0
}
1537
1538
/**
1539
 * gnutls_session_get_random:
1540
 * @session: is a #gnutls_session_t type.
1541
 * @client: the client part of the random
1542
 * @server: the server part of the random
1543
 *
1544
 * This function returns pointers to the client and server
1545
 * random fields used in the TLS handshake. The pointers are
1546
 * not to be modified or deallocated.
1547
 *
1548
 * If a client random value has not yet been established, the output
1549
 * will be garbage.
1550
 *
1551
 * Since: 3.0
1552
 **/
1553
void gnutls_session_get_random(gnutls_session_t session, gnutls_datum_t *client,
1554
             gnutls_datum_t *server)
1555
0
{
1556
0
  if (client) {
1557
0
    client->data = session->security_parameters.client_random;
1558
0
    client->size =
1559
0
      sizeof(session->security_parameters.client_random);
1560
0
  }
1561
1562
0
  if (server) {
1563
0
    server->data = session->security_parameters.server_random;
1564
0
    server->size =
1565
0
      sizeof(session->security_parameters.server_random);
1566
0
  }
1567
0
}
1568
1569
/**
1570
 * gnutls_session_get_master_secret:
1571
 * @session: is a #gnutls_session_t type.
1572
 * @secret: the session's master secret
1573
 *
1574
 * This function returns pointers to the master secret
1575
 * used in the TLS session. The pointers are not to be modified or deallocated.
1576
 *
1577
 * This function is only applicable under TLS 1.2 or earlier versions.
1578
 *
1579
 * Since: 3.5.0
1580
 **/
1581
void gnutls_session_get_master_secret(gnutls_session_t session,
1582
              gnutls_datum_t *secret)
1583
0
{
1584
0
  secret->data = session->security_parameters.master_secret;
1585
0
  secret->size = sizeof(session->security_parameters.master_secret);
1586
0
}
1587
1588
unsigned int timespec_sub_ms(struct timespec *a, struct timespec *b)
1589
0
{
1590
0
  time_t dsecs;
1591
1592
0
  dsecs = a->tv_sec - b->tv_sec;
1593
0
  if (!INT_MULTIPLY_OVERFLOW(dsecs, 1000)) {
1594
0
    return (dsecs * 1000 +
1595
0
      (a->tv_nsec - b->tv_nsec) / (1000 * 1000));
1596
0
  } else {
1597
0
    return UINT_MAX;
1598
0
  }
1599
0
}
1600
1601
/**
1602
 * gnutls_handshake_set_random:
1603
 * @session: is a #gnutls_session_t type.
1604
 * @random: a random value of 32-bytes
1605
 *
1606
 * This function will explicitly set the server or client hello 
1607
 * random value in the subsequent TLS handshake. The random value 
1608
 * should be a 32-byte value.
1609
 *
1610
 * Note that this function should not normally be used as gnutls
1611
 * will select automatically a random value for the handshake.
1612
 *
1613
 * This function should not be used when resuming a session.
1614
 *
1615
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1616
 *
1617
 * Since 3.1.9
1618
 **/
1619
int gnutls_handshake_set_random(gnutls_session_t session,
1620
        const gnutls_datum_t *random)
1621
0
{
1622
0
  if (random->size != GNUTLS_RANDOM_SIZE)
1623
0
    return GNUTLS_E_INVALID_REQUEST;
1624
1625
0
  session->internals.sc_random_set = 1;
1626
0
  if (session->security_parameters.entity == GNUTLS_CLIENT)
1627
0
    memcpy(session->internals.resumed_security_parameters
1628
0
             .client_random,
1629
0
           random->data, random->size);
1630
0
  else
1631
0
    memcpy(session->internals.resumed_security_parameters
1632
0
             .server_random,
1633
0
           random->data, random->size);
1634
1635
0
  return 0;
1636
0
}
1637
1638
/**
1639
 * gnutls_handshake_set_hook_function:
1640
 * @session: is a #gnutls_session_t type
1641
 * @htype: the %gnutls_handshake_description_t of the message to hook at
1642
 * @when: %GNUTLS_HOOK_* depending on when the hook function should be called
1643
 * @func: is the function to be called
1644
 *
1645
 * This function will set a callback to be called after or before the specified
1646
 * handshake message has been received or generated. This is a
1647
 * generalization of gnutls_handshake_set_post_client_hello_function().
1648
 *
1649
 * To call the hook function prior to the message being generated or processed
1650
 * use %GNUTLS_HOOK_PRE as @when parameter, %GNUTLS_HOOK_POST to call
1651
 * after, and %GNUTLS_HOOK_BOTH for both cases.
1652
 *
1653
 * This callback must return 0 on success or a gnutls error code to
1654
 * terminate the handshake.
1655
 *
1656
 * To hook at all handshake messages use an @htype of %GNUTLS_HANDSHAKE_ANY.
1657
 *
1658
 * Warning: You should not use this function to terminate the
1659
 * handshake based on client input unless you know what you are
1660
 * doing. Before the handshake is finished there is no way to know if
1661
 * there is a man-in-the-middle attack being performed.
1662
 **/
1663
void gnutls_handshake_set_hook_function(gnutls_session_t session,
1664
          unsigned int htype, int when,
1665
          gnutls_handshake_hook_func func)
1666
0
{
1667
0
  session->internals.h_hook = func;
1668
0
  session->internals.h_type = htype;
1669
0
  session->internals.h_post = when;
1670
0
}
1671
1672
/**
1673
 * gnutls_handshake_set_read_function:
1674
 * @session: is #gnutls_session_t type
1675
 * @func: is the function to be called
1676
 *
1677
 * This function will set a callback to be called when a handshake
1678
 * message is being sent.
1679
 *
1680
 * Since: 3.7.0
1681
 */
1682
void gnutls_handshake_set_read_function(gnutls_session_t session,
1683
          gnutls_handshake_read_func func)
1684
0
{
1685
0
  session->internals.h_read_func = func;
1686
0
}
1687
1688
/**
1689
 * gnutls_alert_set_read_function:
1690
 * @session: is #gnutls_session_t type
1691
 * @func: is the function to be called
1692
 *
1693
 * This function will set a callback to be called when an alert
1694
 * message is being sent.
1695
 *
1696
 * Since: 3.7.0
1697
 */
1698
void gnutls_alert_set_read_function(gnutls_session_t session,
1699
            gnutls_alert_read_func func)
1700
0
{
1701
0
  session->internals.alert_read_func = func;
1702
0
}
1703
1704
/**
1705
 * gnutls_record_get_state:
1706
 * @session: is a #gnutls_session_t type
1707
 * @read: if non-zero the read parameters are returned, otherwise the write
1708
 * @mac_key: the key used for MAC (if a MAC is used)
1709
 * @IV: the initialization vector or nonce used
1710
 * @cipher_key: the cipher key
1711
 * @seq_number: A 64-bit sequence number
1712
 *
1713
 * This function will return the parameters of the current record state.
1714
 * These are only useful to be provided to an external off-loading device
1715
 * or subsystem. The returned values should be considered constant
1716
 * and valid for the lifetime of the session.
1717
 *
1718
 * In that case, to sync the state back you must call gnutls_record_set_state().
1719
 *
1720
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1721
 *
1722
 * Since 3.4.0
1723
 **/
1724
int gnutls_record_get_state(gnutls_session_t session, unsigned read,
1725
          gnutls_datum_t *mac_key, gnutls_datum_t *IV,
1726
          gnutls_datum_t *cipher_key,
1727
          unsigned char seq_number[8])
1728
0
{
1729
0
  record_parameters_st *record_params;
1730
0
  record_state_st *record_state;
1731
0
  unsigned int epoch;
1732
0
  int ret;
1733
1734
0
  if (read)
1735
0
    epoch = EPOCH_READ_CURRENT;
1736
0
  else
1737
0
    epoch = EPOCH_WRITE_CURRENT;
1738
1739
0
  ret = _gnutls_epoch_get(session, epoch, &record_params);
1740
0
  if (ret < 0)
1741
0
    return gnutls_assert_val(ret);
1742
1743
0
  if (!record_params->initialized)
1744
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1745
1746
0
  if (read)
1747
0
    record_state = &record_params->read;
1748
0
  else
1749
0
    record_state = &record_params->write;
1750
1751
0
  if (mac_key) {
1752
0
    mac_key->data = record_state->mac_key;
1753
0
    mac_key->size = record_state->mac_key_size;
1754
0
  }
1755
1756
0
  if (IV) {
1757
0
    IV->data = record_state->iv;
1758
0
    IV->size = record_state->iv_size;
1759
0
  }
1760
1761
0
  if (cipher_key) {
1762
0
    cipher_key->data = record_state->key;
1763
0
    cipher_key->size = record_state->key_size;
1764
0
  }
1765
1766
0
  if (seq_number)
1767
0
    _gnutls_write_uint64(record_state->sequence_number, seq_number);
1768
0
  return 0;
1769
0
}
1770
1771
/**
1772
 * gnutls_record_set_state:
1773
 * @session: is a #gnutls_session_t type
1774
 * @read: if non-zero the read parameters are returned, otherwise the write
1775
 * @seq_number: A 64-bit sequence number
1776
 *
1777
 * This function will set the sequence number in the current record state.
1778
 * This function is useful if sending and receiving are offloaded from
1779
 * gnutls. That is, if gnutls_record_get_state() was used.
1780
 *
1781
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1782
 *
1783
 * Since 3.4.0
1784
 **/
1785
int gnutls_record_set_state(gnutls_session_t session, unsigned read,
1786
          const unsigned char seq_number[8])
1787
0
{
1788
0
  record_parameters_st *record_params;
1789
0
  record_state_st *record_state;
1790
0
  int epoch, ret;
1791
1792
0
  if (read)
1793
0
    epoch = EPOCH_READ_CURRENT;
1794
0
  else
1795
0
    epoch = EPOCH_WRITE_CURRENT;
1796
1797
0
  ret = _gnutls_epoch_get(session, epoch, &record_params);
1798
0
  if (ret < 0)
1799
0
    return gnutls_assert_val(ret);
1800
1801
0
  if (!record_params->initialized)
1802
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1803
1804
0
  if (read)
1805
0
    record_state = &record_params->read;
1806
0
  else
1807
0
    record_state = &record_params->write;
1808
1809
0
  record_state->sequence_number = _gnutls_read_uint64(seq_number);
1810
1811
0
  if (IS_DTLS(session)) {
1812
0
    _dtls_reset_window(record_params);
1813
0
  }
1814
1815
0
  return 0;
1816
0
}
1817
1818
/**
1819
 * gnutls_session_get_flags:
1820
 * @session: is a #gnutls_session_t type.
1821
 *
1822
 * This function will return a series (ORed) of flags, applicable
1823
 * for the current session.
1824
 *
1825
 * This replaces individual informational functions such as
1826
 * gnutls_safe_renegotiation_status(), gnutls_session_ext_master_secret_status(),
1827
 * etc.
1828
 *
1829
 * Returns: An ORed sequence of flags (see %gnutls_session_flags_t)
1830
 *
1831
 * Since: 3.5.0
1832
 **/
1833
unsigned gnutls_session_get_flags(gnutls_session_t session)
1834
0
{
1835
0
  unsigned flags = 0;
1836
1837
0
  if (gnutls_safe_renegotiation_status(session))
1838
0
    flags |= GNUTLS_SFLAGS_SAFE_RENEGOTIATION;
1839
0
  if (gnutls_session_ext_master_secret_status(session))
1840
0
    flags |= GNUTLS_SFLAGS_EXT_MASTER_SECRET;
1841
0
  if (gnutls_session_etm_status(session))
1842
0
    flags |= GNUTLS_SFLAGS_ETM;
1843
0
  if (gnutls_heartbeat_allowed(session, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND))
1844
0
    flags |= GNUTLS_SFLAGS_HB_LOCAL_SEND;
1845
0
  if (gnutls_heartbeat_allowed(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND))
1846
0
    flags |= GNUTLS_SFLAGS_HB_PEER_SEND;
1847
0
  if (session->internals.hsk_flags & HSK_FALSE_START_USED)
1848
0
    flags |= GNUTLS_SFLAGS_FALSE_START;
1849
0
  if ((session->internals.hsk_flags & HSK_EARLY_START_USED) &&
1850
0
      (session->internals.flags & GNUTLS_ENABLE_EARLY_START))
1851
0
    flags |= GNUTLS_SFLAGS_EARLY_START;
1852
0
  if (session->internals.hsk_flags & HSK_USED_FFDHE)
1853
0
    flags |= GNUTLS_SFLAGS_RFC7919;
1854
0
  if (session->internals.hsk_flags & HSK_TICKET_RECEIVED)
1855
0
    flags |= GNUTLS_SFLAGS_SESSION_TICKET;
1856
0
  if (session->security_parameters.post_handshake_auth)
1857
0
    flags |= GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH;
1858
0
  if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED)
1859
0
    flags |= GNUTLS_SFLAGS_EARLY_DATA;
1860
0
  if (session->internals.hsk_flags & HSK_OCSP_REQUESTED)
1861
0
    flags |= GNUTLS_SFLAGS_CLI_REQUESTED_OCSP;
1862
0
  if (session->internals.hsk_flags & HSK_CLIENT_OCSP_REQUESTED)
1863
0
    flags |= GNUTLS_SFLAGS_SERV_REQUESTED_OCSP;
1864
1865
0
  return flags;
1866
0
}