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:
@@ -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 <npa-usage>`.
|
||||
|
||||
.. 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 <morgner@informatik.hu-berlin.de>
|
||||
|
||||
@@ -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
|
||||
=====
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
137
npa/src/example.c
Normal file
137
npa/src/example.c
Normal 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;
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
* npa. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "binutil.h"
|
||||
#include "config.h"
|
||||
|
||||
Reference in New Issue
Block a user