diff --git a/doc/tools/iasecc-tool.1.xml b/doc/tools/iasecc-tool.1.xml
new file mode 100644
index 00000000..ba0ac0ab
--- /dev/null
+++ b/doc/tools/iasecc-tool.1.xml
@@ -0,0 +1,81 @@
+
+
+
+ iasecc-tool
+ 1
+ OpenSC
+ OpenSC Tools
+ opensc
+
+
+
+ iasecc-tool
+ displays information about IAS/ECC card
+
+
+
+
+
+ iasecc-tool
+ OPTIONS
+
+
+
+
+ Description
+
+ The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards.
+
+
+
+
+ Options
+
+
+
+
+ number,
+
+ Specify the reader number number to use.
+ The default is reader 0.
+
+
+
+ ,
+
+ Get list of the on-card applications.
+
+
+
+ hex-aid,
+
+ Select hex-aid before processing.
+
+
+
+ sdo-type,
+
+ List SDOs of the given sdo-type,
+ present in default or selected application.
+
+
+
+ ,
+
+
+ Causes cardos-tool to be more verbose.
+ Specify this flag several times to enable debug output in the opensc library.
+
+
+
+ ,
+
+
+ Causes iasecc-tool to wait for the token
+ to be inserted into reader.
+
+
+
+
+
+
diff --git a/doc/tools/tools.xml b/doc/tools/tools.xml
index a109d368..e9fe9179 100644
--- a/doc/tools/tools.xml
+++ b/doc/tools/tools.xml
@@ -13,6 +13,7 @@
+
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 0a5131ff..783bb2a5 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -5,7 +5,7 @@ EXTRA_DIST = Makefile.mak
noinst_HEADERS = util.h
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \
- pkcs11-tool cardos-tool eidenv openpgp-tool
+ pkcs11-tool cardos-tool eidenv openpgp-tool iasecc-tool
if ENABLE_OPENSSL
bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool westcos-tool
endif
@@ -32,7 +32,7 @@ pkcs11_tool_LDADD = \
pkcs15_crypt_SOURCES = pkcs15-crypt.c util.c
pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS)
cryptoflex_tool_SOURCES = cryptoflex-tool.c util.c
-cryptoflex_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
+cryptoflex_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
pkcs15_init_SOURCES = pkcs15-init.c util.c
pkcs15_init_LDADD = $(OPTIONAL_OPENSSL_LIBS)
cardos_tool_SOURCES = cardos-tool.c util.c
@@ -44,6 +44,8 @@ westcos_tool_SOURCES = westcos-tool.c util.c
westcos_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
openpgp_tool_SOURCES = openpgp-tool.c util.c
openpgp_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
+iasecc_tool_SOURCES = iasecc-tool.c util.c
+iasecc_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
if WIN32
opensc_tool_SOURCES += $(top_builddir)/win32/versioninfo.rc
@@ -59,4 +61,5 @@ eidenv_SOURCES += $(top_builddir)/win32/versioninfo.rc
netkey_tool_SOURCES += $(top_builddir)/win32/versioninfo.rc
westcos_tool_SOURCES += $(top_builddir)/win32/versioninfo.rc
openpgp_tool_SOURCES += $(top_builddir)/win32/versioninfo.rc
+iasecc_tool_SOURCES += $(top_builddir)/win32/versioninfo.rc
endif
diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c
new file mode 100644
index 00000000..1e020e56
--- /dev/null
+++ b/src/tools/iasecc-tool.c
@@ -0,0 +1,300 @@
+/*
+ * iasecc-tool.c: Tool for accessing smart cards with libopensc
+ *
+ * Copyright (C) 2001 Juha Yrjölä
+ * Copyright (C) 2011 Viktor TARASOV
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include
+#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+#include
+#include
+#include
+#include
+
+#include "libopensc/opensc.h"
+#include "libopensc/cardctl.h"
+#include "libopensc/asn1.h"
+#include "libopensc/iasecc.h"
+#include "util.h"
+
+static const char *app_name = "iasecc-tool";
+
+static char * opt_bind_to_aid = NULL;
+static char * opt_reader = NULL;
+static char * opt_sdo_tag = 0;
+static int opt_wait = 0;
+static int verbose = 0;
+
+enum {
+ OPT_READER = 0x100,
+ OPT_BIND_TO_AID,
+ OPT_LIST_SDOS,
+ OPT_LIST_APPLICATIONS
+};
+
+static const struct option options[] = {
+ { "reader", required_argument, NULL, OPT_READER },
+ { "aid", required_argument, NULL, OPT_BIND_TO_AID },
+ { "list-applications", no_argument, NULL, OPT_LIST_APPLICATIONS },
+ { "list-sdos", required_argument, NULL, OPT_LIST_SDOS },
+ { "wait", no_argument, NULL, 'w' },
+ { "verbose", no_argument, NULL, 'v' },
+ { NULL, 0, NULL, 0 }
+};
+
+static const char *option_help[] = {
+ "Uses reader number ",
+ "Specify AID of the on-card PKCS#15 application to be binded to (in hexadecimal form)",
+ "List the on-card PKCS#15 applications",
+ "List the SDOs with the tag in the current ADF",
+ "Wait for card insertion",
+ "Verbose operation. Use several times to enable debug output.",
+ NULL
+};
+
+static int list_sdos(char *sdo_tag);
+
+static sc_context_t *ctx = NULL;
+static sc_card_t *card = NULL;
+static struct sc_pkcs15_card *p15card = NULL;
+
+static void
+_iasecc_print_tlv(char *label, int format_text, struct iasecc_extended_tlv *tlv)
+{
+ unsigned ii;
+
+ if (!tlv->value)
+ return;
+
+ printf("%s:\t", label);
+ for(ii=0; iisize; ii++) {
+ if (format_text) {
+ printf("%c", *(tlv->value + ii));
+ }
+ else {
+ if (ii) printf(":");
+ printf("%02X", *(tlv->value + ii));
+ }
+ }
+ printf("\n");
+
+}
+
+static void
+_iasecc_print_docp(struct iasecc_sdo_docp *docp)
+{
+ _iasecc_print_tlv("\tname:", 1, &docp->name);
+ _iasecc_print_tlv("\tcontact ACLs", 0, &docp->acls_contact);
+ _iasecc_print_tlv("\tnon repudiation", 0, &docp->non_repudiation);
+ _iasecc_print_tlv("\tsize", 0, &docp->size);
+ _iasecc_print_tlv("\ttries maximum", 0, &docp->tries_maximum);
+ _iasecc_print_tlv("\ttries remaining", 0, &docp->tries_remaining);
+ _iasecc_print_tlv("\tusage maximum", 0, &docp->usage_maximum);
+ _iasecc_print_tlv("\tusage remaining", 0, &docp->usage_remaining);
+}
+
+static void
+_iasecc_print_crt(struct sc_crt *crt)
+{
+ printf("\tCRT #%X:\tusage %02X; algo %02X; ref %02X:%02X:...\n",
+ crt->tag, crt->usage, crt->algo, crt->refs[0], crt->refs[1]);
+}
+
+static int list_sdos(char *sdo_tag)
+{
+ struct iasecc_sdo sdo;
+ struct iasecc_se_info se;
+ unsigned sdo_class = 0;
+ int rv, ii, jj;
+
+ if (!sdo_tag)
+ goto usage;
+
+ if (*sdo_tag == 'x' || *sdo_tag == 'X')
+ sdo_class = strtol(sdo_tag + 1, NULL, 16);
+ else if ((strlen(sdo_tag) > 2) && (*(sdo_tag + 1) == 'x' || *(sdo_tag + 1) == 'X'))
+ sdo_class = strtol(sdo_tag + 2, NULL, 16);
+ else
+ sdo_class = strtol(sdo_tag, NULL, 10);
+
+ sdo_class &= 0x7F;
+ if (sdo_class == IASECC_SDO_CLASS_SE) {
+ for (ii=1; ii<0x20; ii++) {
+ memset(&se, 0, sizeof(se));
+ se.reference = ii;
+
+ rv = sc_card_ctl(card, SC_CARDCTL_GET_SE_INFO, &se);
+ if (!rv) {
+ printf("Found SE #%X\n", se.reference);
+ _iasecc_print_docp(&se.docp);
+ for(jj=0; jj");
+ return -1;
+}
+
+static int list_apps(FILE *fout)
+{
+ unsigned j;
+ int i;
+
+ for (i=0; i < card->app_count; i++) {
+ struct sc_app_info *info = card->app[i];
+
+ fprintf(fout, "Application '%s':\n", info->label);
+ fprintf(fout, "\tAID: ");
+ for(j=0;jaid.len;j++)
+ fprintf(fout, "%02X", info->aid.value[j]);
+ fprintf(fout, "\n");
+
+ if (info->ddo.value && info->ddo.len) {
+ fprintf(fout, "\tDDO: ");
+ for(j=0;jddo.len;j++)
+ fprintf(fout, "%02X", info->ddo.value[j]);
+ fprintf(fout, "\n");
+ }
+
+ fprintf(fout, "\n");
+ }
+ return 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;
+}