Coverage Report

Created: 2025-03-06 06:58

/src/gnutls/lib/global.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2015-2016 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
#include "gnutls_int.h"
25
#include "errors.h"
26
#include <libtasn1.h>
27
#include "dh.h"
28
#include "compress.h"
29
#include "random.h"
30
#include <gnutls/pkcs11.h>
31
32
#include "hello_ext.h" /* for _gnutls_hello_ext_init */
33
#include "supplemental.h" /* for _gnutls_supplemental_deinit */
34
#include "locks.h"
35
#include "system.h"
36
#include "accelerated/cryptodev.h"
37
#include "accelerated/afalg.h"
38
#include "accelerated/accelerated.h"
39
#include "fips.h"
40
#include "atfork.h"
41
#include "system-keys.h"
42
#include "str.h"
43
#include "global.h"
44
#include "liboqs/liboqs.h"
45
46
/* Minimum library versions we accept. */
47
2
#define GNUTLS_MIN_LIBTASN1_VERSION "0.3.4"
48
49
#ifdef __sun
50
#pragma fini(lib_deinit)
51
#pragma init(lib_init)
52
#define _CONSTRUCTOR
53
#define _DESTRUCTOR
54
#else
55
#define _CONSTRUCTOR __attribute__((constructor))
56
#define _DESTRUCTOR __attribute__((destructor))
57
#endif
58
59
#ifndef _WIN32
60
int __attribute__((weak)) _gnutls_global_init_skip(void);
61
int _gnutls_global_init_skip(void)
62
2
{
63
2
  return 0;
64
2
}
65
#else
66
inline static int _gnutls_global_init_skip(void)
67
{
68
  return 0;
69
}
70
#endif
71
72
/* created by asn1c */
73
extern const asn1_static_node gnutls_asn1_tab[];
74
extern const asn1_static_node pkix_asn1_tab[];
75
76
asn1_node _gnutls_pkix1_asn = NULL;
77
asn1_node _gnutls_gnutls_asn = NULL;
78
79
gnutls_log_func _gnutls_log_func = NULL;
80
gnutls_audit_log_func _gnutls_audit_log_func = NULL;
81
int _gnutls_log_level = 0; /* default log level */
82
83
unsigned int _gnutls_global_version = GNUTLS_VERSION_NUMBER;
84
85
static int _gnutls_global_init(unsigned constructor);
86
static void _gnutls_global_deinit(unsigned destructor);
87
88
static void default_log_func(int level, const char *str)
89
0
{
90
0
  fprintf(stderr, "gnutls[%d]: %s", level, str);
91
0
}
92
93
/**
94
 * gnutls_global_set_log_function:
95
 * @log_func: it's a log function
96
 *
97
 * This is the function where you set the logging function gnutls is
98
 * going to use.  This function only accepts a character array.
99
 * Normally you may not use this function since it is only used for
100
 * debugging purposes.
101
 *
102
 * @gnutls_log_func is of the form,
103
 * void (*gnutls_log_func)( int level, const char*);
104
 **/
105
void gnutls_global_set_log_function(gnutls_log_func log_func)
106
0
{
107
0
  _gnutls_log_func = log_func;
108
0
}
109
110
/**
111
 * gnutls_global_set_audit_log_function:
112
 * @log_func: it is the audit log function
113
 *
114
 * This is the function to set the audit logging function. This
115
 * is a function to report important issues, such as possible
116
 * attacks in the protocol. This is different from gnutls_global_set_log_function()
117
 * because it will report also session-specific events. The session
118
 * parameter will be null if there is no corresponding TLS session.
119
 *
120
 * @gnutls_audit_log_func is of the form,
121
 * void (*gnutls_audit_log_func)( gnutls_session_t, const char*);
122
 *
123
 * Since: 3.0
124
 **/
125
void gnutls_global_set_audit_log_function(gnutls_audit_log_func log_func)
126
0
{
127
0
  _gnutls_audit_log_func = log_func;
128
0
}
129
130
static void gettime_from_time(struct timespec *t)
131
0
{
132
0
  t->tv_sec = gnutls_time(NULL);
133
0
  t->tv_nsec = 0;
134
0
}
135
136
/**
137
 * gnutls_global_set_time_function:
138
 * @time_func: it's the system time function, a gnutls_time_func() callback.
139
 *
140
 * This is the function where you can override the default system time
141
 * function.  The application provided function should behave the same
142
 * as the standard function.
143
 *
144
 * Since: 2.12.0
145
 **/
146
void gnutls_global_set_time_function(gnutls_time_func time_func)
147
0
{
148
0
  gnutls_time = time_func;
149
150
  /* When the time function is overridden, also override the
151
   * gettime function to use the derived value, even if its
152
   * resolution is lower.
153
   */
154
0
  _gnutls_global_set_gettime_function(gettime_from_time);
155
0
}
156
157
/**
158
 * gnutls_global_set_log_level:
159
 * @level: it's an integer from 0 to 99.
160
 *
161
 * This is the function that allows you to set the log level.  The
162
 * level is an integer between 0 and 9.  Higher values mean more
163
 * verbosity. The default value is 0.  Larger values should only be
164
 * used with care, since they may reveal sensitive information.
165
 *
166
 * Use a log level over 10 to enable all debugging options.
167
 **/
168
void gnutls_global_set_log_level(int level)
169
0
{
170
0
  _gnutls_log_level = level;
171
0
}
172
173
/**
174
 * gnutls_global_set_mem_functions:
175
 * @alloc_func: it's the default memory allocation function. Like malloc().
176
 * @secure_alloc_func: This is the memory allocation function that will be used for sensitive data.
177
 * @is_secure_func: a function that returns 0 if the memory given is not secure. May be NULL.
178
 * @realloc_func: A realloc function
179
 * @free_func: The function that frees allocated data. Must accept a NULL pointer.
180
 *
181
 * Deprecated: since 3.3.0 it is no longer possible to replace the internally used 
182
 *  memory allocation functions
183
 *
184
 * This is the function where you set the memory allocation functions
185
 * gnutls is going to use. By default the libc's allocation functions
186
 * (malloc(), free()), are used by gnutls, to allocate both sensitive
187
 * and not sensitive data.  This function is provided to set the
188
 * memory allocation functions to something other than the defaults
189
 *
190
 * This function must be called before gnutls_global_init() is called.
191
 * This function is not thread safe.
192
 **/
193
void gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func,
194
             gnutls_alloc_function secure_alloc_func,
195
             gnutls_is_secure_function is_secure_func,
196
             gnutls_realloc_function realloc_func,
197
             gnutls_free_function free_func)
198
0
{
199
0
  _gnutls_debug_log(
200
0
    "called the deprecated gnutls_global_set_mem_functions()\n");
201
0
}
202
203
GNUTLS_STATIC_MUTEX(global_init_mutex);
204
static int _gnutls_init = 0;
205
206
/* cache the return code */
207
static int _gnutls_init_ret = 0;
208
209
/**
210
 * gnutls_global_init:
211
 *
212
 * Since GnuTLS 3.3.0 this function is no longer necessary to be explicitly
213
 * called. To disable the implicit call (in a library constructor) of this
214
 * function set the environment variable %GNUTLS_NO_IMPLICIT_INIT to 1.
215
 *
216
 * This function performs any required precalculations, detects
217
 * the supported CPU capabilities and initializes the underlying
218
 * cryptographic backend. In order to free any resources 
219
 * taken by this call you should gnutls_global_deinit() 
220
 * when gnutls usage is no longer needed.
221
 *
222
 * This function increments a global counter, so that
223
 * gnutls_global_deinit() only releases resources when it has been
224
 * called as many times as gnutls_global_init().  This is useful when
225
 * GnuTLS is used by more than one library in an application.  This
226
 * function can be called many times, but will only do something the
227
 * first time. It is thread safe since GnuTLS 3.3.0.
228
 *
229
 * A subsequent call of this function if the initial has failed will
230
 * return the same error code.
231
 *
232
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
233
 *   otherwise a negative error code is returned.
234
 **/
235
int gnutls_global_init(void)
236
0
{
237
0
  return _gnutls_global_init(0);
238
0
}
239
240
static int _gnutls_global_init(unsigned constructor)
241
2
{
242
2
  int ret = 0, res;
243
2
  int level;
244
2
  const char *e;
245
246
2
  if (!constructor) {
247
0
    ret = gnutls_static_mutex_lock(&global_init_mutex);
248
0
    if (ret < 0) {
249
0
      return gnutls_assert_val(ret);
250
0
    }
251
0
  }
252
253
2
  _gnutls_init++;
254
2
  if (_gnutls_init > 1) {
255
0
    ret = _gnutls_init_ret;
256
0
    goto out;
257
0
  }
258
259
2
  _gnutls_switch_lib_state(LIB_STATE_INIT);
260
261
2
  e = secure_getenv("GNUTLS_DEBUG_LEVEL");
262
2
  if (e != NULL) {
263
0
    level = atoi(e);
264
0
    gnutls_global_set_log_level(level);
265
0
    if (_gnutls_log_func == NULL)
266
0
      gnutls_global_set_log_function(default_log_func);
267
0
    _gnutls_debug_log("Enabled GnuTLS " VERSION " logging...\n");
268
0
  }
269
270
2
#ifdef HAVE_DCGETTEXT
271
2
  bindtextdomain(PACKAGE, LOCALEDIR);
272
2
#endif
273
274
2
  res = gnutls_crypto_init();
275
2
  if (res != 0) {
276
0
    gnutls_assert();
277
0
    ret = GNUTLS_E_CRYPTO_INIT_FAILED;
278
0
    goto out;
279
0
  }
280
281
2
  ret = _gnutls_system_key_init();
282
2
  if (ret != 0) {
283
0
    gnutls_assert();
284
0
  }
285
286
  /* initialize ASN.1 parser
287
   */
288
2
  if (asn1_check_version(GNUTLS_MIN_LIBTASN1_VERSION) == NULL) {
289
0
    gnutls_assert();
290
0
    _gnutls_debug_log("Checking for libtasn1 failed: %s < %s\n",
291
0
          asn1_check_version(NULL),
292
0
          GNUTLS_MIN_LIBTASN1_VERSION);
293
0
    ret = GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY;
294
0
    goto out;
295
0
  }
296
297
2
  _gnutls_pkix1_asn = NULL;
298
2
  res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
299
2
  if (res != ASN1_SUCCESS) {
300
0
    gnutls_assert();
301
0
    ret = _gnutls_asn2err(res);
302
0
    goto out;
303
0
  }
304
305
2
  res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
306
2
  if (res != ASN1_SUCCESS) {
307
0
    gnutls_assert();
308
0
    ret = _gnutls_asn2err(res);
309
0
    goto out;
310
0
  }
311
312
  /* Initialize the random generator */
313
2
  ret = _gnutls_rnd_preinit();
314
2
  if (ret < 0) {
315
0
    gnutls_assert();
316
0
    goto out;
317
0
  }
318
319
  /* Initialize the default TLS extensions */
320
2
  ret = _gnutls_hello_ext_init();
321
2
  if (ret < 0) {
322
0
    gnutls_assert();
323
0
    goto out;
324
0
  }
325
326
2
  ret = gnutls_system_global_init();
327
2
  if (ret < 0) {
328
0
    gnutls_assert();
329
0
    goto out;
330
0
  }
331
332
2
#ifndef _WIN32
333
2
  ret = _gnutls_register_fork_handler();
334
2
  if (ret < 0) {
335
0
    gnutls_assert();
336
0
    goto out;
337
0
  }
338
2
#endif
339
340
#ifdef ENABLE_FIPS140
341
  res = _gnutls_fips_mode_enabled();
342
  /* res == 1 -> fips140-2 mode enabled
343
   * res == 2 -> only self checks performed - but no failure
344
   * res == not in fips140 mode
345
   */
346
  if (res != 0) {
347
    _gnutls_debug_log("FIPS140-2 mode: %d\n", res);
348
    _gnutls_priority_update_fips();
349
350
    /* first round of self checks, these are done on the
351
     * nettle algorithms which are used internally */
352
    _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
353
    ret = _gnutls_fips_perform_self_checks1();
354
    if (ret < 0) {
355
      _gnutls_switch_lib_state(LIB_STATE_ERROR);
356
      _gnutls_audit_log(
357
        NULL, "FIPS140-2 self testing part1 failed\n");
358
      if (res != 2) {
359
        gnutls_assert();
360
        goto out;
361
      }
362
    }
363
  }
364
#endif
365
366
2
  _gnutls_register_accel_crypto();
367
2
  _gnutls_cryptodev_init();
368
2
  _gnutls_afalg_init();
369
370
#ifdef ENABLE_FIPS140
371
  /* These self tests are performed on the overridden algorithms
372
   * (e.g., AESNI overridden AES). They are after _gnutls_register_accel_crypto()
373
   * intentionally */
374
  if (res != 0) {
375
    _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
376
    ret = _gnutls_fips_perform_self_checks2();
377
    if (ret < 0) {
378
      _gnutls_switch_lib_state(LIB_STATE_ERROR);
379
      _gnutls_audit_log(
380
        NULL, "FIPS140-2 self testing part 2 failed\n");
381
      if (res != 2) {
382
        gnutls_assert();
383
        goto out;
384
      }
385
    }
386
    _gnutls_fips_mode_reset_zombie();
387
  }
388
#endif
389
2
  _gnutls_prepare_to_load_system_priorities();
390
2
  _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL);
391
2
  ret = 0;
392
393
2
out:
394
2
  _gnutls_init_ret = ret;
395
2
  if (!constructor) {
396
0
    (void)gnutls_static_mutex_unlock(&global_init_mutex);
397
0
  }
398
2
  return ret;
399
2
}
400
401
static void _gnutls_global_deinit(unsigned destructor)
402
0
{
403
0
  if (!destructor) {
404
0
    if (gnutls_static_mutex_lock(&global_init_mutex) < 0) {
405
0
      return;
406
0
    }
407
0
  }
408
409
0
  if (_gnutls_init == 1) {
410
0
    _gnutls_init = 0;
411
0
    if (_gnutls_init_ret < 0) {
412
      /* only deinitialize if gnutls_global_init() has
413
       * succeeded */
414
0
      gnutls_assert();
415
0
      goto fail;
416
0
    }
417
418
0
    _gnutls_system_key_deinit();
419
0
    gnutls_crypto_deinit();
420
0
    _gnutls_compression_deinit();
421
0
    _gnutls_rnd_deinit();
422
0
    _gnutls_hello_ext_deinit();
423
0
    asn1_delete_structure(&_gnutls_gnutls_asn);
424
0
    asn1_delete_structure(&_gnutls_pkix1_asn);
425
426
0
    _gnutls_crypto_deregister();
427
0
    gnutls_system_global_deinit();
428
0
    _gnutls_cryptodev_deinit();
429
430
0
    _gnutls_supplemental_deinit();
431
0
    _gnutls_unload_system_priorities();
432
433
#ifdef ENABLE_PKCS11
434
    /* Do not try to deinitialize the PKCS #11 libraries
435
     * from the destructor. If we do and the PKCS #11 modules
436
     * are already being unloaded, we may crash.
437
     */
438
    if (destructor == 0) {
439
      gnutls_pkcs11_deinit();
440
    }
441
#endif
442
#ifdef HAVE_TROUSERS
443
    _gnutls_tpm_global_deinit();
444
#endif
445
#ifdef HAVE_TPM2
446
    _gnutls_tpm2_deinit();
447
#endif
448
#ifdef HAVE_LIBOQS
449
    _gnutls_liboqs_deinit();
450
#endif
451
452
0
    _gnutls_nss_keylog_deinit();
453
0
  } else {
454
0
    if (_gnutls_init > 0)
455
0
      _gnutls_init--;
456
0
  }
457
458
0
fail:
459
0
  if (!destructor) {
460
0
    (void)gnutls_static_mutex_unlock(&global_init_mutex);
461
0
  }
462
0
}
463
464
/**
465
 * gnutls_global_deinit:
466
 *
467
 * This function deinitializes the global data, that were initialized
468
 * using gnutls_global_init().
469
 *
470
 * Since GnuTLS 3.3.0 this function is no longer necessary to be explicitly
471
 * called. GnuTLS will automatically deinitialize on library destructor. See
472
 * gnutls_global_init() for disabling the implicit initialization/deinitialization.
473
 *
474
 **/
475
void gnutls_global_deinit(void)
476
0
{
477
0
  _gnutls_global_deinit(0);
478
0
}
479
480
/**
481
 * gnutls_check_version:
482
 * @req_version: version string to compare with, or %NULL.
483
 *
484
 * Check the GnuTLS Library version against the provided string.
485
 * See %GNUTLS_VERSION for a suitable @req_version string.
486
 *
487
 * See also gnutls_check_version_numeric(), which provides this
488
 * functionality as a macro.
489
 *
490
 * Returns: Check that the version of the library is at
491
 *   minimum the one given as a string in @req_version and return the
492
 *   actual version string of the library; return %NULL if the
493
 *   condition is not met.  If %NULL is passed to this function no
494
 *   check is done and only the version string is returned.
495
  **/
496
const char *gnutls_check_version(const char *req_version)
497
0
{
498
0
  if (!req_version || strverscmp(req_version, VERSION) <= 0)
499
0
    return VERSION;
500
501
0
  return NULL;
502
0
}
503
504
static void _CONSTRUCTOR lib_init(void)
505
2
{
506
2
  int ret;
507
2
  const char *e;
508
509
2
  if (_gnutls_global_init_skip() != 0)
510
0
    return;
511
512
2
  e = secure_getenv("GNUTLS_NO_IMPLICIT_INIT");
513
2
  if (e != NULL) {
514
0
    ret = atoi(e);
515
0
    if (ret == 1)
516
0
      return;
517
0
  }
518
519
2
  e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
520
2
  if (e != NULL) {
521
0
    _gnutls_debug_log(
522
0
      "GNUTLS_NO_EXPLICIT_INIT is deprecated; use GNUTLS_NO_IMPLICIT_INIT\n");
523
0
    ret = atoi(e);
524
0
    if (ret == 1)
525
0
      return;
526
0
  }
527
528
2
  ret = _gnutls_global_init(1);
529
2
  if (ret < 0) {
530
0
    fprintf(stderr, "Error in GnuTLS initialization: %s\n",
531
0
      gnutls_strerror(ret));
532
0
    _gnutls_switch_lib_state(LIB_STATE_ERROR);
533
0
  }
534
2
}
535
536
static void _DESTRUCTOR lib_deinit(void)
537
0
{
538
0
  int ret;
539
0
  const char *e;
540
541
0
  if (_gnutls_global_init_skip() != 0)
542
0
    return;
543
544
0
  e = secure_getenv("GNUTLS_NO_IMPLICIT_INIT");
545
0
  if (e != NULL) {
546
0
    ret = atoi(e);
547
0
    if (ret == 1)
548
0
      return;
549
0
  }
550
551
0
  e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
552
0
  if (e != NULL) {
553
0
    _gnutls_debug_log(
554
0
      "GNUTLS_NO_EXPLICIT_INIT is deprecated; use GNUTLS_NO_IMPLICIT_INIT\n");
555
0
    ret = atoi(e);
556
0
    if (ret == 1)
557
0
      return;
558
0
  }
559
560
0
  _gnutls_global_deinit(1);
561
0
}
562
563
static const struct gnutls_library_config_st _gnutls_library_config[] = {
564
#ifdef FIPS_MODULE_NAME
565
  { "fips-module-name", FIPS_MODULE_NAME },
566
#endif
567
#ifdef FIPS_MODULE_VERSION
568
  { "fips-module-version", FIPS_MODULE_VERSION },
569
#endif
570
#ifdef GNUTLS_LIBRARY_SONAME
571
  { "libgnutls-soname", GNUTLS_LIBRARY_SONAME },
572
#endif
573
#ifdef NETTLE_LIBRARY_SONAME
574
  { "libnettle-soname", NETTLE_LIBRARY_SONAME },
575
#endif
576
#ifdef HOGWEED_LIBRARY_SONAME
577
  { "libhogweed-soname", HOGWEED_LIBRARY_SONAME },
578
#endif
579
#ifdef GMP_LIBRARY_SONAME
580
  { "libgmp-soname", GMP_LIBRARY_SONAME },
581
#endif
582
  { "hardware-features", HW_FEATURES },
583
  { "tls-features", TLS_FEATURES },
584
  { "default-system-config", SYSTEM_PRIORITY_FILE },
585
  { NULL, NULL }
586
};
587
588
/**
589
 * gnutls_get_library_config:
590
 *
591
 * Returns the library configuration as key value pairs.
592
 * Currently defined keys are:
593
 *
594
 *  - fips-module-name: the name of the FIPS140 module
595
 *
596
 *  - fips-module-version: the version of the FIPS140 module
597
 *
598
 *  - libgnutls-soname: the SONAME of the library itself
599
 *
600
 *  - libnettle-soname: the library SONAME of linked libnettle
601
 *
602
 *  - libhogweed-soname: the library SONAME of linked libhogweed
603
 *
604
 *  - libgmp-soname: the library SONAME of linked libgmp
605
 *
606
 *  - hardware-features: enabled hardware support features
607
 *
608
 *  - tls-features: enabled TLS protocol features
609
 *
610
 * Returns: a NUL-terminated %gnutls_library_config_st array
611
 *
612
 * Since: 3.7.3
613
 */
614
const gnutls_library_config_st *gnutls_get_library_config(void)
615
0
{
616
0
  return _gnutls_library_config;
617
0
}