Coverage Report

Created: 2024-07-23 07:36

/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
20
#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
20
{
63
20
  return 0;
64
20
}
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
20
{
242
20
  int ret = 0, res;
243
20
  int level;
244
20
  const char *e;
245
246
20
  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
20
  _gnutls_init++;
254
20
  if (_gnutls_init > 1) {
255
0
    ret = _gnutls_init_ret;
256
0
    goto out;
257
0
  }
258
259
20
  _gnutls_switch_lib_state(LIB_STATE_INIT);
260
261
20
  e = secure_getenv("GNUTLS_DEBUG_LEVEL");
262
20
  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
20
#ifdef HAVE_DCGETTEXT
271
20
  bindtextdomain(PACKAGE, LOCALEDIR);
272
20
#endif
273
274
20
  res = gnutls_crypto_init();
275
20
  if (res != 0) {
276
0
    gnutls_assert();
277
0
    ret = GNUTLS_E_CRYPTO_INIT_FAILED;
278
0
    goto out;
279
0
  }
280
281
20
  ret = _gnutls_system_key_init();
282
20
  if (ret != 0) {
283
0
    gnutls_assert();
284
0
  }
285
286
  /* initialize ASN.1 parser
287
   */
288
20
  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
20
  _gnutls_pkix1_asn = NULL;
298
20
  res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
299
20
  if (res != ASN1_SUCCESS) {
300
0
    gnutls_assert();
301
0
    ret = _gnutls_asn2err(res);
302
0
    goto out;
303
0
  }
304
305
20
  res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
306
20
  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
20
  ret = _gnutls_rnd_preinit();
314
20
  if (ret < 0) {
315
0
    gnutls_assert();
316
0
    goto out;
317
0
  }
318
319
  /* Initialize the default TLS extensions */
320
20
  ret = _gnutls_hello_ext_init();
321
20
  if (ret < 0) {
322
0
    gnutls_assert();
323
0
    goto out;
324
0
  }
325
326
20
  ret = gnutls_system_global_init();
327
20
  if (ret < 0) {
328
0
    gnutls_assert();
329
0
    goto out;
330
0
  }
331
332
#ifdef HAVE_LIBOQS
333
  _gnutls_liboqs_init();
334
#endif
335
336
20
#ifndef _WIN32
337
20
  ret = _gnutls_register_fork_handler();
338
20
  if (ret < 0) {
339
0
    gnutls_assert();
340
0
    goto out;
341
0
  }
342
20
#endif
343
344
#ifdef ENABLE_FIPS140
345
  res = _gnutls_fips_mode_enabled();
346
  /* res == 1 -> fips140-2 mode enabled
347
   * res == 2 -> only self checks performed - but no failure
348
   * res == not in fips140 mode
349
   */
350
  if (res != 0) {
351
    _gnutls_debug_log("FIPS140-2 mode: %d\n", res);
352
    _gnutls_priority_update_fips();
353
354
    /* first round of self checks, these are done on the
355
     * nettle algorithms which are used internally */
356
    _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
357
    ret = _gnutls_fips_perform_self_checks1();
358
    if (ret < 0) {
359
      _gnutls_switch_lib_state(LIB_STATE_ERROR);
360
      _gnutls_audit_log(
361
        NULL, "FIPS140-2 self testing part1 failed\n");
362
      if (res != 2) {
363
        gnutls_assert();
364
        goto out;
365
      }
366
    }
367
  }
368
#endif
369
370
20
  _gnutls_register_accel_crypto();
371
20
  _gnutls_cryptodev_init();
372
20
  _gnutls_afalg_init();
373
374
#ifdef ENABLE_FIPS140
375
  /* These self tests are performed on the overridden algorithms
376
   * (e.g., AESNI overridden AES). They are after _gnutls_register_accel_crypto()
377
   * intentionally */
378
  if (res != 0) {
379
    _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
380
    ret = _gnutls_fips_perform_self_checks2();
381
    if (ret < 0) {
382
      _gnutls_switch_lib_state(LIB_STATE_ERROR);
383
      _gnutls_audit_log(
384
        NULL, "FIPS140-2 self testing part 2 failed\n");
385
      if (res != 2) {
386
        gnutls_assert();
387
        goto out;
388
      }
389
    }
390
    _gnutls_fips_mode_reset_zombie();
391
  }
392
#endif
393
20
  _gnutls_prepare_to_load_system_priorities();
394
20
  _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL);
395
20
  ret = 0;
396
397
20
out:
398
20
  _gnutls_init_ret = ret;
399
20
  if (!constructor) {
400
0
    (void)gnutls_static_mutex_unlock(&global_init_mutex);
401
0
  }
402
20
  return ret;
403
20
}
404
405
static void _gnutls_global_deinit(unsigned destructor)
406
0
{
407
0
  if (!destructor) {
408
0
    if (gnutls_static_mutex_lock(&global_init_mutex) < 0) {
409
0
      return;
410
0
    }
411
0
  }
412
413
0
  if (_gnutls_init == 1) {
414
0
    _gnutls_init = 0;
415
0
    if (_gnutls_init_ret < 0) {
416
      /* only deinitialize if gnutls_global_init() has
417
       * succeeded */
418
0
      gnutls_assert();
419
0
      goto fail;
420
0
    }
421
422
0
    _gnutls_system_key_deinit();
423
0
    gnutls_crypto_deinit();
424
0
    _gnutls_compression_deinit();
425
0
    _gnutls_rnd_deinit();
426
0
    _gnutls_hello_ext_deinit();
427
0
    asn1_delete_structure(&_gnutls_gnutls_asn);
428
0
    asn1_delete_structure(&_gnutls_pkix1_asn);
429
430
0
    _gnutls_crypto_deregister();
431
0
    gnutls_system_global_deinit();
432
0
    _gnutls_cryptodev_deinit();
433
434
0
    _gnutls_supplemental_deinit();
435
0
    _gnutls_unload_system_priorities();
436
437
#ifdef ENABLE_PKCS11
438
    /* Do not try to deinitialize the PKCS #11 libraries
439
     * from the destructor. If we do and the PKCS #11 modules
440
     * are already being unloaded, we may crash.
441
     */
442
    if (destructor == 0) {
443
      gnutls_pkcs11_deinit();
444
    }
445
#endif
446
#ifdef HAVE_TROUSERS
447
    _gnutls_tpm_global_deinit();
448
#endif
449
#ifdef HAVE_TPM2
450
    _gnutls_tpm2_deinit();
451
#endif
452
#ifdef HAVE_LIBOQS
453
    _gnutls_liboqs_deinit();
454
#endif
455
456
0
    _gnutls_nss_keylog_deinit();
457
0
  } else {
458
0
    if (_gnutls_init > 0)
459
0
      _gnutls_init--;
460
0
  }
461
462
0
fail:
463
0
  if (!destructor) {
464
0
    (void)gnutls_static_mutex_unlock(&global_init_mutex);
465
0
  }
466
0
}
467
468
/**
469
 * gnutls_global_deinit:
470
 *
471
 * This function deinitializes the global data, that were initialized
472
 * using gnutls_global_init().
473
 *
474
 * Since GnuTLS 3.3.0 this function is no longer necessary to be explicitly
475
 * called. GnuTLS will automatically deinitialize on library destructor. See
476
 * gnutls_global_init() for disabling the implicit initialization/deinitialization.
477
 *
478
 **/
479
void gnutls_global_deinit(void)
480
0
{
481
0
  _gnutls_global_deinit(0);
482
0
}
483
484
/**
485
 * gnutls_check_version:
486
 * @req_version: version string to compare with, or %NULL.
487
 *
488
 * Check the GnuTLS Library version against the provided string.
489
 * See %GNUTLS_VERSION for a suitable @req_version string.
490
 *
491
 * See also gnutls_check_version_numeric(), which provides this
492
 * functionality as a macro.
493
 *
494
 * Returns: Check that the version of the library is at
495
 *   minimum the one given as a string in @req_version and return the
496
 *   actual version string of the library; return %NULL if the
497
 *   condition is not met.  If %NULL is passed to this function no
498
 *   check is done and only the version string is returned.
499
  **/
500
const char *gnutls_check_version(const char *req_version)
501
0
{
502
0
  if (!req_version || strverscmp(req_version, VERSION) <= 0)
503
0
    return VERSION;
504
505
0
  return NULL;
506
0
}
507
508
static void _CONSTRUCTOR lib_init(void)
509
20
{
510
20
  int ret;
511
20
  const char *e;
512
513
20
  if (_gnutls_global_init_skip() != 0)
514
0
    return;
515
516
20
  e = secure_getenv("GNUTLS_NO_IMPLICIT_INIT");
517
20
  if (e != NULL) {
518
0
    ret = atoi(e);
519
0
    if (ret == 1)
520
0
      return;
521
0
  }
522
523
20
  e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
524
20
  if (e != NULL) {
525
0
    _gnutls_debug_log(
526
0
      "GNUTLS_NO_EXPLICIT_INIT is deprecated; use GNUTLS_NO_IMPLICIT_INIT\n");
527
0
    ret = atoi(e);
528
0
    if (ret == 1)
529
0
      return;
530
0
  }
531
532
20
  ret = _gnutls_global_init(1);
533
20
  if (ret < 0) {
534
0
    fprintf(stderr, "Error in GnuTLS initialization: %s\n",
535
0
      gnutls_strerror(ret));
536
0
    _gnutls_switch_lib_state(LIB_STATE_ERROR);
537
0
  }
538
20
}
539
540
static void _DESTRUCTOR lib_deinit(void)
541
0
{
542
0
  int ret;
543
0
  const char *e;
544
545
0
  if (_gnutls_global_init_skip() != 0)
546
0
    return;
547
548
0
  e = secure_getenv("GNUTLS_NO_IMPLICIT_INIT");
549
0
  if (e != NULL) {
550
0
    ret = atoi(e);
551
0
    if (ret == 1)
552
0
      return;
553
0
  }
554
555
0
  e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
556
0
  if (e != NULL) {
557
0
    _gnutls_debug_log(
558
0
      "GNUTLS_NO_EXPLICIT_INIT is deprecated; use GNUTLS_NO_IMPLICIT_INIT\n");
559
0
    ret = atoi(e);
560
0
    if (ret == 1)
561
0
      return;
562
0
  }
563
564
0
  _gnutls_global_deinit(1);
565
0
}
566
567
static const struct gnutls_library_config_st _gnutls_library_config[] = {
568
#ifdef FIPS_MODULE_NAME
569
  { "fips-module-name", FIPS_MODULE_NAME },
570
#endif
571
#ifdef FIPS_MODULE_VERSION
572
  { "fips-module-version", FIPS_MODULE_VERSION },
573
#endif
574
#ifdef GNUTLS_LIBRARY_SONAME
575
  { "libgnutls-soname", GNUTLS_LIBRARY_SONAME },
576
#endif
577
#ifdef NETTLE_LIBRARY_SONAME
578
  { "libnettle-soname", NETTLE_LIBRARY_SONAME },
579
#endif
580
#ifdef HOGWEED_LIBRARY_SONAME
581
  { "libhogweed-soname", HOGWEED_LIBRARY_SONAME },
582
#endif
583
#ifdef GMP_LIBRARY_SONAME
584
  { "libgmp-soname", GMP_LIBRARY_SONAME },
585
#endif
586
  { "hardware-features", HW_FEATURES },
587
  { "tls-features", TLS_FEATURES },
588
  { "default-system-config", SYSTEM_PRIORITY_FILE },
589
  { NULL, NULL }
590
};
591
592
/**
593
 * gnutls_get_library_config:
594
 *
595
 * Returns the library configuration as key value pairs.
596
 * Currently defined keys are:
597
 *
598
 *  - fips-module-name: the name of the FIPS140 module
599
 *
600
 *  - fips-module-version: the version of the FIPS140 module
601
 *
602
 *  - libgnutls-soname: the SONAME of the library itself
603
 *
604
 *  - libnettle-soname: the library SONAME of linked libnettle
605
 *
606
 *  - libhogweed-soname: the library SONAME of linked libhogweed
607
 *
608
 *  - libgmp-soname: the library SONAME of linked libgmp
609
 *
610
 *  - hardware-features: enabled hardware support features
611
 *
612
 *  - tls-features: enabled TLS protocol features
613
 *
614
 * Returns: a NUL-terminated %gnutls_library_config_st array
615
 *
616
 * Since: 3.7.3
617
 */
618
const gnutls_library_config_st *gnutls_get_library_config(void)
619
0
{
620
0
  return _gnutls_library_config;
621
0
}