including a simple example program mainly for documentation

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@573 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2011-10-26 13:07:12 +00:00
parent 9c3b56708b
commit 7fd5d06b4d
5 changed files with 152 additions and 38 deletions

View File

@@ -73,39 +73,10 @@ Defines
Example Example
======= =======
The following example are fragments of the npa-tool, which uses libnpa to acces Note that in order to compile and execute this example you need to correctly
the nPA with and without SM enabled. First set up the environment: :ref:`set up your environment <npa-usage>`.
.. literalinclude:: ../npa/src/npa-tool.c .. literalinclude:: ../npa/src/example.c
:lines: 49-74,198-212 :lines: 20-
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-
.. @author Frank Morgner <morgner@informatik.hu-berlin.de> .. @author Frank Morgner <morgner@informatik.hu-berlin.de>

View File

@@ -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_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" OPENSSL_LIBS="-L/path/to/openssl-1.0.0d_with_openpace-0.6 -lcrypto"
.. _npa-usage:
===== =====
Usage Usage
===== =====

View File

@@ -10,8 +10,12 @@ npa_tool_SOURCES = npa-tool.c binutil.c
npa_tool_LDADD = $(OPENSSL_LIBS) $(OPENSC_LIBS) libnpa.la npa_tool_LDADD = $(OPENSSL_LIBS) $(OPENSC_LIBS) libnpa.la
npa_tool_CFLAGS = $(OPENSSL_CFLAGS) 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 lib_LTLIBRARIES = libnpa.la

137
npa/src/example.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
/* 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 <libopensc/log.h>
#include <npa/npa.h>
#include <npa/scutil.h>
#include <openssl/pace.h>
#include <string.h>
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;
}

View File

@@ -1,20 +1,20 @@
/* /*
* Copyright (C) 2010 Frank Morgner * 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 * 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 * Foundation, either version 3 of the License, or (at your option) any later
* version. * 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 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* ccid. If not, see <http://www.gnu.org/licenses/>. * npa. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "binutil.h" #include "binutil.h"
#include "config.h" #include "config.h"