Exemplo n.º 1
0
/* Do PKCS-1 RSA encryption. 
 * params is modulus, public exp.
 */
int
_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
			   const gnutls_datum_t * plaintext,
			   mpi_t * params, unsigned params_len,
			   unsigned btype)
{
  unsigned int i, pad;
  int ret;
  mpi_t m, res;
  opaque *edata, *ps;
  size_t k, psize;
  size_t mod_bits;

  mod_bits = _gnutls_mpi_get_nbits (params[0]);
  k = mod_bits / 8;
  if (mod_bits % 8 != 0)
    k++;

  if (plaintext->size > k - 11)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_ENCRYPTION_FAILED;
    }

  edata = gnutls_alloca (k);
  if (edata == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* EB = 00||BT||PS||00||D 
   * (use block type 'btype')
   */

  edata[0] = 0;
  edata[1] = btype;
  psize = k - 3 - plaintext->size;

  ps = &edata[2];
  switch (btype)
    {
    case 2:
      /* using public key */
      if (params_len < RSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      if (gc_pseudo_random (ps, psize) != GC_OK)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_RANDOM_FAILED;
	}
      for (i = 0; i < psize; i++)
	while (ps[i] == 0)
	  {
	    if (gc_pseudo_random (&ps[i], 1) != GC_OK)
	      {
		gnutls_assert ();
		gnutls_afree (edata);
		return GNUTLS_E_RANDOM_FAILED;
	      }
	  }
      break;
    case 1:
      /* using private key */

      if (params_len < RSA_PRIVATE_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      for (i = 0; i < psize; i++)
	ps[i] = 0xff;
      break;
    default:
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ps[psize] = 0;
  memcpy (&ps[psize + 1], plaintext->data, plaintext->size);

  if (_gnutls_mpi_scan_nz (&m, edata, &k) != 0)
    {
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  gnutls_afree (edata);

  if (btype == 2)		/* encrypt */
    ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len);
  else				/* sign */
    ret = _gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len);

  _gnutls_mpi_release (&m);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_mpi_print (NULL, &psize, res);

  if (psize < k)
    {
      /* padding psize */
      pad = k - psize;
      psize = k;
    }
  else if (psize == k)
    {
      pad = 0;
    }
  else
    {				/* psize > k !!! */
      /* This is an impossible situation */
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ciphertext->data = gnutls_malloc (psize);
  if (ciphertext->data == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_MEMORY_ERROR;
    }
  _gnutls_mpi_print (&ciphertext->data[pad], &psize, res);
  for (i = 0; i < pad; i++)
    ciphertext->data[i] = 0;

  ciphertext->size = k;

  _gnutls_mpi_release (&res);

  return 0;
}
Exemplo n.º 2
0
/**
  * gnutls_global_init - This function initializes the global data to defaults.
  *
  * 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 must call gnutls_global_deinit() when gnutls usage is no longer needed
  * Returns zero on success.
  *
  * 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.
  *
  **/
int
gnutls_global_init (void)
{
  int result = 0;
  int res;
  char c;

  if (_gnutls_init++)
    goto out;

#if HAVE_WINSOCK
  {
    WORD requested;
    WSADATA data;
    int err;

    requested = MAKEWORD (1, 1);
    err = WSAStartup (requested, &data);
    if (err != 0)
      {
	_gnutls_debug_log ("WSAStartup failed: %d.\n", err);
	return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
      }

    if (data.wVersion < requested)
      {
	_gnutls_debug_log ("WSAStartup version check failed (%d < %d).\n",
			   data.wVersion, requested);
	WSACleanup ();
	return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
      }
  }
#endif

  bindtextdomain (PACKAGE, LOCALEDIR);

  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P) == 0)
    {
      const char *p;
      p = strchr (GNUTLS_GCRYPT_VERSION, ':');
      if (p == NULL)
	p = GNUTLS_GCRYPT_VERSION;
      else
	p++;

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

      /* for gcrypt in order to be able to allocate memory */
      gcry_set_allocation_handler (gnutls_malloc, gnutls_secure_malloc,
				   _gnutls_is_secure_memory, gnutls_realloc,
				   gnutls_free);

      /* gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING, NULL, 0); */

      gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);

#ifdef DEBUG
      /* applications may want to override that, so we only use
       * it in debugging mode.
       */
      gcry_set_log_handler (_gnutls_gcry_log_handler, NULL);
#endif
    }

  if (gc_init () != GC_OK)
    {
      gnutls_assert ();
      _gnutls_debug_log ("Initializing crypto backend failed\n");
      return GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY;
    }

  /* for gcrypt in order to be able to allocate memory */
  gc_set_allocators (gnutls_malloc, gnutls_secure_malloc,
		     _gnutls_is_secure_memory, gnutls_realloc, gnutls_free);

#ifdef DEBUG
  gnutls_global_set_log_function (dlog);
#endif

  /* initialize parser 
   * This should not deal with files in the final
   * version.
   */

  if (asn1_check_version (GNUTLS_LIBTASN1_VERSION) == NULL)
    {
      gnutls_assert ();
      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 gcrypt (if used random generator) */
  gc_pseudo_random (&c, 1);

out:
  return result;
}