From 7fd5d06b4de1bf2d8aa51a4117702f6ac5d5f46f Mon Sep 17 00:00:00 2001 From: frankmorgner Date: Wed, 26 Oct 2011 13:07:12 +0000 Subject: [PATCH] including a simple example program mainly for documentation git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@573 96b47cad-a561-4643-ad3b-153ac7d7599c --- doc/npaapi.rst | 37 ++---------- npa/README.dox | 2 + npa/src/Makefile.am | 6 +- npa/src/example.c | 137 ++++++++++++++++++++++++++++++++++++++++++++ npa/src/npa-tool.c | 8 +-- 5 files changed, 152 insertions(+), 38 deletions(-) create mode 100644 npa/src/example.c diff --git a/doc/npaapi.rst b/doc/npaapi.rst index 08cfc38..fd8d285 100644 --- a/doc/npaapi.rst +++ b/doc/npaapi.rst @@ -73,39 +73,10 @@ Defines Example ======= -The following example are fragments of the npa-tool, which uses libnpa to acces -the nPA with and without SM enabled. First set up the environment: +Note that in order to compile and execute this example you need to correctly +:ref:`set up your environment `. - .. literalinclude:: ../npa/src/npa-tool.c - :lines: 49-74,198-212 - -Connect to a reader and the nPA: - - .. literalinclude:: ../npa/src/npa-tool.c - :lines: 331-341 - -Now we try to change the PIN. Therefor we need to establish a SM channel with -PACE. You could set your PIN with `pin = "123456"` or just leave it out to be -asked for it. The same applies to the new PIN `newpin`. - - .. literalinclude:: ../npa/src/npa-tool.c - :lines: 484-501 - -Imagine you want to transmit additional APDUs in the established SM channel. -Declare the APDU to something like:: - - const unsigned char buf[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0x3F, 0x00}; - size_t apdulen = sizeof buf;` - sc_apdu_t apdu; - -Now parse and transmit the APDU with SM: - - .. literalinclude:: ../npa/src/npa-tool.c - :lines: 171-173,175-183,185 - -Free up memory and wipe it if necessary (e.g. for keys stored in :npa:`sm_ctx`) - - .. literalinclude:: ../npa/src/npa-tool.c - :lines: 563- +.. literalinclude:: ../npa/src/example.c + :lines: 20- .. @author Frank Morgner diff --git a/npa/README.dox b/npa/README.dox index 6de7928..08c5e48 100644 --- a/npa/README.dox +++ b/npa/README.dox @@ -43,6 +43,8 @@ against use something like the following command: :: OPENSSL_CFLAGS="-I/path/to/openssl-1.0.0d_with_openpace-0.6/include" \ OPENSSL_LIBS="-L/path/to/openssl-1.0.0d_with_openpace-0.6 -lcrypto" +.. _npa-usage: + ===== Usage ===== diff --git a/npa/src/Makefile.am b/npa/src/Makefile.am index c69dc18..c604207 100644 --- a/npa/src/Makefile.am +++ b/npa/src/Makefile.am @@ -10,8 +10,12 @@ npa_tool_SOURCES = npa-tool.c binutil.c npa_tool_LDADD = $(OPENSSL_LIBS) $(OPENSC_LIBS) libnpa.la npa_tool_CFLAGS = $(OPENSSL_CFLAGS) +example_SOURCES = example.c +example_LDADD = $(OPENSSL_LIBS) $(OPENSC_LIBS) libnpa.la +example_CFLAGS = $(OPENSSL_CFLAGS) -bin_PROGRAMS = npa-tool + +bin_PROGRAMS = npa-tool example lib_LTLIBRARIES = libnpa.la diff --git a/npa/src/example.c b/npa/src/example.c new file mode 100644 index 0000000..88cc906 --- /dev/null +++ b/npa/src/example.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 Frank Morgner + * + * This file is part of npa. + * + * npa is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * npa 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 General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * npa. If not, see . + */ + +/* This example shows how to use the library functions EstablishPACEChannel to + * get a secure channel to the nPA. We use the builtin function npa_change_pin + * to modify the PIN using the secure channel. Then we transmit an arbitrary + * APDU encrypted and authenticated to the card using sm_transmit_apdu. */ +#include +#include +#include +#include +#include + +static int reader_num = -1; + +static const char *newpin = NULL; +static const char *pin = NULL; + +const unsigned char apdubuf[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0x3F, 0x00}; + +int +main (int argc, char **argv) +{ + /* Set up the environment */ + int r; + + sc_context_t *ctx = NULL; + sc_card_t *card = NULL; + sc_reader_t *reader = NULL; + + sc_apdu_t apdu; + u8 buf[0xffff]; + + struct sm_ctx sctx; + struct establish_pace_channel_input pace_input; + struct establish_pace_channel_output pace_output; + + memset(&sctx, 0, sizeof sctx); + memset(&pace_input, 0, sizeof pace_input); + memset(&pace_output, 0, sizeof pace_output); + + + /* Connect to a reader and the nPA */ + r = initialize(reader_num, NULL, 0, &ctx, &reader); + if (r < 0) { + fprintf(stderr, "Can't initialize reader\n"); + exit(1); + } + + if (sc_connect_card(reader, &card) < 0) { + fprintf(stderr, "Could not connect to card\n"); + sc_release_context(ctx); + exit(1); + } + + + /* Now we try to change the PIN. Therefor we need to establish a SM channel + * with PACE. + * + * You could set your PIN with `pin = “123456”;` or just leave it at NULL + * to be asked for it. The same applies to the new PIN newpin. */ + pace_input.pin_id = PACE_PIN; + pace_input.pin = pin; + pace_input.pin_length = pin ? strlen(pin) : 0; + + r = EstablishPACEChannel(NULL, card, pace_input, &pace_output, + &sctx); + if (r < 0) + goto err; + printf("Established PACE channel with PIN.\n"); + + r = npa_change_pin(&sctx, card, newpin, newpin ? strlen(newpin) : 0); + if (r < 0) + goto err; + printf("Changed PIN.\n"); + + + /* Now we want to transmit additional APDUs in the established SM channel. + * + * Here we are parsing the raw apdu buffer apdubuf to be transformed into + * an sc_apdu_t. Alternatively you could also set CLA, INS, P1, P2, ... by + * hand in the sc_apdu_t object. */ + r = sc_bytes2apdu(card->ctx, apdubuf, sizeof apdubuf, &apdu); + if (r < 0) { + bin_log(ctx, SC_LOG_DEBUG_NORMAL, "Invalid C-APDU", apdubuf, sizeof apdubuf); + goto err; + } + + /* write the response data to buf */ + apdu.resp = buf; + apdu.resplen = sizeof buf; + + /* Transmit the APDU with SM */ + r = sm_transmit_apdu(&sctx, card, &apdu); + if (r < 0) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Could not send C-APDU: %s", sc_strerror(r)); + goto err; + } + + +err: + /* Free up memory and wipe it if necessary (e.g. for keys stored in sm_ctx) */ + sm_ctx_clear_free(&sctx); + if (pace_output.ef_cardaccess) + free(pace_output.ef_cardaccess); + if (pace_output.recent_car) + free(pace_output.recent_car); + if (pace_output.previous_car) + free(pace_output.previous_car); + if (pace_output.id_icc) + free(pace_output.id_icc); + if (pace_output.id_pcd) + free(pace_output.id_pcd); + + sc_reset(card, 1); + sc_disconnect_card(card); + sc_release_context(ctx); + + return -r; +} diff --git a/npa/src/npa-tool.c b/npa/src/npa-tool.c index 2e8a501..40fb30a 100644 --- a/npa/src/npa-tool.c +++ b/npa/src/npa-tool.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2010 Frank Morgner * - * This file is part of ccid. + * This file is part of npa. * - * ccid is free software: you can redistribute it and/or modify it under the + * npa is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * - * ccid is distributed in the hope that it will be useful, but WITHOUT ANY + * npa 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with - * ccid. If not, see . + * npa. If not, see . */ #include "binutil.h" #include "config.h"