Coverage Report

Created: 2023-03-26 07:33

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