Exemplo n.º 1
0
/**
 * gnutls_global_init:
 *
 * This function initializes the global data to defaults.  Every
 * gnutls application has a global data which holds common parameters
 * shared by gnutls session structures.  You should call
 * gnutls_global_deinit() when gnutls usage is no longer needed
 *
 * Note that this function will also initialize libgcrypt, if it has
 * not been initialized before.  Thus if you want to manually
 * initialize libgcrypt you must do it before calling this function.
 * This is useful in cases you want to disable libgcrypt's internal
 * lockings etc.
 *
 * This function increment a global counter, so that
 * gnutls_global_deinit() only releases resources when it has been
 * called as many times as gnutls_global_init().  This is useful when
 * GnuTLS is used by more than one library in an application.  This
 * function can be called many times, but will only do something the
 * first time.
 *
 * Note!  This function is not thread safe.  If two threads call this
 * function simultaneously, they can cause a race between checking
 * the global counter and incrementing it, causing both threads to
 * execute the library initialization code.  That would lead to a
 * memory leak.  To handle this, your application could invoke this
 * function after aquiring a thread mutex.  To ignore the potential
 * memory leak is also an option.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
 *   otherwise an error code is returned.
 **/
int
gnutls_global_init (void)
{
  int result = 0;
  int res;

  if (_gnutls_init++)
    goto out;

  if (gl_sockets_startup (SOCKETS_1_1))
    return GNUTLS_E_LIBRARY_VERSION_MISMATCH;

  bindtextdomain (PACKAGE, LOCALEDIR);

  /* Initialize libgcrypt if it hasn't already been initialized. */
  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P) == 0)
    {
      const char *p;

      p = gcry_check_version (GNUTLS_MIN_LIBGCRYPT_VERSION);

      if (p == NULL)
	{
	  gnutls_assert ();
	  _gnutls_debug_log ("Checking for libgcrypt failed: %s < %s\n",
			     gcry_check_version (NULL),
			     GNUTLS_MIN_LIBGCRYPT_VERSION);
	  return GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY;
	}

      /* for gcrypt in order to be able to allocate memory */
      gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0);

      gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
    }

  /* initialize ASN.1 parser
   * This should not deal with files in the final
   * version.
   */
  if (asn1_check_version (GNUTLS_MIN_LIBTASN1_VERSION) == NULL)
    {
      gnutls_assert ();
      _gnutls_debug_log ("Checking for libtasn1 failed: %s < %s\n",
			 asn1_check_version (NULL),
			 GNUTLS_MIN_LIBTASN1_VERSION);
      return GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY;
    }

  res = asn1_array2tree (pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
  if (res != ASN1_SUCCESS)
    {
      result = _gnutls_asn2err (res);
      goto out;
    }

  res = asn1_array2tree (gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
  if (res != ASN1_SUCCESS)
    {
      asn1_delete_structure (&_gnutls_pkix1_asn);
      result = _gnutls_asn2err (res);
      goto out;
    }

  /* Initialize the random generator */
  result = _gnutls_rnd_init ();
  if (result < 0)
    {
      gnutls_assert ();
      goto out;
    }

  /* Initialize the default TLS extensions */
  result = _gnutls_ext_init ();
  if (result < 0)
    {
      gnutls_assert ();
      goto out;
    }

  _gnutls_cryptodev_init ();

out:
  return result;
}
Exemplo n.º 2
0
/**
 * gnutls_global_init:
 *
 * This function performs any required precalculations, detects
 * the supported CPU capabilities and initializes the underlying
 * cryptographic backend. In order to free any resources 
 * taken by this call you should gnutls_global_deinit() 
 * when gnutls usage is no longer needed.
 *
 * This function increments a global counter, so that
 * gnutls_global_deinit() only releases resources when it has been
 * called as many times as gnutls_global_init().  This is useful when
 * GnuTLS is used by more than one library in an application.  This
 * function can be called many times, but will only do something the
 * first time.
 *
 * Since GnuTLS 3.3.0 this function is only required in systems that
 * do not support library constructors and static linking. This
 * function also became thread safe.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int gnutls_global_init(void)
{
	int ret = 0, res;
	int level;
	const char* e;
	
	GNUTLS_STATIC_MUTEX_LOCK(global_init_mutex);

	_gnutls_init++;
	if (_gnutls_init > 1) {
		ret = 0;
		goto out;
	}

	_gnutls_switch_lib_state(LIB_STATE_INIT);

	e = getenv("GNUTLS_DEBUG_LEVEL");
	if (e != NULL) {
		level = atoi(e);
		gnutls_global_set_log_level(level);
		if (_gnutls_log_func == NULL)
			gnutls_global_set_log_function(default_log_func);
		_gnutls_debug_log("Enabled GnuTLS logging...\n");
	}

	bindtextdomain(PACKAGE, LOCALEDIR);

	res = gnutls_crypto_init();
	if (res != 0) {
		gnutls_assert();
		ret = GNUTLS_E_CRYPTO_INIT_FAILED;
		goto out;
	}

	/* initialize ASN.1 parser
	 */
	if (asn1_check_version(GNUTLS_MIN_LIBTASN1_VERSION) == NULL) {
		gnutls_assert();
		_gnutls_debug_log
		    ("Checking for libtasn1 failed: %s < %s\n",
		     asn1_check_version(NULL),
		     GNUTLS_MIN_LIBTASN1_VERSION);
		ret = GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY;
		goto out;
	}

	res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
	if (res != ASN1_SUCCESS) {
		ret = _gnutls_asn2err(res);
		goto out;
	}

	res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
	if (res != ASN1_SUCCESS) {
		ret = _gnutls_asn2err(res);
		goto out;
	}

	/* Initialize the random generator */
	ret = _gnutls_rnd_init();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	/* Initialize the default TLS extensions */
	ret = _gnutls_ext_init();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	ret = gnutls_mutex_init(&_gnutls_file_mutex);
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	ret = gnutls_mutex_init(&_gnutls_pkcs11_mutex);
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	ret = gnutls_system_global_init();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	_gnutls_register_accel_crypto();
	_gnutls_cryptodev_init();

#ifdef ENABLE_FIPS140
	/* Perform FIPS140 checks last, so that all modules
	 * have been loaded */
	res = _gnutls_fips_mode_enabled();
	/* res == 1 -> fips140-2 mode enabled
	 * res == 2 -> only self checks performed - but no failure
	 * res == not in fips140 mode
	 */
	if (res != 0) {
		_gnutls_priority_update_fips();

		ret = _gnutls_fips_perform_self_checks();
		if (res != 2) {
			if (ret < 0) {
				gnutls_assert();
				goto out;
			}
		}
	}
#endif
	_gnutls_switch_lib_state(LIB_STATE_OPERATIONAL);
	ret = 0;

      out:
	GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
	return ret;
}
Exemplo n.º 3
0
static int _gnutls_global_init(unsigned constructor)
{
	int ret = 0, res;
	int level;
	const char* e;

	if (!constructor) {
		GNUTLS_STATIC_MUTEX_LOCK(global_init_mutex);
	}

	_gnutls_init++;
	if (_gnutls_init > 1) {
		if (_gnutls_init == 2 && _gnutls_init_ret == 0) {
			/* some applications may close the urandom fd 
			 * before calling gnutls_global_init(). in that
			 * case reopen it */
			ret = _gnutls_rnd_check();
			if (ret < 0) {
				gnutls_assert();
				goto out;
			}
		}
		ret = _gnutls_init_ret;
		goto out;
	}

	_gnutls_switch_lib_state(LIB_STATE_INIT);

	e = secure_getenv("GNUTLS_DEBUG_LEVEL");
	if (e != NULL) {
		level = atoi(e);
		gnutls_global_set_log_level(level);
		if (_gnutls_log_func == NULL)
			gnutls_global_set_log_function(default_log_func);
		_gnutls_debug_log("Enabled GnuTLS "VERSION" logging...\n");
	}

#ifdef HAVE_DCGETTEXT
	bindtextdomain(PACKAGE, LOCALEDIR);
#endif

	res = gnutls_crypto_init();
	if (res != 0) {
		gnutls_assert();
		ret = GNUTLS_E_CRYPTO_INIT_FAILED;
		goto out;
	}

	ret = _gnutls_system_key_init();
	if (ret != 0) {
		gnutls_assert();
	}

	/* initialize ASN.1 parser
	 */
	if (asn1_check_version(GNUTLS_MIN_LIBTASN1_VERSION) == NULL) {
		gnutls_assert();
		_gnutls_debug_log
		    ("Checking for libtasn1 failed: %s < %s\n",
		     asn1_check_version(NULL),
		     GNUTLS_MIN_LIBTASN1_VERSION);
		ret = GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY;
		goto out;
	}

	_gnutls_pkix1_asn = ASN1_TYPE_EMPTY;
	res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
	if (res != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(res);
		goto out;
	}

	res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
	if (res != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(res);
		goto out;
	}

	/* Initialize the random generator */
	ret = _gnutls_rnd_preinit();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	/* Initialize the default TLS extensions */
	ret = _gnutls_ext_init();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	ret = gnutls_mutex_init(&_gnutls_file_mutex);
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	ret = gnutls_mutex_init(&_gnutls_pkcs11_mutex);
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

	ret = gnutls_system_global_init();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}

#ifndef _WIN32
	ret = _gnutls_register_fork_handler();
	if (ret < 0) {
		gnutls_assert();
		goto out;
	}
#endif

#ifdef ENABLE_FIPS140
	res = _gnutls_fips_mode_enabled();
	/* res == 1 -> fips140-2 mode enabled
	 * res == 2 -> only self checks performed - but no failure
	 * res == not in fips140 mode
	 */
	if (res != 0) {
		_gnutls_debug_log("FIPS140-2 mode: %d\n", res);
		_gnutls_priority_update_fips();

		/* first round of self checks, these are done on the
		 * nettle algorithms which are used internally */
		ret = _gnutls_fips_perform_self_checks1();
		if (res != 2) {
			if (ret < 0) {
				gnutls_assert();
				goto out;
			}
		}
	}
#endif

	_gnutls_register_accel_crypto();
	_gnutls_cryptodev_init();
	_gnutls_load_system_priorities();

#ifdef ENABLE_FIPS140
	/* These self tests are performed on the overriden algorithms
	 * (e.g., AESNI overriden AES). They are after _gnutls_register_accel_crypto()
	 * intentionally */
	if (res != 0) {
		ret = _gnutls_fips_perform_self_checks2();
		if (res != 2) {
			if (ret < 0) {
				gnutls_assert();
				goto out;
			}
		}
		_gnutls_fips_mode_reset_zombie();
	}
#endif
	_gnutls_switch_lib_state(LIB_STATE_OPERATIONAL);
	ret = 0;

      out:
	_gnutls_init_ret = ret;
	if (!constructor) {
		GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
	}
	return ret;
}
Exemplo n.º 4
0
/**
 * gnutls_global_init:
 *
 * This function performs any required precalculations, detects
 * the supported CPU capabilities and initializes the underlying
 * cryptographic backend. In order to free any resources 
 * taken by this call you should gnutls_global_deinit() 
 * when gnutls usage is no longer needed.
 *
 * This function increments a global counter, so that
 * gnutls_global_deinit() only releases resources when it has been
 * called as many times as gnutls_global_init().  This is useful when
 * GnuTLS is used by more than one library in an application.  This
 * function can be called many times, but will only do something the
 * first time.
 *
 * Note!  This function is not thread safe.  If two threads call this
 * function simultaneously, they can cause a race between checking
 * the global counter and incrementing it, causing both threads to
 * execute the library initialization code.  That would lead to a
 * memory leak.  To handle this, your application could invoke this
 * function after aquiring a thread mutex.  To ignore the potential
 * memory leak is also an option.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int
gnutls_global_init (void)
{
  int result = 0;
  int res;

  if (_gnutls_init++)
    goto out;

  if (gl_sockets_startup (SOCKETS_1_1))
    return gnutls_assert_val(GNUTLS_E_FILE_ERROR);

  bindtextdomain (PACKAGE, LOCALEDIR);

  res = gnutls_crypto_init ();
  if (res != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_CRYPTO_INIT_FAILED;
    }

  _gnutls_register_accel_crypto();

  /* initialize ASN.1 parser
   * This should not deal with files in the final
   * version.
   */
  if (asn1_check_version (GNUTLS_MIN_LIBTASN1_VERSION) == NULL)
    {
      gnutls_assert ();
      _gnutls_debug_log ("Checking for libtasn1 failed: %s < %s\n",
                         asn1_check_version (NULL),
                         GNUTLS_MIN_LIBTASN1_VERSION);
      return GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY;
    }

  res = asn1_array2tree (pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
  if (res != ASN1_SUCCESS)
    {
      result = _gnutls_asn2err (res);
      goto out;
    }

  res = asn1_array2tree (gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
  if (res != ASN1_SUCCESS)
    {
      result = _gnutls_asn2err (res);
      goto out;
    }

  /* Initialize the random generator */
  result = _gnutls_rnd_init ();
  if (result < 0)
    {
      gnutls_assert ();
      goto out;
    }

  /* Initialize the default TLS extensions */
  result = _gnutls_ext_init ();
  if (result < 0)
    {
      gnutls_assert ();
      goto out;
    }

  result = gnutls_mutex_init(&_gnutls_file_mutex);
  if (result < 0)
    {
      gnutls_assert();
      goto out;
    }

  result = gnutls_system_global_init ();
  if (result < 0)
    {
      gnutls_assert ();
      goto out;
    }

#ifdef ENABLE_PKCS11
  gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_AUTO, NULL);
#endif

  _gnutls_cryptodev_init ();

out:
  return result;
}