- added openssl debug code to ccid emulator

- fixed some bugs due to changes in recent opensc version
- added support for changing pin via standard leser


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@511 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2011-08-30 15:55:40 +00:00
parent 9aa24f9e4a
commit 495022b38a
10 changed files with 124 additions and 34 deletions

View File

@@ -99,6 +99,7 @@ LIBS="$saved_LIBS"
AM_CONDITIONAL(WITH_PACE, test "${enable_pace}" != "no")
AM_COND_IF(WITH_PACE, [AC_DEFINE(WITH_PACE, 1, [enable PACE support])])
AM_COND_IF(WITH_PACE, [AC_DEFINE(BUERGERCLIENT_WORKAROUND, 1, [Always get EF.CardAccess, when connecting to a smart card. This is a workaround for the recent Buergerclient])])
#AM_COND_IF(WITH_PACE, [AC_DEFINE(MODIFY_PIN, 1, [Change the PIN after authentication.])])
# --disable-cats

View File

@@ -2,7 +2,7 @@ EXTRA_DIST = $(shell find $(top_srcdir)/src/opensc -path '*/.svn' -prune -o -typ
AM_CPPFLAGS = -I$(top_srcdir)/src/opensc/src
ccid_emulator_SOURCES = ccid.c usbstring.c usb.c binutil.c
ccid_emulator_SOURCES = ccid.c usbstring.c usb.c binutil.c sslutil.c
ccid_emulator_LDADD = $(OPENSSL_LIBS) $(PTHREAD_LIBS)
ccid_emulator_CFLAGS = $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS)
@@ -18,6 +18,7 @@ noinst_HEADERS = \
pcscutil.h \
scutil.h \
ccid.h \
sslutil.h \
usbstring.h
if WITH_CCID

View File

@@ -186,7 +186,7 @@ main(int argc, char *argv[])
SCARDHANDLE hCard;
LPSTR readers = NULL;
BYTE sendbuf[16], recvbuf[1024];
DWORD ctl, recvlen, protocol;
DWORD pace_ctl, modify_ctl, recvlen, protocol;
time_t t_start, t_end;
size_t l, pinlen = 0;
char *pin = NULL;
@@ -275,25 +275,28 @@ main(int argc, char *argv[])
goto err;
}
ctl = 0;
pace_ctl = 0;
for (i = 0; i <= recvlen-PCSC_TLV_ELEMENT_SIZE; i += PCSC_TLV_ELEMENT_SIZE) {
if (recvbuf[i] == FEATURE_EXECUTE_PACE) {
memcpy(&ctl, recvbuf+i+2, 4);
break;
memcpy(&pace_ctl, recvbuf+i+2, 4);
}
if (recvbuf[i] == FEATURE_MODIFY_PIN_DIRECT) {
memcpy(&modify_ctl, recvbuf+i+2, 4);
}
}
if (0 == ctl) {
if (0 == pace_ctl) {
printf("Reader does not support PACE\n");
goto err;
}
/* convert to host byte order to use for SCardControl */
ctl = ntohl(ctl);
pace_ctl = ntohl(pace_ctl);
modify_ctl = ntohl(modify_ctl);
recvlen = sizeof(recvbuf);
sendbuf[0] = 0x01; /* idxFunction = GetReadersPACECapabilities */
sendbuf[1] = 0x00; /* lengthInputData */
sendbuf[2] = 0x00; /* lengthInputData */
r = SCardControl(hCard, ctl,
r = SCardControl(hCard, pace_ctl,
sendbuf, 3,
recvbuf, sizeof(recvbuf), &recvlen);
if (r != SCARD_S_SUCCESS) {
@@ -314,7 +317,7 @@ main(int argc, char *argv[])
sendbuf[6+pinlen] = 0x00; /* length certificate description */
sendbuf[7+pinlen] = 0x00; /* length certificate description */
t_start = time(NULL);
r = SCardControl(hCard, ctl,
r = SCardControl(hCard, pace_ctl,
sendbuf, 8+pinlen,
recvbuf, sizeof(recvbuf), &recvlen);
t_end = time(NULL);
@@ -391,6 +394,20 @@ main(int argc, char *argv[])
}
#endif
#ifdef MODIFY_PIN
if (0 == modify_ctl) {
printf("Reader does not support MODIFY_PIN_DIRECT\n");
goto err;
}
BYTE = bufs2[] = {0x15, 0x05, 0x82, 0x08, 0x00, 0x00, 0x00, 0x06, 0x06,
0x01, 0x02, 0x02, 0x09, 0x04, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x00, 0x2C, 0x02, 0x03, 0x00};
recvlen = sizeof(recvbuf);
rv = SCardControl(hCard, modify_ioctl, bufs2,
sizeof bufs2, recvbuf, sizeof recvbuf, &recvlen);
#endif
err:
stringify_error(r);
pcsc_disconnect(hContext, hCard, readers);

View File

@@ -27,6 +27,7 @@
#include <string.h>
#include "ccid.h"
#include "sslutil.h"
#include "config.h"
#ifdef WITH_PACE
@@ -48,12 +49,14 @@ static sc_context_t *ctx = NULL;
static sc_card_t *card = NULL;
static sc_reader_t *reader = NULL;
unsigned int skipfirst = 0;
struct ccid_class_descriptor
ccid_desc = {
.bLength = sizeof ccid_desc,
.bDescriptorType = 0x21,
.bcdCCID = __constant_cpu_to_le16(0x0110),
.bMaxSlotIndex = 1,
.bMaxSlotIndex = 0,
.bVoltageSupport = 0x01, // 5.0V
.dwProtocols = __constant_cpu_to_le32(
0x01| // T=0
@@ -242,7 +245,12 @@ static __u8 get_bStatus(int sc_result)
int flags;
__u8 bstatus = 0;
flags = detect_card_presence();
if (skipfirst > 10)
flags = detect_card_presence();
else {
skipfirst += 1;
flags = SC_SUCCESS;
}
if (flags >= 0) {
if (sc_result < 0) {
@@ -435,8 +443,8 @@ perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *
|| request->abRFU2 != 0)
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed PC_to_RDR_IccPowerOff");
sc_reset(card, 1);
sc_result = sc_disconnect_card(card);
//sc_reset(card, 1);
//sc_result = sc_disconnect_card(card);
return get_RDR_to_PC_SlotStatus(request->bSeq, sc_result,
out, outlen, NULL, 0);
@@ -689,8 +697,7 @@ write_pin_length(sc_apdu_t *apdu, const struct sc_pin_cmd_pin *pin,
if (!apdu || !apdu->data || !pin || apdu->datalen <= pin->length_offset ||
!sc_result) {
if (sc_result)
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
return 0;
}
@@ -1112,6 +1119,7 @@ static int
perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outlen)
{
int sc_result;
u8 curr_pin_data[0xff], new_pin_data[0xff];
struct sc_pin_cmd_pin curr_pin, new_pin;
sc_apdu_t apdu;
const PC_to_RDR_Secure_t *request = (PC_to_RDR_Secure_t *) in;
@@ -1123,6 +1131,12 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
memset(&curr_pin, 0, sizeof(curr_pin));
memset(&new_pin, 0, sizeof(new_pin));
memset(curr_pin_data, 0, sizeof curr_pin_data);
memset(new_pin_data, 0, sizeof new_pin_data);
curr_pin.data = curr_pin_data;
curr_pin.len = sizeof curr_pin_data;
new_pin.data = new_pin_data;
new_pin.len = sizeof new_pin_data;
if (!in || !out || !outlen)
@@ -1225,6 +1239,12 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
new_pin.min_length = curr_pin.min_length = wPINMaxExtraDigit >> 8;
new_pin.min_length = curr_pin.max_length = wPINMaxExtraDigit & 0x00ff;
if (new_pin.min_length > new_pin.max_length) {
/* If maximum length is smaller than minimum length, suppose minimum
* length defines the exact length of the pin. */
curr_pin.max_length = curr_pin.min_length;
new_pin.max_length = new_pin.min_length;
}
uint8_t system_units = bmFormatString & CCID_PIN_UNITS_BYTES;
uint8_t pin_offset = (bmFormatString >> 3) & 0xf;
uint8_t length_offset = bmPINLengthFormat & 0xf;
@@ -1259,6 +1279,7 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
0)) {
sc_result = SC_ERROR_INTERNAL;
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not read PIN.\n");
ssl_error(ctx);
goto err;
}
} else {
@@ -1270,6 +1291,7 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
0)) {
sc_result = SC_ERROR_INTERNAL;
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not read current PIN.\n");
ssl_error(ctx);
goto err;
}
}
@@ -1280,6 +1302,10 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
modify->bConfirmPIN & CCID_PIN_CONFIRM_NEW)) {
sc_result = SC_ERROR_INTERNAL;
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n");
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "min %d max %d confirm %d.\n",
new_pin.min_length, new_pin.max_length, modify->bConfirmPIN
& CCID_PIN_CONFIRM_NEW);
ssl_error(ctx);
goto err;
}
}
@@ -1321,14 +1347,8 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
sc_mem_clear((u8 *) apdu.data, apdu.datalen);
err:
if (curr_pin.data) {
sc_mem_clear((u8 *) curr_pin.data, curr_pin.len);
free((u8 *) curr_pin.data);
}
if (new_pin.data) {
sc_mem_clear((u8 *) new_pin.data, new_pin.len);
free((u8 *) new_pin.data);
}
sc_mem_clear((u8 *) curr_pin.data, curr_pin.len);
sc_mem_clear((u8 *) new_pin.data, new_pin.len);
sc_result = get_RDR_to_PC_DataBlock(request->bSeq, sc_result, out,
outlen, abDataOut, abDataOutLen);

1
ccid/src/sslutil.c Symbolic link
View File

@@ -0,0 +1 @@
../../npa/src/sslutil.c

1
ccid/src/sslutil.h Symbolic link
View File

@@ -0,0 +1 @@
../../npa/src/sslutil.h

View File

@@ -2,7 +2,7 @@ EXTRA_DIST = $(shell find $(top_srcdir)/src/opensc -path '*/.svn' -prune -o -typ
AM_CPPFLAGS = -I$(top_srcdir)/src/npa -I$(top_srcdir)/src/opensc/src
libnpa_la_SOURCES = sm.c scutil.c npa.c
libnpa_la_SOURCES = sm.c scutil.c npa.c sslutil.c
libnpa_la_LIBADD = $(OPENSSL_LIBS) $(OPENSC_LIBS)
libnpa_la_CFLAGS = $(OPENSSL_CFLAGS)
@@ -16,6 +16,7 @@ bin_PROGRAMS = npa-tool
lib_LTLIBRARIES = libnpa.la
noinst_HEADERS = \
sslutil.h \
binutil.h
nobase_include_HEADERS = \

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Frank Morgner
* Copyright (C) 2011 Frank Morgner
*
* This file is part of ccid.
*
@@ -19,6 +19,7 @@
#include "npa.h"
#include "sm.h"
#include "scutil.h"
#include "sslutil.h"
#include <libopensc/asn1.h>
#include <libopensc/log.h>
#include <libopensc/opensc.h>
@@ -906,15 +907,6 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id
return r;
}
void ssl_error(sc_context_t *ctx) {
unsigned long r;
ERR_load_crypto_strings();
for (r = ERR_get_error(); r; r = ERR_get_error()) {
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, ERR_error_string(r, NULL));
}
ERR_free_strings();
}
int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
struct establish_pace_channel_input pace_input,
struct establish_pace_channel_output *pace_output,

30
npa/src/sslutil.c Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2011 Frank Morgner
*
* This file is part of ccid.
*
* ccid 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
* 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/>.
*/
#include "sslutil.h"
#include <openssl/err.h>
#include <libopensc/log.h>
void ssl_error(sc_context_t *ctx) {
unsigned long r;
ERR_load_crypto_strings();
for (r = ERR_get_error(); r; r = ERR_get_error()) {
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, ERR_error_string(r, NULL));
}
ERR_free_strings();
}

26
npa/src/sslutil.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2011 Frank Morgner
*
* This file is part of ccid.
*
* ccid 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
* 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/>.
*/
#ifndef _CCID_SSLUTIL_H
#define _CCID_SSLUTIL_H
#include <libopensc/opensc.h>
void ssl_error(sc_context_t *ctx);
#endif