Exemplo n.º 1
0
void
pkcs11_get_random(FILE * outfile, const char *url, unsigned bytes,
		  common_info_st * info)
{
	int ret;
	uint8_t *output;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	output = malloc(bytes);
	if (output == NULL) {
		fprintf(stderr, "Memory error\n");
		exit(1);
	}

	ret = gnutls_pkcs11_token_get_random(url, output, bytes);
	if (ret < 0) {
		fprintf(stderr, "gnutls_pkcs11_token_get_random: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fwrite(output, 1, bytes, outfile);

	return;
}
Exemplo n.º 2
0
void
pkcs11_mechanism_list(FILE * outfile, const char *url, unsigned int flags,
		      common_info_st * info)
{
	int ret;
	int idx;
	unsigned long mechanism;
	const char *str;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	idx = 0;
	do {
		ret =
		    gnutls_pkcs11_token_get_mechanism(url, idx++,
						      &mechanism);
		if (ret >= 0) {
			str = NULL;
			if (mechanism <=
			    sizeof(mech_list) / sizeof(mech_list[0]))
				str = mech_list[mechanism];
			if (str == NULL)
				str = "UNKNOWN";

			fprintf(outfile, "[0x%.4lx] %s\n", mechanism, str);
		}
	}
	while (ret >= 0);


	return;
}
Exemplo n.º 3
0
void
pkcs11_init(FILE * outfile, const char *url, const char *label,
	    common_info_st * info)
{
	int ret;
	const char *pin;
	char so_pin[32];

	pkcs11_common(info);

	if (url == NULL) {
		fprintf(stderr, "error: no token URL given to initialize!\n");
		exit(1);
	}

	if (info->so_pin != NULL)
		pin = info->so_pin;
	else {
		pin = getenv("GNUTLS_SO_PIN");
		if (pin == NULL && info->batch == 0)
			pin = getpass("Enter Security Officer's PIN: ");
		if (pin == NULL)
			exit(1);
	}

	if (strlen(pin) >= sizeof(so_pin) || pin[0] == '\n')
		exit(1);

	strcpy(so_pin, pin);

	if (info->so_pin != NULL) {
		pin = info->pin;
	} else {
		pin = getenv("GNUTLS_PIN");
		if (pin == NULL && info->batch == 0)
			pin = getpass("Enter new User's PIN: ");
		if (pin == NULL)
			exit(1);
	}

	if (pin[0] == '\n')
		exit(1);

	ret = gnutls_pkcs11_token_init(url, so_pin, label);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_token_set_pin(url, NULL, pin, GNUTLS_PIN_USER);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	return;
}
Exemplo n.º 4
0
void
pkcs11_generate(FILE * outfile, const char *url, gnutls_pk_algorithm_t pk,
		unsigned int bits,
		const char *label, const char *id, int detailed,
		unsigned int flags, common_info_st * info)
{
	int ret;
	gnutls_datum_t pubkey;
	gnutls_datum_t cid = {NULL, 0};
	unsigned char raw_id[128];
	size_t raw_id_size;

	pkcs11_common(info);

	FIX(url, outfile, detailed, info);
	CHECK_LOGIN_FLAG(flags);

	if (id != NULL) {
		raw_id_size = sizeof(raw_id);
		ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size);
		if (ret < 0) {
			fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		cid.data = raw_id;
		cid.size = raw_id_size;
	}

	if (outfile == stderr || outfile == stdout) {
		fprintf(stderr, "warning: no --outfile was specified and the generated public key will be printed on screen.\n");
	}

	if (label == NULL && info->batch == 0) {
		label = read_str("warning: Label was not specified.\nLabel: ");
	}

	ret =
	    gnutls_pkcs11_privkey_generate3(url, pk, bits, label, &cid,
					    GNUTLS_X509_FMT_PEM, &pubkey,
					    info->key_usage,
					    flags);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		if (bits != 1024 && pk == GNUTLS_PK_RSA)
			fprintf(stderr,
				"note: several smart cards do not support arbitrary size keys; try --bits 1024 or 2048.\n");
		exit(1);
	}

	fwrite(pubkey.data, 1, pubkey.size, outfile);
	gnutls_free(pubkey.data);

	UNFIX;
	return;
}
Exemplo n.º 5
0
void
pkcs11_set_pin(FILE * outfile, const char *url, common_info_st * info, unsigned so)
{
	int ret;
	const char *pin;

	pkcs11_common(info);

	if (url == NULL) {
		fprintf(stderr, "error: no token URL given to initialize!\n");
		exit(1);
	}

	fprintf(stderr, "Setting token's user PIN...\n");

	if (so) {
		if (info->so_pin != NULL) {
			pin = info->so_pin;
		} else {
			pin = getenv("GNUTLS_SO_PIN");
			if (pin == NULL && info->batch == 0)
				pin = getpass("Enter Administrators's new PIN: ");
			if (pin == NULL)
				exit(1);
		}
	} else {
		if (info->pin != NULL) {
			pin = info->pin;
		} else {
			pin = getenv("GNUTLS_PIN");
			if (pin == NULL && info->batch == 0)
				pin = getpass("Enter User's new PIN: ");
			if (pin == NULL)
				exit(1);
		}
	}

	if (pin == NULL || pin[0] == '\n')
		exit(1);

	ret = gnutls_pkcs11_token_set_pin(url, NULL, pin, (so!=0)?GNUTLS_PIN_SO:GNUTLS_PIN_USER);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	return;
}
Exemplo n.º 6
0
void
pkcs11_export_pubkey(FILE * outfile, const char *url, int detailed, unsigned int flags, common_info_st * info)
{
	int ret;
	gnutls_datum_t pubkey;
	gnutls_pkcs11_privkey_t pkey;

	pkcs11_common(info);

	FIX(url, outfile, detailed, info);
	CHECK_LOGIN_FLAG(flags);

	if (outfile == stderr || outfile == stdout) {
		fprintf(stderr, "warning: no --outfile was specified and the public key will be printed on screen.\n");
		sleep(3);
	}

	ret = gnutls_pkcs11_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_privkey_import_url(pkey, url, 0);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_pkcs11_privkey_export_pubkey(pkey,
					        GNUTLS_X509_FMT_PEM, &pubkey,
					        flags);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	gnutls_pkcs11_privkey_deinit(pkey);

	fwrite(pubkey.data, 1, pubkey.size, outfile);
	gnutls_free(pubkey.data);

	UNFIX;
	return;
}
Exemplo n.º 7
0
void
pkcs11_init(FILE * outfile, const char *url, const char *label,
	    common_info_st * info)
{
	int ret;
	const char *pin;
	char so_pin[32];

	pkcs11_common(info);

	if (url == NULL) {
		fprintf(stderr, "error: no token URL given to initialize!\n");
		exit(1);
	}

	if (label == NULL) {
		fprintf(stderr, "error: no label provided for token initialization!\n");
		exit(1);
	}

	if (info->so_pin != NULL)
		pin = info->so_pin;
	else {
		pin = getenv("GNUTLS_SO_PIN");
		if (pin == NULL && info->batch == 0)
			pin = getpass("Enter Security Officer's PIN: ");
		if (pin == NULL)
			exit(1);
	}

	if (strlen(pin) >= sizeof(so_pin) || pin[0] == '\n')
		exit(1);

	strcpy(so_pin, pin);

	fprintf(stderr, "Initializing token... ");
	ret = gnutls_pkcs11_token_init(url, so_pin, label);
	if (ret < 0) {
		fprintf(stderr, "\nError in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	fprintf(stderr, "done\n");

	fprintf(stderr, "\nToken was successfully initialized; use --initialize-pin and --initialize-so-pin to set or reset PINs\n");

	return;
}
Exemplo n.º 8
0
void
pkcs11_export(FILE * outfile, const char *url, unsigned int flags,
	      common_info_st * info)
{
	gnutls_pkcs11_obj_t obj;
	gnutls_datum_t t;
	int ret;
	unsigned int obj_flags = flags;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	ret = gnutls_pkcs11_obj_init(&obj);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_obj_import_url(obj, url, obj_flags);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_obj_export3(obj, info->outcert_format, &t);
	if (ret < 0) {
        	fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
                exit(1);
        }

	fwrite(t.data, 1, t.size, outfile);
	gnutls_free(t.data);

	if (info->outcert_format == GNUTLS_X509_FMT_PEM)
        	fputs("\n\n", outfile);

	gnutls_pkcs11_obj_deinit(obj);

	UNFIX;
	return;
}
Exemplo n.º 9
0
/* If there is a single token only present, return its URL.
 */
static
char *get_single_token_url(common_info_st * info)
{
	int ret;
	char *url = NULL, *t = NULL;

	pkcs11_common(info);

	ret = gnutls_pkcs11_token_get_url(0, 0, &url);
	if (ret < 0)
		return NULL;

	ret = gnutls_pkcs11_token_get_url(1, 0, &t);
	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		gnutls_free(t);
		gnutls_free(url);
		return NULL;
	}

	return url;
}
Exemplo n.º 10
0
static
void pkcs11_set_val(FILE * outfile, const char *url, int detailed,
		   unsigned int flags, common_info_st * info,
		   gnutls_pkcs11_obj_info_t val_type, const char *val)
{
	int ret;
	gnutls_pkcs11_obj_t obj;

	pkcs11_common(info);

	FIX(url, outfile, detailed, info);
	CHECK_LOGIN_FLAG(flags);

	ret = gnutls_pkcs11_obj_init(&obj);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_obj_import_url(obj, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_pkcs11_obj_set_info(obj, val_type, val, strlen(val), flags);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	gnutls_pkcs11_obj_deinit(obj);

	return;
}
Exemplo n.º 11
0
/* lists certificates from a token
 */
void
pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags,
	    unsigned int detailed, common_info_st * info)
{
	gnutls_pkcs11_obj_t *crt_list;
	unsigned int crt_list_size = 0, i, j;
	int ret, otype;
	char *output, *str;
	int attrs, print_exts = 0;
	gnutls_x509_ext_st *exts;
	unsigned exts_size;
	unsigned int obj_flags = flags;

	pkcs11_common(info);

	FIX(url, outfile, detailed, info);

	gnutls_pkcs11_token_get_flags(url, &flags);
	if (flags & GNUTLS_PKCS11_TOKEN_TRUSTED)
		print_exts = 1;

	if (type == PKCS11_TYPE_TRUSTED) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
	} else if (type == PKCS11_TYPE_PK) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
	} else if (type == PKCS11_TYPE_CRT_ALL) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
		if (print_exts != 0) print_exts++;
	} else if (type == PKCS11_TYPE_PRIVKEY) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
	} else if (type == PKCS11_TYPE_INFO) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_MATCH;
	} else {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
	}

	/* give some initial value to avoid asking for the pkcs11 pin twice.
	 */
	ret =
	    gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size,
					       url, attrs, obj_flags);
	if (ret < 0) {
		fprintf(stderr, "Error in crt_list_import (1): %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	if (crt_list_size == 0) {
		fprintf(stderr, "No matching objects found\n");
		exit(2);
	}

	for (i = 0; i < crt_list_size; i++) {
		char buf[128];
		size_t size;
		unsigned int oflags;

		ret =
		    gnutls_pkcs11_obj_export_url(crt_list[i], detailed,
						 &output);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		if (info->only_urls) {
			fprintf(outfile, "%s\n", output);
			gnutls_free(output);
			continue;
		} else {
			fprintf(outfile, "Object %d:\n\tURL: %s\n", i, output);
			gnutls_free(output);
		}

		otype = gnutls_pkcs11_obj_get_type(crt_list[i]);
		fprintf(outfile, "\tType: %s\n",
			gnutls_pkcs11_type_get_name(otype));

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_obj_get_info(crt_list[i],
					       GNUTLS_PKCS11_OBJ_LABEL,
					       buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		fprintf(outfile, "\tLabel: %s\n", buf);

		oflags = 0;
		ret = gnutls_pkcs11_obj_get_flags(crt_list[i], &oflags);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		str = gnutls_pkcs11_obj_flags_get_str(oflags);
		if (str != NULL) {
			fprintf(outfile, "\tFlags: %s\n", str);
			gnutls_free(str);
		}

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_obj_get_info(crt_list[i],
					       GNUTLS_PKCS11_OBJ_ID_HEX,
					       buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		fprintf(outfile, "\tID: %s\n", buf);

		if (otype == GNUTLS_PKCS11_OBJ_X509_CRT && print_exts > 0) {
			ret = gnutls_pkcs11_obj_get_exts(crt_list[i], &exts, &exts_size, 0);
			if (ret >= 0 && exts_size > 0) {
				gnutls_datum_t txt;

				if (print_exts > 1) {
					fprintf(outfile, "\tAttached extensions:\n");
					ret = gnutls_x509_ext_print(exts, exts_size, 0, &txt);
					if (ret >= 0) {
						fprintf(outfile, "%s", (char*)txt.data);
						gnutls_free(txt.data);
					}
				} else {
					fprintf(outfile, "\tAttached extensions:");
					for (j=0;j<exts_size;j++) {
						fprintf(outfile, "%s%s", exts[j].oid, (j!=exts_size-1)?",":" ");
					}
				}
				for (j=0;j<exts_size;j++) {
					gnutls_x509_ext_deinit(&exts[j]);
				}
				gnutls_free(exts);
				fprintf(outfile, "\n");
			}
		}

		fprintf(outfile, "\n");
	}

	UNFIX;
	return;
}
Exemplo n.º 12
0
void
pkcs11_export (FILE * outfile, const char *url, unsigned int login,
               common_info_st * info)
{
  gnutls_pkcs11_obj_t crt;
  gnutls_x509_crt_t xcrt;
  gnutls_pubkey_t pubkey;
  int ret;
  size_t size;
  unsigned int obj_flags = 0;

  if (login)
    obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;

  pkcs11_common ();

  if (url == NULL)
    url = "pkcs11:";

  ret = gnutls_pkcs11_obj_init (&crt);
  if (ret < 0)
    {
      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
               gnutls_strerror (ret));
      exit (1);
    }

  ret = gnutls_pkcs11_obj_import_url (crt, url, obj_flags);
  if (ret < 0)
    {
      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
               gnutls_strerror (ret));
      exit (1);
    }

  switch (gnutls_pkcs11_obj_get_type (crt))
    {
    case GNUTLS_PKCS11_OBJ_X509_CRT:
      ret = gnutls_x509_crt_init (&xcrt);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      size = buffer_size;
      ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fwrite (buffer, 1, size, outfile);

      gnutls_x509_crt_deinit (xcrt);
      break;
    case GNUTLS_PKCS11_OBJ_PUBKEY:
      ret = gnutls_pubkey_init (&pubkey);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      ret = gnutls_pubkey_import_pkcs11 (pubkey, crt, 0);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      size = buffer_size;
      ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fwrite (buffer, 1, size, outfile);

      gnutls_pubkey_deinit (pubkey);
      break;
    default:
      {
        gnutls_datum_t data, enc;

        size = buffer_size;
        ret = gnutls_pkcs11_obj_export (crt, buffer, &size);
        if (ret < 0)
          {
            break;
          }

        data.data = buffer;
        data.size = size;

        ret = gnutls_pem_base64_encode_alloc ("DATA", &data, &enc);
        if (ret < 0)
          {
            fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                     gnutls_strerror (ret));
            exit (1);
          }

        fwrite (enc.data, 1, enc.size, outfile);

        gnutls_free (enc.data);
        break;
      }
    }
  fputs ("\n\n", outfile);


  gnutls_pkcs11_obj_deinit (crt);

  return;

}
Exemplo n.º 13
0
/* lists certificates from a token
 */
void
pkcs11_list (FILE * outfile, const char *url, int type, unsigned int login,
             unsigned int detailed, common_info_st * info)
{
  gnutls_pkcs11_obj_t *crt_list;
  gnutls_x509_crt_t xcrt;
  unsigned int crt_list_size = 0;
  int ret;
  char *output;
  int i, attrs;
  unsigned int obj_flags = 0;

  if (login)
    obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;

  pkcs11_common ();

  if (url == NULL)
    url = "pkcs11:";

  if (type == PKCS11_TYPE_TRUSTED)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
    }
  else if (type == PKCS11_TYPE_PK)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
    }
  else if (type == PKCS11_TYPE_CRT_ALL)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
    }
  else if (type == PKCS11_TYPE_PRIVKEY)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
    }
  else
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
    }

  /* give some initial value to avoid asking for the pkcs11 pin twice.
   */
  crt_list_size = 128;
  crt_list = malloc (sizeof (*crt_list) * crt_list_size);
  if (crt_list == NULL)
    {
      fprintf (stderr, "Memory error\n");
      exit (1);
    }

  ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url,
                                           attrs, obj_flags);
  if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      fprintf (stderr, "Error in crt_list_import (1): %s\n",
               gnutls_strerror (ret));
      exit (1);
    }

  if (crt_list_size == 0)
    {
      fprintf (stderr, "No matching objects found\n");
      exit (0);
    }

  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      crt_list = realloc (crt_list, sizeof (*crt_list) * crt_list_size);
      if (crt_list == NULL)
        {
          fprintf (stderr, "Memory error\n");
          exit (1);
        }

      ret =
        gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url,
                                           attrs, obj_flags);
      if (ret < 0)
        {
          fprintf (stderr, "Error in crt_list_import: %s\n",
                   gnutls_strerror (ret));
          exit (1);
        }
    }

  for (i = 0; i < crt_list_size; i++)
    {
      char buf[128];
      size_t size;

      ret = gnutls_pkcs11_obj_export_url (crt_list[i], detailed, &output);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      fprintf (outfile, "Object %d:\n\tURL: %s\n", i, output);

      fprintf (outfile, "\tType: %s\n",
               gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_get_type
                                            (crt_list[i])));

      size = sizeof (buf);
      ret =
        gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_LABEL, buf,
                                    &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fprintf (outfile, "\tLabel: %s\n", buf);

      size = sizeof (buf);
      ret =
        gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_ID_HEX,
                                    buf, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fprintf (outfile, "\tID: %s\n\n", buf);



      if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL
          || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
        continue;

      ret = gnutls_x509_crt_init (&xcrt);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt_list[i]);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

#if 0
      size = buffer_size;
      ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      fwrite (buffer, 1, size, outfile);
      fputs ("\n\n", outfile);
#endif

      gnutls_x509_crt_deinit (xcrt);


    }

  return;
}
Exemplo n.º 14
0
void
pkcs11_write(FILE * outfile, const char *url, const char *label,
	     const char *id, unsigned flags, common_info_st * info)
{
	gnutls_x509_crt_t xcrt;
	gnutls_x509_privkey_t xkey;
	gnutls_pubkey_t xpubkey;
	int ret;
	gnutls_datum_t *secret_key;
	unsigned key_usage = 0;
	unsigned char raw_id[128];
	size_t raw_id_size;
	gnutls_datum_t cid = {NULL, 0};

	pkcs11_common(info);

	FIX(url, outfile, 0, info);
	CHECK_LOGIN_FLAG(flags);

	if (label == NULL && info->batch == 0) {
		label = read_str("warning: The object's label was not specified.\nLabel: ");
	}

	if (id != NULL) {
		raw_id_size = sizeof(raw_id);
		ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size);
		if (ret < 0) {
			fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		cid.data = raw_id;
		cid.size = raw_id_size;
	}

	secret_key = load_secret_key(0, info);
	if (secret_key != NULL) {
		ret =
		    gnutls_pkcs11_copy_secret_key(url, secret_key, label,
						  info->key_usage,
						  flags |
						  GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
	}

	xcrt = load_cert(0, info);
	if (xcrt != NULL) {
		ret = gnutls_pkcs11_copy_x509_crt2(url, xcrt, label, &cid, flags);
		if (ret < 0) {
			fprintf(stderr, "Error writing certificate: %s\n", gnutls_strerror(ret));
			if (((flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) ||
			     (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED)) && 
			    (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO) == 0)
				fprintf(stderr, "note: some tokens may require security officer login for this operation\n");
			exit(1);
		}

		gnutls_x509_crt_get_key_usage(xcrt, &key_usage, NULL);
		gnutls_x509_crt_deinit(xcrt);
	}

	xkey = load_x509_private_key(0, info);
	if (xkey != NULL) {
		ret =
		    gnutls_pkcs11_copy_x509_privkey2(url, xkey, label,
						     &cid, key_usage|info->key_usage,
						     flags |
						     GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_privkey_deinit(xkey);
	}

	xpubkey = load_pubkey(0, info);
	if (xpubkey != NULL) {
		ret =
		    gnutls_pkcs11_copy_pubkey(url, xpubkey, label,
						     &cid,
						     0, flags);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		gnutls_pubkey_deinit(xpubkey);
	}

	if (xkey == NULL && xcrt == NULL && secret_key == NULL && xpubkey == NULL) {
		fprintf(stderr,
			"You must use --load-privkey, --load-certificate, --load-pubkey or --secret-key to load the file to be copied\n");
		exit(1);
	}

	UNFIX;
	return;
}
Exemplo n.º 15
0
void
pkcs11_token_list(FILE * outfile, unsigned int detailed,
		  common_info_st * info, unsigned brief)
{
	int ret;
	int i;
	char *url;
	char buf[128];
	size_t size;
	unsigned flags;

	pkcs11_common(info);

	for (i = 0;; i++) {
		ret = gnutls_pkcs11_token_get_url(i, detailed, &url);
		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
			break;

		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		if (brief != 0) {
			fprintf(outfile, "%s\n", url);
			goto cont;
		} else {
			fprintf(outfile, "Token %d:\n\tURL: %s\n", i, url);
		}

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_token_get_info(url,
						 GNUTLS_PKCS11_TOKEN_LABEL,
						 buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		fprintf(outfile, "\tLabel: %s\n", buf);

		ret = gnutls_pkcs11_token_get_flags(url, &flags);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
		} else {
			print_type(outfile, flags);
		}

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_token_get_info(url,
						 GNUTLS_PKCS11_TOKEN_MANUFACTURER,
						 buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		fprintf(outfile, "\tManufacturer: %s\n", buf);

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_token_get_info(url,
						 GNUTLS_PKCS11_TOKEN_MODEL,
						 buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		fprintf(outfile, "\tModel: %s\n", buf);

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_token_get_info(url,
						 GNUTLS_PKCS11_TOKEN_SERIAL,
						 buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		fprintf(outfile, "\tSerial: %s\n", buf);

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_token_get_info(url,
						 GNUTLS_PKCS11_TOKEN_MODNAME,
						 buf, &size);
		if (ret >= 0) {
			fprintf(outfile, "\tModule: %s\n", buf);
		}
		fprintf(outfile, "\n\n");
 cont:
		gnutls_free(url);

	}

	return;
}
Exemplo n.º 16
0
void
pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
	    common_info_st * info)
{
	gnutls_privkey_t privkey;
	gnutls_pubkey_t pubkey;
	int ret;
	gnutls_datum_t data, sig = {NULL, 0};
	int pk;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	data.data = (void*)TEST_DATA;
	data.size = sizeof(TEST_DATA)-1;

	ret = gnutls_privkey_init(&privkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__,
			__LINE__, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_init(&pubkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__,
			__LINE__, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_import_url(privkey, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot import private key: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot import public key: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot sign data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);

	fprintf(stderr, "Verifying against private key parameters... ");
	ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
		0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot verify signed data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(stderr, "ok\n");

	/* now try to verify against a public key within the token */
	gnutls_pubkey_deinit(pubkey);
	ret = gnutls_pubkey_init(&pubkey);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__,
			__LINE__, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_import_url(pubkey, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot find a corresponding public key object in token: %s\n",
			gnutls_strerror(ret));
		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
			exit(0);
		exit(1);
	}

	fprintf(stderr, "Verifying against public key in the token... ");
	ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
		0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot verify signed data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(stderr, "ok\n");

	gnutls_free(sig.data);
	gnutls_pubkey_deinit(pubkey);
	gnutls_privkey_deinit(privkey);
	UNFIX;
}
Exemplo n.º 17
0
int
main (int argc, char **argv)
{
  int ret;
  int ii, i, inp;
  char buffer[MAX_BUF + 1];
  char *session_data = NULL;
  char *session_id = NULL;
  size_t session_data_size;
  size_t session_id_size = 0;
  int user_term = 0, retval = 0;
  socket_st hd;
  ssize_t bytes;

  set_program_name (argv[0]);
  gaa_parser (argc, argv);

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (info.debug);

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

#ifdef ENABLE_PKCS11
  pkcs11_common ();
#endif

  if (hostname == NULL)
    {
      fprintf (stderr, "No hostname given\n");
      exit (1);
    }

  sockets_init ();

#ifndef _WIN32
  signal (SIGPIPE, SIG_IGN);
#endif

  init_global_tls_stuff ();

  socket_open (&hd, hostname, service);
  socket_connect (&hd);

  hd.session = init_tls_session (hostname);
  if (starttls)
    goto after_handshake;

  for (i = 0; i < 2; i++)
    {


      if (i == 1)
        {
          hd.session = init_tls_session (hostname);
          gnutls_session_set_data (hd.session, session_data,
                                   session_data_size);
          free (session_data);
        }

      ret = do_handshake (&hd);

      if (ret < 0)
        {
          fprintf (stderr, "*** Handshake has failed\n");
          gnutls_perror (ret);
          gnutls_deinit (hd.session);
          return 1;
        }
      else
        {
          printf ("- Handshake was completed\n");
          if (gnutls_session_is_resumed (hd.session) != 0)
            printf ("*** This is a resumed session\n");
        }

      if (resume != 0 && i == 0)
        {

          gnutls_session_get_data (hd.session, NULL, &session_data_size);
          session_data = malloc (session_data_size);

          gnutls_session_get_data (hd.session, session_data,
                                   &session_data_size);

          gnutls_session_get_id (hd.session, NULL, &session_id_size);

          session_id = malloc (session_id_size);
          gnutls_session_get_id (hd.session, session_id, &session_id_size);

          /* print some information */
          print_info (hd.session, hostname, info.insecure);

          printf ("- Disconnecting\n");
          socket_bye (&hd);

          printf
            ("\n\n- Connecting again- trying to resume previous session\n");
          socket_open (&hd, hostname, service);
          socket_connect (&hd);
        }
      else
        {
          break;
        }
    }

after_handshake:

  /* Warning!  Do not touch this text string, it is used by external
     programs to search for when gnutls-cli has reached this point. */
  printf ("\n- Simple Client Mode:\n\n");

  if (rehandshake)
    {
      ret = do_handshake (&hd);

      if (ret < 0)
        {
          fprintf (stderr, "*** ReHandshake has failed\n");
          gnutls_perror (ret);
          gnutls_deinit (hd.session);
          return 1;
        }
      else
        {
          printf ("- ReHandshake was completed\n");
        }
    }

#ifndef _WIN32
  signal (SIGALRM, &starttls_alarm);
#endif

  fflush (stdout);
  fflush (stderr);

  /* do not buffer */
#if !(defined _WIN32 || defined __WIN32__)
  setbuf (stdin, NULL);
#endif
  setbuf (stdout, NULL);
  setbuf (stderr, NULL);

  for (;;)
    {
      if (starttls_alarmed && !hd.secure)
        {
          /* Warning!  Do not touch this text string, it is used by
             external programs to search for when gnutls-cli has
             reached this point. */
          fprintf (stderr, "*** Starting TLS handshake\n");
          ret = do_handshake (&hd);
          if (ret < 0)
            {
              fprintf (stderr, "*** Handshake has failed\n");
              user_term = 1;
              retval = 1;
              break;
            }
        }

      inp = check_net_or_keyboard_input(&hd);

      if (inp == IN_NET)
        {
          memset (buffer, 0, MAX_BUF + 1);
          ret = socket_recv (&hd, buffer, MAX_BUF);

          if (ret == 0)
            {
              printf ("- Peer has closed the GnuTLS connection\n");
              break;
            }
          else if (handle_error (&hd, ret) < 0 && user_term == 0)
            {
              fprintf (stderr,
                       "*** Server has terminated the connection abnormally.\n");
              retval = 1;
              break;
            }
          else if (ret > 0)
            {
              if (verbose != 0)
                printf ("- Received[%d]: ", ret);
              for (ii = 0; ii < ret; ii++)
                {
                  fputc (buffer[ii], stdout);
                }
              fflush (stdout);
            }

          if (user_term != 0)
            break;
        }

      if (inp == IN_KEYBOARD)
        {
          if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
            {
              if (hd.secure == 0)
                {
                  /* Warning!  Do not touch this text string, it is
                     used by external programs to search for when
                     gnutls-cli has reached this point. */
                  fprintf (stderr, "*** Starting TLS handshake\n");
                  ret = do_handshake (&hd);
                  clearerr (stdin);
                  if (ret < 0)
                    {
                      fprintf (stderr, "*** Handshake has failed\n");
                      user_term = 1;
                      retval = 1;
                      break;
                    }
                }
              else
                {
                  user_term = 1;
                  break;
                }
              continue;
            }

          buffer[bytes] = 0;
          if (crlf != 0)
            {
              char *b = strchr (buffer, '\n');
              if (b != NULL)
                {
                  strcpy (b, "\r\n");
                  bytes++;
                }
            }

          ret = socket_send (&hd, buffer, bytes);

          if (ret > 0)
            {
              if (verbose != 0)
                printf ("- Sent: %d bytes\n", ret);
            }
          else
            handle_error (&hd, ret);

        }
    }

  if (user_term != 0)
    socket_bye (&hd);
  else
    gnutls_deinit (hd.session);

#ifdef ENABLE_SRP
  if (srp_cred)
    gnutls_srp_free_client_credentials (srp_cred);
#endif
#ifdef ENABLE_PSK
  if (psk_cred)
    gnutls_psk_free_client_credentials (psk_cred);
#endif

  gnutls_certificate_free_credentials (xcred);

#ifdef ENABLE_ANON
  gnutls_anon_free_client_credentials (anon_cred);
#endif

  gnutls_global_deinit ();

  return retval;
}
Exemplo n.º 18
0
static void cmd_parser(int argc, char **argv)
{
	int ret, privkey_op = 0;
	common_info_st cinfo;
	const char *proto = "tcp";
	unsigned int port = 443;

	optionProcess(&danetoolOptions, argc, argv);

	if (HAVE_OPT(OUTFILE)) {
		outfile = safe_open_rw(OPT_ARG(OUTFILE), privkey_op);
		if (outfile == NULL) {
			fprintf(stderr, "%s", OPT_ARG(OUTFILE));
			exit(1);
		}
	} else
		outfile = stdout;

	default_dig = GNUTLS_DIG_UNKNOWN;
	if (HAVE_OPT(HASH)) {
		if (strcasecmp(OPT_ARG(HASH), "md5") == 0) {
			fprintf(stderr,
				"Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
			default_dig = GNUTLS_DIG_MD5;
		} else if (strcasecmp(OPT_ARG(HASH), "sha1") == 0)
			default_dig = GNUTLS_DIG_SHA1;
		else if (strcasecmp(OPT_ARG(HASH), "sha256") == 0)
			default_dig = GNUTLS_DIG_SHA256;
		else if (strcasecmp(OPT_ARG(HASH), "sha224") == 0)
			default_dig = GNUTLS_DIG_SHA224;
		else if (strcasecmp(OPT_ARG(HASH), "sha384") == 0)
			default_dig = GNUTLS_DIG_SHA384;
		else if (strcasecmp(OPT_ARG(HASH), "sha512") == 0)
			default_dig = GNUTLS_DIG_SHA512;
		else if (strcasecmp(OPT_ARG(HASH), "rmd160") == 0)
			default_dig = GNUTLS_DIG_RMD160;
		else {
			fprintf(stderr, "invalid hash: %s", OPT_ARG(HASH));
			exit(1);
		}
	}

	gnutls_global_set_log_function(tls_log_func);

	if (HAVE_OPT(DEBUG)) {
		gnutls_global_set_log_level(OPT_VALUE_DEBUG);
		printf("Setting log level to %d\n", (int) OPT_VALUE_DEBUG);
	}

	if ((ret = gnutls_global_init()) < 0) {
		fprintf(stderr, "global_init: %s", gnutls_strerror(ret));
		exit(1);
	}
#ifdef ENABLE_PKCS11
	pkcs11_common(NULL);
#endif

	memset(&cinfo, 0, sizeof(cinfo));

	if (HAVE_OPT(INDER) || HAVE_OPT(INRAW))
		cinfo.incert_format = GNUTLS_X509_FMT_DER;
	else
		cinfo.incert_format = GNUTLS_X509_FMT_PEM;

	if (HAVE_OPT(VERBOSE))
		cinfo.verbose = 1;

	if (HAVE_OPT(LOAD_PUBKEY))
		cinfo.pubkey = OPT_ARG(LOAD_PUBKEY);

	if (HAVE_OPT(LOAD_CERTIFICATE))
		cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);

	if (HAVE_OPT(PORT)) {
		port = OPT_VALUE_PORT;
	} else {
		if (HAVE_OPT(STARTTLS_PROTO))
			port = starttls_proto_to_port(OPT_ARG(STARTTLS_PROTO));
	}
	if (HAVE_OPT(PROTO))
		proto = OPT_ARG(PROTO);

	if (HAVE_OPT(TLSA_RR))
		dane_info(OPT_ARG(HOST), proto, port,
			  HAVE_OPT(CA), ENABLED_OPT(DOMAIN), &cinfo);
	else if (HAVE_OPT(CHECK))
		dane_check(OPT_ARG(CHECK), proto, port, &cinfo);
	else
		USAGE(1);

	fclose(outfile);

#ifdef ENABLE_PKCS11
	gnutls_pkcs11_deinit();
#endif
	gnutls_global_deinit();
}
Exemplo n.º 19
0
void
pkcs11_export_chain(FILE * outfile, const char *url, unsigned int flags,
	      common_info_st * info)
{
	gnutls_pkcs11_obj_t obj;
	gnutls_x509_crt_t xcrt;
	gnutls_datum_t t;
	int ret;
	unsigned int obj_flags = flags;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	ret = gnutls_pkcs11_obj_init(&obj);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_obj_import_url(obj, url, obj_flags);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	/* make a crt */
	ret = gnutls_x509_crt_init(&xcrt);
	if (ret < 0) {
		fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_crt_import_pkcs11(xcrt, obj);
	if (ret < 0) {
        	fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
                exit(1);
        }

	ret = gnutls_pkcs11_obj_export3(obj, GNUTLS_X509_FMT_PEM, &t);
	if (ret < 0) {
        	fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
                exit(1);
        }
	fwrite(t.data, 1, t.size, outfile);
       	fputs("\n\n", outfile);
        gnutls_free(t.data);

        gnutls_pkcs11_obj_deinit(obj);
        
        do {
                ret = gnutls_pkcs11_get_raw_issuer(url, xcrt, &t, GNUTLS_X509_FMT_PEM, 0);
        	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
	                break;
        	if (ret < 0) {
                	fprintf(stderr, "Error in %s:%d: %s\n", __func__,
		        		__LINE__, gnutls_strerror(ret));
                        exit(1);
                }
                
        	fwrite(t.data, 1, t.size, outfile);
               	fputs("\n\n", outfile);

               	gnutls_x509_crt_deinit(xcrt);

               	ret = gnutls_x509_crt_init(&xcrt);
        	if (ret < 0) {
                	fprintf(stderr, "Error in %s:%d: %s\n", __func__,
		        		__LINE__, gnutls_strerror(ret));
                        exit(1);
                }

               	ret = gnutls_x509_crt_import(xcrt, &t, GNUTLS_X509_FMT_PEM);
        	if (ret < 0) {
                	fprintf(stderr, "Error in %s:%d: %s\n", __func__,
		        		__LINE__, gnutls_strerror(ret));
                        exit(1);
                }

                gnutls_free(t.data);
                
                ret = gnutls_x509_crt_check_issuer(xcrt, xcrt);
                if (ret != 0) {
                        /* self signed */
                        break;
                }
                
        } while(1);
        
	UNFIX;
	return;
}