int main(int argc, char *argv[])
{
	int i;

	i = sc_test_init(&argc, argv);
	if (i < 0)
		return 1;
	printf("Looking for a PKCS#15 compatible Smart Card... ");
	fflush(stdout);
	sc_lock(card);
	i = sc_pkcs15_bind(card, &p15card);
	/* Keep card locked to prevent useless calls to sc_logout */
	if (i) {
		fprintf(stderr, "failed: %s\n", sc_strerror(i));
		return 1;
	}
	printf("found.\n");
	sc_test_print_card(p15card);

	dump_objects("PIN codes", SC_PKCS15_TYPE_AUTH_PIN);
	dump_objects("Private keys", SC_PKCS15_TYPE_PRKEY);
	dump_objects("Public keys", SC_PKCS15_TYPE_PUBKEY);
	dump_objects("X.509 certificates", SC_PKCS15_TYPE_CERT_X509);
	dump_objects("data objects", SC_PKCS15_TYPE_DATA_OBJECT);
	dump_unusedspace();

	sc_pkcs15_unbind(p15card);
	sc_unlock(card);
	sc_test_cleanup();
	return 0;
}
static int
sc_init(void)
{
	int r;

	r = sc_establish_context(&ctx, "openssh");
	if (r)
		goto err;
	if (sc_reader_id >= ctx->reader_count) {
		r = SC_ERROR_NO_READERS_FOUND;
		error("Illegal reader number %d (max %d)", sc_reader_id,
		    ctx->reader_count -1);
		goto err;
	}
	r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card);
	if (r)
		goto err;
	r = sc_pkcs15_bind(card, &p15card);
	if (r)
		goto err;
	return 0;
err:
	sc_close();
	return r;
}
static int init_pkcs15(PluginInstance *inst)
{
        int r;
        
        r = sc_establish_context(&inst->ctx, "opensc-signer");
        if (r)
                return r;
        inst->reader_id = 0;
        r = sc_connect_card(inst->ctx->reader[inst->reader_id], 0, &inst->card);
        if (r)
                return r;
        r = sc_pkcs15_bind(inst->card, &inst->p15card);
        if (r)
                return r;
        return 0;
}
Example #4
0
int main(int argc, char *argv[])
{
	struct sc_pkcs15_object **objs = NULL;
	int i, count;

	i = sc_test_init(&argc, argv);
	if (i < 0)
		return 1;
	if (card->reader->capabilities & SC_READER_CAP_PIN_PAD)
		printf("Slot is capable of doing pinpad operations!\n");
	printf("Looking for a PKCS#15 compatible Smart Card... ");
	fflush(stdout);
	if (SC_SUCCESS != sc_lock(card))
		return 1;
	i = sc_pkcs15_bind(card, NULL, &p15card);
	if (SC_SUCCESS != sc_unlock(card))
		return 1;
	if (i) {
		fprintf(stderr, "failed: %s\n", sc_strerror(i));
		sc_test_cleanup();
		return 1;
	}
	printf("found.\n");
	printf("Enumerating PIN codes...\n");
	if (SC_SUCCESS != sc_lock(card))
		return 1;
	count = enum_pins(&objs);
	if (SC_SUCCESS != sc_unlock(card))
		return 1;
	if (count < 0) {
		sc_pkcs15_unbind(p15card);
		sc_test_cleanup();
		return 1;
	}
	for (i = 0; i < count; i++) {
		ask_and_verify_pin(objs[i]);
	}
	sc_pkcs15_unbind(p15card);
	sc_test_cleanup();
	return 0;
}
Example #5
0
int main(int argc, char * const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int do_decipher = 0;
	int do_sign = 0;
	int action_count = 0;
        struct sc_pkcs15_object *key;
	sc_context_param_t ctx_param;

	while (1) {
		c = getopt_long(argc, argv, "sck:r:i:o:f:Rp:vw", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c) {
		case 's':
			do_sign++;
			action_count++;
			break;
		case 'c':
			do_decipher++;
			action_count++;
			break;
		case 'k':
			opt_key_id = optarg;
			action_count++;
			break;
		case 'r':
			opt_reader = optarg;
			break;
		case 'i':
			opt_input = optarg;
			break;
		case 'o':
			opt_output = optarg;
			break;
		case 'f':
			opt_sig_format = optarg;
			break;
		case 'R':
			opt_raw = 1;
			break;
		case OPT_SHA1:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
			break;
		case OPT_SHA256:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
			break;
		case OPT_SHA384:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
			break;
		case OPT_SHA512:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
			break;
		case OPT_SHA224:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224;
			break;
		case OPT_MD5:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5;
			break;
		case OPT_PKCS1:
			opt_crypt_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
			break;
		case 'v':
			verbose++;
			break;
		case 'p':
			opt_pincode = optarg;
			break;
		case OPT_BIND_TO_AID:
			opt_bind_to_aid = optarg;
			break;
		case 'w':
			opt_wait = 1;
			break;
		}
	}
	if (action_count == 0)
		util_print_usage_and_die(app_name, options, option_help, NULL);

	if (!(opt_crypt_flags & SC_ALGORITHM_RSA_HASHES))
		opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_NONE;

	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r) {
		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}

	if (verbose > 1) {
		ctx->debug = verbose;
		sc_ctx_log_to_file(ctx, "stderr");
	}

	err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
	if (err)
		goto end;

	if (verbose)
		fprintf(stderr, "Trying to find a PKCS #15 compatible card...\n");
	if (opt_bind_to_aid)   {
		struct sc_aid aid;

		aid.len = sizeof(aid.value);
		if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len))   {
			fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
			return 1;
		}

		r = sc_pkcs15_bind(card, &aid, &p15card);
	}
	else   {
		r = sc_pkcs15_bind(card, NULL, &p15card);
	}
	if (r) {
		fprintf(stderr, "PKCS #15 binding failed: %s\n", sc_strerror(r));
		err = 1;
		goto end;
	}
	if (verbose)
		fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label);

	if (do_decipher) {
		if ((err = get_key(SC_PKCS15_PRKEY_USAGE_DECRYPT, &key))
		 || (err = decipher(key)))
			goto end;
		action_count--;
	}

	if (do_sign) {
		if ((err = get_key(SC_PKCS15_PRKEY_USAGE_SIGN|
				   SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|
				   SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, &key))
		 || (err = sign(key)))
			goto end;
		action_count--;
	}
end:
	if (p15card)
		sc_pkcs15_unbind(p15card);
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);
	return err;
}
Example #6
0
int main(int argc, char * const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int do_list_sdos = 0;
	int do_list_apps = 0;
	int action_count = 0;
	sc_context_param_t ctx_param;

	setbuf(stderr, NULL);
	setbuf(stdout, NULL);

	while (1) {
		c = getopt_long(argc, argv, "v", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c) {
                case OPT_LIST_SDOS:
                        do_list_sdos = 1;
                        opt_sdo_tag = optarg;
                        action_count++;
                        break;
		case OPT_LIST_APPLICATIONS:
			do_list_apps = 1;
			action_count++;
			break;
                case OPT_BIND_TO_AID:
			opt_bind_to_aid = optarg;
			break;
		case OPT_READER:
			opt_reader = optarg;
			break;
		case 'v':
			verbose++;
			break;
		}
	}
	if (action_count == 0)
		util_print_usage_and_die(app_name, options, option_help, NULL);

	memset(&ctx_param, 0, sizeof(sc_context_param_t));
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r != SC_SUCCESS) {
		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}

	/* Only change if not in opensc.conf */
	if (verbose > 1 && ctx->debug == 0) {
		ctx->debug = verbose;
		sc_ctx_log_to_file(ctx, "stderr");
	}

	if (action_count <= 0)
		goto end;

	err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
	if (err)
		goto end;

        if (opt_bind_to_aid)   {
		struct sc_aid aid;

		aid.len = sizeof(aid.value);
		if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len))   {
			fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
			return 1;
		}

		r = sc_pkcs15_bind(card, &aid, &p15card);
	}
	else   if (!do_list_sdos) {
		r = sc_pkcs15_bind(card, NULL, &p15card);
	}

	if (do_list_sdos) {
		if ((err = list_sdos(opt_sdo_tag)))
			goto end;
		action_count--;
	}
	if (do_list_apps) {
		if ((err = list_apps(stdout)))
			goto end;
		action_count--;
	}
end:
	if (p15card)
		sc_pkcs15_unbind(p15card);

	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);

	return err;
}
Example #7
0
/* Retrieve the serial number and the time of the last update of the
   card.  The serial number is returned as a malloced string (hex
   encoded) in SERIAL and the time of update is returned in STAMP.
   If no update time is available the returned value is 0.  The serial
   is mandatory for a PKCS_15 application and an error will be
   returned if this value is not availbale.  For non-PKCS-15 cards a
   serial number is constructed by other means. Caller must free
   SERIAL unless the function returns an error. */
int
card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
{
#ifdef HAVE_OPENSC
  int rc;
  struct sc_path path;
  struct sc_file *file;
  unsigned char buf[256];
  int buflen;
#endif

  if (!card || !serial || !stamp)
    return gpg_error (GPG_ERR_INV_VALUE);

  *serial = NULL;
  *stamp = 0; /* not available */

#ifdef HAVE_OPENSC
  if (!card->fnc.initialized)
    {
      card->fnc.initialized = 1;
      /* The first use of this card tries to figure out the type of the card
         and sets up the function pointers. */
      rc = sc_pkcs15_bind (card->scard, &card->p15card);
      if (rc)
        {
          if (rc != SC_ERROR_PKCS15_APP_NOT_FOUND)
            log_error ("binding of existing PKCS-15 failed in reader %d: %s\n",
                       card->reader, sc_strerror (rc));
          card->p15card = NULL;
          rc = 0;
        }
      if (card->p15card)
        card_p15_bind (card);
      card->fnc.initialized = 1;
    }


  /* We should lookup the iso 7812-1 and 8583-3 - argh ISO
     practice is suppressing innovation - IETF rules!  So we
     always get the serialnumber from the 2F02 GDO file.  */
  /* FIXME: in case we can't parse the 2F02 EF and we have a P15 card,
     we should get the serial number from the respective P15 file */
  sc_format_path ("3F002F02", &path);
  rc = sc_select_file (card->scard, &path, &file);
  if (rc)
    {
      log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
      return gpg_error (GPG_ERR_CARD);
    }
  if (file->type != SC_FILE_TYPE_WORKING_EF
      || file->ef_structure != SC_FILE_EF_TRANSPARENT)
    {
      log_error ("wrong type or structure of GDO file\n");
      sc_file_free (file);
      return gpg_error (GPG_ERR_CARD);
    }

  if (!file->size || file->size >= DIM(buf) )
    { /* FIXME: Use a real parser */
      log_error ("unsupported size of GDO file (%d)\n", file->size);
      sc_file_free (file);
      return gpg_error (GPG_ERR_CARD);
    }
  buflen = file->size;

  rc = sc_read_binary (card->scard, 0, buf, buflen, 0);
  sc_file_free (file);
  if (rc < 0)
    {
      log_error ("error reading GDO file: %s\n", sc_strerror (rc));
      return gpg_error (GPG_ERR_CARD);
    }
  if (rc != buflen)
    {
      log_error ("short read on GDO file\n");
      return gpg_error (GPG_ERR_CARD);
    }

  rc = find_iccsn (buf, buflen, serial);
  if (gpg_err_code (rc) == GPG_ERR_CARD)
    log_error ("invalid structure of GDO file\n");
  if (!rc && card->p15card && !strcmp (*serial, "D27600000000000000000000"))
    { /* This is a German card with a silly serial number.  Try to get
         the serial number from the EF(TokenInfo). We indicate such a
         serial number by the using the prefix: "FF0100". */
      const char *efser = card->p15card->serial_number;
      char *p;

      if (!efser)
        efser = "";

      xfree (*serial);
      *serial = NULL;
      p = xtrymalloc (strlen (efser) + 7);
      if (!p)
          rc = gpg_error (gpg_err_code_from_errno (errno));
      else
        {
          strcpy (p, "FF0100");
          strcpy (p+6, efser);
          *serial = p;
        }
    }
  else if (!rc && **serial == 'F' && (*serial)[1] == 'F')
    { /* The serial number starts with our special prefix.  This
         requires that we put our default prefix "FF0000" in front. */
      char *p = xtrymalloc (strlen (*serial) + 7);
      if (!p)
        {
          xfree (*serial);
          *serial = NULL;
          rc = gpg_error (gpg_err_code_from_errno (errno));
        }
      else
        {
          strcpy (p, "FF0000");
          strcpy (p+6, *serial);
          xfree (*serial);
          *serial = p;
        }
    }
  return rc;
#else
  return gpg_error (GPG_ERR_NOT_SUPPORTED);
#endif
}