void dh_params::export_pkcs3 (gnutls_x509_crt_fmt_t format,
                              unsigned char *params_data,
                              size_t * params_data_size)
{
    RETWRAP (gnutls_dh_params_export_pkcs3
             (params, format, params_data, params_data_size));
}
Esempio n. 2
0
void dh_info(FILE * infile, FILE * outfile, common_info_st * ci)
{
	gnutls_datum_t params;
	size_t size;
	int ret;
	gnutls_dh_params_t dh_params;
	gnutls_datum_t p, g;
	unsigned int q_bits = 0;

	if (gnutls_dh_params_init(&dh_params) < 0) {
		fprintf(stderr, "Error in dh parameter initialization\n");
		exit(1);
	}

	params.data = (void *) fread_file(infile, &size);
	params.size = size;

	ret =
	    gnutls_dh_params_import_pkcs3(dh_params, &params,
					  ci->incert_format);
	if (ret < 0) {
		fprintf(stderr, "Error parsing dh params: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_dh_params_export_raw(dh_params, &p, &g, &q_bits);
	if (ret < 0) {
		fprintf(stderr, "Error exporting parameters: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	if (ci->outcert_format == GNUTLS_X509_FMT_PEM)
		print_dh_info(outfile, &p, &g, q_bits, ci->cprint);

	if (!ci->cprint) {	/* generate a PKCS#3 structure */
		size_t len = buffer_size;

		ret =
		    gnutls_dh_params_export_pkcs3(dh_params,
						  ci->outcert_format,
						  buffer, &len);

		if (ret == 0) {
			if (ci->outcert_format == GNUTLS_X509_FMT_PEM) {
				fprintf(outfile, "\n%s", buffer);
			} else {
				fwrite(buffer, 1, len, outfile);
			}
		} else {
			fprintf(stderr, "Error: %s\n",
				gnutls_strerror(ret));
		}
	}

	gnutls_dh_params_deinit(dh_params);
}
Esempio n. 3
0
void    Plugin::_loadDHParams()
{
    QByteArray      data;
    QFile           file(this->dhParamsFile);
    int             bits;
    gnutls_datum_t  datum;
    int             error;

    if (!file.open(QIODevice::ReadWrite))
        throw Properties("error", "Unable to open the Diffie-Hellman parameters file").add("file", this->dhParamsFile);
    bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, this->secParam);
    ASSERT_INIT(gnutls_dh_params_init(&this->dhParams), "dh_params");
    // The Diffie-Hellman parameters expired
    if (QFileInfo(file).lastModified() < this->dhParamsExpiration)
        file.resize(0);
    // Import the DH parameters from the PEM file
    if (file.size() > 0)
    {
        data = file.readAll();
        datum.data = (unsigned char *)data.data();
        datum.size = data.size();
        if (gnutls_dh_params_import_pkcs3(this->dhParams, &datum, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS)
            file.resize(0);
    }
    // Generates the DH parameters and store them in a PEM file
    if (file.size() == 0)
    {
        LOG_INFO("Generating new Diffie-Hellman parameters. This might take some time.", Properties("secParam", gnutls_sec_param_get_name(this->secParam)).add("bits", bits).toMap(), "Plugin", "_generateDHParams");
        data.resize(bits);
        datum.data = (unsigned char *)data.data();
        datum.size = bits;
        ASSERT(gnutls_dh_params_generate2(this->dhParams, bits));
        size_t size = datum.size;
        ASSERT(gnutls_dh_params_export_pkcs3(this->dhParams, GNUTLS_X509_FMT_PEM, datum.data, &size));
        file.write(data.data(), size);
    }
}
Esempio n. 4
0
/* If how is zero then the included parameters are used.
 */
int generate_prime(FILE * outfile, int how, common_info_st * info)
{
	int ret;
	gnutls_dh_params_t dh_params;
	gnutls_datum_t p, g;
	int bits = get_bits(GNUTLS_PK_DH, info->bits, info->sec_param, 1);
	unsigned int q_bits = 0;

	gnutls_dh_params_init(&dh_params);

	if (how != 0) {
		fprintf(stderr, "Generating DH parameters (%d bits)...\n",
			bits);
		fprintf(stderr, "(might take long time)\n");
	} else
		fprintf(stderr, "Retrieving DH parameters...\n");

	if (how != 0) {
		ret = gnutls_dh_params_generate2(dh_params, bits);
		if (ret < 0) {
			fprintf(stderr,
				"Error generating parameters: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		ret =
		    gnutls_dh_params_export_raw(dh_params, &p, &g,
						&q_bits);
		if (ret < 0) {
			fprintf(stderr, "Error exporting parameters: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
	} else {
#ifdef ENABLE_SRP
		if (bits <= 1024) {
			p = gnutls_srp_1024_group_prime;
			g = gnutls_srp_1024_group_generator;
			bits = 1024;
		} else if (bits <= 1536) {
			p = gnutls_srp_1536_group_prime;
			g = gnutls_srp_1536_group_generator;
			bits = 1536;
		} else if (bits <= 2048) {
			p = gnutls_srp_2048_group_prime;
			g = gnutls_srp_2048_group_generator;
			bits = 2048;
		} else if (bits <= 3072) {
			p = gnutls_srp_3072_group_prime;
			g = gnutls_srp_3072_group_generator;
			bits = 3072;
		} else {
			p = gnutls_srp_4096_group_prime;
			g = gnutls_srp_4096_group_generator;
			bits = 4096;
		}

		ret = gnutls_dh_params_import_raw(dh_params, &p, &g);
		if (ret < 0) {
			fprintf(stderr, "Error exporting parameters: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
#else
		fprintf(stderr,
			"Parameters unavailable as SRP is disabled.\n");
		exit(1);
#endif
	}

	print_dh_info(outfile, &p, &g, q_bits, info->cprint);

	if (!info->cprint) {	/* generate a PKCS#3 structure */
		size_t len = buffer_size;

		ret =
		    gnutls_dh_params_export_pkcs3(dh_params,
						  GNUTLS_X509_FMT_PEM,
						  buffer, &len);

		if (ret == 0) {
			fprintf(outfile, "\n%s", buffer);
		} else {
			fprintf(stderr, "Error: %s\n",
				gnutls_strerror(ret));
		}

	}

	gnutls_dh_params_deinit(dh_params);

	return 0;
}
Esempio n. 5
0
/* If how is zero then the included parameters are used.
 */
int
generate_prime (int bits, int how)
{
  unsigned int i;
  int ret;
  gnutls_dh_params dh_params;
  gnutls_datum p, g;

  gnutls_dh_params_init (&dh_params);

  fprintf (stderr, "Generating DH parameters...");

  if (how != 0)
    {
      ret = gnutls_dh_params_generate2 (dh_params, bits);
      if (ret < 0)
	{
	  fprintf (stderr, "Error generating parameters: %s\n",
		   gnutls_strerror (ret));
	  exit (1);
	}

      ret = gnutls_dh_params_export_raw (dh_params, &p, &g, NULL);
      if (ret < 0)
	{
	  fprintf (stderr, "Error exporting parameters: %s\n",
		   gnutls_strerror (ret));
	  exit (1);
	}
    }
  else
    {
#ifdef ENABLE_SRP
      if (bits <= 1024)
	{
	  p = gnutls_srp_1024_group_prime;
	  g = gnutls_srp_1024_group_generator;
	}
      else if (bits <= 1536)
	{
	  p = gnutls_srp_1536_group_prime;
	  g = gnutls_srp_1536_group_generator;
	}
      else
	{
	  p = gnutls_srp_2048_group_prime;
	  g = gnutls_srp_2048_group_generator;
	}

      ret = gnutls_dh_params_import_raw (dh_params, &p, &g);
      if (ret < 0)
	{
	  fprintf (stderr, "Error exporting parameters: %s\n",
		   gnutls_strerror (ret));
	  exit (1);
	}
#else
      fprintf (stderr, "Parameters unavailable as SRP disabled.\n");
#endif
    }

  if (cparams)
    {

      fprintf (outfile, "/* generator */\n");
      fprintf (outfile, "\nconst uint8 g[%d] = { ", g.size);

      for (i = 0; i < g.size; i++)
	{
	  if (i % 7 == 0)
	    fprintf (outfile, "\n\t");
	  fprintf (outfile, "0x%.2x", g.data[i]);
	  if (i != g.size - 1)
	    fprintf (outfile, ", ");
	}

      fprintf (outfile, "\n};\n\n");
    }
  else
    {
      fprintf (outfile, "\nGenerator: ");

      for (i = 0; i < g.size; i++)
	{
	  if (i != 0 && i % 12 == 0)
	    fprintf (outfile, "\n\t");
	  else if (i != 0 && i != g.size)
	    fprintf (outfile, ":");

	  fprintf (outfile, "%.2x", g.data[i]);
	}

      fprintf (outfile, "\n\n");
    }

  /* print prime */

  if (cparams)
    {
      fprintf (outfile, "/* prime - %d bits */\n", p.size * 8);
      fprintf (outfile, "\nconst uint8 prime[%d] = { ", p.size);

      for (i = 0; i < p.size; i++)
	{
	  if (i % 7 == 0)
	    fprintf (outfile, "\n\t");
	  fprintf (outfile, "0x%.2x", p.data[i]);
	  if (i != p.size - 1)
	    fprintf (outfile, ", ");
	}

      fprintf (outfile, "\n};\n");
    }
  else
    {
      fprintf (outfile, "Prime: ");

      for (i = 0; i < p.size; i++)
	{
	  if (i != 0 && i % 12 == 0)
	    fprintf (outfile, "\n\t");
	  else if (i != 0 && i != p.size)
	    fprintf (outfile, ":");
	  fprintf (outfile, "%.2x", p.data[i]);
	}

      fprintf (outfile, "\n\n");

    }

  if (!cparams)
    {				/* generate a PKCS#3 structure */

      int ret;
      size_t len = buffer_size;

      ret = gnutls_dh_params_export_pkcs3 (dh_params, GNUTLS_X509_FMT_PEM,
					   buffer, &len);

      if (ret == 0)
	{
	  fprintf (outfile, "\n%s", buffer);
	}
      else
	{
	  fprintf (stderr, "Error: %s\n", gnutls_strerror (ret));
	}

    }

  return 0;
}
Esempio n. 6
0
static void
print_dh_info (gnutls_session_t session, const char *str, int print)
{
    printf ("- %sDiffie-Hellman parameters\n", str);
    printf (" - Using prime: %d bits\n",
            gnutls_dh_get_prime_bits (session));
    printf (" - Secret key: %d bits\n",
            gnutls_dh_get_secret_bits (session));
    printf (" - Peer's public key: %d bits\n",
            gnutls_dh_get_peers_public_bits (session));

    if (print)
      {
          int ret;
          gnutls_datum_t raw_gen = { NULL, 0 };
          gnutls_datum_t raw_prime = { NULL, 0 };
          gnutls_dh_params_t dh_params = NULL;
          unsigned char *params_data = NULL;
          size_t params_data_size = 0;

          ret = gnutls_dh_get_group (session, &raw_gen, &raw_prime);
          if (ret)
            {
                fprintf (stderr, "gnutls_dh_get_group %d\n", ret);
                goto out;
            }

          ret = gnutls_dh_params_init (&dh_params);
          if (ret)
            {
                fprintf (stderr, "gnutls_dh_params_init %d\n", ret);
                goto out;
            }

          ret =
              gnutls_dh_params_import_raw (dh_params, &raw_prime,
                                           &raw_gen);
          if (ret)
            {
                fprintf (stderr, "gnutls_dh_params_import_raw %d\n", ret);
                goto out;
            }

          ret = gnutls_dh_params_export_pkcs3 (dh_params,
                                               GNUTLS_X509_FMT_PEM,
                                               params_data,
                                               &params_data_size);
          if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
            {
                fprintf (stderr, "gnutls_dh_params_export_pkcs3 %d\n",
                         ret);
                goto out;
            }

          params_data = gnutls_malloc (params_data_size);
          if (!params_data)
            {
                fprintf (stderr, "gnutls_malloc %d\n", ret);
                goto out;
            }

          ret = gnutls_dh_params_export_pkcs3 (dh_params,
                                               GNUTLS_X509_FMT_PEM,
                                               params_data,
                                               &params_data_size);
          if (ret)
            {
                fprintf (stderr, "gnutls_dh_params_export_pkcs3-2 %d\n",
                         ret);
                goto out;
            }

          printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size,
                  params_data);

        out:
          gnutls_free (params_data);
          gnutls_free (raw_prime.data);
          gnutls_free (raw_gen.data);
          gnutls_dh_params_deinit (dh_params);
      }
}
Esempio n. 7
0
File: tls-gnu.c Progetto: fanf2/exim
static int
init_dh(host_item *host)
{
int fd;
int ret;
gnutls_datum m;
uschar filename[200];

/* Initialize the data structures for holding the parameters */

ret = gnutls_dh_params_init(&dh_params);
if (ret < 0) return tls_error(US"init dh_params", host, gnutls_strerror(ret));

/* Set up the name of the cache file */

if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
      spool_directory))
  return tls_error(US"overlong filename", host, NULL);

/* Open the cache file for reading and if successful, read it and set up the
parameters. */

fd = Uopen(filename, O_RDONLY, 0);
if (fd >= 0)
  {
  struct stat statbuf;
  if (fstat(fd, &statbuf) < 0)
    {
    (void)close(fd);
    return tls_error(US"TLS cache stat failed", host, strerror(errno));
    }

  m.size = statbuf.st_size;
  m.data = malloc(m.size);
  if (m.data == NULL)
    return tls_error(US"memory allocation failed", host, strerror(errno));
  errno = 0;
  if (read(fd, m.data, m.size) != m.size)
    return tls_error(US"TLS cache read failed", host, strerror(errno));
  (void)close(fd);

  ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
  if (ret < 0)
    return tls_error(US"DH params import", host, gnutls_strerror(ret));
  DEBUG(D_tls) debug_printf("read D-H parameters from file\n");

  free(m.data);
  }

/* If the file does not exist, fall through to compute new data and cache it.
If there was any other opening error, it is serious. */

else if (errno == ENOENT)
  {
  ret = -1;
  DEBUG(D_tls)
    debug_printf("parameter cache file %s does not exist\n", filename);
  }
else
  return tls_error(string_open_failed(errno, "%s for reading", filename),
    host, NULL);

/* If ret < 0, either the cache file does not exist, or the data it contains
is not useful. One particular case of this is when upgrading from an older
release of Exim in which the data was stored in a different format. We don't
try to be clever and support both formats; we just regenerate new data in this
case. */

if (ret < 0)
  {
  uschar tempfilename[sizeof(filename) + 10];

  DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
    DH_BITS);
  ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
  if (ret < 0) return tls_error(US"D-H key generation", host, gnutls_strerror(ret));

  /* Write the parameters to a file in the spool directory so that we
  can use them from other Exim processes. */

  sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
  fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
  if (fd < 0)
    return tls_error(string_open_failed(errno, "%s for writing", filename),
      host, NULL);
  (void)fchown(fd, exim_uid, exim_gid);   /* Probably not necessary */

  /* export the parameters in a format that can be generated using GNUTLS'
   * certtool or other programs.
   *
   * The commands for certtool are:
   * $ certtool --generate-dh-params --bits 1024 > params
   */

  m.size = PARAM_SIZE;
  m.data = malloc(m.size);
  if (m.data == NULL)
    return tls_error(US"memory allocation failed", host, strerror(errno));

  m.size = PARAM_SIZE;
  ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
    &m.size);
  if (ret < 0)
    return tls_error(US"DH params export", host, gnutls_strerror(ret));

  m.size = Ustrlen(m.data);
  errno = 0;
  if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
    return tls_error(US"TLS cache write failed", host, strerror(errno));

  free(m.data);
  (void)close(fd);

  if (rename(CS tempfilename, CS filename) < 0)
    return tls_error(string_sprintf("failed to rename %s as %s",
      tempfilename, filename), host, strerror(errno));

  DEBUG(D_tls) debug_printf("wrote D-H parameters to file %s\n", filename);
  }

DEBUG(D_tls) debug_printf("initialized D-H parameters\n");
return OK;
}
Esempio n. 8
0
/* If how is zero then the included parameters are used.
 */
int generate_prime(FILE * outfile, int how, common_info_st * info)
{
	int ret;
	gnutls_dh_params_t dh_params;
	gnutls_datum_t p, g;
	int bits = get_bits(GNUTLS_PK_DH, info->bits, info->sec_param, 1);
	unsigned int q_bits = 0, key_bits = 0;

	fix_lbuffer(0);

	gnutls_dh_params_init(&dh_params);

	if (how != 0) {
		fprintf(stderr, "Generating DH parameters (%d bits)...\n",
			bits);
		fprintf(stderr, "(might take long time)\n");
	} else
		fprintf(stderr, "Retrieving DH parameters...\n");

	if (how != 0) {
		if (info->provable != 0) {
			gnutls_x509_privkey_t pkey;
			unsigned save;

			ret = gnutls_x509_privkey_init(&pkey);
			if (ret < 0) {
				fprintf(stderr,
					"Error initializing key: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			if (info->seed_size > 0) {
				gnutls_keygen_data_st data;

				if (info->seed_size < 32) {
					fprintf(stderr, "For DH parameter generation a 32-byte seed value or larger is expected (have: %d); use -d 2 for more information.\n", (int)info->seed_size);
					exit(1);
				}

				data.type = GNUTLS_KEYGEN_SEED;
				data.data = (void*)info->seed;
				data.size = info->seed_size;

				ret = gnutls_x509_privkey_generate2(pkey, GNUTLS_PK_DSA, bits, GNUTLS_PRIVKEY_FLAG_PROVABLE, &data, 1);
			} else {
				ret = gnutls_x509_privkey_generate(pkey, GNUTLS_PK_DSA, bits, GNUTLS_PRIVKEY_FLAG_PROVABLE);
			}

			if (ret < 0) {
				fprintf(stderr,
					"Error generating DSA parameters: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			if (info->outcert_format == GNUTLS_X509_FMT_PEM) {
				save = info->no_compat;
				info->no_compat = 1;
				print_private_key(outfile, info, pkey);
				info->no_compat = save;
			}

			ret = gnutls_dh_params_import_dsa(dh_params, pkey);
			if (ret < 0) {
				fprintf(stderr,
					"Error importing DSA parameters: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			gnutls_x509_privkey_deinit(pkey);
		} else {
			ret = gnutls_dh_params_generate2(dh_params, bits);
			if (ret < 0) {
				fprintf(stderr,
					"Error generating parameters: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}
		}

		ret =
		    gnutls_dh_params_export_raw(dh_params, &p, &g,
						&q_bits);
		if (ret < 0) {
			fprintf(stderr, "Error exporting parameters: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
	} else {
		if (info->provable != 0) {
			fprintf(stderr, "The DH parameters obtained via this option are not provable\n");
			exit(1);
		}
#if defined(ENABLE_DHE) || defined(ENABLE_ANON)
		if (bits <= 2048) {
			p = gnutls_ffdhe_2048_group_prime;
			g = gnutls_ffdhe_2048_group_generator;
			key_bits = gnutls_ffdhe_2048_key_bits;
			bits = 2048;
		} else if (bits <= 3072) {
			p = gnutls_ffdhe_3072_group_prime;
			g = gnutls_ffdhe_3072_group_generator;
			key_bits = gnutls_ffdhe_3072_key_bits;
			bits = 3072;
		} else if (bits <= 4096) {
			p = gnutls_ffdhe_4096_group_prime;
			g = gnutls_ffdhe_4096_group_generator;
			key_bits = gnutls_ffdhe_4096_key_bits;
			bits = 4096;
		} else {
			p = gnutls_ffdhe_8192_group_prime;
			g = gnutls_ffdhe_8192_group_generator;
			key_bits = gnutls_ffdhe_8192_key_bits;
			bits = 8192;
		}

		ret = gnutls_dh_params_import_raw2(dh_params, &p, &g, key_bits);
		if (ret < 0) {
			fprintf(stderr, "Error exporting parameters: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
#elif defined(ENABLE_SRP)
		if (bits <= 1024) {
			p = gnutls_srp_1024_group_prime;
			g = gnutls_srp_1024_group_generator;
			bits = 1024;
		} else if (bits <= 1536) {
			p = gnutls_srp_1536_group_prime;
			g = gnutls_srp_1536_group_generator;
			bits = 1536;
		} else if (bits <= 2048) {
			p = gnutls_srp_2048_group_prime;
			g = gnutls_srp_2048_group_generator;
			bits = 2048;
		} else if (bits <= 3072) {
			p = gnutls_srp_3072_group_prime;
			g = gnutls_srp_3072_group_generator;
			bits = 3072;
		} else {
			p = gnutls_srp_4096_group_prime;
			g = gnutls_srp_4096_group_generator;
			bits = 4096;
		}

		ret = gnutls_dh_params_import_raw(dh_params, &p, &g);
		if (ret < 0) {
			fprintf(stderr, "Error exporting parameters: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
#else
		fprintf(stderr,
			"Parameters unavailable as SRP is disabled.\n");
		exit(1);
#endif
	}

	if (info->outcert_format == GNUTLS_X509_FMT_PEM)
		print_dh_info(outfile, &p, &g, q_bits, info->cprint);

	if (!info->cprint) {	/* generate a PKCS#3 structure */
		size_t len = lbuffer_size;

		ret =
		    gnutls_dh_params_export_pkcs3(dh_params,
						  info->outcert_format,
						  lbuffer, &len);

		if (ret == 0) {
			if (info->outcert_format == GNUTLS_X509_FMT_PEM)
				fprintf(outfile, "\n%s", lbuffer);
			else
				fwrite(lbuffer, 1, len, outfile);

		} else {
			fprintf(stderr, "Error: %s\n",
				gnutls_strerror(ret));
		}

	}

	if (how != 0) {
		gnutls_free(p.data);
		gnutls_free(g.data);
	}

	gnutls_dh_params_deinit(dh_params);

	return 0;
}