Esempio n. 1
0
static gnutls_x509_crt generate_certificate(requiem_client_profile_t *cp, gnutls_x509_privkey key, int expire)
{
        int ret;
        char buf[1024];
        gnutls_x509_crt crt;
        uint64_t analyzerid;
        size_t size = sizeof(buf);

        ret = gnutls_x509_crt_init(&crt);
        if ( ret < 0 ) {
                fprintf(stderr, "error creating x509 certificate: %s.\n", gnutls_strerror(ret));
                return NULL;
        }

        if ( ! expire )
                expire = 0x7fffffff;
        else
                expire = time(NULL) + expire * 24 * 60 * 60;

        gnutls_x509_crt_set_version(crt, 3);
        gnutls_x509_crt_set_ca_status(crt, 0);
        gnutls_x509_crt_set_activation_time(crt, time(NULL));
        gnutls_x509_crt_set_expiration_time(crt, expire);

        analyzerid = requiem_client_profile_get_analyzerid(cp);

        ret = snprintf(buf, sizeof(buf), "%" REQUIEM_PRIu64, analyzerid);
        ret = gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_DN_QUALIFIER, 0, buf, ret);
        if ( ret < 0 ) {
                fprintf(stderr, "error setting common name: %s.\n", gnutls_strerror(ret));
                return NULL;
        }

        gnutls_x509_crt_set_serial(crt, &analyzerid, sizeof(analyzerid));

        if ( ! key )
                return crt;

        gnutls_x509_crt_set_key(crt, key);

        ret = gnutls_x509_crt_get_key_id(crt, 0, (unsigned char *) buf, &size);
        if ( ret == 0 ) {

                ret = gnutls_x509_crt_set_subject_key_id(crt, buf, size);
                if ( ret < 0 ) {
                        gnutls_x509_crt_deinit(crt);
                        fprintf(stderr, "error setting subject key ID: %s\n", gnutls_strerror(ret));
                        return NULL;
                }
        }

        return crt;
}
Esempio n. 2
0
File: tls.c Progetto: GNOME/libepc
/**
 * epc_tls_certificate_new:
 * @hostname: the name of the host that will use this certificate
 * @validity: the number of days the certificate will remain valid
 * @key: the private key for signing the certificate
 * @error: return location for a #GError, or %NULL
 *
 * Creates a self signed X.509 certificate. The certificate will mention
 * @hostname as common name and as DNS host name, and it will be valid
 * for @validity days.
 *
 * If the call was successful, the newly created certificate is returned. This
 * certificate can be used with functions of the <citetitle>GNU TLS</citetitle>
 * library. If the call was not successful, it returns %NULL and sets @error.
 * The error domain is #EPC_TLS_ERROR. Error codes are taken from the
 * <citetitle>GNU TLS</citetitle> library.
 *
 * Returns: The newly created certificate object, or %NULL.
 */
gnutls_x509_crt_t
epc_tls_certificate_new (const gchar            *hostname,
                         guint                   validity,
                         gnutls_x509_privkey_t   key,
                         GError                **error)
{
  gint rc = GNUTLS_E_SUCCESS;
  gnutls_x509_crt_t crt = NULL;
  time_t now = time (NULL);
  uuid_t serial;

  g_return_val_if_fail (NULL != key, NULL);
  g_return_val_if_fail (NULL != hostname, NULL);

  if (EPC_DEBUG_LEVEL (1))
    g_debug ("%s: Generating self signed server certificate for `%s'", G_STRLOC, hostname);

  uuid_generate_time (serial);

  epc_tls_check (rc = gnutls_x509_crt_init (&crt));
  epc_tls_check (rc = gnutls_x509_crt_set_version (crt, 1));
  epc_tls_check (rc = gnutls_x509_crt_set_key (crt, key));
  epc_tls_check (rc = gnutls_x509_crt_set_serial (crt, serial, sizeof serial));
  epc_tls_check (rc = gnutls_x509_crt_set_activation_time (crt, now));
  epc_tls_check (rc = gnutls_x509_crt_set_expiration_time (crt, now + validity));
  epc_tls_check (rc = gnutls_x509_crt_set_subject_alternative_name (crt, GNUTLS_SAN_DNSNAME, hostname));
  epc_tls_check (rc = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_X520_COMMON_NAME, 0, hostname, strlen (hostname)));
  epc_tls_check (rc = gnutls_x509_crt_sign (crt, crt, key));

out:
  if (GNUTLS_E_SUCCESS != rc)
    {
      g_set_error (error, EPC_TLS_ERROR, rc,
                   _("Cannot create self signed server key for '%s': %s"),
                   hostname, gnutls_strerror (rc));

      if (crt)
        gnutls_x509_crt_deinit (crt);

      crt = NULL;
    }

  return crt;
}
Esempio n. 3
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"));
}
Esempio n. 4
0
void doit(void)
{
	gnutls_x509_privkey_t pkey;
	gnutls_x509_crt_t crt;
	gnutls_x509_crt_t crt2;
	const char *err = NULL;
	gnutls_datum_t out;
	size_t s = 0;
	int ret;

	ret = global_init();
	if (ret < 0)
		fail("global_init\n");

	gnutls_global_set_time_function(mytime);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	ret = gnutls_x509_crt_init(&crt);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_init(&crt2);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM);
	if (ret != 0)
		fail("gnutls_x509_crt_import\n");

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret != 0)
		fail("gnutls_x509_privkey_init\n");

	ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM);
	if (ret != 0)
		fail("gnutls_x509_privkey_import\n");

	/* Setup CRT */

	ret = gnutls_x509_crt_set_version(crt, 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_version\n");

	ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_serial\n");

	ret = gnutls_x509_crt_set_expiration_time(crt, -1);
	if (ret != 0)
		fail("error\n");

	ret = gnutls_x509_crt_set_activation_time(crt, mytime(0));
	if (ret != 0)
		fail("error\n");

	ret = gnutls_x509_crt_set_key(crt, pkey);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key\n");

	ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1);
	if (ret < 0) {
		fail("error\n");
	}

	ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_usage %d\n", ret);

	ret = gnutls_x509_crt_set_dn(crt, "o = none to\\, mention,cn = nikos", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err);
	}


	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "foo", 3, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "*****@*****.**", strlen("*****@*****.**"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "ινβάλιντ@bar.org", strlen("ινβάλιντ@bar.org"), 1);
	if (ret != GNUTLS_E_INVALID_UTF8_EMAIL)
		fail("gnutls_x509_crt_set_subject_alt_name\n");


	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
						   "\xc1\x5c\x96\x3", 4, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
						   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "apa", 3, 0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "απαλό.com", strlen("απαλό.com"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

#ifdef HAVE_LIBIDN
	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "test@νίκο.org", strlen("test@νίκο.org"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");
#endif

	s = 0;
	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);

	s = 0;
	ret =
	    gnutls_x509_crt_set_key_purpose_oid(crt,
						GNUTLS_KP_TLS_WWW_SERVER,
						0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret);

	s = 0;
	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);

	s = 0;
	ret =
	    gnutls_x509_crt_set_key_purpose_oid(crt,
						GNUTLS_KP_TLS_WWW_CLIENT,
						1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret);

	ret = gnutls_x509_crt_set_issuer_dn(crt, "cn = my CA, o = big\\, and one", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err);
	}

	ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0);
	if (ret < 0)
		fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret));



	ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out);
	if (ret != 0)
		fail("gnutls_x509_crt_print\n");
	if (debug)
		printf("crt: %.*s\n", out.size, out.data);
	gnutls_free(out.data);


	s = 0;
	ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
		fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret));

	s = 0;
	ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s);
	if (ret != 0)
		fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret));

	ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		hexprint(out.data, out.size);
		fail("issuer DN comparison failed\n");
	}
	gnutls_free(out.data);

	ret = gnutls_x509_crt_get_raw_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		fail("DN comparison failed\n");
	}
	gnutls_free(out.data);

	ret = gnutls_x509_crt_equals(crt, crt);
	if (ret == 0) {
		fail("equality test failed\n");
	}

	ret = gnutls_x509_crt_equals(crt, crt2);
	if (ret != 0) {
		fail("equality test failed\n");
	}
	assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0);

#ifdef HAVE_LIBIDN
	assert(out.size == saved_crt.size);
	assert(memcmp(out.data, saved_crt.data, out.size)==0);
#endif

	gnutls_free(out.data);

	gnutls_x509_crt_deinit(crt);
	gnutls_x509_crt_deinit(crt2);
	gnutls_x509_privkey_deinit(pkey);

	gnutls_global_deinit();
}
Esempio n. 5
0
void
doit (void)
{
  gnutls_x509_privkey_t pkey;
  gnutls_x509_crt_t crt;
  gnutls_x509_crq_t crq;

  gnutls_datum_t out;

  size_t s = 0;

  char smallbuf[10];

  int ret;

  ret = gnutls_global_init ();
  if (ret < 0)
    fail ("gnutls_global_init\n");

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

  ret = gnutls_x509_crq_init (&crq);
  if (ret != 0)
    fail ("gnutls_x509_crq_init\n");

  ret = gnutls_x509_privkey_init (&pkey);
  if (ret != 0)
    fail ("gnutls_x509_privkey_init\n");

  ret = gnutls_x509_crt_init (&crt);
  if (ret != 0)
    fail ("gnutls_x509_crt_init\n");

  ret = gnutls_x509_privkey_import (pkey, &key, GNUTLS_X509_FMT_PEM);
  if (ret != 0)
    fail ("gnutls_x509_privkey_import\n");

  ret = gnutls_x509_crq_set_version (crq, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_version\n");

  ret = gnutls_x509_crq_set_key (crq, pkey);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key\n");

  s = 0;
  ret = gnutls_x509_crq_get_extension_info (crq, 0, NULL, &s, NULL);
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    fail ("gnutls_x509_crq_get_extension_info\n");

  ret = gnutls_x509_crq_set_basic_constraints (crq, 0, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_basic_constraints %d\n", ret);

  ret = gnutls_x509_crq_set_key_usage (crq, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key_usage %d\n", ret);

  ret = gnutls_x509_crq_get_challenge_password (crq, NULL, &s);
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    fail ("gnutls_x509_crq_get_challenge_password %d\n", ret);

  ret = gnutls_x509_crq_set_challenge_password (crq, "foo");
  if (ret != 0)
    fail ("gnutls_x509_crq_set_challenge_password %d\n", ret);

  s = 0;
  ret = gnutls_x509_crq_get_challenge_password (crq, NULL, &s);
  if (ret != 0 || s != 3)
    fail ("gnutls_x509_crq_get_challenge_password2 %d/%d\n", ret, (int) s);

  s = 10;
  ret = gnutls_x509_crq_get_challenge_password (crq, smallbuf, &s);
  if (ret != 0 || s != 3 || strcmp (smallbuf, "foo") != 0)
    fail ("gnutls_x509_crq_get_challenge_password3 %d/%d/%s\n",
          ret, (int) s, smallbuf);

  s = 0;
  ret = gnutls_x509_crq_get_extension_info (crq, 0, NULL, &s, NULL);
  if (ret != 0)
    fail ("gnutls_x509_crq_get_extension_info2\n");

  s = 0;
  ret = gnutls_x509_crq_get_extension_data (crq, 0, NULL, &s);
  if (ret != 0)
    fail ("gnutls_x509_crq_get_extension_data\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "foo", 3, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "bar", 3, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "apa", 3, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "foo", 3, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  s = 0;
  ret = gnutls_x509_crq_get_key_purpose_oid (crq, 0, NULL, &s, NULL);
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    fail ("gnutls_x509_crq_get_key_purpose_oid %d\n", ret);

  s = 0;
  ret =
    gnutls_x509_crq_set_key_purpose_oid (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key_purpose_oid %d\n", ret);

  s = 0;
  ret = gnutls_x509_crq_get_key_purpose_oid (crq, 0, NULL, &s, NULL);
  if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
    fail ("gnutls_x509_crq_get_key_purpose_oid %d\n", ret);

  s = 0;
  ret =
    gnutls_x509_crq_set_key_purpose_oid (crq, GNUTLS_KP_TLS_WWW_CLIENT, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key_purpose_oid2 %d\n", ret);

  ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &out);
  if (ret != 0)
    fail ("gnutls_x509_crq_print\n");
  if (debug)
    printf ("crq: %.*s\n", out.size, out.data);
  gnutls_free (out.data);

  ret = gnutls_x509_crt_set_version (crt, 3);
  if (ret != 0)
    fail ("gnutls_x509_crt_set_version\n");

  ret = gnutls_x509_crt_set_crq_extensions (crt, crq);
  if (ret != 0)
    fail ("gnutls_x509_crt_set_crq_extensions\n");

  ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &out);
  if (ret != 0)
    fail ("gnutls_x509_crt_print\n");
  if (debug)
    printf ("crt: %.*s\n", out.size, out.data);
  gnutls_free (out.data);

  gnutls_x509_crq_deinit (crq);
  gnutls_x509_crt_deinit (crt);
  gnutls_x509_privkey_deinit (pkey);

  gnutls_global_deinit ();
}
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);
}
Esempio n. 7
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;
}
Esempio n. 8
0
int
main(int argc, char *argv[])
{
    int ret = 1;
    int i;
    gnutls_pubkey_t pubkey = NULL;
    gnutls_x509_privkey_t sigkey = NULL;
    gnutls_x509_crt_t sigcert = NULL;
    gnutls_x509_crt_t crt = NULL;
    const char *pubkey_filename = NULL;
    const char *sigkey_filename = NULL;
    const char *cert_filename = NULL;
    const char *modulus_str = NULL;
    const char *issuercert_filename = NULL;
    unsigned char *modulus_bin = NULL;
    int modulus_len = 0;
    gnutls_datum_t datum = { NULL, 0},  out = { NULL, 0};
    int serial = 1;
    time_t now;
    int err;
    FILE *cert_file;
    char *subject = NULL;
    const char *error = NULL;
    int days = 365;
    char *sigkeypass = NULL;
    uint32_t ser_number;
    long int exponent = 0x10001;
    bool write_pem = false;
    uint8_t id[512];
    size_t id_size = sizeof(id);
    enum cert_type_t certtype = CERT_TYPE_EK;
    const char *oid;
    unsigned int key_usage;
    char *tpm_manufacturer = NULL;
    char *tpm_version = NULL;
    char *tpm_model = NULL;
    char *platf_manufacturer = NULL;
    char *platf_version = NULL;
    char *platf_model = NULL;

    i = 1;
    while (i < argc) {
        if (!strcmp(argv[i], "--pubkey")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --pubkey.\n");
                goto cleanup;
            }
            pubkey_filename = argv[i];
        } else if (!strcmp(argv[i], "--modulus")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --modulus.\n");
                goto cleanup;
            }
            modulus_str = argv[i];
            if (!(modulus_bin = hex_str_to_bin(modulus_str, &modulus_len))) {
                goto cleanup;
            }
        } else if (!strcmp(argv[i], "--exponent")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --exponent.\n");
                goto cleanup;
            }
            exponent = strtol(argv[i], NULL, 0);
            if (exponent == 0) {
                fprintf(stderr, "Exponent is wrong and cannot be 0.\n");
                goto cleanup;
            }
            if (exponent > UINT_MAX) {
                fprintf(stderr, "Exponent must fit into 32bits.\n");
                goto cleanup;
            }
        } else if (!strcmp(argv[i], "--signkey")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --signkey.\n");
                goto cleanup;
            }
            sigkey_filename = argv[i];
        } else if (!strcmp(argv[i], "--signkey-password")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --signkey-password.\n");
                goto cleanup;
            }
            sigkeypass = argv[i];
        } else if (!strcmp(argv[i], "--issuercert")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --issuercert.\n");
                goto cleanup;
            }
            issuercert_filename = argv[i];
        } else if (!strcmp(argv[i], "--out-cert")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --out-cert.\n");
                goto cleanup;
            }
            cert_filename = argv[i];
        } else if (!strcmp(argv[i], "--subject")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --subject.\n");
                goto cleanup;
            }
            subject = argv[i];
        } else if (!strcmp(argv[i], "--days")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --days.\n");
                goto cleanup;
            }
            days = atoi(argv[i]);
        } else if (!strcmp(argv[i], "--serial")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --serial.\n");
                goto cleanup;
            }
            serial = atoi(argv[i]);
        } else if (!strcmp(argv[i], "--type")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --type.\n");
                goto cleanup;
            }
            if (!strcasecmp(argv[i], "ek")) {
                certtype = CERT_TYPE_EK;
            } else if (!strcasecmp(argv[i], "platform")) {
                certtype = CERT_TYPE_PLATFORM;
//            } else if (!strcasecmp(argv[i], "aik")) {
//                /* AIK cert needs EK cert as input */
//                certtype = CERT_TYPE_AIK;
            } else {
                fprintf(stderr, "Unknown certificate type '%s'.\n",
                        argv[i]);
                goto cleanup;
            }
        } else if (!strcmp(argv[i], "--tpm-manufacturer")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --tpm-manufacturer.\n");
                goto cleanup;
            }
            tpm_manufacturer = argv[i];
        } else if (!strcmp(argv[i], "--tpm-model")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --tpm-model.\n");
                goto cleanup;
            }
            tpm_model = argv[i];
        } else if (!strcmp(argv[i], "--tpm-version")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --tpm-version.\n");
                goto cleanup;
            }
            tpm_version = argv[i];
        } else if (!strcmp(argv[i], "--platform-manufacturer")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --platform-manufacturer.\n");
                goto cleanup;
            }
            platf_manufacturer = argv[i];
        } else if (!strcmp(argv[i], "--platform-model")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --platform-model.\n");
                goto cleanup;
            }
            platf_model = argv[i];
        } else if (!strcmp(argv[i], "--platform-version")) {
            i++;
            if (i == argc) {
                fprintf(stderr, "Missing argument for --platform-version.\n");
                goto cleanup;
            }
            platf_version = argv[i];
        } else if (!strcmp(argv[i], "--pem")) {
            write_pem = true;
        } else if (!strcmp(argv[i], "--help")) {
            usage(argv[0]);
            exit(0);
        } else {
            fprintf(stderr, "Unknown command line parameter '%s'.\n", argv[i]);
            usage(argv[0]);
            exit(1);
        }
        i++;
    }
    
    ser_number = htonl(serial);

    if (pubkey_filename == NULL && modulus_bin == NULL) {
        fprintf(stderr, "Missing public EK file and modulus.\n");
        usage(argv[0]);
        goto cleanup;
    }

    if (issuercert_filename == NULL) {
        fprintf(stderr, "The issuer certificate name is required.\n");
        goto cleanup;
    }

    switch (certtype) {
    case CERT_TYPE_EK:
    case CERT_TYPE_PLATFORM:
        if (tpm_manufacturer == NULL ||
            tpm_model == NULL ||
            tpm_version == NULL) {
            fprintf(stderr, "--tpm-manufacturer and --tpm-model and "
                            "--tpm version "
                            "must all be provided\n");
            goto cleanup;
        }
        break;
    case CERT_TYPE_AIK:
        break;
    }

    switch (certtype) {
    case CERT_TYPE_PLATFORM:
        if (platf_manufacturer == NULL ||
            platf_model == NULL ||
            platf_version == NULL) {
            fprintf(stderr, "--platform-manufacturer and --platform-model and "
                            "--platform version "
                            "must all be provided\n");
            goto cleanup;
        }
        break;
    case CERT_TYPE_EK:
    case CERT_TYPE_AIK:
        break;
    }

    err = gnutls_global_init();
    if (err < 0) {
            fprintf(stderr, "gnutls_global_init failed.\n");
            goto cleanup;
    }
    gnutls_x509_privkey_init(&sigkey);

    if (pubkey_filename) {
        gnutls_pubkey_init(&pubkey);

        err = gnutls_load_file(pubkey_filename, &datum);
        if (err != GNUTLS_E_SUCCESS) {
            fprintf(stderr, "Could not open file for EK public key: %s\n",
                strerror(errno));
            goto cleanup;
        }

        err = gnutls_pubkey_import(pubkey, &datum, GNUTLS_X509_FMT_PEM);
        gnutls_free(datum.data);
        datum.data = NULL;
        if (err != GNUTLS_E_SUCCESS) {
            fprintf(stderr, "Could not import EK.\n");
            goto cleanup;
        }
    } else {
        pubkey = create_rsa_from_modulus(modulus_bin, modulus_len,
                                         exponent);
        free(modulus_bin);
        modulus_bin = NULL;

        if (pubkey == NULL)
            goto cleanup;
    }

    /* all types of keys must have pubkey set now otherwise the signing
       will not work */

    if (sigkey_filename == NULL) {
        fprintf(stderr, "Missing signature key.\n");
        usage(argv[0]);
        exit(1);
    }

#define CHECK_GNUTLS_ERROR(_err, _msg, ...) \
if (_err != GNUTLS_E_SUCCESS) {             \
    fprintf(stderr, _msg, __VA_ARGS__);     \
    goto cleanup;                           \
}

    err = gnutls_load_file(sigkey_filename, &datum);
    CHECK_GNUTLS_ERROR(err, "Could not read signing key from file %s: %s\n",
                       sigkey_filename, gnutls_strerror(err));

    if (sigkeypass) {
        err = gnutls_x509_privkey_import2(sigkey, &datum, GNUTLS_X509_FMT_PEM,
                                          sigkeypass, 0);
    } else {
        err = gnutls_x509_privkey_import(sigkey, &datum, GNUTLS_X509_FMT_PEM);
    }
    gnutls_free(datum.data);
    datum.data = NULL;
    CHECK_GNUTLS_ERROR(err, "Could not import signing key : %s\n",
                       gnutls_strerror(err));

    err = gnutls_load_file(issuercert_filename, &datum);
    CHECK_GNUTLS_ERROR(err, "Could not read certificate from file %s : %s\n",
                       issuercert_filename, gnutls_strerror(err));

    gnutls_x509_crt_init(&sigcert);

    err = gnutls_x509_crt_import(sigcert, &datum, GNUTLS_X509_FMT_PEM);
    gnutls_free(datum.data);
    datum.data = NULL;
    CHECK_GNUTLS_ERROR(err, "Could not import issuer certificate: %s\n",
                       gnutls_strerror(err));

    err = gnutls_x509_crt_init(&crt);
    CHECK_GNUTLS_ERROR(err, "CRT init failed: %s\n", gnutls_strerror(err))

    /* 3.5.1 Version */
    err = gnutls_x509_crt_set_version(crt, 3);
    CHECK_GNUTLS_ERROR(err, "Could not set version on CRT: %s\n",
                       gnutls_strerror(err))

    /* 3.5.2 Serial Number */
    err = gnutls_x509_crt_set_serial(crt, &ser_number, sizeof(ser_number));
    CHECK_GNUTLS_ERROR(err, "Could not set serial on CRT: %s\n",
                       gnutls_strerror(err))

    /* 3.5.5 Validity */
    now = time(NULL);
    err = gnutls_x509_crt_set_activation_time(crt, now);
    CHECK_GNUTLS_ERROR(err, "Could not set activation time on CRT: %s\n",
                       gnutls_strerror(err))

    err = gnutls_x509_crt_set_expiration_time(crt,
             now + (time_t)days * 24 * 60 * 60);
    CHECK_GNUTLS_ERROR(err, "Could not set expiration time on CRT: %s\n",
                       gnutls_strerror(err))

    /* 3.5.6 Subject -- should be empty, but we allow it anyway */
    if (subject) {
        err = gnutls_x509_crt_set_dn(crt, subject, &error);
        CHECK_GNUTLS_ERROR(err,
                           "Could not set DN on CRT: %s\n"
                           "DN '%s must be fault after %s\n.'",
                           gnutls_strerror(err),
                           subject, error)
    }

    /* 3.5.7 Public Key Info */
    switch (certtype) {
    case CERT_TYPE_EK:
        oid = "1.2.840.113549.1.1.7";
        break;
    case CERT_TYPE_PLATFORM:
        oid = NULL;
        break;
    case CERT_TYPE_AIK:
        oid = "1.2.840.113549.1.1.1";
        break;
    default:
        fprintf(stderr, "Internal error: unhandle case in line %d\n",
                __LINE__);
        goto cleanup;
    }
    if (oid) {
        err = gnutls_x509_crt_set_key_purpose_oid(crt, oid, 0);
        CHECK_GNUTLS_ERROR(err, "Could not set key purpose on CRT: %s\n",
                           gnutls_strerror(err))
    }

    /* 3.5.8 Certificate Policies -- skip since not mandated */
    /* 3.5.9 Subject Alternative Names -- missing code */
    err = create_tpm_manufacturer_info(tpm_manufacturer, tpm_model,
                                       tpm_version, &datum);
    if (!err && datum.size > 0) {
        /*
         * GNUTLS's write_new_general_name can only handle a few GNUTLS_SAN_*
         * -> we have to use GNUTLS_SAN_URI
         */
        err = gnutls_x509_crt_set_subject_alt_name(crt,
                                                   GNUTLS_SAN_URI,
                                                   datum.data, datum.size,
                                                   GNUTLS_FSAN_SET);
        CHECK_GNUTLS_ERROR(err, "Could not set subject alt name: %s\n",
                           gnutls_strerror(err))
    }
Esempio n. 9
0
crypto::Identity
generateIdentity(const std::string& name, crypto::Identity ca)
{
    int rc = gnutls_global_init();
    if (rc != GNUTLS_E_SUCCESS)
        return {};

    auto shared_key = std::make_shared<PrivateKey>(PrivateKey::generate());

    gnutls_x509_crt_t cert;
    if (gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS)
        return {};
    auto shared_crt = std::make_shared<Certificate>(cert);

    gnutls_x509_crt_set_activation_time(cert, time(NULL));
    gnutls_x509_crt_set_expiration_time(cert, time(NULL) + (700 * 24 * 60 * 60));
    if (gnutls_x509_crt_set_key(cert, shared_key->x509_key) != GNUTLS_E_SUCCESS) {
        std::cerr << "Error when setting certificate key" << std::endl;
        return {};
    }
    if (gnutls_x509_crt_set_version(cert, 3) != GNUTLS_E_SUCCESS) {
        std::cerr << "Error when setting certificate version" << std::endl;
        return {};
    }

    // TODO: compute the subject key using the recommended RFC method
    auto pk_id = shared_key->getPublicKey().getId();
    gnutls_x509_crt_set_subject_key_id(cert, &pk_id, sizeof(pk_id));

    gnutls_x509_crt_set_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, name.data(), name.length());

    const std::string& uid_str = shared_key->getPublicKey().getId().toString();
    gnutls_x509_crt_set_dn_by_oid(cert, GNUTLS_OID_LDAP_UID, 0, uid_str.data(), uid_str.length());

    {
        random_device rdev;
        std::uniform_int_distribution<uint64_t> dist{};
        uint64_t cert_serial = dist(rdev);
        gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial));
    }

    if (ca.first && ca.second) {
        gnutls_x509_crt_set_key_usage (cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_DATA_ENCIPHERMENT);
        //if (gnutls_x509_crt_sign2(cert, ca.second->cert, ca.first->x509_key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
        if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
            std::cerr << "Error when signing certificate" << std::endl;
            return {};
        }
        shared_crt->issuer = ca.second;
    } else {
        gnutls_x509_crt_set_ca_status(cert, 1);
        gnutls_x509_crt_set_key_usage (cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_CERT_SIGN);
        //if (gnutls_x509_crt_sign2(cert, cert, key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
        if (gnutls_x509_crt_privkey_sign(cert, cert, shared_key->key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) {
            std::cerr << "Error when signing certificate" << std::endl;
            return {};
        }
    }

    gnutls_global_deinit();

    return {shared_key, shared_crt};
}
Esempio n. 10
0
void    Plugin::_loadCertificate()
{
    QFile            file(this->crtFile);
    gnutls_datum_t   datum;
    size_t           size = 2048;
    QByteArray       data;
    gnutls_privkey_t privkey;
    gnutls_pubkey_t  pubkey;
    gnutls_pubkey_t  pubkeyCrt;
    int              error;
    QMap<char *, QByteArray> oid;
    gnutls_digest_algorithm_t digest;

    if (!file.open(QIODevice::ReadWrite))
        throw Properties("error", "Unable to open the certificate file").add("file", this->crtFile);
    ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt");
    ASSERT(gnutls_privkey_init(&privkey));
    ASSERT(gnutls_privkey_import_x509(privkey, this->key, 0));
    ASSERT(gnutls_pubkey_init(&pubkey));
    ASSERT(gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0));
    // Verifies that the certificate is valid
    if (file.size() > 0)
    {
        ASSERT(gnutls_pubkey_init(&pubkeyCrt));
        data = file.readAll();
        datum.size = data.size();
        datum.data = (unsigned char *)data.data();
        if (gnutls_x509_crt_import(this->crt, &datum, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS)
            file.resize(0);
        else if (gnutls_x509_crt_get_expiration_time(this->crt) < ::time(NULL) + CRT_EXPIRATION_REGEN)
            file.resize(0);
        else if (gnutls_pubkey_import_x509(pubkeyCrt, this->crt, 0) != GNUTLS_E_SUCCESS)
            file.resize(0);
        // Ensures that the public keys of the certificate and the private key match
        size_t size1 = size, size2 = size;
        QByteArray pub1((int)size1, 0), pub2((int)size2, 0);
        if (gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, pub1.data(), &size1) != GNUTLS_E_SUCCESS
            || gnutls_pubkey_export(pubkeyCrt, GNUTLS_X509_FMT_PEM, pub2.data(), &size2) != GNUTLS_E_SUCCESS
            || size1 != size2 || pub1 != pub2)
            file.resize(0);
        gnutls_pubkey_deinit(pubkeyCrt);
    }
    // Generates a new certificate
    if (file.size() == 0)
    {
        gnutls_x509_crt_deinit(this->crt);
        this->init.removeAll("crt");
        ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt");
        LOG_INFO("Generating a new certificate", "Plugin", "_generateCertificate");
        oid.insert((char *)GNUTLS_OID_X520_COMMON_NAME, "LightBird");
        oid.insert((char *)GNUTLS_OID_X520_ORGANIZATION_NAME, "LightBird");
        QMapIterator<char *, QByteArray> it(oid);
        while (it.hasNext())
            ASSERT(gnutls_x509_crt_set_dn_by_oid(this->crt, it.key(), 0, it.value().data(), it.next().value().size()));
        ASSERT(gnutls_x509_crt_set_pubkey(this->crt, pubkey));
        data = this->_generateSerial();
        ASSERT(gnutls_x509_crt_set_serial(this->crt, data.data(), data.size()));
        ASSERT(gnutls_x509_crt_set_activation_time(this->crt, ::time(NULL)));
        ASSERT(gnutls_x509_crt_set_expiration_time(this->crt, ::time(NULL) + CRT_EXPIRATION));
        ASSERT(gnutls_x509_crt_set_basic_constraints(this->crt, 0, -1));
        ASSERT(gnutls_x509_crt_set_key_purpose_oid(this->crt, GNUTLS_KP_TLS_WWW_SERVER, 0));
        ASSERT(gnutls_x509_crt_set_key_usage(this->crt, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT));
        data.resize((int)size);
        ASSERT(gnutls_x509_crt_get_key_id(this->crt, 0, (unsigned char *)data.data(), &size));
        ASSERT(gnutls_x509_crt_set_subject_key_id(this->crt, (unsigned char *)data.data(), size));
        ASSERT(gnutls_x509_crt_set_version(this->crt, 3));
        ASSERT(gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &digest, NULL));
        ASSERT(gnutls_x509_crt_privkey_sign(this->crt, this->crt, privkey, digest, 0));
        size = data.size();
        ASSERT(gnutls_x509_crt_export(this->crt, GNUTLS_X509_FMT_PEM, data.data(), &size));
        data.resize((int)size);
        file.write(data);
    }
    gnutls_pubkey_deinit(pubkey);
    gnutls_privkey_deinit(privkey);
}
Esempio n. 11
0
static void run_set_extension_by_oid(gnutls_x509_crq_t crq)
{
	gnutls_x509_crt_t crt;
	const char *err = NULL;
	size_t oid_size;
	gnutls_datum_t out, out2;
	unsigned i;
	int ret;
	char oid[128];

	ret = global_init();
	if (ret < 0)
		fail("global_init\n");

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


	ret = gnutls_x509_crt_init(&crt);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_set_crq(crt, crq);
	if (ret != 0)
		fail("gnutls_x509_crt_set_crq: %s\n", gnutls_strerror(ret));

	ret = gnutls_x509_crt_set_issuer_dn(crt, "o = big\\, and one,cn = my CA", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err);
	}

	ret = gnutls_x509_crt_set_version(crt, 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_version\n");

	ret = gnutls_x509_crt_set_crq_extension_by_oid(crt, crq, GNUTLS_X509EXT_OID_EXTENDED_KEY_USAGE, 0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_crq_extension_by_oid\n");

	oid_size = sizeof(oid);
	ret = gnutls_x509_crt_get_extension_info(crt, 0, oid, &oid_size, NULL);
	if (ret != 0)
		fail("gnutls_x509_crt_get_extension_info\n");

	if (strcmp(oid, GNUTLS_X509EXT_OID_EXTENDED_KEY_USAGE) != 0)
		fail("strcmp\n");

	ret = gnutls_x509_crt_get_extension_data2(crt, 0, &out);
	if (ret != 0)
		fail("gnutls_x509_crt_get_extension_data2\n");

	for (i=0;;i++) {
		oid_size = sizeof(oid);
		ret = gnutls_x509_crq_get_extension_info(crq, i, oid, &oid_size, NULL);
		if (ret < 0)
			fail("loop: ext not found: %s\n", gnutls_strerror(ret));
		if (strcmp(oid, GNUTLS_X509EXT_OID_EXTENDED_KEY_USAGE) == 0) {
			ret = gnutls_x509_crq_get_extension_data2(crq, 3, &out2);
			if (ret != 0)
				fail("gnutls_x509_crt_get_extension_data2\n");
			break;
		}

	}

	if (out.size != out2.size || memcmp(out.data, out2.data, out.size) != 0) {
		fail("memcmp %d, %d\n", out.size, out2.size);
	}

	gnutls_free(out.data);
	gnutls_free(out2.data);

	oid_size = sizeof(oid);
	ret = gnutls_x509_crt_get_extension_info(crt, 1, oid, &oid_size, NULL);
	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
		fail("gnutls_x509_crt_get_extension_info\n");


	ret = gnutls_x509_crt_get_raw_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		fail("DN comparison failed\n");
	}
	gnutls_free(out.data);

	gnutls_x509_crt_deinit(crt);

	gnutls_global_deinit();
}
Esempio n. 12
0
static void run_set_extensions(gnutls_x509_crq_t crq)
{
	gnutls_x509_crt_t crt;
	const char *err = NULL;
	gnutls_datum_t out;
	int ret;

	ret = global_init();
	if (ret < 0)
		fail("global_init\n");

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


	ret = gnutls_x509_crt_init(&crt);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_set_crq(crt, crq);
	if (ret != 0)
		fail("gnutls_x509_crt_set_crq: %s\n", gnutls_strerror(ret));

	ret = gnutls_x509_crt_set_issuer_dn(crt, "o = big\\, and one, cn = my CA", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err);
	}

	ret = gnutls_x509_crt_set_version(crt, 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_version\n");

	ret = gnutls_x509_crt_set_crq_extensions(crt, crq);
	if (ret != 0)
		fail("gnutls_x509_crt_set_crq_extensions\n");

	ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out);
	if (ret != 0)
		fail("gnutls_x509_crt_print\n");
	if (debug)
		printf("crt: %.*s\n", out.size, out.data);
	gnutls_free(out.data);

	ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 41 ||
	    memcmp(out.data, "\x30\x27\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6d\x79\x20\x43\x41\x31\x15\x30\x13\x06\x03\x55\x04\x0a\x13\x0c\x62\x69\x67\x2c\x20\x61\x6e\x64\x20\x6f\x6e\x65", 41) != 0) {
		hexprint(out.data, out.size);
		fail("issuer DN comparison failed\n");
	}
	gnutls_free(out.data);

	ret = gnutls_x509_crt_get_raw_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		fail("DN comparison failed\n");
	}
	gnutls_free(out.data);

	gnutls_x509_crt_deinit(crt);

	gnutls_global_deinit();
}
Esempio n. 13
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);
}
/*!
  Set the version of the X.509 certificate. In general the version will be 3.
 */
bool CertificateBuilder::setVersion(int version)
{
    d->errnumber = gnutls_x509_crt_set_version(d->crt, version);
    return GNUTLS_E_SUCCESS == d->errnumber;
}
Esempio n. 15
0
void doit(void)
{
	gnutls_x509_privkey_t pkey;
	gnutls_x509_crt_t crt;
	gnutls_x509_crt_t crt2;
	const char *err = NULL;
	unsigned char buf[64];
	gnutls_datum_t out;
	size_t s = 0;
	int ret;

	ret = global_init();
	if (ret < 0)
		fail("global_init\n");

	gnutls_global_set_time_function(mytime);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	ret = gnutls_x509_crt_init(&crt);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_init(&crt2);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM);
	if (ret != 0)
		fail("gnutls_x509_crt_import\n");

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret != 0)
		fail("gnutls_x509_privkey_init\n");

	ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM);
	if (ret != 0)
		fail("gnutls_x509_privkey_import\n");

	/* Setup CRT */

	ret = gnutls_x509_crt_set_version(crt, 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_version\n");

	ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_serial\n");

	ret = gnutls_x509_crt_set_expiration_time(crt, -1);
	if (ret != 0)
		fail("error\n");

	ret = gnutls_x509_crt_set_activation_time(crt, mytime(0));
	if (ret != 0)
		fail("error\n");

	ret = gnutls_x509_crt_set_key(crt, pkey);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key\n");

	ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1);
	if (ret < 0) {
		fail("error\n");
	}

	ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_usage %d\n", ret);

	ret = gnutls_x509_crt_set_dn(crt, "o = none to\\, mention,cn = nikos", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err);
	}


	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "foo", 3, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "*****@*****.**", strlen("*****@*****.**"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "ινβάλιντ@bar.org", strlen("ινβάλιντ@bar.org"), 1);
	if (ret != GNUTLS_E_INVALID_UTF8_EMAIL)
		fail("gnutls_x509_crt_set_subject_alt_name\n");


	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
						   "\xc1\x5c\x96\x3", 4, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
						   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "apa", 3, 0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "απαλό.com", strlen("απαλό.com"), 1);
#if defined(HAVE_LIBIDN2) || defined(HAVE_LIBIDN)
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name: %s\n", gnutls_strerror(ret));

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "test@νίκο.org", strlen("test@νίκο.org"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");
#else
	if (ret != GNUTLS_E_UNIMPLEMENTED_FEATURE)
		fail("gnutls_x509_crt_set_subject_alt_name: %s\n", gnutls_strerror(ret));
#endif

	s = 0;
	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);

	s = 0;
	ret =
	    gnutls_x509_crt_set_key_purpose_oid(crt,
						GNUTLS_KP_TLS_WWW_SERVER,
						0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret);

	s = 0;
	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);

	s = 0;
	ret =
	    gnutls_x509_crt_set_key_purpose_oid(crt,
						GNUTLS_KP_TLS_WWW_CLIENT,
						1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret);

	/* in the end this will be ignored as the issuer will be set
	 * by gnutls_x509_crt_sign2() */
	ret = gnutls_x509_crt_set_issuer_dn(crt, "cn = my CA, o = big\\, and one", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err);
	}

#define ISSUER_UNIQUE_ID "\x00\x01\x02\x03"
#define SUBJECT_UNIQUE_ID "\x04\x03\x02\x01"
	ret = gnutls_x509_crt_set_issuer_unique_id(crt, ISSUER_UNIQUE_ID, sizeof(ISSUER_UNIQUE_ID)-1);
	if (ret < 0)
		fail("error: %s\n", gnutls_strerror(ret));

	ret = gnutls_x509_crt_set_subject_unique_id(crt, SUBJECT_UNIQUE_ID, sizeof(SUBJECT_UNIQUE_ID)-1);
	if (ret < 0)
		fail("error: %s\n", gnutls_strerror(ret));

	/* Sign and finalize the certificate */
	ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0);
	if (ret < 0)
		fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret));


	ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out);
	if (ret != 0)
		fail("gnutls_x509_crt_print\n");
	if (debug)
		printf("crt: %.*s\n", out.size, out.data);
	gnutls_free(out.data);

	/* Verify whether selected input is present */
	s = 0;
	ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
		fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret));

	s = 0;
	ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s);
	if (ret != 0)
		fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret));

	ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		hexprint(out.data, out.size);
		fail("issuer DN comparison failed\n");
	}
	gnutls_free(out.data);

	s = sizeof(buf);
	ret = gnutls_x509_crt_get_issuer_unique_id(crt, (void*)buf, &s);
	if (ret < 0)
		fail("error: %s\n", gnutls_strerror(ret));

	if (s != sizeof(ISSUER_UNIQUE_ID)-1 ||
		memcmp(buf, ISSUER_UNIQUE_ID, s) != 0) {
		fail("issuer unique id comparison failed\n");
	}

	s = sizeof(buf);
	ret = gnutls_x509_crt_get_subject_unique_id(crt, (void*)buf, &s);
	if (ret < 0)
		fail("error: %s\n", gnutls_strerror(ret));

	if (s != sizeof(SUBJECT_UNIQUE_ID)-1 ||
		memcmp(buf, SUBJECT_UNIQUE_ID, s) != 0) {
		fail("subject unique id comparison failed\n");
	}

	ret = gnutls_x509_crt_get_raw_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		fail("DN comparison failed\n");
	}
	gnutls_free(out.data);

	ret = gnutls_x509_crt_equals(crt, crt);
	if (ret == 0) {
		fail("equality test failed\n");
	}

	ret = gnutls_x509_crt_equals(crt, crt2);
	if (ret != 0) {
		fail("equality test failed\n");
	}
	assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0);

	if (debug)
		fprintf(stderr, "%s\n", out.data);
#if defined(HAVE_LIBIDN2)
	assert(out.size == saved_crt.size);
	assert(memcmp(out.data, saved_crt.data, out.size)==0);
#endif

	gnutls_free(out.data);

	gnutls_x509_crt_deinit(crt);
	gnutls_x509_crt_deinit(crt2);
	gnutls_x509_privkey_deinit(pkey);

	gnutls_global_deinit();
}