Coverage Report

Created: 2025-07-23 07:16

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