Exemple #1
0
void
print_private_key(FILE *outfile, common_info_st * cinfo, gnutls_x509_privkey_t key)
{
	int ret;
	size_t size;

	if (!key)
		return;

	if (!cinfo->pkcs8) {
		/* Only print private key parameters when an unencrypted
		 * format is used */
		if (cinfo->outcert_format == GNUTLS_X509_FMT_PEM)
			privkey_info_int(outfile, cinfo, key);

		size = lbuffer_size;
		ret = gnutls_x509_privkey_export(key, cinfo->outcert_format,
						 lbuffer, &size);
		if (ret < 0) {
			fprintf(stderr, "privkey_export: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (cinfo->no_compat == 0 && gnutls_x509_privkey_get_seed(key, NULL, NULL, 0) != GNUTLS_E_INVALID_REQUEST) {
			gnutls_x509_privkey_set_flags(key, GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT);

			fwrite(lbuffer, 1, size, outfile);

			size = lbuffer_size;
			ret = gnutls_x509_privkey_export(key, cinfo->outcert_format,
						 lbuffer, &size);
			if (ret < 0) {
				fprintf(stderr, "privkey_export: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}
		}

	} else {
		unsigned int flags = 0;
		const char *pass;

		pass = get_password(cinfo, &flags, 0);
		flags |= cipher_to_flags(cinfo->pkcs_cipher);

		size = lbuffer_size;
		ret =
		    gnutls_x509_privkey_export_pkcs8(key, cinfo->outcert_format,
						     pass, flags, lbuffer,
						     &size);
		if (ret < 0) {
			fprintf(stderr, "privkey_export_pkcs8: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
	}

	fwrite(lbuffer, 1, size, outfile);
}
static gnutls_x509_privkey gen_crypto(requiem_client_profile_t *cp,
                                      const char *filename, requiem_uid_t uid, requiem_gid_t gid)
{
        int ret;
        char buf[65535];
        gnutls_x509_privkey key;
        size_t size = sizeof(buf);

        key = generate_private_key();
        if ( ! key ) {
                fprintf(stderr, "error while generating RSA private key.\n");
                return NULL;
        }

        ret = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &size);
        if ( ret < 0 ) {
                fprintf(stderr, "error exporting private key: %s\n", gnutls_strerror(ret));
                gnutls_x509_privkey_deinit(key);
                return NULL;
        }

        ret = save_buf(filename, uid, gid, (unsigned char *) buf, size);
        if ( ret < 0 ) {
                fprintf(stderr, "error saving private key.\n");
                return NULL;
        }

        return key;
}
Exemple #3
0
/**
  * gnutls_rsa_params_export_pkcs1 - This function will export RSA params to a pkcs1 structure
  * @params: Holds the RSA parameters
  * @format: the format of output params. One of PEM or DER.
  * @params_data: will contain a PKCS1 RSAPublicKey structure PEM or DER encoded
  * @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
  *
  * This function will export the given RSA parameters to a PKCS1
  * RSAPublicKey structure. If the buffer provided is not long enough to 
  * hold the output, then GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
  *
  * If the structure is PEM encoded, it will have a header
  * of "BEGIN RSA PRIVATE KEY".
  *
  * In case of failure a negative value will be returned, and
  * 0 on success.
  *
  **/
int
gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params,
				gnutls_x509_crt_fmt_t format,
				unsigned char *params_data,
				size_t * params_data_size)
{
  return gnutls_x509_privkey_export (params, format,
				     params_data, params_data_size);
}
Exemple #4
0
/* 
   auto-generate a set of self signed certificates
*/
void tls_cert_generate(TALLOC_CTX *mem_ctx, 
		       const char *hostname, 
		       const char *keyfile, const char *certfile,
		       const char *cafile)
{
	gnutls_x509_crt cacrt, crt;
	gnutls_x509_privkey key, cakey;
	uint32_t serial = (uint32_t)time(NULL);
	unsigned char keyid[100];
	char buf[4096];
	size_t bufsize;
	size_t keyidsize = sizeof(keyid);
	time_t activation = time(NULL), expiry = activation + LIFETIME;
	int ret;

	if (file_exist(keyfile) || file_exist(certfile) || file_exist(cafile)) {
		DEBUG(0,("TLS autogeneration skipped - some TLS files already exist\n"));
		return;
	}

#define TLSCHECK(call) do { \
	ret = call; \
	if (ret < 0) { \
		DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \
		goto failed; \
	} \
} while (0)

	TLSCHECK(gnutls_global_init());

	DEBUG(0,("Attempting to autogenerate TLS self-signed keys for https for hostname '%s'\n", 
		 hostname));
	
#if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3)
	DEBUG(3,("Enabling QUICK mode in gcrypt\n"));
	gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#endif

	DEBUG(3,("Generating private key\n"));
	TLSCHECK(gnutls_x509_privkey_init(&key));
	TLSCHECK(gnutls_x509_privkey_generate(key,   GNUTLS_PK_RSA, RSA_BITS, 0));

	DEBUG(3,("Generating CA private key\n"));
	TLSCHECK(gnutls_x509_privkey_init(&cakey));
	TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0));

	DEBUG(3,("Generating CA certificate\n"));
	TLSCHECK(gnutls_x509_crt_init(&cacrt));
	TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 
				      GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
				      ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
	TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 
				      GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
				      CA_NAME, strlen(CA_NAME)));
	TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt,
				      GNUTLS_OID_X520_COMMON_NAME, 0,
				      hostname, strlen(hostname)));
	TLSCHECK(gnutls_x509_crt_set_key(cacrt, cakey));
	TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial)));
	TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation));
	TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry));
	TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1));
	TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN));
	TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3));
	TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize));
#if HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID
	TLSCHECK(gnutls_x509_crt_set_subject_key_id(cacrt, keyid, keyidsize));
#endif
	TLSCHECK(gnutls_x509_crt_sign2(cacrt, cacrt, cakey,
				       GNUTLS_DIG_SHA256, 0));

	DEBUG(3,("Generating TLS certificate\n"));
	TLSCHECK(gnutls_x509_crt_init(&crt));
	TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, 
				      GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
				      ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
	TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, 
				      GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
				      UNIT_NAME, strlen(UNIT_NAME)));
	TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt,
				      GNUTLS_OID_X520_COMMON_NAME, 0,
				      hostname, strlen(hostname)));
	TLSCHECK(gnutls_x509_crt_set_key(crt, key));
	TLSCHECK(gnutls_x509_crt_set_serial(crt, &serial, sizeof(serial)));
	TLSCHECK(gnutls_x509_crt_set_activation_time(crt, activation));
	TLSCHECK(gnutls_x509_crt_set_expiration_time(crt, expiry));
	TLSCHECK(gnutls_x509_crt_set_ca_status(crt, 0));
#ifdef GNUTLS_KP_TLS_WWW_SERVER
	TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0));
#endif
	TLSCHECK(gnutls_x509_crt_set_version(crt, 3));
	TLSCHECK(gnutls_x509_crt_get_key_id(crt, 0, keyid, &keyidsize));
#if HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID
	TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize));
#endif
	TLSCHECK(gnutls_x509_crt_sign2(crt, crt, key,
				       GNUTLS_DIG_SHA256, 0));
	TLSCHECK(gnutls_x509_crt_sign2(crt, cacrt, cakey,
				       GNUTLS_DIG_SHA256, 0));

	DEBUG(3,("Exporting TLS keys\n"));

	bufsize = sizeof(buf);
	TLSCHECK(gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
	if (!file_save(certfile, buf, bufsize)) {
		DEBUG(0,("Unable to save certificate in %s parent dir exists ?\n", certfile));
		goto failed;
	}

	bufsize = sizeof(buf);
	TLSCHECK(gnutls_x509_crt_export(cacrt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
	if (!file_save(cafile, buf, bufsize)) {
		DEBUG(0,("Unable to save ca cert in %s parent dir exists ?\n", cafile));
		goto failed;
	}

	bufsize = sizeof(buf);
	TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize));
	if (!file_save_mode(keyfile, buf, bufsize, 0600)) {
		DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile));
		goto failed;
	}

	gnutls_x509_privkey_deinit(key);
	gnutls_x509_privkey_deinit(cakey);
	gnutls_x509_crt_deinit(cacrt);
	gnutls_x509_crt_deinit(crt);
	gnutls_global_deinit();

	DEBUG(0,("TLS self-signed keys generated OK\n"));
	return;

failed:
	DEBUG(0,("TLS certificate generation failed\n"));
}
Exemple #5
0
void doit(void)
{
	gnutls_certificate_credentials_t x509_cred;
	int ret;
	unsigned int i;
	gnutls_x509_crt_t issuer;
	gnutls_x509_crt_t list[LIST_SIZE];
	char dn[128];
	size_t dn_size;
	unsigned int list_size;
	size_t buf_size;

	gnutls_x509_privkey_t get_key;
	gnutls_x509_crt_t *get_crts;
	unsigned n_get_crts;
	gnutls_datum_t get_datum, chain_datum[2] = {server_ca3_cert, subca3_cert};
	gnutls_x509_trust_list_t trust_list;
	gnutls_x509_trust_list_iter_t trust_iter;
	gnutls_x509_crt_t get_ca_crt;
	unsigned n_get_ca_crts;

	/* this must be called once in the program
	 */
	global_init();

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	gnutls_certificate_allocate_credentials(&x509_cred);
	gnutls_certificate_set_x509_trust_mem(x509_cred, &ca3_cert,
					      GNUTLS_X509_FMT_PEM);

	gnutls_certificate_set_x509_key_mem(x509_cred, &server_ca3_cert_chain,
					    &server_ca3_key,
					    GNUTLS_X509_FMT_PEM);

	/* test for gnutls_certificate_get_issuer() */

	/* check whether gnutls_x509_crt_list_import will fail if given a single
	 * certificate */
	list_size = LIST_SIZE;
	ret =
	    gnutls_x509_crt_list_import(list, &list_size, &ca3_cert,
					GNUTLS_X509_FMT_PEM,
					GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0)
		fail("gnutls_x509_crt_list_import (failed with a single cert)");
	gnutls_x509_crt_deinit(list[0]);

	list_size = LIST_SIZE;
	ret =
	    gnutls_x509_crt_list_import(list, &list_size, &cli_ca3_cert_chain,
					GNUTLS_X509_FMT_PEM,
					GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0)
		fail("gnutls_x509_crt_list_import");

	ret =
	    gnutls_certificate_get_issuer(x509_cred, list[list_size-1], &issuer, 0);
	if (ret < 0)
		fail("gnutls_certificate_get_isser");

	ret =
	    gnutls_certificate_get_issuer(x509_cred, list[list_size-1], &issuer, GNUTLS_TL_GET_COPY);
	if (ret < 0)
		fail("gnutls_certificate_get_isser");

	dn_size = sizeof(dn);
	ret = gnutls_x509_crt_get_dn(issuer, dn, &dn_size);
	if (ret < 0)
		fail("gnutls_certificate_get_dn");
	gnutls_x509_crt_deinit(issuer);

	if (dn_size != strlen(dn)) {
		fail("gnutls_x509_crt_get_dn: lengths don't match\n");
		exit(1);
	}

	if (debug)
		fprintf(stderr, "Issuer's DN: %s\n", dn);

	/* test the getter functions of gnutls_certificate_credentials_t */

	ret =
	    gnutls_certificate_get_x509_key(x509_cred, 0, &get_key);
	if (ret < 0)
		fail("gnutls_certificate_get_x509_key");

	ret =
	    gnutls_x509_privkey_export2(get_key,
					GNUTLS_X509_FMT_PEM,
					&get_datum);
	if (ret < 0)
		fail("gnutls_x509_privkey_export2");

	if (get_datum.size != server_ca3_key.size ||
	    memcmp(get_datum.data, server_ca3_key.data, get_datum.size) != 0) {
		fail(
		    "exported key %u vs. %u\n\n%s\n\nvs.\n\n%s",
		    get_datum.size, server_ca3_key.size,
		    get_datum.data, server_ca3_key.data);
	}

	if (strlen((char*)get_datum.data) != get_datum.size) {
		fail("exported key %u vs. %u\n\n%s\n",
		     get_datum.size, (unsigned)strlen((char*)get_datum.data),
		     get_datum.data);
	}

	gnutls_free(get_datum.data);

	buf_size = sizeof(buf);
	ret =
	    gnutls_x509_privkey_export(get_key,
					GNUTLS_X509_FMT_PEM,
					buf, &buf_size);
	if (ret < 0)
		fail("gnutls_x509_privkey_export");

	if (buf_size != get_datum.size ||
	    buf_size != strlen(buf) ||
	    memcmp(buf, server_ca3_key.data, buf_size) != 0) {
		fail(
		    "exported key %u vs. %u\n\n%s\n\nvs.\n\n%s",
		    (int)buf_size, server_ca3_key.size,
		    buf, server_ca3_key.data);
	}

	ret =
	    gnutls_certificate_get_x509_crt(x509_cred, 0, &get_crts, &n_get_crts);
	if (ret < 0)
		fail("gnutls_certificate_get_x509_crt");
	if (n_get_crts != 2)
		fail("gnutls_certificate_get_x509_crt: n_crts != 2");

	for (i = 0; i < n_get_crts; i++) {
		ret =
			gnutls_x509_crt_export2(get_crts[i],
						GNUTLS_X509_FMT_PEM,
						&get_datum);
		if (ret < 0)
			fail("gnutls_x509_crt_export2");

		if (get_datum.size != chain_datum[i].size ||
		    memcmp(get_datum.data, chain_datum[i].data, get_datum.size) != 0) {
			fail(
				"exported certificate %u vs. %u\n\n%s\n\nvs.\n\n%s",
				get_datum.size, chain_datum[i].size,
				get_datum.data, chain_datum[i].data);
		}

		gnutls_free(get_datum.data);
	}

	gnutls_certificate_get_trust_list(x509_cred, &trust_list);

	n_get_ca_crts = 0;
	trust_iter = NULL;
	while (gnutls_x509_trust_list_iter_get_ca(trust_list,
						  &trust_iter,
						  &get_ca_crt) !=
		GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		ret =
		    gnutls_x509_crt_export2(get_ca_crt,
					    GNUTLS_X509_FMT_PEM,
					    &get_datum);
		if (ret < 0)
			fail("gnutls_x509_crt_export2");

		if (get_datum.size != ca3_cert.size ||
		    memcmp(get_datum.data, ca3_cert.data, get_datum.size) != 0) {
			fail(
			    "exported CA certificate %u vs. %u\n\n%s\n\nvs.\n\n%s",
			    get_datum.size, ca3_cert.size,
			    get_datum.data, ca3_cert.data);
		}

		gnutls_x509_crt_deinit(get_ca_crt);
		gnutls_free(get_datum.data);

		++n_get_ca_crts;
	}

	if (n_get_ca_crts != 1)
		fail("gnutls_x509_trust_list_iter_get_ca: n_cas != 1");
	if (trust_iter != NULL)
		fail("gnutls_x509_trust_list_iter_get_ca: iterator not NULL after iteration");

	gnutls_x509_privkey_deinit(get_key);
	for (i = 0; i < n_get_crts; i++)
		gnutls_x509_crt_deinit(get_crts[i]);
	gnutls_free(get_crts);

	for (i = 0; i < list_size; i++)
		gnutls_x509_crt_deinit(list[i]);
	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("success");
}
Exemple #6
0
/**
 * epc_tls_private_key_save:
 * @key: a private X.509 key
 * @filename: name of a file to write the private key to, in the GLib file name encoding
 * @error: return location for a #GError, or %NULL
 *
 * Writes a PEM encoded private X.509 key.
 *
 * If the call was successful, it returns %TRUE. If the call was not
 * successful, it returns %FALSE and sets @error. The error domain is
 * #EPC_TLS_ERROR. Error codes are taken from the <citetitle>GNU
 * TLS</citetitle> library.
 *
 * Returns: %TRUE on successful, %FALSE if an error occured
 */
gboolean
epc_tls_private_key_save (gnutls_x509_privkey_t  key,
                          const gchar           *filename,
                          GError               **error)
{
  gint rc = GNUTLS_E_SUCCESS;
  gchar *display_name = NULL;
  guchar *contents = NULL;
  gchar *dirname = NULL;
  gsize length = 0;
  gint fd = -1;

  g_return_val_if_fail (NULL != key, FALSE);
  g_return_val_if_fail (NULL != filename, FALSE);

  if (EPC_DEBUG_LEVEL (1))
    g_debug ("%s: Writing server key `%s'", G_STRLOC, filename);

  rc = gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, NULL, &length);
  g_assert (GNUTLS_E_SHORT_MEMORY_BUFFER == rc);

  contents = g_malloc (length);

  if (GNUTLS_E_SUCCESS != (rc =
      gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, contents, &length)))
    {
      g_set_error (error, EPC_TLS_ERROR, rc,
                   _("Cannot export private key to PEM format: %s"),
                   gnutls_strerror (rc));

      goto out;
    }

  if (g_mkdir_with_parents (dirname = g_path_get_dirname (filename), 0700))
    {
      display_name = g_filename_display_name (dirname);
      rc = GNUTLS_E_FILE_ERROR;

      g_set_error (error,
                   G_FILE_ERROR,
                   g_file_error_from_errno (errno),
                   _("Failed to create private key folder '%s': %s"),
                   display_name, g_strerror (errno));

      goto out;
    }

  fd = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);

  if (-1 == fd)
    {
      display_name = g_filename_display_name (filename);
      rc = GNUTLS_E_FILE_ERROR;

      g_set_error (error,
                   G_FILE_ERROR,
                   g_file_error_from_errno (errno),
                   _("Failed to create private key file '%s': %s"),
                   display_name, g_strerror (errno));

      goto out;
    }

  if (write (fd, contents, length) < (gssize)length)
    {
      display_name = g_filename_display_name (filename);
      rc = GNUTLS_E_FILE_ERROR;

      g_set_error (error,
                   G_FILE_ERROR,
                   g_file_error_from_errno (errno),
                   _("Failed to write private key file '%s': %s"),
                   display_name, g_strerror (errno));

      goto out;
    }

out:
  if (-1 != fd)
    close (fd);

  if (GNUTLS_E_SUCCESS != rc)
    g_unlink (filename);

  g_free (display_name);
  g_free (contents);
  g_free (dirname);

  return (GNUTLS_E_SUCCESS == rc);
}
static int				/* O - 1 on success, 0 on failure */
make_certificate(cupsd_client_t *con)	/* I - Client connection */
{
  gnutls_x509_crt	crt;		/* Self-signed certificate */
  gnutls_x509_privkey	key;		/* Encryption key */
  cups_lang_t		*language;	/* Default language info */
  cups_file_t		*fp;		/* Key/cert file */
  unsigned char		buffer[8192];	/* Buffer for x509 data */
  size_t		bytes;		/* Number of bytes of data */
  unsigned char		serial[4];	/* Serial number buffer */
  time_t		curtime;	/* Current time */
  int			result;		/* Result of GNU TLS calls */


 /*
  * Create the encryption key...
  */

  cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key...");

  gnutls_x509_privkey_init(&key);
  gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0);

 /*
  * Save it...
  */

  bytes = sizeof(buffer);

  if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM,
                                           buffer, &bytes)) < 0)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s",
                    gnutls_strerror(result));
    gnutls_x509_privkey_deinit(key);
    return (0);
  }
  else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL)
  {
    cupsFileWrite(fp, (char *)buffer, bytes);
    cupsFileClose(fp);

    cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...",
		    ServerKey);
  }
  else
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to create SSL server key file \"%s\" - %s",
		    ServerKey, strerror(errno));
    gnutls_x509_privkey_deinit(key);
    return (0);
  }

 /*
  * Create the self-signed certificate...
  */

  cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate...");

  language  = cupsLangDefault();
  curtime   = time(NULL);
  serial[0] = curtime >> 24;
  serial[1] = curtime >> 16;
  serial[2] = curtime >> 8;
  serial[3] = curtime;

  gnutls_x509_crt_init(&crt);
  if (strlen(language->language) == 5)
    gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
                                  language->language + 3, 2);
  else
    gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
                                  "US", 2);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0,
                                ServerName, strlen(ServerName));
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
                                ServerName, strlen(ServerName));
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
                                0, "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0,
                                "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0,
                                "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0,
                                ServerAdmin, strlen(ServerAdmin));
  gnutls_x509_crt_set_key(crt, key);
  gnutls_x509_crt_set_serial(crt, serial, sizeof(serial));
  gnutls_x509_crt_set_activation_time(crt, curtime);
  gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400);
  gnutls_x509_crt_set_ca_status(crt, 0);
  gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME,
                                               ServerName);
  gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0);
  gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT);
  gnutls_x509_crt_set_version(crt, 3);

  bytes = sizeof(buffer);
  if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0)
    gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes);

  gnutls_x509_crt_sign(crt, crt, key);

 /*
  * Save it...
  */

  bytes = sizeof(buffer);
  if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM,
                                       buffer, &bytes)) < 0)
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to export SSL server certificate - %s",
		    gnutls_strerror(result));
  else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL)
  {
    cupsFileWrite(fp, (char *)buffer, bytes);
    cupsFileClose(fp);

    cupsdLogMessage(CUPSD_LOG_INFO,
                    "Created SSL server certificate file \"%s\"...",
		    ServerCertificate);
  }
  else
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to create SSL server certificate file \"%s\" - %s",
		    ServerCertificate, strerror(errno));

 /*
  * Cleanup...
  */

  gnutls_x509_crt_deinit(crt);
  gnutls_x509_privkey_deinit(key);

  return (1);
}
Exemple #8
0
/** Private function which generate private keys and certificates.
 *
 * @return 1 if keys were successfully generated, 0 otherwise
 */
static userpref_error_t userpref_gen_keys_and_cert(void)
{
	userpref_error_t ret = USERPREF_E_SSL_ERROR;

	gnutls_x509_privkey_t root_privkey;
	gnutls_x509_crt_t root_cert;
	gnutls_x509_privkey_t host_privkey;
	gnutls_x509_crt_t host_cert;

	gnutls_global_deinit();
	gnutls_global_init();

	//use less secure random to speed up key generation
	gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM);

	gnutls_x509_privkey_init(&root_privkey);
	gnutls_x509_privkey_init(&host_privkey);

	gnutls_x509_crt_init(&root_cert);
	gnutls_x509_crt_init(&host_cert);

	/* generate root key */
	gnutls_x509_privkey_generate(root_privkey, GNUTLS_PK_RSA, 2048, 0);
	gnutls_x509_privkey_generate(host_privkey, GNUTLS_PK_RSA, 2048, 0);

	/* generate certificates */
	gnutls_x509_crt_set_key(root_cert, root_privkey);
	gnutls_x509_crt_set_serial(root_cert, "\x00", 1);
	gnutls_x509_crt_set_version(root_cert, 3);
	gnutls_x509_crt_set_ca_status(root_cert, 1);
	gnutls_x509_crt_set_activation_time(root_cert, time(NULL));
	gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
	gnutls_x509_crt_sign(root_cert, root_cert, root_privkey);

	gnutls_x509_crt_set_key(host_cert, host_privkey);
	gnutls_x509_crt_set_serial(host_cert, "\x00", 1);
	gnutls_x509_crt_set_version(host_cert, 3);
	gnutls_x509_crt_set_ca_status(host_cert, 0);
	gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE);
	gnutls_x509_crt_set_activation_time(host_cert, time(NULL));
	gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
	gnutls_x509_crt_sign(host_cert, root_cert, root_privkey);

	/* export to PEM format */
	size_t root_key_export_size = 0;
	size_t host_key_export_size = 0;
	gnutls_datum_t root_key_pem = { NULL, 0 };
	gnutls_datum_t host_key_pem = { NULL, 0 };

	gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, NULL, &root_key_export_size);
	gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, NULL, &host_key_export_size);

	root_key_pem.data = gnutls_malloc(root_key_export_size);
	host_key_pem.data = gnutls_malloc(host_key_export_size);

	gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, root_key_pem.data, &root_key_export_size);
	root_key_pem.size = root_key_export_size;
	gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, host_key_pem.data, &host_key_export_size);
	host_key_pem.size = host_key_export_size;

	size_t root_cert_export_size = 0;
	size_t host_cert_export_size = 0;
	gnutls_datum_t root_cert_pem = { NULL, 0 };
	gnutls_datum_t host_cert_pem = { NULL, 0 };

	gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, NULL, &root_cert_export_size);
	gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, NULL, &host_cert_export_size);

	root_cert_pem.data = gnutls_malloc(root_cert_export_size);
	host_cert_pem.data = gnutls_malloc(host_cert_export_size);

	gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, root_cert_pem.data, &root_cert_export_size);
	root_cert_pem.size = root_cert_export_size;
	gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_export_size);
	host_cert_pem.size = host_cert_export_size;

	if (NULL != root_cert_pem.data && 0 != root_cert_pem.size &&
		NULL != host_cert_pem.data && 0 != host_cert_pem.size)
		ret = USERPREF_E_SUCCESS;

	/* store values in config file */
	userpref_set_keys_and_certs( &root_key_pem, &root_cert_pem, &host_key_pem, &host_cert_pem);

	gnutls_free(root_key_pem.data);
	gnutls_free(root_cert_pem.data);
	gnutls_free(host_key_pem.data);
	gnutls_free(host_cert_pem.data);

	//restore gnutls env
	gnutls_global_deinit();
	gnutls_global_init();

	return ret;
}
static void
inf_test_certificate_request_finished_cb(InfRequest* request,
                                         const InfRequestResult* result,
                                         const GError* error,
                                         gpointer user_data)
{
  InfTestCertificateRequest* test;
  InfCertificateChain* chain;
  guint n_certs;
  guint i;
  gnutls_datum_t datum;

  gnutls_x509_crt_t cert;
  size_t cert_size;
  gchar* cert_pem;

  test = (InfTestCertificateRequest*)user_data;

  if(error != NULL)
  {
    fprintf(stderr, "Error: %s\n", error->message);
  }
  else
  {
    fprintf(stderr, "Certificate generated!\n\n");
    inf_request_result_get_create_acl_account(result, NULL, NULL, &chain);

    n_certs = inf_certificate_chain_get_n_certificates(chain);
    for(i = 0; i < n_certs; ++i)
    {
      fprintf(stderr, "Certificate %d", i);
      if(i == 0) fprintf(stderr, " (own)");
      if(i == 1) fprintf(stderr, " (issuer)");
      if(i == n_certs - 1) fprintf(stderr, " (CA)");
      fprintf(stderr, ":\n\n");

      cert = inf_certificate_chain_get_nth_certificate(chain, i);
      gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &datum);

      fprintf(stderr, "%s\n", datum.data);

      gnutls_free(datum.data);
    }

    for(i = 0; i < n_certs; ++i)
    {
      cert = inf_certificate_chain_get_nth_certificate(chain, i);
      cert_size = 0;
      gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, NULL, &cert_size);
      cert_pem = g_malloc(cert_size);
      gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, cert_pem, &cert_size);
      printf("%s\n\n", cert_pem);
      g_free(cert_pem);
    }

    cert_size = 0;
    gnutls_x509_privkey_export(
      test->key,
      GNUTLS_X509_FMT_PEM,
      NULL,
      &cert_size
    );

    cert_pem = g_malloc(cert_size);

    gnutls_x509_privkey_export(
      test->key,
      GNUTLS_X509_FMT_PEM,
      cert_pem,
      &cert_size
    );

    printf("%s\n", cert_pem);
    g_free(cert_pem);
  }

  if(inf_standalone_io_loop_running(test->io))
    inf_standalone_io_loop_quit(test->io);
}
Exemple #10
0
int
main (void)
{
  gnutls_x509_crq_t crq;
  gnutls_x509_privkey_t key;
  unsigned char buffer[10 * 1024];
  size_t buffer_size = sizeof (buffer);
  unsigned int bits;

  gnutls_global_init ();

  /* Initialize an empty certificate request, and
   * an empty private key.
   */
  gnutls_x509_crq_init (&crq);

  gnutls_x509_privkey_init (&key);

  /* Generate an RSA key of moderate security.
   */
  bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_NORMAL);
  gnutls_x509_privkey_generate (key, GNUTLS_PK_RSA, bits, 0);

  /* Add stuff to the distinguished name
   */
  gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COUNTRY_NAME,
                                 0, "GR", 2);

  gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME,
                                 0, "Nikos", strlen ("Nikos"));

  /* Set the request version.
   */
  gnutls_x509_crq_set_version (crq, 1);

  /* Set a challenge password.
   */
  gnutls_x509_crq_set_challenge_password (crq, "something to remember here");

  /* Associate the request with the private key
   */
  gnutls_x509_crq_set_key (crq, key);

  /* Self sign the certificate request.
   */
  gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);

  /* Export the PEM encoded certificate request, and
   * display it.
   */
  gnutls_x509_crq_export (crq, GNUTLS_X509_FMT_PEM, buffer, &buffer_size);

  printf ("Certificate Request: \n%s", buffer);


  /* Export the PEM encoded private key, and
   * display it.
   */
  buffer_size = sizeof (buffer);
  gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &buffer_size);

  printf ("\n\nPrivate key: \n%s", buffer);

  gnutls_x509_crq_deinit (crq);
  gnutls_x509_privkey_deinit (key);

  return 0;

}
Exemple #11
0
int					/* O - 1 on success, 0 on failure */
cupsMakeServerCredentials(
    const char *path,			/* I - Path to keychain/directory */
    const char *common_name,		/* I - Common name */
    int        num_alt_names,		/* I - Number of subject alternate names */
    const char **alt_names,		/* I - Subject Alternate Names */
    time_t     expiration_date)		/* I - Expiration date */
{
  gnutls_x509_crt_t	crt;		/* Self-signed certificate */
  gnutls_x509_privkey_t	key;		/* Encryption private key */
  char			temp[1024],	/* Temporary directory name */
 			crtfile[1024],	/* Certificate filename */
			keyfile[1024];	/* Private key filename */
  cups_lang_t		*language;	/* Default language info */
  cups_file_t		*fp;		/* Key/cert file */
  unsigned char		buffer[8192];	/* Buffer for x509 data */
  size_t		bytes;		/* Number of bytes of data */
  unsigned char		serial[4];	/* Serial number buffer */
  time_t		curtime;	/* Current time */
  int			result;		/* Result of GNU TLS calls */


  DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date));

 /*
  * Filenames...
  */

  if (!path)
    path = http_gnutls_default_path(temp, sizeof(temp));

  if (!path || !common_name)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  http_gnutls_make_path(crtfile, sizeof(crtfile), path, common_name, "crt");
  http_gnutls_make_path(keyfile, sizeof(keyfile), path, common_name, "key");

 /*
  * Create the encryption key...
  */

  DEBUG_puts("1cupsMakeServerCredentials: Creating key pair.");

  gnutls_x509_privkey_init(&key);
  gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0);

  DEBUG_puts("1cupsMakeServerCredentials: Key pair created.");

 /*
  * Save it...
  */

  bytes = sizeof(buffer);

  if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to export private key: %s", gnutls_strerror(result)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(result), 0);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }
  else if ((fp = cupsFileOpen(keyfile, "w")) != NULL)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Writing private key to \"%s\".", keyfile));
    cupsFileWrite(fp, (char *)buffer, bytes);
    cupsFileClose(fp);
  }
  else
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to create private key file \"%s\": %s", keyfile, strerror(errno)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }

 /*
  * Create the self-signed certificate...
  */

  DEBUG_puts("1cupsMakeServerCredentials: Generating self-signed X.509 certificate.");

  language  = cupsLangDefault();
  curtime   = time(NULL);
  serial[0] = curtime >> 24;
  serial[1] = curtime >> 16;
  serial[2] = curtime >> 8;
  serial[3] = curtime;

  gnutls_x509_crt_init(&crt);
  if (strlen(language->language) == 5)
    gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
                                  language->language + 3, 2);
  else
    gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
                                  "US", 2);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0,
                                common_name, strlen(common_name));
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
                                common_name, strlen(common_name));
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
                                0, "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0,
                                "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0,
                                "Unknown", 7);
/*  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0,
                                ServerAdmin, strlen(ServerAdmin));*/
  gnutls_x509_crt_set_key(crt, key);
  gnutls_x509_crt_set_serial(crt, serial, sizeof(serial));
  gnutls_x509_crt_set_activation_time(crt, curtime);
  gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400);
  gnutls_x509_crt_set_ca_status(crt, 0);
  if (num_alt_names > 0)
    gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, alt_names[0]);
  gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0);
  gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT);
  gnutls_x509_crt_set_version(crt, 3);

  bytes = sizeof(buffer);
  if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0)
    gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes);

  gnutls_x509_crt_sign(crt, crt, key);

 /*
  * Save it...
  */

  bytes = sizeof(buffer);
  if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to export public key and X.509 certificate: %s", gnutls_strerror(result)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(result), 0);
    gnutls_x509_crt_deinit(crt);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }
  else if ((fp = cupsFileOpen(crtfile, "w")) != NULL)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Writing public key and X.509 certificate to \"%s\".", crtfile));
    cupsFileWrite(fp, (char *)buffer, bytes);
    cupsFileClose(fp);
  }
  else
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to create public key and X.509 certificate file \"%s\": %s", crtfile, strerror(errno)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    gnutls_x509_crt_deinit(crt);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }

 /*
  * Cleanup...
  */

  gnutls_x509_crt_deinit(crt);
  gnutls_x509_privkey_deinit(key);

  DEBUG_puts("1cupsMakeServerCredentials: Successfully created credentials.");

  return (1);
}