eidenv - small utility for Estonian ID card *nix only)
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2224 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
e336488431
commit
8baf433e36
|
@ -11,7 +11,7 @@ PROGRAMS_SSL = cryptoflex-tool pkcs15-init
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \
|
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \
|
||||||
pkcs11-tool cardos-info \
|
pkcs11-tool cardos-info eidenv \
|
||||||
$(PROGRAMS_SSL)
|
$(PROGRAMS_SSL)
|
||||||
|
|
||||||
opensc_tool_SOURCES = opensc-tool.c util.c
|
opensc_tool_SOURCES = opensc-tool.c util.c
|
||||||
|
@ -30,5 +30,6 @@ pkcs15_init_SOURCES = pkcs15-init.c util.c
|
||||||
pkcs15_init_LDADD = @GETOPTSRC@ @LIBCRYPTO@ ../pkcs15init/libpkcs15init.la
|
pkcs15_init_LDADD = @GETOPTSRC@ @LIBCRYPTO@ ../pkcs15init/libpkcs15init.la
|
||||||
cardos_info_SOURCES = cardos-info.c util.c
|
cardos_info_SOURCES = cardos-info.c util.c
|
||||||
cardos_info_LDADD = @GETOPTSRC@
|
cardos_info_LDADD = @GETOPTSRC@
|
||||||
|
eidenv_SOURCES = eidenv.c
|
||||||
|
|
||||||
noinst_HEADERS = util.h
|
noinst_HEADERS = util.h
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
/* eidenv.c - EstEID utility
|
||||||
|
* Copyright (C) 2004 martin paljak <martin@paljak.pri.ee>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <opensc/opensc.h>
|
||||||
|
|
||||||
|
#include "../libopensc/cards.h"
|
||||||
|
#include "../libopensc/esteid.h"
|
||||||
|
|
||||||
|
static int reader_num = 0;
|
||||||
|
static int stats = 0;
|
||||||
|
static char *exec_program = NULL;
|
||||||
|
static int exit_status = EXIT_FAILURE;
|
||||||
|
|
||||||
|
|
||||||
|
static struct option const long_options[] = {
|
||||||
|
{"reader", required_argument, 0, 'r'},
|
||||||
|
{"print", no_argument, 0, 'n'},
|
||||||
|
{"exec", required_argument, 0, 'x'},
|
||||||
|
{"stats", no_argument, 0, 't'},
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"version", no_argument, 0, 'V'},
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
const char *env_name;
|
||||||
|
int recno;
|
||||||
|
} esteid_data[] = {
|
||||||
|
{"Surname", "ESTEID_SURNAME", 1},
|
||||||
|
{"Given names 1", "ESTEID_GIVEN_NAMES1", 2},
|
||||||
|
{"Given names 2", "ESTEID_GIVEN_NAMES2", 3},
|
||||||
|
{"Sex", "ESTEID_SEX", 4},
|
||||||
|
{"Citizenship", "ESTEID_CITIZENSHIP", 5},
|
||||||
|
{"Date of birth", "ESTEID_DATE_OF_BIRTH", 6},
|
||||||
|
{"Personal ID code", "ESTEID_PERSONAL_ID", 7},
|
||||||
|
{"Document number", "ESTEID_DOCUMENT_NR", 8},
|
||||||
|
{"Expiry date", "ESTEID_EXPIRY_DATE", 9},
|
||||||
|
{"Place of birth", "ESTEID_PLACE_OF_BIRTH", 10},
|
||||||
|
{"Issuing date", "ESTEID_ISSUING_DATE", 11},
|
||||||
|
{"Permit type", "ESTEID_PERMIT_TYPE", 12},
|
||||||
|
{"Remark 1", "ESTEID_REMARK1", 13},
|
||||||
|
{"Remark 2", "ESTEID_REMARK2", 14},
|
||||||
|
{"Remark 3", "ESTEID_REMARK3", 15},
|
||||||
|
{"Remark 4", "ESTEID_REMARK4", 16},
|
||||||
|
{NULL, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void show_version(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"eidenv - EstEID utility version " VERSION "\n"
|
||||||
|
"\n"
|
||||||
|
"Copyright (c) 2004 martin paljak <martin@paljak.pri.ee>\n"
|
||||||
|
"Licensed under GPL v2\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_help(void)
|
||||||
|
{
|
||||||
|
show_version();
|
||||||
|
fprintf(stderr,
|
||||||
|
"-h --help - show this text and exit\n"
|
||||||
|
"-v --version - show version and exit\n"
|
||||||
|
"-r --reader - the reader to use\n"
|
||||||
|
"-n --print - print the datafile\n"
|
||||||
|
"-t --stats - show usage counts of keys\n"
|
||||||
|
"-x --exec - execute a program with data in env vars.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void decode_options(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv,"ptr:x:hV", long_options, (int *) 0)) != EOF) {
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'r':
|
||||||
|
reader_num = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
stats = !stats;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
if (exec_program)
|
||||||
|
free(exec_program);
|
||||||
|
exec_program = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
show_help();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
show_version();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
show_help();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = NULL;
|
||||||
|
sc_reader_t *reader = NULL;
|
||||||
|
struct sc_card *card = NULL;
|
||||||
|
struct sc_path path;
|
||||||
|
int r, i;
|
||||||
|
char buff[512];
|
||||||
|
|
||||||
|
/* get options */
|
||||||
|
decode_options(argc, argv);
|
||||||
|
|
||||||
|
/* connect to the card */
|
||||||
|
r = sc_establish_context(&ctx, "eidenv");
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Failed to establish context: %s\n",
|
||||||
|
sc_strerror(r));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (reader_num > ctx->reader_count) {
|
||||||
|
fprintf(stderr, "Illegal reader number. Only %d reader(s) configured.\n", ctx->reader_count);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
reader = ctx->reader[reader_num];
|
||||||
|
|
||||||
|
r = sc_connect_card(reader, 0, &card);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sc_lock(card);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Failed to lock card: %s\n", sc_strerror(r));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure it is an EstEID card */
|
||||||
|
if (card->type != SC_CARD_TYPE_MCRD_ESTEID) {
|
||||||
|
fprintf(stderr, "Not an EstEID card!\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats) {
|
||||||
|
int key_used[4];
|
||||||
|
sc_format_path("3f00eeee0013", &path);
|
||||||
|
r = sc_select_file(card, &path, NULL);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Failed to select key counters: %s\n", sc_strerror(r));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print the counters */
|
||||||
|
for (i = 1; i <= 4; i++) {
|
||||||
|
r = sc_read_record(card, i, buff, 128, SC_RECORD_BY_REC_NR);
|
||||||
|
key_used[i - 1] = 0xffffff - ((unsigned char) buff[0xc] * 65536
|
||||||
|
+ (unsigned char) buff[0xd] * 256
|
||||||
|
+ (unsigned char) buff[0xe]);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
printf("Key generation #%d usage:\n\tsign: %d\n\tauth: %d\n",
|
||||||
|
i, key_used[i], key_used[i + 2]);
|
||||||
|
}
|
||||||
|
exit_status = EXIT_SUCCESS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Or just read the datafile */
|
||||||
|
sc_format_path("3f00eeee5044", &path);
|
||||||
|
r = sc_select_file(card, &path, NULL);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Failed to select DF: %s\n", sc_strerror(r));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; esteid_data[i].recno != 0; i++) {
|
||||||
|
r = sc_read_record(card, esteid_data[i].recno, buff, 50, SC_RECORD_BY_REC_NR);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf (stderr, "Failed to read record %d from card: %s\n",
|
||||||
|
esteid_data[i].recno, sc_strerror (r));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
buff[r] = '\0';
|
||||||
|
if (exec_program) {
|
||||||
|
setenv(esteid_data[i].env_name, buff, 1);
|
||||||
|
} else {
|
||||||
|
printf("%s: %s\n", esteid_data[i].name, buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_status = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
if (exec_program) {
|
||||||
|
char *largv[2];
|
||||||
|
sc_unlock(card);
|
||||||
|
sc_disconnect_card(card, 0);
|
||||||
|
sc_release_context(ctx);
|
||||||
|
largv[0] = exec_program;
|
||||||
|
largv[1] = NULL;
|
||||||
|
execv(exec_program, largv);
|
||||||
|
/* we should not get here */
|
||||||
|
perror("execv()");
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
sc_unlock(card);
|
||||||
|
sc_disconnect_card(card, 0);
|
||||||
|
sc_release_context(ctx);
|
||||||
|
exit(exit_status);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue